[PARPORT] [patch] ieee1284 nibble mode


Andrea Arcangeli (andrea@e-mind.com)
Wed, 20 Jan 1999 22:15:49 +0100 (CET)


There's a lot of mess in the ieee1284 detection (I never took a look at it
before today). The _main_ problem is that only free specs I found is at
http://www.fapo.com/ and disagree in many points with the official kernel
code and with the new IEEE1284 patches from Tim. And the specs itself
looks not trustable since it's buggy in some points. Ah and please Tim and
Carsten ignore my previous patch I sent to you to try out because I did
not understood the mess of nSIGNAL which logical level is reversed from
the graphics I found on the web.

More bad the 2.2.0 kernel code disagree with Tim's code.

I discovered now that my printer support IEEE1284 mode (because in Tim's
1284code with debugging enabled parport_probe died in nibble_read and not
in parport_negotiation ;).

So I fixed Tim's latest code for my hardware. The most wrong thing I can
see here is that PARPORT_STATUS_ERROR is `random' set here, and to know
when the printer has finished I had to wait for a timeout ;). Really it's
not random, it's set at count == 1, 2, 4, 6, 8, 9, 11, and other strange
fixed sequence numbers. I see it completly unrealiable though.

There's also a bug in parport_read() that when it has to change mode it
doesn't send the ID request, and so it was requesting mode 0x0 (not
supported here) instead of the real normal nibble mode 0x4.

This patch against the latest Tim's 1284 code I merged, fix everything
here (P2B motherboard and Epson Stylus Color 740 printer), with this patch
applyed both parport_probing and lp readback works fine.

Index: parport_ieee1284.c
===================================================================
RCS file: /var/cvs/linux/drivers/misc/parport_ieee1284.c,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.5
diff -u -r1.1.2.2 -r1.1.2.5
--- parport_ieee1284.c 1999/01/19 23:24:44 1.1.2.2
+++ linux/drivers/misc/parport_ieee1284.c 1999/01/20 20:37:03 1.1.2.5
@@ -5,6 +5,8 @@
  * Carsten Gross <carsten@sol.wohnheim.uni-ulm.de>
  * Jose Renau <renau@acm.org>
  * Tim Waugh <tim@cyberelk.demon.co.uk> (largely rewritten)
+ *
+ * BugFix: Andrea Arcangeli
  */
 
 #include <linux/tasks.h>
@@ -189,8 +191,14 @@
                               0);
 
         /* Event 6: nAck goes high */
- parport_wait_peripheral (port,
- PARPORT_STATUS_ACK, PARPORT_STATUS_ACK);
+ if (parport_wait_peripheral (port, PARPORT_STATUS_ACK,
+ PARPORT_STATUS_ACK))
+ {
+ /* Timeout */
+ DPRINTK (KERN_DEBUG "Peripheral not IEEE1284 compliant - 2\n");
+ port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
+ return -1; /* Not IEEE1284 compliant */
+ }
 
         xflag = parport_read_status (port) & PARPORT_STATUS_SELECT;
         /* xflag should be high for all modes other than nibble (0) */
@@ -392,7 +400,9 @@
         /* Use the mode we're in. */
         switch (mode) {
         case IEEE1284_MODE_COMPAT:
- if (parport_negotiate (port, IEEE1284_MODE_NIBBLE))
+ DPRINTK (KERN_DEBUG "Going to nibble mode\n");
+ if (parport_negotiate (port, IEEE1284_MODE_NIBBLE |
+ IEEE1284_DEVICEID))
                         return -EIO;
         case IEEE1284_MODE_NIBBLE:
                 DPRINTK (KERN_DEBUG "Using nibble mode\n");
Index: parport_ieee1284_ops.c
===================================================================
RCS file: /var/cvs/linux/drivers/misc/parport_ieee1284_ops.c,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.4
diff -u -r1.1.2.2 -r1.1.2.4
--- parport_ieee1284_ops.c 1999/01/19 23:24:44 1.1.2.2
+++ linux/drivers/misc/parport_ieee1284_ops.c 1999/01/20 20:36:07 1.1.2.4
@@ -1,6 +1,8 @@
 /* IEEE-1284 operations for parport.
  *
  * Author: Tim Waugh <tim@cyberelk.demon.co.uk>
+ *
+ * BugFix: Andrea Arcangeli
  */
 
 #include <linux/parport.h>
@@ -269,10 +271,14 @@
         unsigned char byte = 0;
         ssize_t count = 0;
 
+ /* no 1284 mode -arca */
+ parport_frob_control (port, PARPORT_CONTROL_SELECT, 0);
+
         len *= 2; /* in nibbles */
         for (i=0; i < len; i++) {
                 unsigned char nibble;
 
+#if 0 /* completly breaks Epson Stylus Color */
                 /* Does the error line indicate end of data? */
                 if (parport_read_status(port) & PARPORT_STATUS_ERROR) {
                         port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
@@ -287,6 +293,7 @@
                         port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
                         break;
                 }
+#endif
 
                 /* Event 7: Set nAutoFd low. */
                 parport_frob_control (port,
@@ -330,9 +337,6 @@
                         count++;
                 } else
                         byte = nibble;
-
- /* Canon BJC-210 seems to assert nAck too early. */
- udelay (1);
         }
 
         if (i == len) {

I removed also Tim's printer hack ;) because it looks to me suspectious
that there's a so silly bug in the hardware while instead everything else
in it works fine...

Now that I know how to drive the ieee1284 negotiate and nibble mode I also
put in sync the parport_ieee1284.c file in clean pre8. If this patch is
fine it should go into Linus's tree:

Index: parport_ieee1284.c
===================================================================
RCS file: /var/cvs/linux/drivers/misc/parport_ieee1284.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 parport_ieee1284.c
--- parport_ieee1284.c 1999/01/18 01:28:54 1.1.1.1
+++ linux/drivers/misc/parport_ieee1284.c 1999/01/20 20:50:13
@@ -4,6 +4,7 @@
  * Authors: Phil Blundell <Philip.Blundell@pobox.com>
  * Carsten Gross <carsten@sol.wohnheim.uni-ulm.de>
  * Jose Renau <renau@acm.org>
+ * Andrea Arcangeli
  */
 
 #include <linux/tasks.h>
@@ -47,22 +48,29 @@
  */
 int parport_ieee1284_nibble_mode_ok(struct parport *port, unsigned char mode)
 {
+ unsigned char backup;
+
+ backup = parport_read_control(port);
+
         parport_write_data(port, mode);
- udelay(500);
+ udelay(5);
         /* nSelectIn high, nAutoFd low */
         parport_write_control(port, (parport_read_control(port) & ~8) | 2);
         if (parport_wait_peripheral(port, 0x78, 0x38)) {
- parport_write_control(port,
- (parport_read_control(port) & ~2) | 8);
+ parport_write_control(port, backup);
                 return 0;
         }
+
         /* nStrobe low */
         parport_write_control(port, parport_read_control(port) | 1);
         udelay(5); /* Strobe wait */
- /* nStrobe high */
- parport_write_control(port, parport_read_control(port) & ~1);
- udelay(5);
- /* nAutoFd low */
- parport_write_control(port, parport_read_control(port) & ~2);
- return (parport_wait_peripheral(port, 0x20, 0))?2:1;
+ /* nStrobe and nAutoFd high */
+ parport_write_control(port, (parport_read_control(port) & ~1) | ~2);
+
+ if (parport_wait_peripheral(port, 0x40, 0x40))
+ {
+ parport_write_control(port, backup);
+ return 0;
+ }
+ return parport_read_status(port) & 0x10 ? 2 : 1;
 }

Comments from other parport guys?

Andrea Arcangeli

-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --



This archive was generated by hypermail 2.0b3 on Wed 20 Jan 1999 - 16:19:24 EST