aboutsummaryrefslogtreecommitdiff
path: root/drivers/parport/daisy.c
diff options
context:
space:
mode:
authorMarko Kohtala2006-01-06 00:19:45 -0800
committerLinus Torvalds2006-01-06 08:33:56 -0800
commit310c8c324f988625a2880deab67607bf4e5aeb8a (patch)
tree7b295c4d0875455b332534902fca5739678f28ff /drivers/parport/daisy.c
parent742ec650e9b63ea61891455bb6f76bac37025c78 (diff)
[PATCH] parport: daisy chain end detection fix
Daisy chain end detection failed at least with older daisy chain devices that do not implement the last device signal. Signed-off-by: Marko Kohtala <marko.kohtala@gmail.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/parport/daisy.c')
-rw-r--r--drivers/parport/daisy.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c
index 075c7eb5c85d..6915114b9536 100644
--- a/drivers/parport/daisy.c
+++ b/drivers/parport/daisy.c
@@ -436,7 +436,7 @@ static int select_port (struct parport *port)
static int assign_addrs (struct parport *port)
{
- unsigned char s, last_dev;
+ unsigned char s;
unsigned char daisy;
int thisdev = numdevs;
int detected;
@@ -472,10 +472,13 @@ static int assign_addrs (struct parport *port)
}
parport_write_data (port, 0x78); udelay (2);
- last_dev = 0; /* We've just been speaking to a device, so we
- know there must be at least _one_ out there. */
+ s = parport_read_status (port);
- for (daisy = 0; daisy < 4; daisy++) {
+ for (daisy = 0;
+ (s & (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT))
+ == (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT)
+ && daisy < 4;
+ ++daisy) {
parport_write_data (port, daisy);
udelay (2);
parport_frob_control (port,
@@ -485,14 +488,18 @@ static int assign_addrs (struct parport *port)
parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
udelay (1);
- if (last_dev)
- /* No more devices. */
- break;
+ add_dev (numdevs++, port, daisy);
- last_dev = !(parport_read_status (port)
- & PARPORT_STATUS_BUSY);
+ /* See if this device thought it was the last in the
+ * chain. */
+ if (!(s & PARPORT_STATUS_BUSY))
+ break;
- add_dev (numdevs++, port, daisy);
+ /* We are seeing pass through status now. We see
+ last_dev from next device or if last_dev does not
+ work status lines from some non-daisy chain
+ device. */
+ s = parport_read_status (port);
}
parport_write_data (port, 0xff); udelay (2);