X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fparport%2Fparport_serial.c;h=40e208d130f5b8ccf5a6e95be316f8af7e35440a;hb=8a56df632e524a1c444c56bb7ce9fe8d94e639e0;hp=d121644646b9e53a377ebd6916a8dec04a7405da;hpb=91bca4b3e2f1aaaf67e62a36914f33ca1e7d5a06;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index d121644..40e208d 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -30,6 +32,7 @@ enum parport_pc_pci_cards { titan_210l, netmos_9xx5_combo, netmos_9855, + netmos_9855_2p, avlab_1s1p, avlab_1s2p, avlab_2s1p, @@ -62,14 +65,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

is the number of * parallel ports and 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; } @@ -78,6 +96,7 @@ 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_1s2p */ { 2, { { 1, 2}, { 3, 4 },} }, /* avlab_2s1p */ { 1, { { 2, 3}, } }, @@ -100,11 +119,13 @@ 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 ...*/ { PCI_VENDOR_ID_AFAVLAB, 0x2110, @@ -192,6 +213,12 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { .base_baud = 115200, .uart_offset = 8, }, + [netmos_9855_2p] = { + .flags = FL_BASE4 | FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, [avlab_1s1p] = { /* n/t */ .flags = FL_BASE0 | FL_BASE_BARS, .num_ports = 1, @@ -286,6 +313,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 @@ -304,10 +332,20 @@ static int __devinit parport_register (struct pci_dev *dev, "hi" as an offset (see SYBA def.) */ /* TODO: test if sharing interrupts works */ - dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " - "%#lx(%#lx)\n", 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; @@ -326,10 +364,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); @@ -376,6 +413,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); @@ -393,6 +431,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); @@ -400,7 +439,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); @@ -409,14 +453,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 };