tg3: Fix napi assignments in loopback test
[safe/jmp/linux-2.6] / drivers / parport / parport_serial.c
index 166de35..c3bb84a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
 #include <linux/parport.h>
 #include <linux/parport_pc.h>
 #include <linux/8250_pci.h>
@@ -30,15 +31,10 @@ enum parport_pc_pci_cards {
        titan_210l,
        netmos_9xx5_combo,
        netmos_9855,
+       netmos_9855_2p,
        avlab_1s1p,
-       avlab_1s1p_650,
-       avlab_1s1p_850,
        avlab_1s2p,
-       avlab_1s2p_650,
-       avlab_1s2p_850,
        avlab_2s1p,
-       avlab_2s1p_650,
-       avlab_2s1p_850,
        siig_1s1p_10x,
        siig_2s1p_10x,
        siig_2p1s_20x,
@@ -68,14 +64,29 @@ struct parport_pc_pci {
                                struct parport_pc_pci *card, int failed);
 };
 
-static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma)
+static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par, int autoirq, int autodma)
 {
+       /* the rule described below doesn't hold for this device */
+       if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
+                       dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+                       dev->subsystem_device == 0x0299)
+               return -ENODEV;
        /*
         * Netmos uses the subdevice ID to indicate the number of parallel
         * and serial ports.  The form is 0x00PS, where <P> is the number of
         * parallel ports and <S> is the number of serial ports.
         */
-       card->numports = (dev->subsystem_device & 0xf0) >> 4;
+       par->numports = (dev->subsystem_device & 0xf0) >> 4;
+       if (par->numports > ARRAY_SIZE(par->addr))
+               par->numports = ARRAY_SIZE(par->addr);
+       /*
+        * This function is currently only called for cards with up to
+        * one parallel port.
+        * Parallel port BAR is either before or after serial ports BARS;
+        * hence, lo should be either 0 or equal to the number of serial ports.
+        */
+       if (par->addr[0].lo != 0)
+               par->addr[0].lo = dev->subsystem_device & 0xf;
        return 0;
 }
 
@@ -84,15 +95,10 @@ static struct parport_pc_pci cards[] __devinitdata = {
        /* titan_210l */                { 1, { { 3, -1 }, } },
        /* netmos_9xx5_combo */         { 1, { { 2, -1 }, }, netmos_parallel_init },
        /* netmos_9855 */               { 1, { { 0, -1 }, }, netmos_parallel_init },
+       /* netmos_9855_2p */            { 2, { { 0, -1 }, { 2, -1 }, } },
        /* avlab_1s1p     */            { 1, { { 1, 2}, } },
-       /* avlab_1s1p_650 */            { 1, { { 1, 2}, } },
-       /* avlab_1s1p_850 */            { 1, { { 1, 2}, } },
        /* avlab_1s2p     */            { 2, { { 1, 2}, { 3, 4 },} },
-       /* avlab_1s2p_650 */            { 2, { { 1, 2}, { 3, 4 },} },
-       /* avlab_1s2p_850 */            { 2, { { 1, 2}, { 3, 4 },} },
        /* avlab_2s1p     */            { 1, { { 2, 3}, } },
-       /* avlab_2s1p_650 */            { 1, { { 2, 3}, } },
-       /* avlab_2s1p_850 */            { 1, { { 2, 3}, } },
        /* siig_1s1p_10x */             { 1, { { 3, 4 }, } },
        /* siig_2s1p_10x */             { 1, { { 4, 5 }, } },
        /* siig_2p1s_20x */             { 2, { { 1, 2 }, { 3, 4 }, } },
@@ -112,22 +118,33 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
-       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
        { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+         0x1000, 0x0020, 0, 0, netmos_9855_2p },
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+         0x1000, 0x0022, 0, 0, netmos_9855_2p },
+       { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
        /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
-       { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p},
-       { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650},
-       { 0x14db, 0x2112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_850},
-       { 0x14db, 0x2140, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p},
-       { 0x14db, 0x2141, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p_650},
-       { 0x14db, 0x2142, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p_850},
-       { 0x14db, 0x2160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p},
-       { 0x14db, 0x2161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p_650},
-       { 0x14db, 0x2162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p_850},
+       { PCI_VENDOR_ID_AFAVLAB, 0x2110,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
+       { PCI_VENDOR_ID_AFAVLAB, 0x2111,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
+       { PCI_VENDOR_ID_AFAVLAB, 0x2112,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
+       { PCI_VENDOR_ID_AFAVLAB, 0x2140,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
+       { PCI_VENDOR_ID_AFAVLAB, 0x2141,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
+       { PCI_VENDOR_ID_AFAVLAB, 0x2142,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
+       { PCI_VENDOR_ID_AFAVLAB, 0x2160,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
+       { PCI_VENDOR_ID_AFAVLAB, 0x2161,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
+       { PCI_VENDOR_ID_AFAVLAB, 0x2162,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
        { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
@@ -195,19 +212,13 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = {
                .base_baud      = 115200,
                .uart_offset    = 8,
        },
-       [avlab_1s1p] = { /* n/t */
-               .flags          = FL_BASE0 | FL_BASE_BARS,
+       [netmos_9855_2p] = {
+               .flags          = FL_BASE4 | FL_BASE_BARS,
                .num_ports      = 1,
                .base_baud      = 115200,
                .uart_offset    = 8,
        },
-       [avlab_1s1p_650] = { /* nt */
-               .flags          = FL_BASE0 | FL_BASE_BARS,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [avlab_1s1p_850] = { /* nt */
+       [avlab_1s1p] = { /* n/t */
                .flags          = FL_BASE0 | FL_BASE_BARS,
                .num_ports      = 1,
                .base_baud      = 115200,
@@ -219,36 +230,12 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = {
                .base_baud      = 115200,
                .uart_offset    = 8,
        },
-       [avlab_1s2p_650] = { /* nt */
-               .flags          = FL_BASE0 | FL_BASE_BARS,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [avlab_1s2p_850] = { /* nt */
-               .flags          = FL_BASE0 | FL_BASE_BARS,
-               .num_ports      = 1,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
        [avlab_2s1p] = { /* n/t */
                .flags          = FL_BASE0 | FL_BASE_BARS,
                .num_ports      = 2,
                .base_baud      = 115200,
                .uart_offset    = 8,
        },
-       [avlab_2s1p_650] = { /* nt */
-               .flags          = FL_BASE0 | FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-       [avlab_2s1p_850] = { /* nt */
-               .flags          = FL_BASE0 | FL_BASE_BARS,
-               .num_ports      = 2,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
        [siig_1s1p_10x] = {
                .flags          = FL_BASE2,
                .num_ports      = 1,
@@ -312,8 +299,7 @@ static int __devinit parport_register (struct pci_dev *dev,
 {
        struct parport_pc_pci *card;
        struct parport_serial_private *priv = pci_get_drvdata (dev);
-       int i = id->driver_data, n;
-       int success = 0;
+       int n, success = 0;
 
        priv->par = cards[id->driver_data];
        card = &priv->par;
@@ -326,6 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev,
                int lo = card->addr[n].lo;
                int hi = card->addr[n].hi;
                unsigned long io_lo, io_hi;
+               int irq;
 
                if (priv->num_par == ARRAY_SIZE (priv->port)) {
                        printk (KERN_WARNING
@@ -344,12 +331,20 @@ static int __devinit parport_register (struct pci_dev *dev,
                                         "hi" as an offset (see SYBA
                                         def.) */
                /* TODO: test if sharing interrupts works */
-               printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
-                       "I/O at %#lx(%#lx)\n",
-                       parport_serial_pci_tbl[i].vendor,
-                       parport_serial_pci_tbl[i].device, io_lo, io_hi);
-               port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
-                                             PARPORT_DMA_NONE, dev);
+               irq = dev->irq;
+               if (irq == IRQ_NONE) {
+                       dev_dbg(&dev->dev,
+                       "PCI parallel port detected: I/O at %#lx(%#lx)\n",
+                               io_lo, io_hi);
+                       irq = PARPORT_IRQ_NONE;
+               } else {
+                       dev_dbg(&dev->dev,
+               "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
+                               io_lo, io_hi, irq);
+                       irq = PARPORT_IRQ_NONE;
+               }
+               port = parport_pc_probe_port (io_lo, io_hi, irq,
+                             PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
                if (port) {
                        priv->port[priv->num_par++] = port;
                        success = 1;
@@ -359,7 +354,7 @@ static int __devinit parport_register (struct pci_dev *dev,
        if (card->postinit_hook)
                card->postinit_hook (dev, card, !success);
 
-       return success ? 0 : 1;
+       return 0;
 }
 
 static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
@@ -368,10 +363,9 @@ static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
        struct parport_serial_private *priv;
        int err;
 
-       priv = kmalloc (sizeof *priv, GFP_KERNEL);
+       priv = kzalloc (sizeof *priv, GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
-       memset(priv, 0, sizeof(struct parport_serial_private));
        pci_set_drvdata (dev, priv);
 
        err = pci_enable_device (dev);
@@ -418,6 +412,7 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
        return;
 }
 
+#ifdef CONFIG_PM
 static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state)
 {
        struct parport_serial_private *priv = pci_get_drvdata(dev);
@@ -435,6 +430,7 @@ static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state)
 static int parport_serial_pci_resume(struct pci_dev *dev)
 {
        struct parport_serial_private *priv = pci_get_drvdata(dev);
+       int err;
 
        pci_set_power_state(dev, PCI_D0);
        pci_restore_state(dev);
@@ -442,7 +438,12 @@ static int parport_serial_pci_resume(struct pci_dev *dev)
        /*
         * The device may have been disabled.  Re-enable it.
         */
-       pci_enable_device(dev);
+       err = pci_enable_device(dev);
+       if (err) {
+               printk(KERN_ERR "parport_serial: %s: error enabling "
+                       "device for resume (%d)\n", pci_name(dev), err);
+               return err;
+       }
 
        if (priv->serial)
                pciserial_resume_ports(priv->serial);
@@ -451,14 +452,17 @@ static int parport_serial_pci_resume(struct pci_dev *dev)
 
        return 0;
 }
+#endif
 
 static struct pci_driver parport_serial_pci_driver = {
        .name           = "parport_serial",
        .id_table       = parport_serial_pci_tbl,
        .probe          = parport_serial_pci_probe,
        .remove         = __devexit_p(parport_serial_pci_remove),
+#ifdef CONFIG_PM
        .suspend        = parport_serial_pci_suspend,
        .resume         = parport_serial_pci_resume,
+#endif
 };