patch-2.3.13 linux/drivers/parport/ieee1284_ops.c
Next file: linux/drivers/parport/init.c
Previous file: linux/drivers/parport/ieee1284.c
Back to the patch index
Back to the overall index
- Lines: 274
- Date:
Fri Aug 6 15:25:47 1999
- Orig file:
v2.3.12/linux/drivers/parport/ieee1284_ops.c
- Orig date:
Wed Jul 28 14:47:42 1999
diff -u --recursive --new-file v2.3.12/linux/drivers/parport/ieee1284_ops.c linux/drivers/parport/ieee1284_ops.c
@@ -43,6 +43,7 @@
const void *buffer, size_t len,
int flags)
{
+ int no_irq;
ssize_t count = 0;
const unsigned char *addr = buffer;
unsigned char byte;
@@ -54,6 +55,7 @@
parport_enable_irq (port);
port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
+ no_irq = polling (dev);
while (count < len) {
long expire = jiffies + dev->timeout;
long wait = (HZ + 99) / 100;
@@ -97,7 +99,7 @@
first time around the loop, don't let go of
the port. This way, we find out if we have
our interrupt handler called. */
- if (count && polling (dev)) {
+ if (count && no_irq) {
parport_release (dev);
current->state = TASK_INTERRUPTIBLE;
schedule_timeout (wait);
@@ -129,14 +131,30 @@
parport_write_control (port, ctl);
udelay (1); /* hold */
- /* Wait until it's received (up to 20us). */
- for (i = 0; i < 20; i++) {
+ if (no_irq)
+ /* Assume the peripheral received it. */
+ goto done;
+
+ /* Wait until it's received, up to 500us (this ought to be
+ * tuneable). */
+ for (i = 500; i; i--) {
if (!down_trylock (&port->physport->ieee1284.irq) ||
!(parport_read_status (port) & PARPORT_STATUS_ACK))
- break;
+ goto done;
udelay (1);
}
+ /* Two choices:
+ * 1. Assume that the peripheral got the data and just
+ * hasn't acknowledged it yet.
+ * 2. Assume that the peripheral never saw the strobe pulse.
+ *
+ * We can't know for sure, so let's be conservative.
+ */
+ DPRINTK (KERN_DEBUG "%s: no ack", port->name);
+ break;
+
+ done:
count++;
/* Let another process run if it needs to. */
@@ -344,14 +362,14 @@
/* Event 38: Set nAutoFd low */
parport_frob_control (port,
PARPORT_CONTROL_AUTOFD,
- PARPORT_CONTROL_AUTOFD);
+ 0);
parport_data_reverse (port);
udelay (5);
/* Event 39: Set nInit low to initiate bus reversal */
parport_frob_control (port,
PARPORT_CONTROL_INIT,
- PARPORT_CONTROL_INIT);
+ 0);
/* Event 40: PError goes low */
retval = parport_wait_peripheral (port,
@@ -373,9 +391,10 @@
/* Event 47: Set nInit high */
parport_frob_control (port,
- PARPORT_CONTROL_INIT,
- PARPORT_CONTROL_INIT);
- parport_data_reverse (port);
+ PARPORT_CONTROL_INIT
+ | PARPORT_CONTROL_AUTOFD,
+ PARPORT_CONTROL_INIT
+ | PARPORT_CONTROL_AUTOFD);
/* Event 49: PError goes high */
retval = parport_wait_peripheral (port,
@@ -404,7 +423,6 @@
#else
const unsigned char *buf = buffer;
size_t written;
- int ctl = parport_read_control (port) & ~PARPORT_CONTROL_AUTOFD;
int retry;
port = port->physport;
@@ -416,7 +434,11 @@
port->ieee1284.phase = IEEE1284_PH_FWD_DATA;
/* HostAck high (data, not command) */
- parport_write_control (port, ctl);
+ parport_frob_control (port,
+ PARPORT_CONTROL_AUTOFD
+ | PARPORT_CONTROL_STROBE
+ | PARPORT_CONTROL_INIT,
+ PARPORT_CONTROL_INIT);
for (written = 0; written < len; written++, buf++) {
long expire = jiffies + port->cad->timeout;
unsigned char byte;
@@ -424,7 +446,8 @@
byte = *buf;
try_again:
parport_write_data (port, byte);
- parport_write_control (port, ctl | PARPORT_CONTROL_STROBE);
+ parport_frob_control (port, PARPORT_CONTROL_STROBE,
+ PARPORT_CONTROL_STROBE);
udelay (5);
for (retry = 0; retry < 100; retry++) {
if (!parport_wait_peripheral (port,
@@ -432,7 +455,9 @@
goto success;
if (signal_pending (current)) {
- parport_write_control (port, ctl);
+ parport_frob_control (port,
+ PARPORT_CONTROL_STROBE,
+ 0);
break;
}
}
@@ -440,15 +465,16 @@
/* Time for Host Transfer Recovery (page 41 of IEEE1284) */
DPRINTK (KERN_DEBUG "%s: ECP transfer stalled!\n", port->name);
- parport_write_control (port, ctl | PARPORT_CONTROL_INIT);
+ parport_frob_control (port, PARPORT_CONTROL_INIT,
+ PARPORT_CONTROL_INIT);
udelay (50);
if (parport_read_status (port) & PARPORT_STATUS_PAPEROUT) {
/* It's buggered. */
- parport_write_control (port, ctl);
+ parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
break;
}
- parport_write_control (port, ctl);
+ parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
udelay (50);
if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT))
break;
@@ -459,7 +485,7 @@
if (time_after_eq (jiffies, expire)) break;
goto try_again;
success:
- parport_write_control (port, ctl);
+ parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
udelay (5);
if (parport_wait_peripheral (port,
PARPORT_STATUS_BUSY,
@@ -496,7 +522,10 @@
port->ieee1284.phase = IEEE1284_PH_REV_DATA;
/* Set HostAck low to start accepting data. */
- parport_frob_control (port, PARPORT_CONTROL_AUTOFD,
+ parport_frob_control (port,
+ PARPORT_CONTROL_AUTOFD
+ | PARPORT_CONTROL_STROBE
+ | PARPORT_CONTROL_INIT,
PARPORT_CONTROL_AUTOFD);
while (count < len) {
long expire = jiffies + dev->timeout;
@@ -505,9 +534,7 @@
/* Event 43: Peripheral sets nAck low. It can take as
long as it wants. */
- while (parport_wait_peripheral (port,
- PARPORT_STATUS_ACK,
- PARPORT_STATUS_ACK)) {
+ while (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) {
/* The peripheral hasn't given us data in
35ms. If we have data to give back to the
caller, do it now. */
@@ -578,7 +605,8 @@
parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
/* Event 45: The peripheral has 35ms to set nAck high. */
- if (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) {
+ if (parport_wait_peripheral (port, PARPORT_STATUS_ACK,
+ PARPORT_STATUS_ACK)) {
/* It's gone wrong. Return what data we have
to the caller. */
DPRINTK (KERN_DEBUG "ECP read timed out at 45\n");
@@ -615,6 +643,7 @@
}
out:
+ port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
return count;
#endif /* IEEE1284 support */
}
@@ -629,7 +658,6 @@
#else
const unsigned char *buf = buffer;
size_t written;
- int ctl = parport_read_control (port) | PARPORT_CONTROL_AUTOFD;
int retry;
port = port->physport;
@@ -641,7 +669,12 @@
port->ieee1284.phase = IEEE1284_PH_FWD_DATA;
/* HostAck low (command, not data) */
- parport_write_control (port, ctl);
+ parport_frob_control (port,
+ PARPORT_CONTROL_AUTOFD
+ | PARPORT_CONTROL_STROBE
+ | PARPORT_CONTROL_INIT,
+ PARPORT_CONTROL_AUTOFD
+ | PARPORT_CONTROL_INIT);
for (written = 0; written < len; written++, buf++) {
long expire = jiffies + port->cad->timeout;
unsigned char byte;
@@ -649,7 +682,8 @@
byte = *buf;
try_again:
parport_write_data (port, byte);
- parport_write_control (port, ctl | PARPORT_CONTROL_STROBE);
+ parport_frob_control (port, PARPORT_CONTROL_STROBE,
+ PARPORT_CONTROL_STROBE);
udelay (5);
for (retry = 0; retry < 100; retry++) {
if (!parport_wait_peripheral (port,
@@ -657,7 +691,9 @@
goto success;
if (signal_pending (current)) {
- parport_write_control (port, ctl);
+ parport_frob_control (port,
+ PARPORT_CONTROL_STROBE,
+ 0);
break;
}
}
@@ -665,15 +701,16 @@
/* Time for Host Transfer Recovery (page 41 of IEEE1284) */
DPRINTK (KERN_DEBUG "%s: ECP transfer stalled!\n", port->name);
- parport_write_control (port, ctl | PARPORT_CONTROL_INIT);
+ parport_frob_control (port, PARPORT_CONTROL_INIT,
+ PARPORT_CONTROL_INIT);
udelay (50);
if (parport_read_status (port) & PARPORT_STATUS_PAPEROUT) {
/* It's buggered. */
- parport_write_control (port, ctl);
+ parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
break;
}
- parport_write_control (port, ctl);
+ parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
udelay (50);
if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT))
break;
@@ -684,7 +721,7 @@
if (time_after_eq (jiffies, expire)) break;
goto try_again;
success:
- parport_write_control (port, ctl);
+ parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
udelay (5);
if (parport_wait_peripheral (port,
PARPORT_STATUS_BUSY,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)