summaryrefslogtreecommitdiffstats
path: root/drivers/parport
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parport')
-rw-r--r--drivers/parport/Config.in72
-rw-r--r--drivers/parport/ieee1284.c52
-rw-r--r--drivers/parport/parport_pc.c130
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;