patch-2.4.19 linux-2.4.19/drivers/char/lp.c
Next file: linux-2.4.19/drivers/char/machzwd.c
Previous file: linux-2.4.19/drivers/char/logibusmouse.c
Back to the patch index
Back to the overall index
- Lines: 131
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/drivers/char/lp.c
- Orig date:
Mon Feb 25 11:37:57 2002
diff -urN linux-2.4.18/drivers/char/lp.c linux-2.4.19/drivers/char/lp.c
@@ -270,7 +270,7 @@
return error;
}
-static int lp_wait_ready(int minor)
+static int lp_wait_ready(int minor, int nonblock)
{
int error = 0;
@@ -281,7 +281,7 @@
do {
error = lp_check_status (minor);
- if (error && (LP_F(minor) & LP_ABORT))
+ if (error && (nonblock || (LP_F(minor) & LP_ABORT)))
break;
if (signal_pending (current)) {
error = -EINTR;
@@ -300,6 +300,8 @@
ssize_t retv = 0;
ssize_t written;
size_t copy_size = count;
+ int nonblock = ((file->f_flags & O_NONBLOCK) ||
+ (LP_F(minor) & LP_ABORT));
#ifdef LP_STATS
if (jiffies-lp_table[minor].lastcall > LP_TIME(minor))
@@ -326,9 +328,10 @@
lp_table[minor].best_mode);
parport_set_timeout (lp_table[minor].dev,
- lp_table[minor].timeout);
+ (nonblock ? PARPORT_INACTIVITY_O_NONBLOCK
+ : lp_table[minor].timeout));
- if ((retv = lp_wait_ready (minor)) == 0)
+ if ((retv = lp_wait_ready (minor, nonblock)) == 0)
do {
/* Write the data. */
written = parport_write (port, kbuf, copy_size);
@@ -354,12 +357,16 @@
IEEE1284_MODE_COMPAT);
lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
- error = lp_wait_ready (minor);
+ error = lp_wait_ready (minor, nonblock);
if (error) {
if (retv == 0)
retv = error;
break;
+ } else if (nonblock) {
+ if (retv == 0)
+ retv = -EAGAIN;
+ break;
}
parport_yield_blocking (lp_table[minor].dev);
@@ -407,6 +414,8 @@
struct parport *port = lp_table[minor].dev->port;
ssize_t retval = 0;
char *kbuf = lp_table[minor].lp_buffer;
+ int nonblock = ((file->f_flags & O_NONBLOCK) ||
+ (LP_F(minor) & LP_ABORT));
if (count > LP_BUFFER_SIZE)
count = LP_BUFFER_SIZE;
@@ -415,7 +424,54 @@
return -EINTR;
lp_claim_parport_or_block (&lp_table[minor]);
- retval = parport_read (port, kbuf, count);
+
+ parport_set_timeout (lp_table[minor].dev,
+ (nonblock ? PARPORT_INACTIVITY_O_NONBLOCK
+ : lp_table[minor].timeout));
+
+ parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
+ if (parport_negotiate (lp_table[minor].dev->port,
+ IEEE1284_MODE_NIBBLE)) {
+ retval = -EIO;
+ goto out;
+ }
+
+ while (retval == 0) {
+ retval = parport_read (port, kbuf, count);
+
+ if (retval > 0)
+ break;
+
+ if (nonblock) {
+ retval = -EAGAIN;
+ break;
+ }
+
+ /* Wait for data. */
+
+ if (lp_table[minor].dev->port->irq == PARPORT_IRQ_NONE) {
+ parport_negotiate (lp_table[minor].dev->port,
+ IEEE1284_MODE_COMPAT);
+ lp_error (minor);
+ if (parport_negotiate (lp_table[minor].dev->port,
+ IEEE1284_MODE_NIBBLE)) {
+ retval = -EIO;
+ goto out;
+ }
+ } else
+ interruptible_sleep_on_timeout (&lp_table[minor].waitq,
+ LP_TIMEOUT_POLLED);
+
+ if (signal_pending (current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
+
+ if (current->need_resched)
+ schedule ();
+ }
+ parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
+ out:
lp_release_parport (&lp_table[minor]);
if (retval > 0 && copy_to_user (buf, kbuf, retval))
@@ -476,7 +532,6 @@
printk (KERN_INFO "lp%d: ECP mode\n", minor);
lp_table[minor].best_mode = IEEE1284_MODE_ECP;
} else {
- printk (KERN_INFO "lp%d: compatibility mode\n", minor);
lp_table[minor].best_mode = IEEE1284_MODE_COMPAT;
}
/* Leave peripheral in compatibility mode */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)