[Linux-parport] [PATCH] IEEE1284.3 chain end detection fix

Marko Kohtala marko.kohtala at luukku.com
Mon Jan 10 13:28:01 EST 2005


My Kodak Advantix FD 300 does not detect itself as last device in chain. This 
patch fixes the address assignment stop when it sees status from non 
IEEE1284.3 device. Also the logic for last_dev was broken because it assigned 
address one past the last device.

It now correctly finds my one broken DC device, but I have no working device 
to test it with. Please test.

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/01/09 23:31:28+02:00 kohtala at kohtala.home.org
#   Fix parport IEEE1284.3 daisy chain end detection.
#
# drivers/parport/daisy.c
#   2005/01/09 23:31:15+02:00 kohtala at kohtala.home.org +17 -10
#   Some buggy daisy chain devices do not implement last_dev. Detect the end of
#   chain from other false status lines. It used to assign address to device past
#   the last.
#
diff -Nru a/drivers/parport/daisy.c b/drivers/parport/daisy.c
--- a/drivers/parport/daisy.c	2005-01-10 07:58:34 +02:00
+++ b/drivers/parport/daisy.c	2005-01-10 07:58:34 +02:00
@@ -436,7 +436,7 @@

  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 @@
  	}

  	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 @@
  		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);




More information about the Linux-parport mailing list