0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/interrupt.h>
0015 #include <linux/module.h>
0016 #include <linux/parport.h>
0017 #include <linux/parport_pc.h>
0018 #include <linux/pci.h>
0019 #include <linux/slab.h>
0020 #include <linux/types.h>
0021
0022 #include <linux/8250_pci.h>
0023
0024 enum parport_pc_pci_cards {
0025 titan_110l = 0,
0026 titan_210l,
0027 netmos_9xx5_combo,
0028 netmos_9855,
0029 netmos_9855_2p,
0030 netmos_9900,
0031 netmos_9900_2p,
0032 netmos_99xx_1p,
0033 avlab_1s1p,
0034 avlab_1s2p,
0035 avlab_2s1p,
0036 siig_1s1p_10x,
0037 siig_2s1p_10x,
0038 siig_2p1s_20x,
0039 siig_1s1p_20x,
0040 siig_2s1p_20x,
0041 timedia_4078a,
0042 timedia_4079h,
0043 timedia_4085h,
0044 timedia_4088a,
0045 timedia_4089a,
0046 timedia_4095a,
0047 timedia_4096a,
0048 timedia_4078u,
0049 timedia_4079a,
0050 timedia_4085u,
0051 timedia_4079r,
0052 timedia_4079s,
0053 timedia_4079d,
0054 timedia_4079e,
0055 timedia_4079f,
0056 timedia_9079a,
0057 timedia_9079b,
0058 timedia_9079c,
0059 wch_ch353_1s1p,
0060 wch_ch353_2s1p,
0061 wch_ch382_0s1p,
0062 wch_ch382_2s1p,
0063 brainboxes_5s1p,
0064 sunix_4008a,
0065 sunix_5069a,
0066 sunix_5079a,
0067 sunix_5099a,
0068 };
0069
0070
0071 struct parport_pc_pci {
0072 int numports;
0073 struct {
0074
0075 int lo;
0076 int hi;
0077
0078 } addr[4];
0079
0080
0081
0082
0083 int (*preinit_hook) (struct pci_dev *pdev, struct parport_pc_pci *card,
0084 int autoirq, int autodma);
0085
0086
0087
0088 void (*postinit_hook) (struct pci_dev *pdev,
0089 struct parport_pc_pci *card, int failed);
0090 };
0091
0092 static int netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par,
0093 int autoirq, int autodma)
0094 {
0095
0096 if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
0097 dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
0098 dev->subsystem_device == 0x0299)
0099 return -ENODEV;
0100
0101 if (dev->device == PCI_DEVICE_ID_NETMOS_9912) {
0102 par->numports = 1;
0103 } else {
0104
0105
0106
0107
0108
0109 par->numports = (dev->subsystem_device & 0xf0) >> 4;
0110 if (par->numports > ARRAY_SIZE(par->addr))
0111 par->numports = ARRAY_SIZE(par->addr);
0112 }
0113
0114 return 0;
0115 }
0116
0117 static struct parport_pc_pci cards[] = {
0118 { 1, { { 3, -1 }, } },
0119 { 1, { { 3, -1 }, } },
0120 { 1, { { 2, -1 }, }, netmos_parallel_init },
0121 { 1, { { 0, -1 }, }, netmos_parallel_init },
0122 { 2, { { 0, -1 }, { 2, -1 }, } },
0123 {1, { { 3, 4 }, }, netmos_parallel_init },
0124 {2, { { 0, 1 }, { 3, 4 }, } },
0125 {1, { { 0, 1 }, } },
0126 { 1, { { 1, 2}, } },
0127 { 2, { { 1, 2}, { 3, 4 },} },
0128 { 1, { { 2, 3}, } },
0129 { 1, { { 3, 4 }, } },
0130 { 1, { { 4, 5 }, } },
0131 { 2, { { 1, 2 }, { 3, 4 }, } },
0132 { 1, { { 1, 2 }, } },
0133 { 1, { { 2, 3 }, } },
0134 { 1, { { 2, -1 }, } },
0135 { 1, { { 2, 3 }, } },
0136 { 2, { { 2, -1 }, { 4, -1 }, } },
0137 { 2, { { 2, 3 }, { 4, 5 }, } },
0138 { 2, { { 2, 3 }, { 4, 5 }, } },
0139 { 2, { { 2, 3 }, { 4, 5 }, } },
0140 { 2, { { 2, 3 }, { 4, 5 }, } },
0141 { 1, { { 2, -1 }, } },
0142 { 1, { { 2, 3 }, } },
0143 { 2, { { 2, -1 }, { 4, -1 }, } },
0144 { 1, { { 2, 3 }, } },
0145 { 1, { { 2, 3 }, } },
0146 { 1, { { 2, 3 }, } },
0147 { 1, { { 2, 3 }, } },
0148 { 1, { { 2, 3 }, } },
0149 { 1, { { 2, 3 }, } },
0150 { 1, { { 2, 3 }, } },
0151 { 1, { { 2, 3 }, } },
0152 { 1, { { 1, -1}, } },
0153 { 1, { { 2, -1}, } },
0154 { 1, { { 2, -1}, } },
0155 { 1, { { 2, -1}, } },
0156 { 1, { { 3, -1 }, } },
0157 { 1, { { 1, 2 }, } },
0158 { 1, { { 1, 2 }, } },
0159 { 1, { { 1, 2 }, } },
0160 { 1, { { 1, 2 }, } },
0161 };
0162
0163 static struct pci_device_id parport_serial_pci_tbl[] = {
0164
0165 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L,
0166 PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l },
0167 { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L,
0168 PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l },
0169 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735,
0170 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
0171 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9745,
0172 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
0173 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
0174 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
0175 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
0176 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
0177 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
0178 0x1000, 0x0020, 0, 0, netmos_9855_2p },
0179 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
0180 0x1000, 0x0022, 0, 0, netmos_9855_2p },
0181 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
0182 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
0183 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
0184 0xA000, 0x3011, 0, 0, netmos_9900 },
0185 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
0186 0xA000, 0x3012, 0, 0, netmos_9900 },
0187 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
0188 0xA000, 0x3020, 0, 0, netmos_9900_2p },
0189 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
0190 0xA000, 0x2000, 0, 0, netmos_99xx_1p },
0191
0192 { PCI_VENDOR_ID_AFAVLAB, 0x2110,
0193 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
0194 { PCI_VENDOR_ID_AFAVLAB, 0x2111,
0195 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
0196 { PCI_VENDOR_ID_AFAVLAB, 0x2112,
0197 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
0198 { PCI_VENDOR_ID_AFAVLAB, 0x2140,
0199 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
0200 { PCI_VENDOR_ID_AFAVLAB, 0x2141,
0201 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
0202 { PCI_VENDOR_ID_AFAVLAB, 0x2142,
0203 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
0204 { PCI_VENDOR_ID_AFAVLAB, 0x2160,
0205 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
0206 { PCI_VENDOR_ID_AFAVLAB, 0x2161,
0207 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
0208 { PCI_VENDOR_ID_AFAVLAB, 0x2162,
0209 PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
0210 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
0211 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
0212 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
0213 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
0214 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
0215 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
0216 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
0217 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
0218 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
0219 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
0220 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
0221 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
0222 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
0223 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
0224 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
0225 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
0226 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
0227 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
0228 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
0229 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
0230 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
0231 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
0232 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
0233 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
0234 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
0235 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
0236 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
0237 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
0238 { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
0239 PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
0240
0241 { 0x1409, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a },
0242 { 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h },
0243 { 0x1409, 0x7168, 0x1409, 0x4085, 0, 0, timedia_4085h },
0244 { 0x1409, 0x7168, 0x1409, 0x4088, 0, 0, timedia_4088a },
0245 { 0x1409, 0x7168, 0x1409, 0x4089, 0, 0, timedia_4089a },
0246 { 0x1409, 0x7168, 0x1409, 0x4095, 0, 0, timedia_4095a },
0247 { 0x1409, 0x7168, 0x1409, 0x4096, 0, 0, timedia_4096a },
0248 { 0x1409, 0x7168, 0x1409, 0x5078, 0, 0, timedia_4078u },
0249 { 0x1409, 0x7168, 0x1409, 0x5079, 0, 0, timedia_4079a },
0250 { 0x1409, 0x7168, 0x1409, 0x5085, 0, 0, timedia_4085u },
0251 { 0x1409, 0x7168, 0x1409, 0x6079, 0, 0, timedia_4079r },
0252 { 0x1409, 0x7168, 0x1409, 0x7079, 0, 0, timedia_4079s },
0253 { 0x1409, 0x7168, 0x1409, 0x8079, 0, 0, timedia_4079d },
0254 { 0x1409, 0x7168, 0x1409, 0x9079, 0, 0, timedia_4079e },
0255 { 0x1409, 0x7168, 0x1409, 0xa079, 0, 0, timedia_4079f },
0256 { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a },
0257 { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b },
0258 { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c },
0259
0260
0261 { 0x4348, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, wch_ch353_1s1p},
0262 { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p},
0263 { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382_0s1p},
0264 { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p},
0265
0266
0267 { PCI_VENDOR_ID_INTASHIELD, 0x4100,
0268 PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_5s1p },
0269
0270
0271 { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
0272 0x0100, 0, 0, sunix_4008a },
0273 { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
0274 0x0101, 0, 0, sunix_5069a },
0275 { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
0276 0x0102, 0, 0, sunix_5079a },
0277 { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
0278 0x0104, 0, 0, sunix_5099a },
0279
0280 { 0, }
0281 };
0282 MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
0283
0284
0285
0286
0287
0288
0289
0290
0291 static struct pciserial_board pci_parport_serial_boards[] = {
0292 [titan_110l] = {
0293 .flags = FL_BASE1 | FL_BASE_BARS,
0294 .num_ports = 1,
0295 .base_baud = 921600,
0296 .uart_offset = 8,
0297 },
0298 [titan_210l] = {
0299 .flags = FL_BASE1 | FL_BASE_BARS,
0300 .num_ports = 2,
0301 .base_baud = 921600,
0302 .uart_offset = 8,
0303 },
0304 [netmos_9xx5_combo] = {
0305 .flags = FL_BASE0 | FL_BASE_BARS,
0306 .num_ports = 1,
0307 .base_baud = 115200,
0308 .uart_offset = 8,
0309 },
0310 [netmos_9855] = {
0311 .flags = FL_BASE2 | FL_BASE_BARS,
0312 .num_ports = 1,
0313 .base_baud = 115200,
0314 .uart_offset = 8,
0315 },
0316 [netmos_9855_2p] = {
0317 .flags = FL_BASE4 | FL_BASE_BARS,
0318 .num_ports = 1,
0319 .base_baud = 115200,
0320 .uart_offset = 8,
0321 },
0322 [netmos_9900] = {
0323 .flags = FL_BASE0 | FL_BASE_BARS,
0324 .num_ports = 1,
0325 .base_baud = 115200,
0326 .uart_offset = 8,
0327 },
0328 [netmos_9900_2p] = {
0329 .flags = FL_BASE0,
0330 .num_ports = 0,
0331 .base_baud = 115200,
0332 .uart_offset = 8,
0333 },
0334 [netmos_99xx_1p] = {
0335 .flags = FL_BASE0,
0336 .num_ports = 0,
0337 .base_baud = 115200,
0338 .uart_offset = 8,
0339 },
0340 [avlab_1s1p] = {
0341 .flags = FL_BASE0 | FL_BASE_BARS,
0342 .num_ports = 1,
0343 .base_baud = 115200,
0344 .uart_offset = 8,
0345 },
0346 [avlab_1s2p] = {
0347 .flags = FL_BASE0 | FL_BASE_BARS,
0348 .num_ports = 1,
0349 .base_baud = 115200,
0350 .uart_offset = 8,
0351 },
0352 [avlab_2s1p] = {
0353 .flags = FL_BASE0 | FL_BASE_BARS,
0354 .num_ports = 2,
0355 .base_baud = 115200,
0356 .uart_offset = 8,
0357 },
0358 [siig_1s1p_10x] = {
0359 .flags = FL_BASE2,
0360 .num_ports = 1,
0361 .base_baud = 460800,
0362 .uart_offset = 8,
0363 },
0364 [siig_2s1p_10x] = {
0365 .flags = FL_BASE2,
0366 .num_ports = 1,
0367 .base_baud = 921600,
0368 .uart_offset = 8,
0369 },
0370 [siig_2p1s_20x] = {
0371 .flags = FL_BASE0,
0372 .num_ports = 1,
0373 .base_baud = 921600,
0374 .uart_offset = 8,
0375 },
0376 [siig_1s1p_20x] = {
0377 .flags = FL_BASE0,
0378 .num_ports = 1,
0379 .base_baud = 921600,
0380 .uart_offset = 8,
0381 },
0382 [siig_2s1p_20x] = {
0383 .flags = FL_BASE0,
0384 .num_ports = 1,
0385 .base_baud = 921600,
0386 .uart_offset = 8,
0387 },
0388 [timedia_4078a] = {
0389 .flags = FL_BASE0|FL_BASE_BARS,
0390 .num_ports = 1,
0391 .base_baud = 921600,
0392 .uart_offset = 8,
0393 },
0394 [timedia_4079h] = {
0395 .flags = FL_BASE0|FL_BASE_BARS,
0396 .num_ports = 1,
0397 .base_baud = 921600,
0398 .uart_offset = 8,
0399 },
0400 [timedia_4085h] = {
0401 .flags = FL_BASE0|FL_BASE_BARS,
0402 .num_ports = 1,
0403 .base_baud = 921600,
0404 .uart_offset = 8,
0405 },
0406 [timedia_4088a] = {
0407 .flags = FL_BASE0|FL_BASE_BARS,
0408 .num_ports = 1,
0409 .base_baud = 921600,
0410 .uart_offset = 8,
0411 },
0412 [timedia_4089a] = {
0413 .flags = FL_BASE0|FL_BASE_BARS,
0414 .num_ports = 1,
0415 .base_baud = 921600,
0416 .uart_offset = 8,
0417 },
0418 [timedia_4095a] = {
0419 .flags = FL_BASE0|FL_BASE_BARS,
0420 .num_ports = 1,
0421 .base_baud = 921600,
0422 .uart_offset = 8,
0423 },
0424 [timedia_4096a] = {
0425 .flags = FL_BASE0|FL_BASE_BARS,
0426 .num_ports = 1,
0427 .base_baud = 921600,
0428 .uart_offset = 8,
0429 },
0430 [timedia_4078u] = {
0431 .flags = FL_BASE0|FL_BASE_BARS,
0432 .num_ports = 1,
0433 .base_baud = 921600,
0434 .uart_offset = 8,
0435 },
0436 [timedia_4079a] = {
0437 .flags = FL_BASE0|FL_BASE_BARS,
0438 .num_ports = 1,
0439 .base_baud = 921600,
0440 .uart_offset = 8,
0441 },
0442 [timedia_4085u] = {
0443 .flags = FL_BASE0|FL_BASE_BARS,
0444 .num_ports = 1,
0445 .base_baud = 921600,
0446 .uart_offset = 8,
0447 },
0448 [timedia_4079r] = {
0449 .flags = FL_BASE0|FL_BASE_BARS,
0450 .num_ports = 1,
0451 .base_baud = 921600,
0452 .uart_offset = 8,
0453 },
0454 [timedia_4079s] = {
0455 .flags = FL_BASE0|FL_BASE_BARS,
0456 .num_ports = 1,
0457 .base_baud = 921600,
0458 .uart_offset = 8,
0459 },
0460 [timedia_4079d] = {
0461 .flags = FL_BASE0|FL_BASE_BARS,
0462 .num_ports = 1,
0463 .base_baud = 921600,
0464 .uart_offset = 8,
0465 },
0466 [timedia_4079e] = {
0467 .flags = FL_BASE0|FL_BASE_BARS,
0468 .num_ports = 1,
0469 .base_baud = 921600,
0470 .uart_offset = 8,
0471 },
0472 [timedia_4079f] = {
0473 .flags = FL_BASE0|FL_BASE_BARS,
0474 .num_ports = 1,
0475 .base_baud = 921600,
0476 .uart_offset = 8,
0477 },
0478 [timedia_9079a] = {
0479 .flags = FL_BASE0|FL_BASE_BARS,
0480 .num_ports = 1,
0481 .base_baud = 921600,
0482 .uart_offset = 8,
0483 },
0484 [timedia_9079b] = {
0485 .flags = FL_BASE0|FL_BASE_BARS,
0486 .num_ports = 1,
0487 .base_baud = 921600,
0488 .uart_offset = 8,
0489 },
0490 [timedia_9079c] = {
0491 .flags = FL_BASE0|FL_BASE_BARS,
0492 .num_ports = 1,
0493 .base_baud = 921600,
0494 .uart_offset = 8,
0495 },
0496 [wch_ch353_1s1p] = {
0497 .flags = FL_BASE0|FL_BASE_BARS,
0498 .num_ports = 1,
0499 .base_baud = 115200,
0500 .uart_offset = 8,
0501 },
0502 [wch_ch353_2s1p] = {
0503 .flags = FL_BASE0|FL_BASE_BARS,
0504 .num_ports = 2,
0505 .base_baud = 115200,
0506 .uart_offset = 8,
0507 },
0508 [wch_ch382_0s1p] = {
0509 .flags = FL_BASE0,
0510 .num_ports = 0,
0511 .base_baud = 115200,
0512 .uart_offset = 8,
0513 },
0514 [wch_ch382_2s1p] = {
0515 .flags = FL_BASE0,
0516 .num_ports = 2,
0517 .base_baud = 115200,
0518 .uart_offset = 8,
0519 .first_offset = 0xC0,
0520 },
0521 [brainboxes_5s1p] = {
0522 .flags = FL_BASE2,
0523 .num_ports = 5,
0524 .base_baud = 921600,
0525 .uart_offset = 8,
0526 },
0527 [sunix_4008a] = {
0528 .num_ports = 0,
0529 },
0530 [sunix_5069a] = {
0531 .num_ports = 1,
0532 .base_baud = 921600,
0533 .uart_offset = 0x8,
0534 },
0535 [sunix_5079a] = {
0536 .num_ports = 2,
0537 .base_baud = 921600,
0538 .uart_offset = 0x8,
0539 },
0540 [sunix_5099a] = {
0541 .num_ports = 4,
0542 .base_baud = 921600,
0543 .uart_offset = 0x8,
0544 },
0545 };
0546
0547 struct parport_serial_private {
0548 struct serial_private *serial;
0549 int num_par;
0550 struct parport *port[PARPORT_MAX];
0551 struct parport_pc_pci par;
0552 };
0553
0554
0555 static int serial_register(struct pci_dev *dev, const struct pci_device_id *id)
0556 {
0557 struct parport_serial_private *priv = pci_get_drvdata (dev);
0558 struct pciserial_board *board;
0559 struct serial_private *serial;
0560
0561 board = &pci_parport_serial_boards[id->driver_data];
0562 if (board->num_ports == 0)
0563 return 0;
0564
0565 serial = pciserial_init_ports(dev, board);
0566 if (IS_ERR(serial))
0567 return PTR_ERR(serial);
0568
0569 priv->serial = serial;
0570 return 0;
0571 }
0572
0573
0574 static int parport_register(struct pci_dev *dev, const struct pci_device_id *id)
0575 {
0576 struct parport_pc_pci *card;
0577 struct parport_serial_private *priv = pci_get_drvdata (dev);
0578 int n, success = 0;
0579
0580 priv->par = cards[id->driver_data];
0581 card = &priv->par;
0582 if (card->preinit_hook &&
0583 card->preinit_hook (dev, card, PARPORT_IRQ_NONE, PARPORT_DMA_NONE))
0584 return -ENODEV;
0585
0586 for (n = 0; n < card->numports; n++) {
0587 struct parport *port;
0588 int lo = card->addr[n].lo;
0589 int hi = card->addr[n].hi;
0590 unsigned long io_lo, io_hi;
0591 int irq;
0592
0593 if (priv->num_par == ARRAY_SIZE (priv->port)) {
0594 dev_warn(&dev->dev,
0595 "only %zu parallel ports supported (%d reported)\n",
0596 ARRAY_SIZE(priv->port), card->numports);
0597 break;
0598 }
0599
0600 io_lo = pci_resource_start (dev, lo);
0601 io_hi = 0;
0602 if ((hi >= 0) && (hi <= 6))
0603 io_hi = pci_resource_start (dev, hi);
0604 else if (hi > 6)
0605 io_lo += hi;
0606
0607
0608
0609 irq = pci_irq_vector(dev, 0);
0610 if (irq < 0)
0611 return irq;
0612 if (irq == 0)
0613 irq = PARPORT_IRQ_NONE;
0614 if (irq == PARPORT_IRQ_NONE) {
0615 dev_dbg(&dev->dev,
0616 "PCI parallel port detected: I/O at %#lx(%#lx)\n",
0617 io_lo, io_hi);
0618 } else {
0619 dev_dbg(&dev->dev,
0620 "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
0621 io_lo, io_hi, irq);
0622 }
0623 port = parport_pc_probe_port (io_lo, io_hi, irq,
0624 PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
0625 if (port) {
0626 priv->port[priv->num_par++] = port;
0627 success = 1;
0628 }
0629 }
0630
0631 if (card->postinit_hook)
0632 card->postinit_hook (dev, card, !success);
0633
0634 return 0;
0635 }
0636
0637 static int parport_serial_pci_probe(struct pci_dev *dev,
0638 const struct pci_device_id *id)
0639 {
0640 struct parport_serial_private *priv;
0641 int err;
0642
0643 priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
0644 if (!priv)
0645 return -ENOMEM;
0646
0647 pci_set_drvdata (dev, priv);
0648
0649 err = pcim_enable_device(dev);
0650 if (err)
0651 return err;
0652
0653 err = parport_register(dev, id);
0654 if (err)
0655 return err;
0656
0657 err = serial_register(dev, id);
0658 if (err) {
0659 int i;
0660 for (i = 0; i < priv->num_par; i++)
0661 parport_pc_unregister_port (priv->port[i]);
0662 return err;
0663 }
0664
0665 return 0;
0666 }
0667
0668 static void parport_serial_pci_remove(struct pci_dev *dev)
0669 {
0670 struct parport_serial_private *priv = pci_get_drvdata (dev);
0671 int i;
0672
0673
0674 if (priv->serial)
0675 pciserial_remove_ports(priv->serial);
0676
0677
0678 for (i = 0; i < priv->num_par; i++)
0679 parport_pc_unregister_port (priv->port[i]);
0680
0681 return;
0682 }
0683
0684 static int __maybe_unused parport_serial_pci_suspend(struct device *dev)
0685 {
0686 struct parport_serial_private *priv = dev_get_drvdata(dev);
0687
0688 if (priv->serial)
0689 pciserial_suspend_ports(priv->serial);
0690
0691
0692 return 0;
0693 }
0694
0695 static int __maybe_unused parport_serial_pci_resume(struct device *dev)
0696 {
0697 struct parport_serial_private *priv = dev_get_drvdata(dev);
0698
0699 if (priv->serial)
0700 pciserial_resume_ports(priv->serial);
0701
0702
0703 return 0;
0704 }
0705
0706 static SIMPLE_DEV_PM_OPS(parport_serial_pm_ops,
0707 parport_serial_pci_suspend, parport_serial_pci_resume);
0708
0709 static struct pci_driver parport_serial_pci_driver = {
0710 .name = "parport_serial",
0711 .id_table = parport_serial_pci_tbl,
0712 .probe = parport_serial_pci_probe,
0713 .remove = parport_serial_pci_remove,
0714 .driver = {
0715 .pm = &parport_serial_pm_ops,
0716 },
0717 };
0718 module_pci_driver(parport_serial_pci_driver);
0719
0720 MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>");
0721 MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards");
0722 MODULE_LICENSE("GPL");