Tim Waugh (twaugh@redhat.com)
Fri, 5 Nov 1999 12:26:42 +0000 (GMT)
Hi guys,
EPP timeouts are much shorter than for other protocols. I've added
parport_poll_peripheral to do the 'short wait' bit of
parport_wait_peripheral, and modified the EPP functions to use it.
They all looked wrong actually. Has anyone tested 2.3.x EPP support
(through ppdev or parport), or are they in a position to do so?
Here's the patch I have.
Tim.
*/
Index: linux/drivers/parport/ieee1284.c
diff -u linux/drivers/parport/ieee1284.c:1.1.1.4 linux/drivers/parport/ieee1284.c:1.6
--- linux/drivers/parport/ieee1284.c:1.1.1.4 Fri Oct 15 18:54:14 1999
+++ linux/drivers/parport/ieee1284.c Fri Nov 5 10:59:50 1999
@@ -80,19 +80,42 @@
* are able to eat the time up to 40ms.
*/
+int parport_poll_peripheral(struct parport *port,
+ unsigned char mask,
+ unsigned char result,
+ int usec)
+{
+ /* Zero return code is success, >0 is timeout. */
+ int counter = usec / 5;
+ unsigned char status;
+ for (; counter > 0; counter--) {
+ status = parport_read_status (port);
+ if ((status & mask) == result)
+ return 0;
+ if (signal_pending (current))
+ return -EINTR;
+ if (current->need_resched)
+ break;
+ udelay (5);
+ }
+
+ return 1;
+}
+
int parport_wait_peripheral(struct parport *port,
unsigned char mask,
unsigned char result)
{
- int counter;
+ int ret;
+ int usec;
long deadline;
unsigned char status;
- counter = port->physport->spintime; /* usecs of fast polling */
+ usec = port->physport->spintime; /* usecs of fast polling */
if (!port->physport->cad->timeout)
/* A zero timeout is "special": busy wait for the
entire 35ms. */
- counter = 35000;
+ usec = 35000;
/* Fast polling.
*
@@ -100,16 +123,9 @@
* How about making a note (in the device structure) of how long
* it takes, so we know for next time?
*/
- for (counter /= 5; counter > 0; counter--) {
- status = parport_read_status (port);
- if ((status & mask) == result)
- return 0;
- if (signal_pending (current))
- return -EINTR;
- if (current->need_resched)
- break;
- udelay(5);
- }
+ ret = parport_poll_peripheral (port, mask, result, usec);
+ if (ret != 1)
+ return ret;
if (!port->physport->cad->timeout)
/* We may be in an interrupt handler, so we can't poll
@@ -369,8 +385,17 @@
PARPORT_CONTROL_STROBE,
PARPORT_CONTROL_STROBE);
+ /* Event 52: nAck goes low */
+ if (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) {
+ /* This peripheral is _very_ slow. */
+ DPRINTK (KERN_DEBUG
+ "%s: Event 52 didn't happen\n",
+ port->name);
+ parport_ieee1284_terminate (port);
+ return 1;
+ }
+
/* Event 53: Set nStrobe high */
- udelay (5);
parport_frob_control (port,
PARPORT_CONTROL_STROBE,
0);
Index: linux/drivers/parport/ieee1284_ops.c
diff -u linux/drivers/parport/ieee1284_ops.c:1.1.1.2 linux/drivers/parport/ieee1284_ops.c:1.3
--- linux/drivers/parport/ieee1284_ops.c:1.1.1.2 Thu Oct 7 22:32:08 1999
+++ linux/drivers/parport/ieee1284_ops.c Fri Nov 5 10:59:50 1999
@@ -734,23 +734,29 @@
PARPORT_CONTROL_SELECT);
port->ops->data_forward (port);
for (; len > 0; len--, bp++) {
+ /* Event 62: Write data and strobe data */
parport_write_data (port, *bp);
-
- if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY,
- PARPORT_STATUS_BUSY))
- break;
-
- /* Strobe data */
parport_frob_control (port, PARPORT_CONTROL_AUTOFD,
PARPORT_CONTROL_AUTOFD);
- if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY, 0))
+ /* Event 58 */
+ if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 10))
break;
+ /* Event 63 */
parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
+
+ /* Event 60 */
+ if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
+ PARPORT_STATUS_BUSY, 5))
+ break;
+
ret++;
}
+ /* Event 61 */
+ parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
+
return ret;
}
@@ -765,23 +771,24 @@
parport_frob_control (port,
PARPORT_CONTROL_STROBE |
- PARPORT_CONTROL_AUTOFD |
PARPORT_CONTROL_SELECT, 0);
port->ops->data_reverse (port);
for (; len > 0; len--, bp++) {
- if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY,
- PARPORT_STATUS_BUSY))
+ parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
+
+ /* Event 58 */
+ if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
+ PARPORT_STATUS_BUSY, 10))
break;
+ *bp = parport_read_data (port);
+
parport_frob_control (port, PARPORT_CONTROL_AUTOFD,
PARPORT_CONTROL_AUTOFD);
- if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY, 0))
+ if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 5))
break;
- *bp = parport_read_data (port);
-
- parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
ret++;
}
port->ops->data_forward (port);
@@ -806,23 +813,25 @@
PARPORT_CONTROL_SELECT);
port->ops->data_forward (port);
for (; len > 0; len--, bp++) {
+ /* Write data and assert nAStrb. */
parport_write_data (port, *bp);
-
- if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY,
- PARPORT_STATUS_BUSY))
- break;
-
- /* Strobe data */
parport_frob_control (port, PARPORT_CONTROL_SELECT,
PARPORT_CONTROL_SELECT);
- if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY, 0))
+ if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
+ PARPORT_STATUS_BUSY, 10))
break;
parport_frob_control (port, PARPORT_CONTROL_SELECT, 0);
+
+ if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 5))
+ break;
+
ret++;
}
+ parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
+
return ret;
}
@@ -837,23 +846,24 @@
parport_frob_control (port,
PARPORT_CONTROL_STROBE |
- PARPORT_CONTROL_SELECT |
PARPORT_CONTROL_AUTOFD, 0);
port->ops->data_reverse (port);
for (; len > 0; len--, bp++) {
- if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY,
- PARPORT_STATUS_BUSY))
+ parport_frob_control (port, PARPORT_CONTROL_SELECT, 0);
+
+ /* Event 58 */
+ if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
+ PARPORT_STATUS_BUSY, 10))
break;
+ *bp = parport_read_data (port);
+
parport_frob_control (port, PARPORT_CONTROL_SELECT,
PARPORT_CONTROL_SELECT);
- if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY, 0))
+ if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 5))
break;
- *bp = parport_read_data (port);
-
- parport_frob_control (port, PARPORT_CONTROL_SELECT, 0);
ret++;
}
port->ops->data_forward (port);
Index: linux/drivers/parport/init.c
diff -u linux/drivers/parport/init.c:1.1.1.3 linux/drivers/parport/init.c:1.4
--- linux/drivers/parport/init.c:1.1.1.3 Fri Oct 8 08:12:38 1999
+++ linux/drivers/parport/init.c Fri Nov 5 10:59:50 1999
@@ -181,6 +181,7 @@
EXPORT_SYMBOL(parport_read);
EXPORT_SYMBOL(parport_ieee1284_wakeup);
EXPORT_SYMBOL(parport_wait_peripheral);
+EXPORT_SYMBOL(parport_poll_peripheral);
EXPORT_SYMBOL(parport_wait_event);
EXPORT_SYMBOL(parport_set_timeout);
EXPORT_SYMBOL(parport_ieee1284_interrupt);
Index: linux/include/linux/parport.h
diff -u linux/include/linux/parport.h:1.1.1.3 linux/include/linux/parport.h:1.4
--- linux/include/linux/parport.h:1.1.1.3 Fri Oct 15 18:50:08 1999
+++ linux/include/linux/parport.h Fri Nov 5 10:59:52 1999
@@ -422,6 +422,10 @@
extern int parport_wait_peripheral (struct parport *port,
unsigned char mask,
unsigned char val);
+extern int parport_poll_peripheral (struct parport *port,
+ unsigned char mask,
+ unsigned char val,
+ int usec);
/* For architectural drivers */
extern void parport_ieee1284_wakeup (struct parport *port);
-- 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 Fri 05 Nov 1999 - 07:28:59 EST