summaryrefslogtreecommitdiffstats
path: root/drivers/usb/printer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/printer.c')
-rw-r--r--drivers/usb/printer.c108
1 files changed, 51 insertions, 57 deletions
diff --git a/drivers/usb/printer.c b/drivers/usb/printer.c
index 96fa971d8..bbbc05f33 100644
--- a/drivers/usb/printer.c
+++ b/drivers/usb/printer.c
@@ -1,10 +1,10 @@
/*
- * printer.c Version 0.5
+ * printer.c Version 0.6
*
* Copyright (c) 1999 Michael Gee <michael@linuxspecific.com>
* Copyright (c) 1999 Pavel Machek <pavel@suse.cz>
- * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2000 Randy Dunlap <randy.dunlap@intel.com>
+ * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
*
* USB Printer Device Class driver for USB printers and printer cables
*
@@ -16,6 +16,7 @@
* v0.3 - cleaner again, waitqueue fixes
* v0.4 - fixes in unidirectional mode
* v0.5 - add DEVICE_ID string support
+ * v0.6 - never time out
*/
/*
@@ -71,7 +72,7 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
#define USBLP_MINORS 16
#define USBLP_MINOR_BASE 0
-#define USBLP_WRITE_TIMEOUT (60*60*HZ) /* 60 minutes */
+#define USBLP_WRITE_TIMEOUT (5*HZ) /* 5 seconds */
struct usblp {
struct usb_device *dev; /* USB device */
@@ -83,10 +84,10 @@ struct usblp {
unsigned char used; /* True if open */
unsigned char bidir; /* interface is bidirectional */
unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */
- /* first 2 bytes are (big-endian) length */
+ /* first 2 bytes are (big-endian) length */
};
-static struct usblp *usblp_table[USBLP_MINORS] = { NULL, /* ... */ };
+static struct usblp *usblp_table[USBLP_MINORS];
/*
* Functions for usblp control messages.
@@ -121,7 +122,8 @@ static void usblp_bulk(struct urb *urb)
return;
if (urb->status)
- warn("nonzero read/write bulk status received: %d", urb->status);
+ warn("usblp%d: nonzero read/write bulk status received: %d",
+ usblp->minor, urb->status);
wake_up_interruptible(&usblp->wait);
}
@@ -130,29 +132,27 @@ static void usblp_bulk(struct urb *urb)
* Get and print printer errors.
*/
-static int usblp_check_status(struct usblp *usblp)
+static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
+
+static int usblp_check_status(struct usblp *usblp, int err)
{
- unsigned char status;
+ unsigned char status, newerr = 0;
if (usblp_read_status(usblp, &status)) {
- err("failed reading usblp status");
- return -EIO;
+ err("usblp%d: failed reading printer status", usblp->minor);
+ return 0;
}
if (~status & LP_PERRORP) {
- if (status & LP_POUTPA) {
- info("usblp%d: out of paper", usblp->minor);
- return -ENOSPC;
- }
- if (~status & LP_PSELECD) {
- info("usblp%d: off-line", usblp->minor);
- return -EIO;
- }
- info("usblp%d: on fire", usblp->minor);
- return -EIO;
+ newerr = 3;
+ if (status & LP_POUTPA) newerr = 1;
+ if (~status & LP_PSELECD) newerr = 2;
}
- return 0;
+ if (newerr != err)
+ info("usblp%d: %s", usblp->minor, usblp_messages[newerr]);
+
+ return newerr;
}
/*
@@ -179,8 +179,10 @@ static int usblp_open(struct inode *inode, struct file *file)
if (usblp->used)
goto out;
- if ((retval = usblp_check_status(usblp)))
+ if ((retval = usblp_check_status(usblp, 0))) {
+ retval = retval > 1 ? -EIO : -ENOSPC;
goto out;
+ }
usblp->used = 1;
file->private_data = usblp;
@@ -228,27 +230,30 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait
static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
- int length;
struct usblp *usblp = file->private_data;
+ int length;
if ((_IOC_TYPE(cmd) != 'P') || (_IOC_DIR(cmd) != _IOC_READ))
return -EINVAL;
switch (_IOC_NR(cmd)) {
- case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */
- length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
-#if 0
- dbg ("usblp_ioctl GET_DEVICE_ID: actlen=%d, user size=%d, string='%s'",
- length, _IOC_SIZE(cmd), &usblp->device_id_string[2]);
-#endif
- if (length > _IOC_SIZE(cmd))
- length = _IOC_SIZE(cmd); /* truncate */
- if (copy_to_user ((unsigned char *)arg, usblp->device_id_string, (unsigned long) length))
- return -EFAULT;
- break;
- default:
- return -EINVAL;
+ case IOCNR_GET_DEVICE_ID: /* get the DEVICE_ID string */
+
+ length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
+
+ dbg ("usblp_ioctl GET_DEVICE_ID actlen: %d, size: %d, string: '%s'",
+ length, _IOC_SIZE(cmd), &usblp->device_id_string[2]);
+
+ if (length > _IOC_SIZE(cmd)) length = _IOC_SIZE(cmd); /* truncate */
+
+ if (copy_to_user((unsigned char *) arg, usblp->device_id_string, (unsigned long) length))
+ return -EFAULT;
+
+ break;
+
+ default:
+ return -EINVAL;
}
return 0;
@@ -257,7 +262,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
{
struct usblp *usblp = file->private_data;
- int retval, timeout, writecount = 0;
+ int timeout, err = 0, writecount = 0;
while (writecount < count) {
@@ -276,28 +281,17 @@ static ssize_t usblp_write(struct file *file, const char *buffer, size_t count,
}
}
- if (usblp->writeurb.status == -EINPROGRESS) {
- usb_unlink_urb(&usblp->writeurb);
- err("usblp%d: timed out", usblp->minor);
- return -EIO;
- }
-
if (!usblp->dev)
return -ENODEV;
- if (!usblp->writeurb.status) {
- writecount += usblp->writeurb.transfer_buffer_length;
- usblp->writeurb.transfer_buffer_length = 0;
- } else {
- if (!(retval = usblp_check_status(usblp))) {
- err("usblp%d: error %d writing to printer (retval=%d)",
- usblp->minor, usblp->writeurb.status, retval);
- return -EIO;
- }
-
- return retval;
+ if (usblp->writeurb.status) {
+ err = usblp_check_status(usblp, err);
+ continue;
}
+ writecount += usblp->writeurb.transfer_buffer_length;
+ usblp->writeurb.transfer_buffer_length = 0;
+
if (writecount == count)
continue;
@@ -368,14 +362,14 @@ static void *usblp_probe(struct usb_device *dev, unsigned int ifnum)
interface = &dev->actconfig->interface[ifnum].altsetting[i];
if (interface->bInterfaceClass != 7 || interface->bInterfaceSubClass != 1 ||
- (interface->bInterfaceProtocol != 1 && interface->bInterfaceProtocol != 2) ||
- (interface->bInterfaceProtocol > interface->bNumEndpoints))
+ interface->bInterfaceProtocol < 1 || interface->bInterfaceProtocol > 3 ||
+ (interface->bInterfaceProtocol > 1 && interface->bNumEndpoints < 2))
continue;
if (alts == -1)
alts = i;
- if (!bidir && interface->bInterfaceProtocol == 2) {
+ if (!bidir && interface->bInterfaceProtocol > 1) {
bidir = 1;
alts = i;
}