diff options
author | Marko Kohtala <marko.kohtala@gmail.com> | 2006-01-06 03:19:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:56 -0500 |
commit | 310c8c324f988625a2880deab67607bf4e5aeb8a (patch) | |
tree | 7b295c4d0875455b332534902fca5739678f28ff /drivers | |
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')
-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) | |||
436 | 436 | ||
437 | static int assign_addrs (struct parport *port) | 437 | static int assign_addrs (struct parport *port) |
438 | { | 438 | { |
439 | unsigned char s, last_dev; | 439 | unsigned char s; |
440 | unsigned char daisy; | 440 | unsigned char daisy; |
441 | int thisdev = numdevs; | 441 | int thisdev = numdevs; |
442 | int detected; | 442 | int detected; |
@@ -472,10 +472,13 @@ static int assign_addrs (struct parport *port) | |||
472 | } | 472 | } |
473 | 473 | ||
474 | parport_write_data (port, 0x78); udelay (2); | 474 | parport_write_data (port, 0x78); udelay (2); |
475 | last_dev = 0; /* We've just been speaking to a device, so we | 475 | s = parport_read_status (port); |
476 | know there must be at least _one_ out there. */ | ||
477 | 476 | ||
478 | for (daisy = 0; daisy < 4; daisy++) { | 477 | for (daisy = 0; |
478 | (s & (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT)) | ||
479 | == (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT) | ||
480 | && daisy < 4; | ||
481 | ++daisy) { | ||
479 | parport_write_data (port, daisy); | 482 | parport_write_data (port, daisy); |
480 | udelay (2); | 483 | udelay (2); |
481 | parport_frob_control (port, | 484 | parport_frob_control (port, |
@@ -485,14 +488,18 @@ static int assign_addrs (struct parport *port) | |||
485 | parport_frob_control (port, PARPORT_CONTROL_STROBE, 0); | 488 | parport_frob_control (port, PARPORT_CONTROL_STROBE, 0); |
486 | udelay (1); | 489 | udelay (1); |
487 | 490 | ||
488 | if (last_dev) | 491 | add_dev (numdevs++, port, daisy); |
489 | /* No more devices. */ | ||
490 | break; | ||
491 | 492 | ||
492 | last_dev = !(parport_read_status (port) | 493 | /* See if this device thought it was the last in the |
493 | & PARPORT_STATUS_BUSY); | 494 | * chain. */ |
495 | if (!(s & PARPORT_STATUS_BUSY)) | ||
496 | break; | ||
494 | 497 | ||
495 | add_dev (numdevs++, port, daisy); | 498 | /* We are seeing pass through status now. We see |
499 | last_dev from next device or if last_dev does not | ||
500 | work status lines from some non-daisy chain | ||
501 | device. */ | ||
502 | s = parport_read_status (port); | ||
496 | } | 503 | } |
497 | 504 | ||
498 | parport_write_data (port, 0xff); udelay (2); | 505 | parport_write_data (port, 0xff); udelay (2); |