#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>
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,
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;
}
/* 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 }, } },
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,
.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,
.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,
{
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;
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
- "parport_serial: %s: only %u parallel ports "
+ "parport_serial: %s: only %zu parallel ports "
"supported (%d reported)\n", pci_name (dev),
- ARRAY_SIZE (priv->port), card->numports);
+ ARRAY_SIZE(priv->port), card->numports);
break;
}
"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;
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,
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);
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);
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);
/*
* 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);
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
};