root/drivers/parport/parport_serial.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. netmos_parallel_init
  2. serial_register
  3. parport_register
  4. parport_serial_pci_probe
  5. parport_serial_pci_remove
  6. parport_serial_pci_suspend
  7. parport_serial_pci_resume

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * Support for common PCI multi-I/O cards (which is most of them)
   4  *
   5  * Copyright (C) 2001  Tim Waugh <twaugh@redhat.com>
   6  *
   7  * Multi-function PCI cards are supposed to present separate logical
   8  * devices on the bus.  A common thing to do seems to be to just use
   9  * one logical device with lots of base address registers for both
  10  * parallel ports and serial ports.  This driver is for dealing with
  11  * that.
  12  */
  13 
  14 #include <linux/interrupt.h>
  15 #include <linux/module.h>
  16 #include <linux/parport.h>
  17 #include <linux/parport_pc.h>
  18 #include <linux/pci.h>
  19 #include <linux/slab.h>
  20 #include <linux/types.h>
  21 
  22 #include <linux/8250_pci.h>
  23 
  24 enum parport_pc_pci_cards {
  25         titan_110l = 0,
  26         titan_210l,
  27         netmos_9xx5_combo,
  28         netmos_9855,
  29         netmos_9855_2p,
  30         netmos_9900,
  31         netmos_9900_2p,
  32         netmos_99xx_1p,
  33         avlab_1s1p,
  34         avlab_1s2p,
  35         avlab_2s1p,
  36         siig_1s1p_10x,
  37         siig_2s1p_10x,
  38         siig_2p1s_20x,
  39         siig_1s1p_20x,
  40         siig_2s1p_20x,
  41         timedia_4078a,
  42         timedia_4079h,
  43         timedia_4085h,
  44         timedia_4088a,
  45         timedia_4089a,
  46         timedia_4095a,
  47         timedia_4096a,
  48         timedia_4078u,
  49         timedia_4079a,
  50         timedia_4085u,
  51         timedia_4079r,
  52         timedia_4079s,
  53         timedia_4079d,
  54         timedia_4079e,
  55         timedia_4079f,
  56         timedia_9079a,
  57         timedia_9079b,
  58         timedia_9079c,
  59         wch_ch353_1s1p,
  60         wch_ch353_2s1p,
  61         wch_ch382_0s1p,
  62         wch_ch382_2s1p,
  63         brainboxes_5s1p,
  64         sunix_4008a,
  65         sunix_5069a,
  66         sunix_5079a,
  67         sunix_5099a,
  68 };
  69 
  70 /* each element directly indexed from enum list, above */
  71 struct parport_pc_pci {
  72         int numports;
  73         struct { /* BAR (base address registers) numbers in the config
  74                     space header */
  75                 int lo;
  76                 int hi; /* -1 if not there, >6 for offset-method (max
  77                            BAR is 6) */
  78         } addr[4];
  79 
  80         /* If set, this is called immediately after pci_enable_device.
  81          * If it returns non-zero, no probing will take place and the
  82          * ports will not be used. */
  83         int (*preinit_hook) (struct pci_dev *pdev, struct parport_pc_pci *card,
  84                                 int autoirq, int autodma);
  85 
  86         /* If set, this is called after probing for ports.  If 'failed'
  87          * is non-zero we couldn't use any of the ports. */
  88         void (*postinit_hook) (struct pci_dev *pdev,
  89                                 struct parport_pc_pci *card, int failed);
  90 };
  91 
  92 static int netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par,
  93                                 int autoirq, int autodma)
  94 {
  95         /* the rule described below doesn't hold for this device */
  96         if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
  97                         dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
  98                         dev->subsystem_device == 0x0299)
  99                 return -ENODEV;
 100 
 101         if (dev->device == PCI_DEVICE_ID_NETMOS_9912) {
 102                 par->numports = 1;
 103         } else {
 104                 /*
 105                  * Netmos uses the subdevice ID to indicate the number of parallel
 106                  * and serial ports.  The form is 0x00PS, where <P> is the number of
 107                  * parallel ports and <S> is the number of serial ports.
 108                  */
 109                 par->numports = (dev->subsystem_device & 0xf0) >> 4;
 110                 if (par->numports > ARRAY_SIZE(par->addr))
 111                         par->numports = ARRAY_SIZE(par->addr);
 112         }
 113 
 114         return 0;
 115 }
 116 
 117 static struct parport_pc_pci cards[] = {
 118         /* titan_110l */                { 1, { { 3, -1 }, } },
 119         /* titan_210l */                { 1, { { 3, -1 }, } },
 120         /* netmos_9xx5_combo */         { 1, { { 2, -1 }, }, netmos_parallel_init },
 121         /* netmos_9855 */               { 1, { { 0, -1 }, }, netmos_parallel_init },
 122         /* netmos_9855_2p */            { 2, { { 0, -1 }, { 2, -1 }, } },
 123         /* netmos_9900 */               {1, { { 3, 4 }, }, netmos_parallel_init },
 124         /* netmos_9900_2p */            {2, { { 0, 1 }, { 3, 4 }, } },
 125         /* netmos_99xx_1p */            {1, { { 0, 1 }, } },
 126         /* avlab_1s1p     */            { 1, { { 1, 2}, } },
 127         /* avlab_1s2p     */            { 2, { { 1, 2}, { 3, 4 },} },
 128         /* avlab_2s1p     */            { 1, { { 2, 3}, } },
 129         /* siig_1s1p_10x */             { 1, { { 3, 4 }, } },
 130         /* siig_2s1p_10x */             { 1, { { 4, 5 }, } },
 131         /* siig_2p1s_20x */             { 2, { { 1, 2 }, { 3, 4 }, } },
 132         /* siig_1s1p_20x */             { 1, { { 1, 2 }, } },
 133         /* siig_2s1p_20x */             { 1, { { 2, 3 }, } },
 134         /* timedia_4078a */             { 1, { { 2, -1 }, } },
 135         /* timedia_4079h */             { 1, { { 2, 3 }, } },
 136         /* timedia_4085h */             { 2, { { 2, -1 }, { 4, -1 }, } },
 137         /* timedia_4088a */             { 2, { { 2, 3 }, { 4, 5 }, } },
 138         /* timedia_4089a */             { 2, { { 2, 3 }, { 4, 5 }, } },
 139         /* timedia_4095a */             { 2, { { 2, 3 }, { 4, 5 }, } },
 140         /* timedia_4096a */             { 2, { { 2, 3 }, { 4, 5 }, } },
 141         /* timedia_4078u */             { 1, { { 2, -1 }, } },
 142         /* timedia_4079a */             { 1, { { 2, 3 }, } },
 143         /* timedia_4085u */             { 2, { { 2, -1 }, { 4, -1 }, } },
 144         /* timedia_4079r */             { 1, { { 2, 3 }, } },
 145         /* timedia_4079s */             { 1, { { 2, 3 }, } },
 146         /* timedia_4079d */             { 1, { { 2, 3 }, } },
 147         /* timedia_4079e */             { 1, { { 2, 3 }, } },
 148         /* timedia_4079f */             { 1, { { 2, 3 }, } },
 149         /* timedia_9079a */             { 1, { { 2, 3 }, } },
 150         /* timedia_9079b */             { 1, { { 2, 3 }, } },
 151         /* timedia_9079c */             { 1, { { 2, 3 }, } },
 152         /* wch_ch353_1s1p*/             { 1, { { 1, -1}, } },
 153         /* wch_ch353_2s1p*/             { 1, { { 2, -1}, } },
 154         /* wch_ch382_0s1p*/             { 1, { { 2, -1}, } },
 155         /* wch_ch382_2s1p*/             { 1, { { 2, -1}, } },
 156         /* brainboxes_5s1p */           { 1, { { 3, -1 }, } },
 157         /* sunix_4008a */               { 1, { { 1, 2 }, } },
 158         /* sunix_5069a */               { 1, { { 1, 2 }, } },
 159         /* sunix_5079a */               { 1, { { 1, 2 }, } },
 160         /* sunix_5099a */               { 1, { { 1, 2 }, } },
 161 };
 162 
 163 static struct pci_device_id parport_serial_pci_tbl[] = {
 164         /* PCI cards */
 165         { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L,
 166           PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l },
 167         { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L,
 168           PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l },
 169         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735,
 170           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 171         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9745,
 172           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 173         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
 174           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 175         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
 176           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 177         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
 178           0x1000, 0x0020, 0, 0, netmos_9855_2p },
 179         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
 180           0x1000, 0x0022, 0, 0, netmos_9855_2p },
 181         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
 182           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
 183         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
 184           0xA000, 0x3011, 0, 0, netmos_9900 },
 185         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
 186           0xA000, 0x3012, 0, 0, netmos_9900 },
 187         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
 188           0xA000, 0x3020, 0, 0, netmos_9900_2p },
 189         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
 190           0xA000, 0x2000, 0, 0, netmos_99xx_1p },
 191         /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
 192         { PCI_VENDOR_ID_AFAVLAB, 0x2110,
 193           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
 194         { PCI_VENDOR_ID_AFAVLAB, 0x2111,
 195           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
 196         { PCI_VENDOR_ID_AFAVLAB, 0x2112,
 197           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
 198         { PCI_VENDOR_ID_AFAVLAB, 0x2140,
 199           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
 200         { PCI_VENDOR_ID_AFAVLAB, 0x2141,
 201           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
 202         { PCI_VENDOR_ID_AFAVLAB, 0x2142,
 203           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
 204         { PCI_VENDOR_ID_AFAVLAB, 0x2160,
 205           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
 206         { PCI_VENDOR_ID_AFAVLAB, 0x2161,
 207           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
 208         { PCI_VENDOR_ID_AFAVLAB, 0x2162,
 209           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
 210         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
 211           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
 212         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
 213           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
 214         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
 215           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
 216         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
 217           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
 218         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
 219           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
 220         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
 221           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
 222         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
 223           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
 224         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
 225           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
 226         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
 227           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
 228         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
 229           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
 230         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
 231           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
 232         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
 233           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
 234         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
 235           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
 236         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
 237           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
 238         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
 239           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
 240         /* PCI_VENDOR_ID_TIMEDIA/SUNIX has many differing cards ...*/
 241         { 0x1409, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a },
 242         { 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h },
 243         { 0x1409, 0x7168, 0x1409, 0x4085, 0, 0, timedia_4085h },
 244         { 0x1409, 0x7168, 0x1409, 0x4088, 0, 0, timedia_4088a },
 245         { 0x1409, 0x7168, 0x1409, 0x4089, 0, 0, timedia_4089a },
 246         { 0x1409, 0x7168, 0x1409, 0x4095, 0, 0, timedia_4095a },
 247         { 0x1409, 0x7168, 0x1409, 0x4096, 0, 0, timedia_4096a },
 248         { 0x1409, 0x7168, 0x1409, 0x5078, 0, 0, timedia_4078u },
 249         { 0x1409, 0x7168, 0x1409, 0x5079, 0, 0, timedia_4079a },
 250         { 0x1409, 0x7168, 0x1409, 0x5085, 0, 0, timedia_4085u },
 251         { 0x1409, 0x7168, 0x1409, 0x6079, 0, 0, timedia_4079r },
 252         { 0x1409, 0x7168, 0x1409, 0x7079, 0, 0, timedia_4079s },
 253         { 0x1409, 0x7168, 0x1409, 0x8079, 0, 0, timedia_4079d },
 254         { 0x1409, 0x7168, 0x1409, 0x9079, 0, 0, timedia_4079e },
 255         { 0x1409, 0x7168, 0x1409, 0xa079, 0, 0, timedia_4079f },
 256         { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a },
 257         { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b },
 258         { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c },
 259 
 260         /* WCH CARDS */
 261         { 0x4348, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, wch_ch353_1s1p},
 262         { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p},
 263         { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382_0s1p},
 264         { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p},
 265 
 266         /* BrainBoxes PX272/PX306 MIO card */
 267         { PCI_VENDOR_ID_INTASHIELD, 0x4100,
 268           PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_5s1p },
 269 
 270         /* Sunix boards */
 271         { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
 272           0x0100, 0, 0, sunix_4008a },
 273         { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
 274           0x0101, 0, 0, sunix_5069a },
 275         { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
 276           0x0102, 0, 0, sunix_5079a },
 277         { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
 278           0x0104, 0, 0, sunix_5099a },
 279 
 280         { 0, } /* terminate list */
 281 };
 282 MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
 283 
 284 /*
 285  * This table describes the serial "geometry" of these boards.  Any
 286  * quirks for these can be found in drivers/serial/8250_pci.c
 287  *
 288  * Cards not tested are marked n/t
 289  * If you have one of these cards and it works for you, please tell me..
 290  */
 291 static struct pciserial_board pci_parport_serial_boards[] = {
 292         [titan_110l] = {
 293                 .flags          = FL_BASE1 | FL_BASE_BARS,
 294                 .num_ports      = 1,
 295                 .base_baud      = 921600,
 296                 .uart_offset    = 8,
 297         },
 298         [titan_210l] = {
 299                 .flags          = FL_BASE1 | FL_BASE_BARS,
 300                 .num_ports      = 2,
 301                 .base_baud      = 921600,
 302                 .uart_offset    = 8,
 303         },
 304         [netmos_9xx5_combo] = {
 305                 .flags          = FL_BASE0 | FL_BASE_BARS,
 306                 .num_ports      = 1,
 307                 .base_baud      = 115200,
 308                 .uart_offset    = 8,
 309         },
 310         [netmos_9855] = {
 311                 .flags          = FL_BASE2 | FL_BASE_BARS,
 312                 .num_ports      = 1,
 313                 .base_baud      = 115200,
 314                 .uart_offset    = 8,
 315         },
 316         [netmos_9855_2p] = {
 317                 .flags          = FL_BASE4 | FL_BASE_BARS,
 318                 .num_ports      = 1,
 319                 .base_baud      = 115200,
 320                 .uart_offset    = 8,
 321         },
 322         [netmos_9900] = { /* n/t */
 323                 .flags          = FL_BASE0 | FL_BASE_BARS,
 324                 .num_ports      = 1,
 325                 .base_baud      = 115200,
 326                 .uart_offset    = 8,
 327         },
 328         [netmos_9900_2p] = { /* parallel only */ /* n/t */
 329                 .flags          = FL_BASE0,
 330                 .num_ports      = 0,
 331                 .base_baud      = 115200,
 332                 .uart_offset    = 8,
 333         },
 334         [netmos_99xx_1p] = { /* parallel only */ /* n/t */
 335                 .flags          = FL_BASE0,
 336                 .num_ports      = 0,
 337                 .base_baud      = 115200,
 338                 .uart_offset    = 8,
 339         },
 340         [avlab_1s1p] = { /* n/t */
 341                 .flags          = FL_BASE0 | FL_BASE_BARS,
 342                 .num_ports      = 1,
 343                 .base_baud      = 115200,
 344                 .uart_offset    = 8,
 345         },
 346         [avlab_1s2p] = { /* n/t */
 347                 .flags          = FL_BASE0 | FL_BASE_BARS,
 348                 .num_ports      = 1,
 349                 .base_baud      = 115200,
 350                 .uart_offset    = 8,
 351         },
 352         [avlab_2s1p] = { /* n/t */
 353                 .flags          = FL_BASE0 | FL_BASE_BARS,
 354                 .num_ports      = 2,
 355                 .base_baud      = 115200,
 356                 .uart_offset    = 8,
 357         },
 358         [siig_1s1p_10x] = {
 359                 .flags          = FL_BASE2,
 360                 .num_ports      = 1,
 361                 .base_baud      = 460800,
 362                 .uart_offset    = 8,
 363         },
 364         [siig_2s1p_10x] = {
 365                 .flags          = FL_BASE2,
 366                 .num_ports      = 1,
 367                 .base_baud      = 921600,
 368                 .uart_offset    = 8,
 369         },
 370         [siig_2p1s_20x] = {
 371                 .flags          = FL_BASE0,
 372                 .num_ports      = 1,
 373                 .base_baud      = 921600,
 374                 .uart_offset    = 8,
 375         },
 376         [siig_1s1p_20x] = {
 377                 .flags          = FL_BASE0,
 378                 .num_ports      = 1,
 379                 .base_baud      = 921600,
 380                 .uart_offset    = 8,
 381         },
 382         [siig_2s1p_20x] = {
 383                 .flags          = FL_BASE0,
 384                 .num_ports      = 1,
 385                 .base_baud      = 921600,
 386                 .uart_offset    = 8,
 387         },
 388         [timedia_4078a] = {
 389                 .flags          = FL_BASE0|FL_BASE_BARS,
 390                 .num_ports      = 1,
 391                 .base_baud      = 921600,
 392                 .uart_offset    = 8,
 393         },
 394         [timedia_4079h] = {
 395                 .flags          = FL_BASE0|FL_BASE_BARS,
 396                 .num_ports      = 1,
 397                 .base_baud      = 921600,
 398                 .uart_offset    = 8,
 399         },
 400         [timedia_4085h] = {
 401                 .flags          = FL_BASE0|FL_BASE_BARS,
 402                 .num_ports      = 1,
 403                 .base_baud      = 921600,
 404                 .uart_offset    = 8,
 405         },
 406         [timedia_4088a] = {
 407                 .flags          = FL_BASE0|FL_BASE_BARS,
 408                 .num_ports      = 1,
 409                 .base_baud      = 921600,
 410                 .uart_offset    = 8,
 411         },
 412         [timedia_4089a] = {
 413                 .flags          = FL_BASE0|FL_BASE_BARS,
 414                 .num_ports      = 1,
 415                 .base_baud      = 921600,
 416                 .uart_offset    = 8,
 417         },
 418         [timedia_4095a] = {
 419                 .flags          = FL_BASE0|FL_BASE_BARS,
 420                 .num_ports      = 1,
 421                 .base_baud      = 921600,
 422                 .uart_offset    = 8,
 423         },
 424         [timedia_4096a] = {
 425                 .flags          = FL_BASE0|FL_BASE_BARS,
 426                 .num_ports      = 1,
 427                 .base_baud      = 921600,
 428                 .uart_offset    = 8,
 429         },
 430         [timedia_4078u] = {
 431                 .flags          = FL_BASE0|FL_BASE_BARS,
 432                 .num_ports      = 1,
 433                 .base_baud      = 921600,
 434                 .uart_offset    = 8,
 435         },
 436         [timedia_4079a] = {
 437                 .flags          = FL_BASE0|FL_BASE_BARS,
 438                 .num_ports      = 1,
 439                 .base_baud      = 921600,
 440                 .uart_offset    = 8,
 441         },
 442         [timedia_4085u] = {
 443                 .flags          = FL_BASE0|FL_BASE_BARS,
 444                 .num_ports      = 1,
 445                 .base_baud      = 921600,
 446                 .uart_offset    = 8,
 447         },
 448         [timedia_4079r] = {
 449                 .flags          = FL_BASE0|FL_BASE_BARS,
 450                 .num_ports      = 1,
 451                 .base_baud      = 921600,
 452                 .uart_offset    = 8,
 453         },
 454         [timedia_4079s] = {
 455                 .flags          = FL_BASE0|FL_BASE_BARS,
 456                 .num_ports      = 1,
 457                 .base_baud      = 921600,
 458                 .uart_offset    = 8,
 459         },
 460         [timedia_4079d] = {
 461                 .flags          = FL_BASE0|FL_BASE_BARS,
 462                 .num_ports      = 1,
 463                 .base_baud      = 921600,
 464                 .uart_offset    = 8,
 465         },
 466         [timedia_4079e] = {
 467                 .flags          = FL_BASE0|FL_BASE_BARS,
 468                 .num_ports      = 1,
 469                 .base_baud      = 921600,
 470                 .uart_offset    = 8,
 471         },
 472         [timedia_4079f] = {
 473                 .flags          = FL_BASE0|FL_BASE_BARS,
 474                 .num_ports      = 1,
 475                 .base_baud      = 921600,
 476                 .uart_offset    = 8,
 477         },
 478         [timedia_9079a] = {
 479                 .flags          = FL_BASE0|FL_BASE_BARS,
 480                 .num_ports      = 1,
 481                 .base_baud      = 921600,
 482                 .uart_offset    = 8,
 483         },
 484         [timedia_9079b] = {
 485                 .flags          = FL_BASE0|FL_BASE_BARS,
 486                 .num_ports      = 1,
 487                 .base_baud      = 921600,
 488                 .uart_offset    = 8,
 489         },
 490         [timedia_9079c] = {
 491                 .flags          = FL_BASE0|FL_BASE_BARS,
 492                 .num_ports      = 1,
 493                 .base_baud      = 921600,
 494                 .uart_offset    = 8,
 495         },
 496         [wch_ch353_1s1p] = {
 497                 .flags          = FL_BASE0|FL_BASE_BARS,
 498                 .num_ports      = 1,
 499                 .base_baud      = 115200,
 500                 .uart_offset    = 8,
 501         },
 502         [wch_ch353_2s1p] = {
 503                 .flags          = FL_BASE0|FL_BASE_BARS,
 504                 .num_ports      = 2,
 505                 .base_baud      = 115200,
 506                 .uart_offset    = 8,
 507         },
 508         [wch_ch382_0s1p] = {
 509                 .flags          = FL_BASE0,
 510                 .num_ports      = 0,
 511                 .base_baud      = 115200,
 512                 .uart_offset    = 8,
 513         },
 514         [wch_ch382_2s1p] = {
 515                 .flags          = FL_BASE0,
 516                 .num_ports      = 2,
 517                 .base_baud      = 115200,
 518                 .uart_offset    = 8,
 519                 .first_offset   = 0xC0,
 520         },
 521         [brainboxes_5s1p] = {
 522                 .flags          = FL_BASE2,
 523                 .num_ports      = 5,
 524                 .base_baud      = 921600,
 525                 .uart_offset    = 8,
 526         },
 527         [sunix_4008a] = {
 528                 .num_ports      = 0,
 529         },
 530         [sunix_5069a] = {
 531                 .num_ports      = 1,
 532                 .base_baud      = 921600,
 533                 .uart_offset    = 0x8,
 534         },
 535         [sunix_5079a] = {
 536                 .num_ports      = 2,
 537                 .base_baud      = 921600,
 538                 .uart_offset    = 0x8,
 539         },
 540         [sunix_5099a] = {
 541                 .num_ports      = 4,
 542                 .base_baud      = 921600,
 543                 .uart_offset    = 0x8,
 544         },
 545 };
 546 
 547 struct parport_serial_private {
 548         struct serial_private   *serial;
 549         int num_par;
 550         struct parport *port[PARPORT_MAX];
 551         struct parport_pc_pci par;
 552 };
 553 
 554 /* Register the serial port(s) of a PCI card. */
 555 static int serial_register(struct pci_dev *dev, const struct pci_device_id *id)
 556 {
 557         struct parport_serial_private *priv = pci_get_drvdata (dev);
 558         struct pciserial_board *board;
 559         struct serial_private *serial;
 560 
 561         board = &pci_parport_serial_boards[id->driver_data];
 562         if (board->num_ports == 0)
 563                 return 0;
 564 
 565         serial = pciserial_init_ports(dev, board);
 566         if (IS_ERR(serial))
 567                 return PTR_ERR(serial);
 568 
 569         priv->serial = serial;
 570         return 0;
 571 }
 572 
 573 /* Register the parallel port(s) of a PCI card. */
 574 static int parport_register(struct pci_dev *dev, const struct pci_device_id *id)
 575 {
 576         struct parport_pc_pci *card;
 577         struct parport_serial_private *priv = pci_get_drvdata (dev);
 578         int n, success = 0;
 579 
 580         priv->par = cards[id->driver_data];
 581         card = &priv->par;
 582         if (card->preinit_hook &&
 583             card->preinit_hook (dev, card, PARPORT_IRQ_NONE, PARPORT_DMA_NONE))
 584                 return -ENODEV;
 585 
 586         for (n = 0; n < card->numports; n++) {
 587                 struct parport *port;
 588                 int lo = card->addr[n].lo;
 589                 int hi = card->addr[n].hi;
 590                 unsigned long io_lo, io_hi;
 591                 int irq;
 592 
 593                 if (priv->num_par == ARRAY_SIZE (priv->port)) {
 594                         dev_warn(&dev->dev,
 595                                  "only %zu parallel ports supported (%d reported)\n",
 596                                  ARRAY_SIZE(priv->port), card->numports);
 597                         break;
 598                 }
 599 
 600                 io_lo = pci_resource_start (dev, lo);
 601                 io_hi = 0;
 602                 if ((hi >= 0) && (hi <= 6))
 603                         io_hi = pci_resource_start (dev, hi);
 604                 else if (hi > 6)
 605                         io_lo += hi; /* Reinterpret the meaning of
 606                                         "hi" as an offset (see SYBA
 607                                         def.) */
 608                 /* TODO: test if sharing interrupts works */
 609                 irq = dev->irq;
 610                 if (irq == IRQ_NONE) {
 611                         dev_dbg(&dev->dev,
 612                                 "PCI parallel port detected: I/O at %#lx(%#lx)\n",
 613                                 io_lo, io_hi);
 614                         irq = PARPORT_IRQ_NONE;
 615                 } else {
 616                         dev_dbg(&dev->dev,
 617                                 "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
 618                                 io_lo, io_hi, irq);
 619                 }
 620                 port = parport_pc_probe_port (io_lo, io_hi, irq,
 621                               PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
 622                 if (port) {
 623                         priv->port[priv->num_par++] = port;
 624                         success = 1;
 625                 }
 626         }
 627 
 628         if (card->postinit_hook)
 629                 card->postinit_hook (dev, card, !success);
 630 
 631         return 0;
 632 }
 633 
 634 static int parport_serial_pci_probe(struct pci_dev *dev,
 635                                     const struct pci_device_id *id)
 636 {
 637         struct parport_serial_private *priv;
 638         int err;
 639 
 640         priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
 641         if (!priv)
 642                 return -ENOMEM;
 643 
 644         pci_set_drvdata (dev, priv);
 645 
 646         err = pcim_enable_device(dev);
 647         if (err)
 648                 return err;
 649 
 650         err = parport_register(dev, id);
 651         if (err)
 652                 return err;
 653 
 654         err = serial_register(dev, id);
 655         if (err) {
 656                 int i;
 657                 for (i = 0; i < priv->num_par; i++)
 658                         parport_pc_unregister_port (priv->port[i]);
 659                 return err;
 660         }
 661 
 662         return 0;
 663 }
 664 
 665 static void parport_serial_pci_remove(struct pci_dev *dev)
 666 {
 667         struct parport_serial_private *priv = pci_get_drvdata (dev);
 668         int i;
 669 
 670         // Serial ports
 671         if (priv->serial)
 672                 pciserial_remove_ports(priv->serial);
 673 
 674         // Parallel ports
 675         for (i = 0; i < priv->num_par; i++)
 676                 parport_pc_unregister_port (priv->port[i]);
 677 
 678         return;
 679 }
 680 
 681 static int __maybe_unused parport_serial_pci_suspend(struct device *dev)
 682 {
 683         struct parport_serial_private *priv = dev_get_drvdata(dev);
 684 
 685         if (priv->serial)
 686                 pciserial_suspend_ports(priv->serial);
 687 
 688         /* FIXME: What about parport? */
 689         return 0;
 690 }
 691 
 692 static int __maybe_unused parport_serial_pci_resume(struct device *dev)
 693 {
 694         struct parport_serial_private *priv = dev_get_drvdata(dev);
 695 
 696         if (priv->serial)
 697                 pciserial_resume_ports(priv->serial);
 698 
 699         /* FIXME: What about parport? */
 700         return 0;
 701 }
 702 
 703 static SIMPLE_DEV_PM_OPS(parport_serial_pm_ops,
 704                          parport_serial_pci_suspend, parport_serial_pci_resume);
 705 
 706 static struct pci_driver parport_serial_pci_driver = {
 707         .name           = "parport_serial",
 708         .id_table       = parport_serial_pci_tbl,
 709         .probe          = parport_serial_pci_probe,
 710         .remove         = parport_serial_pci_remove,
 711         .driver         = {
 712                 .pm     = &parport_serial_pm_ops,
 713         },
 714 };
 715 module_pci_driver(parport_serial_pci_driver);
 716 
 717 MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>");
 718 MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards");
 719 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */