Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 310c8c32 authored by Marko Kohtala's avatar Marko Kohtala Committed by Linus Torvalds
Browse files

[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: default avatarMarko Kohtala <marko.kohtala@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 742ec650
Loading
Loading
Loading
Loading
+17 −10
Original line number Diff line number Diff line
@@ -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);