patch-2.1.47 linux/drivers/misc/parport_ieee1284.c
Next file: linux/drivers/misc/parport_init.c
Previous file: linux/drivers/misc/parport_arc.c
Back to the patch index
Back to the overall index
- Lines: 90
- Date:
Wed Jul 23 11:07:59 1997
- Orig file:
v2.1.46/linux/drivers/misc/parport_ieee1284.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.1.46/linux/drivers/misc/parport_ieee1284.c linux/drivers/misc/parport_ieee1284.c
@@ -0,0 +1,89 @@
+/* $Id$
+ * IEEE-1284 implementation for parport.
+ *
+ * Authors: Philip Blundell <pjb27@cam.ac.uk>
+ * Carsten Gross <carsten@sol.wohnheim.uni-ulm.de>
+ * Jose Renau <renau@acm.org>
+ */
+
+#include <linux/tasks.h>
+
+#include <linux/parport.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+
+/* The following read functions are an implementation of a status readback
+ * and device id request confirming to IEEE1284-1994.
+ *
+ * These probably ought to go in some seperate file, so people like the SPARC
+ * don't have to pull them in.
+ */
+
+/* Wait for Status line(s) to change in 35 ms - see IEEE1284-1994 page 24 to
+ * 25 for this. After this time we can create a timeout because the
+ * peripheral doesn't conform to IEEE1284. We want to save CPU time: we are
+ * waiting a maximum time of 500 us busy (this is for speed). If there is
+ * not the right answer in this time, we call schedule and other processes
+ * are able "to eat" the time up to 30ms. So the maximum load avarage can't
+ * get above 5% for a read even if the peripheral is really slow. (but your
+ * read gets very slow then - only about 10 characters per second. This
+ * should be tuneable). Thanks to Andreas who pointed me to this and ordered
+ * the documentation.
+ */
+
+int parport_wait_peripheral(struct parport *port, unsigned char mask,
+ unsigned char result)
+{
+ int counter=0;
+ unsigned char status;
+
+ do {
+ status = parport_read_status(port);
+ udelay(25);
+ counter++;
+ if (need_resched)
+ schedule();
+ } while ( ((status & mask) != result) && (counter < 20) );
+ if ( (counter == 20) && ((status & mask) != result) ) {
+ current->state=TASK_INTERRUPTIBLE;
+ current->timeout=jiffies+4;
+ schedule(); /* wait for 4 scheduler runs (40ms) */
+ status = parport_read_status(port);
+ if ((status & mask) != result) return 1; /* timeout */
+ }
+ return 0; /* okay right response from device */
+}
+
+/* Test if nibble mode for status readback is okay. Returns the value false
+ * if the printer doesn't support readback at all. If it supports readbacks
+ * and printer data is available the function returns 1, otherwise 2. The
+ * only valid values for "mode" are 0 and 4. 0 requests normal nibble mode,
+ * 4 is for "request device id using nibble mode". The request for the
+ * device id is best done in an ioctl (or at bootup time). There is no
+ * check for an invalid value, the only function using this call at the
+ * moment is lp_read and the ioctl LPGETDEVICEID both fixed calls from
+ * trusted kernel.
+ */
+int parport_ieee1284_nibble_mode_ok(struct parport *port, unsigned char mode)
+{
+ parport_write_data(port, mode);
+ udelay(5);
+ parport_write_control(port, parport_read_control(port) & ~8); /* SelectIN low */
+ parport_write_control(port, parport_read_control(port) | 2); /* AutoFeed high */
+ if (parport_wait_peripheral(port, 0x78, 0x38)) { /* timeout? */
+ parport_write_control(port, (parport_read_control(port) & ~2) | 8);
+ return 0; /* first stage of negotiation failed,
+ * no IEEE1284 compliant device on this port
+ */
+ }
+ parport_write_control(port, parport_read_control(port) | 1); /* Strobe high */
+ udelay(5); /* Strobe wait */
+ parport_write_control(port, parport_read_control(port) & ~1); /* Strobe low */
+ udelay(5);
+ parport_write_control(port, parport_read_control(port) & ~2); /* AutoFeed low */
+ return (parport_wait_peripheral(port, 0x20, 0))?2:1;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov