From: Marko Kohtala 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 Signed-off-by: Andrew Morton --- drivers/parport/daisy.c | 27 +++++++++++++++++---------- 1 files changed, 17 insertions(+), 10 deletions(-) diff -puN drivers/parport/daisy.c~parport-daisy-chain-end-detection-fix drivers/parport/daisy.c --- 25/drivers/parport/daisy.c~parport-daisy-chain-end-detection-fix Wed Sep 7 14:38:25 2005 +++ 25-akpm/drivers/parport/daisy.c Wed Sep 7 14:38:25 2005 @@ -436,7 +436,7 @@ static int select_port (struct parport * 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 } 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 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); _