diff options
Diffstat (limited to 'drivers/parport')
-rw-r--r-- | drivers/parport/Config.in | 72 | ||||
-rw-r--r-- | drivers/parport/ieee1284.c | 52 | ||||
-rw-r--r-- | drivers/parport/parport_pc.c | 130 |
3 files changed, 170 insertions, 84 deletions
diff --git a/drivers/parport/Config.in b/drivers/parport/Config.in index 16a7099c7..812cc1a4c 100644 --- a/drivers/parport/Config.in +++ b/drivers/parport/Config.in @@ -7,41 +7,43 @@ tristate 'Parallel port support' CONFIG_PARPORT if [ "$CONFIG_PARPORT" != "n" ]; then - dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT - if [ "$CONFIG_PARPORT_PC" != "n" ]; then - bool ' Use FIFO/DMA if available' CONFIG_PARPORT_PC_FIFO - fi - if [ "$CONFIG_PARPORT_PC" = "y" ]; then - # Don't bother with this if parport_pc is a module; it only affects - # the presence or not of some __init's, which are no-ops for modules. - bool ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA - fi - if [ "$CONFIG_ARM" = "y" ]; then - dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT - fi - if [ "$CONFIG_AMIGA" = "y" ]; then - dep_tristate ' Amiga builtin port' CONFIG_PARPORT_AMIGA $CONFIG_PARPORT - if [ "$CONFIG_ZORRO" != "n" ]; then - dep_tristate ' Multiface III parallel port' CONFIG_PARPORT_MFC3 $CONFIG_PARPORT - fi - else - define_bool CONFIG_PARPORT_AMIGA n - define_bool CONFIG_PARPORT_MFC3 n - fi - if [ "$CONFIG_ATARI" = "y" ]; then - dep_tristate ' Atari hardware' CONFIG_PARPORT_ATARI $CONFIG_PARPORT - else - define_bool CONFIG_PARPORT_ATARI n - fi - if [ "$CONFIG_SBUS" = "y" ]; then - dep_tristate ' Sparc hardware (EXPERIMENTAL)' CONFIG_PARPORT_SUNBPP $CONFIG_PARPORT - else - define_bool CONFIG_PARPORT_SUNBPP n - fi + dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT + if [ "$CONFIG_PARPORT_PC" != "n" ]; then + bool ' Use FIFO/DMA if available' CONFIG_PARPORT_PC_FIFO + fi + if [ "$CONFIG_PARPORT_PC" = "y" ]; then + # Don't bother with this if parport_pc is a module; it only affects + # the presence or not of some __init's, which are no-ops for modules. + if [ "$CONFIG_PCMCIA" != "n" ]; then + bool ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA + fi + fi + if [ "$CONFIG_ARM" = "y" ]; then + dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + dep_tristate ' Amiga builtin port' CONFIG_PARPORT_AMIGA $CONFIG_PARPORT + if [ "$CONFIG_ZORRO" != "n" ]; then + dep_tristate ' Multiface III parallel port' CONFIG_PARPORT_MFC3 $CONFIG_PARPORT + fi + else + define_bool CONFIG_PARPORT_AMIGA n + define_bool CONFIG_PARPORT_MFC3 n + fi + if [ "$CONFIG_ATARI" = "y" ]; then + dep_tristate ' Atari hardware' CONFIG_PARPORT_ATARI $CONFIG_PARPORT + else + define_bool CONFIG_PARPORT_ATARI n + fi + if [ "$CONFIG_SBUS" = "y" ]; then + dep_tristate ' Sparc hardware (EXPERIMENTAL)' CONFIG_PARPORT_SUNBPP $CONFIG_PARPORT + else + define_bool CONFIG_PARPORT_SUNBPP n + fi - # If exactly one hardware type is selected then parport will optimise away - # support for loading any others. Defeat this if the user is keen. - bool ' Support foreign hardware' CONFIG_PARPORT_OTHER + # If exactly one hardware type is selected then parport will optimise away + # support for loading any others. Defeat this if the user is keen. + bool ' Support foreign hardware' CONFIG_PARPORT_OTHER - bool ' IEEE 1284 transfer modes' CONFIG_PARPORT_1284 + bool ' IEEE 1284 transfer modes' CONFIG_PARPORT_1284 fi diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index 8acf46f58..ba7fc1610 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c @@ -278,6 +278,9 @@ int parport_negotiate (struct parport *port, int mode) return -ENOSYS; /* FIXME (implement BECP) */ } + if (mode & IEEE1284_EXT_LINK) + m = 1<<7; /* request extensibility link */ + port->ieee1284.phase = IEEE1284_PH_NEGOTIATION; /* Start off with nStrobe and nAutoFd high, and nSelectIn low */ @@ -354,12 +357,59 @@ int parport_negotiate (struct parport *port, int mode) return 1; } + /* More to do if we've requested extensibility link. */ + if (mode & IEEE1284_EXT_LINK) { + m = mode & 0x7f; + udelay (1); + parport_write_data (port, m); + udelay (1); + + /* Event 51: Set nStrobe low */ + parport_frob_control (port, + PARPORT_CONTROL_STROBE, + PARPORT_CONTROL_STROBE); + + /* Event 53: Set nStrobe high */ + udelay (5); + parport_frob_control (port, + PARPORT_CONTROL_STROBE, + 0); + + /* Event 55: nAck goes high */ + if (parport_wait_peripheral (port, + PARPORT_STATUS_ACK, + PARPORT_STATUS_ACK)) { + /* This shouldn't really happen with a compliant + * device. */ + DPRINTK (KERN_DEBUG + "%s: Mode 0x%02x not supported? (0x%02x)\n", + port->name, mode, + port->ops->read_status (port)); + parport_ieee1284_terminate (port); + return 1; + } + + /* Event 54: Peripheral sets XFlag to reflect support */ + xflag = parport_read_status (port) & PARPORT_STATUS_SELECT; + + /* xflag should be high. */ + if (!xflag) { + /* Extended mode not supported. */ + DPRINTK (KERN_DEBUG "%s: Extended mode 0x%02x not " + "supported\n", port->name, mode); + parport_ieee1284_terminate (port); + return 1; + } + + /* Any further setup is left to the caller. */ + } + /* Mode is supported */ DPRINTK (KERN_DEBUG "%s: In mode 0x%02x\n", port->name, mode); port->ieee1284.mode = mode; /* But ECP is special */ - if (mode & IEEE1284_MODE_ECP) { + if (!(mode & IEEE1284_EXT_LINK) && (mode & IEEE1284_MODE_ECP)) { port->ieee1284.phase = IEEE1284_PH_ECP_SETUP; /* Event 30: Set nAutoFd low */ diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index a451d85b0..f6516d5b1 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -1207,7 +1207,7 @@ static int __maybe_init parport_ECP_supported(struct parport *pb) outb (ECR_SPP << 5, ECONTROL (pb)); /* Reset FIFO */ outb (0xf4, ECONTROL (pb)); /* Configuration mode */ - config = inb (FIFO (pb)); + config = inb (CONFIGA (pb)); pword = (config >> 4) & 0x7; switch (pword) { case 0: @@ -1230,10 +1230,10 @@ static int __maybe_init parport_ECP_supported(struct parport *pb) priv->pword = pword; printk (KERN_DEBUG "0x%lx: PWord is %d bits\n", pb->base, 8 * pword); - config = inb (CONFIGB (pb)); printk (KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", pb->base, config & 0x80 ? "Level" : "Pulses"); + config = inb (CONFIGB (pb)); if (!(config & 0x40)) { printk (KERN_WARNING "0x%lx: IRQ conflict!\n", pb->base); pb->irq = PARPORT_IRQ_NONE; @@ -1708,58 +1708,83 @@ static int __init parport_pc_init_pci (int irq, int dma) struct { unsigned int vendor; unsigned int device; + unsigned int subvendor; + unsigned int subdevice; unsigned int numports; struct { unsigned long lo; unsigned long hi; /* -ve if not there */ } addr[4]; } cards[] = { - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550, 1, - { { 3, 4 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650, 1, - { { 3, 4 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850, 1, - { { 3, 4 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_10x, 1, - { { 2, 3 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_10x, 2, - { { 2, 3 }, { 4, 5 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550, 1, - { { 4, 5 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650, 1, - { { 4, 5 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850, 1, - { { 4, 5 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_20x, 1, - { { 0, 1 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_20x, 2, - { { 0, 1 }, { 2, 3 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550, 2, - { { 1, 2 }, { 3, 4 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650, 2, - { { 1, 2 }, { 3, 4 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850, 2, - { { 1, 2 }, { 3, 4 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550, 1, - { { 1, 2 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650, 1, - { { 1, 2 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850, 1, - { { 1, 2 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550, 1, - { { 2, 3 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650, 1, - { { 2, 3 }, } }, - { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850, 1, - { { 2, 3 }, } }, - { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PARALLEL, 1, - { { 0, -1 }, } }, - { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_A, 1, - { { 0, -1 }, } }, - { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_B, 1, - { { 0, -1 }, } }, - { PCI_VENDOR_ID_EXSYS, PCI_DEVICE_ID_EXSYS_4014, 2, - { { 2, -1 }, { 3, -1 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 3, 4 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 3, 4 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 3, 4 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_10x, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 2, 3 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_10x, + PCI_ANY_ID, PCI_ANY_ID, + 2, { { 2, 3 }, { 4, 5 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 4, 5 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 4, 5 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 4, 5 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_20x, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 0, 1 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_20x, + PCI_ANY_ID, PCI_ANY_ID, + 2, { { 0, 1 }, { 2, 3 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550, + PCI_ANY_ID, PCI_ANY_ID, + 2, { { 1, 2 }, { 3, 4 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650, + PCI_ANY_ID, PCI_ANY_ID, + 2, { { 1, 2 }, { 3, 4 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850, + PCI_ANY_ID, PCI_ANY_ID, + 2, { { 1, 2 }, { 3, 4 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 1, 2 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 1, 2 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 1, 2 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 2, 3 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 2, 3 }, } }, + { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 2, 3 }, } }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PARALLEL, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 0, -1 }, } }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_A, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 0, -1 }, } }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_B, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 0, -1 }, } }, + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, + PCI_SUBVENDOR_ID_EXSYS, PCI_SUBDEVICE_ID_EXSYS_4014, + 2, { { 4, -1 }, { 5, -1 }, } }, { 0, } }; @@ -1776,6 +1801,15 @@ static int __init parport_pc_init_pci (int irq, int dma) cards[i].device, pcidev)) != NULL) { int n; + + if (cards[i].subvendor != PCI_ANY_ID && + cards[i].subvendor != pcidev->subsystem_vendor) + continue; + + if (cards[i].subdevice != PCI_ANY_ID && + cards[i].subdevice != pcidev->subsystem_device) + continue; + for (n = 0; n < cards[i].numports; n++) { unsigned long lo = cards[i].addr[n].lo; unsigned long hi = cards[i].addr[n].hi; |