diff options
author | Marko Kohtala <marko.kohtala@gmail.com> | 2006-01-06 00:19:45 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 08:33:56 -0800 |
commit | 310c8c324f988625a2880deab67607bf4e5aeb8a (patch) | |
tree | 7b295c4d0875455b332534902fca5739678f28ff /drivers/parport | |
parent | 742ec650e9b63ea61891455bb6f76bac37025c78 (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')
-rw-r--r-- | drivers/parport/daisy.c | 27 |
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); |