On Fri, 30 Mar 2007 20:34:47 +0200, Oliver Neukum <[EMAIL PROTECTED]> wrote:
> > What did I tell you about wait_event? It would be far cleaner
> > to open-code the loop.
>
> Open code? What exactly are you proposing?
Oliver, I've removed wait_event. Please have a look if you have a moment.
This also should fix the endless loop upon a write error, which Jochen
reported.
Unfortunately, the diffstat is unfavourable: +247 -155. This may be the
fault of added comments, because the module itself lost about 700 bytes
on x86_64. I think the code is more regular and clean now, but
please let me know if I muddied waters.
I made a special effort to preserve all oddities of the current driver,
because it had a history of "cleanups" causing regressions. Again, this
is something to pay attention to.
Two remaining items are:
- Tim Waugh's ENOSPC like in drivers/char/lp.c
- Greg-style dynamic URBs
-- Pete
P.S. I'm thinking if I should take usblp for maintenance from Vojtech
since I am reworking it anyway.
P.P.S. Does anyone remember what hash signs in front of copyright
statements mean?
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 6584cf0..4422fe8 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -5,7 +5,7 @@
* Copyright (c) 1999 Pavel Machek <[EMAIL PROTECTED]>
* Copyright (c) 2000 Randy Dunlap <[EMAIL PROTECTED]>
* Copyright (c) 2000 Vojtech Pavlik <[EMAIL PROTECTED]>
- # Copyright (c) 2001 Pete Zaitcev <[EMAIL PROTECTED]>
+ * Copyright (c) 2001,2007 Pete Zaitcev <[EMAIL PROTECTED]>
# Copyright (c) 2001 David Paschal <[EMAIL PROTECTED]>
* Copyright (c) 2006 Oliver Neukum <[EMAIL PROTECTED]>
*
@@ -62,7 +62,6 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.13"
#define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy
Dunlap, Pete Zaitcev, David Paschal"
#define DRIVER_DESC "USB Printer Device Class driver"
@@ -130,12 +129,13 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET
970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H
struct usblp {
struct usb_device *dev; /* USB device */
- struct mutex mut; /* locks this struct,
especially "dev" */
+ struct mutex mut; /* locks usblp, except
[rw]status */
+ spinlock_t lock; /* locks rcomplete, wcomplete */
char *writebuf; /* write
transfer_buffer */
char *readbuf; /* read transfer_buffer
*/
char *statusbuf; /* status
transfer_buffer */
struct urb *readurb, *writeurb; /* The urbs */
- wait_queue_head_t wait; /* Zzzzz ... */
+ wait_queue_head_t rwait, wwait;
int readcount; /* Counter for reads */
int ifnum; /* Interface number */
struct usb_interface *intf; /* The interface */
@@ -148,8 +148,9 @@ struct usblp {
} protocol[USBLP_MAX_PROTOCOLS];
int current_protocol;
int minor; /* minor number of
device */
- int wcomplete; /* writing is completed
*/
- int rcomplete; /* reading is completed
*/
+ int wcomplete, rcomplete;
+ int wstatus; /* bytes written or error */
+ int rstatus; /* bytes ready or error */
unsigned int quirks; /* quirks flags */
unsigned char used; /* True if open */
unsigned char present; /* True if not
disconnected */
@@ -179,8 +180,8 @@ static void usblp_dump(struct usblp *usblp) {
}
dbg("current_protocol=%d", usblp->current_protocol);
dbg("minor=%d", usblp->minor);
- dbg("wcomplete=%d", usblp->wcomplete);
- dbg("rcomplete=%d", usblp->rcomplete);
+ dbg("wstatus=%d", usblp->wstatus);
+ dbg("rstatus=%d", usblp->rstatus);
dbg("quirks=%d", usblp->quirks);
dbg("used=%d", usblp->used);
dbg("bidir=%d", usblp->bidir);
@@ -223,6 +224,10 @@ static const struct quirk_printer_struct quirk_printers[]
= {
{ 0, 0 }
};
+static int usblp_wwait_and_lock(struct usblp *usblp, int nonblock);
+static int usblp_wtest(struct usblp *usblp, int nonblock);
+static int usblp_rwait_and_lock(struct usblp *usblp, int nonblock);
+static int usblp_rtest(struct usblp *usblp, int nonblock);
static int usblp_select_alts(struct usblp *usblp);
static int usblp_set_protocol(struct usblp *usblp, int protocol);
static int usblp_cache_device_id_string(struct usblp *usblp);
@@ -280,33 +285,40 @@ static void usblp_bulk_read(struct urb *urb)
{
struct usblp *usblp = urb->context;
- if (unlikely(!usblp || !usblp->dev || !usblp->used))
- return;
-
- if (unlikely(!usblp->present))
- goto unplug;
- if (unlikely(urb->status))
- warn("usblp%d: nonzero read/write bulk status received: %d",
- usblp->minor, urb->status);
+ if (usblp->present) {
+ if (urb->status)
+ printk(KERN_WARNING "usblp%d: "
+ "nonzero read bulk status received: %d\n",
+ usblp->minor, urb->status);
+ }
+ spin_lock(&usblp->lock);
usblp->rcomplete = 1;
-unplug:
- wake_up_interruptible(&usblp->wait);
+ if (urb->status < 0)
+ usblp->rstatus = urb->status;
+ else
+ usblp->rstatus = urb->actual_length;
+ spin_unlock(&usblp->lock);
+ wake_up_interruptible(&usblp->rwait);
}
static void usblp_bulk_write(struct urb *urb)
{
struct usblp *usblp = urb->context;
- if (unlikely(!usblp || !usblp->dev || !usblp->used))
- return;
- if (unlikely(!usblp->present))
- goto unplug;
- if (unlikely(urb->status))
- warn("usblp%d: nonzero read/write bulk status received: %d",
- usblp->minor, urb->status);
+ if (usblp->present) {
+ if (urb->status)
+ printk(KERN_WARNING "usblp%d: "
+ "nonzero write bulk status received: %d\n",
+ usblp->minor, urb->status);
+ }
+ spin_lock(&usblp->lock);
usblp->wcomplete = 1;
-unplug:
- wake_up_interruptible(&usblp->wait);
+ if (urb->status < 0)
+ usblp->wstatus = urb->status;
+ else
+ usblp->wstatus = urb->actual_length;
+ spin_unlock(&usblp->lock);
+ wake_up_interruptible(&usblp->wwait);
}
/*
@@ -323,7 +335,8 @@ static int usblp_check_status(struct usblp *usblp, int err)
error = usblp_read_status (usblp, usblp->statusbuf);
if (error < 0) {
if (printk_ratelimit())
- err("usblp%d: error %d reading printer status",
+ printk(KERN_ERR
+ "usblp%d: error %d reading printer status\n",
usblp->minor, error);
return 0;
}
@@ -337,8 +350,10 @@ static int usblp_check_status(struct usblp *usblp, int err)
if (~status & LP_PSELECD)
newerr = 2;
- if (newerr != err)
- info("usblp%d: %s", usblp->minor, usblp_messages[newerr]);
+ if (newerr != err) {
+ printk(KERN_INFO "usblp%d: %s\n",
+ usblp->minor, usblp_messages[newerr]);
+ }
return newerr;
}
@@ -408,9 +423,8 @@ static int usblp_open(struct inode *inode, struct file
*file)
usblp->writeurb->transfer_buffer_length = 0;
usblp->wcomplete = 1; /* we begin writeable */
+ usblp->wstatus = 0;
usblp->rcomplete = 0;
- usblp->writeurb->status = 0;
- usblp->readurb->status = 0;
if (handle_bidir(usblp) < 0) {
file->private_data = NULL;
@@ -423,7 +437,7 @@ out:
static void usblp_cleanup (struct usblp *usblp)
{
- info("usblp%d: removed", usblp->minor);
+ printk(KERN_INFO "usblp%d: removed\n", usblp->minor);
kfree (usblp->device_id_string);
kfree (usblp->statusbuf);
@@ -457,10 +471,18 @@ static int usblp_release(struct inode *inode, struct file
*file)
/* No kernel lock - fine */
static unsigned int usblp_poll(struct file *file, struct poll_table_struct
*wait)
{
+ int ret;
+ unsigned long flags;
+
struct usblp *usblp = file->private_data;
- poll_wait(file, &usblp->wait, wait);
- return ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN | POLLRDNORM)
+ /* Should we check file->f_mode & FMODE_WRITE before poll_wait()? */
+ poll_wait(file, &usblp->rwait, wait);
+ poll_wait(file, &usblp->wwait, wait);
+ spin_lock_irqsave(&usblp->lock, flags);
+ ret = ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN | POLLRDNORM)
| (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM);
+ spin_unlock_irqrestore(&usblp->lock, flags);
+ return ret;
}
static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -634,10 +656,11 @@ static long usblp_ioctl(struct file *file, unsigned int
cmd, unsigned long arg)
switch (cmd) {
case LPGETSTATUS:
- if (usblp_read_status(usblp, usblp->statusbuf))
{
+ if ((retval = usblp_read_status(usblp,
usblp->statusbuf))) {
if (printk_ratelimit())
- err("usblp%d: failed reading
printer status",
- usblp->minor);
+ printk(KERN_ERR "usblp%d:"
+ "failed reading printer
status (%d)\n",
+ usblp->minor, retval);
retval = -EIO;
goto done;
}
@@ -658,58 +681,26 @@ done:
static ssize_t usblp_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
struct usblp *usblp = file->private_data;
- int timeout, intr, rv, err = 0, transfer_length = 0;
- size_t writecount = 0;
+ int rv, transfer_length = 0;
+ ssize_t writecount = 0;
while (writecount < count) {
- if (!usblp->wcomplete) {
- barrier();
- if (file->f_flags & O_NONBLOCK) {
- writecount += transfer_length;
- return writecount ? writecount : -EAGAIN;
- }
-
- timeout = USBLP_WRITE_TIMEOUT;
-
- rv = wait_event_interruptible_timeout(usblp->wait,
usblp->wcomplete || !usblp->present , timeout);
- if (rv < 0)
- return writecount ? writecount : -EINTR;
- }
- intr = mutex_lock_interruptible (&usblp->mut);
- if (intr)
- return writecount ? writecount : -EINTR;
- if (!usblp->present) {
- mutex_unlock (&usblp->mut);
- return -ENODEV;
- }
-
- if (usblp->sleeping) {
- mutex_unlock (&usblp->mut);
- return writecount ? writecount : -ENODEV;
- }
+ rv = usblp_wwait_and_lock(usblp, !!(file->f_flags&O_NONBLOCK));
+ if (rv < 0)
+ return writecount ? writecount : rv;
- if (usblp->writeurb->status != 0) {
- if (usblp->quirks & USBLP_QUIRK_BIDIR) {
- if (!usblp->wcomplete)
- err("usblp%d: error %d writing to
printer",
- usblp->minor,
usblp->writeurb->status);
- err = usblp->writeurb->status;
- } else
- err = usblp_check_status(usblp, err);
+ if (usblp->wstatus < 0) {
+ usblp_check_status(usblp, 0);
mutex_unlock (&usblp->mut);
-
- /* if the fault was due to disconnect, let khubd's
- * call to usblp_disconnect() grab usblp->mut ...
- */
- schedule ();
- continue;
+ return writecount ? writecount : -EIO;
}
/* We must increment writecount here, and not at the
* end of the loop. Otherwise, the final loop iteration may
* be skipped, leading to incomplete printer output.
*/
- writecount += transfer_length;
+ if (usblp->wstatus <= transfer_length)
+ writecount += usblp->wstatus;
if (writecount == count) {
mutex_unlock(&usblp->mut);
break;
@@ -729,90 +720,72 @@ static ssize_t usblp_write(struct file *file, const char
__user *buffer, size_t
usblp->writeurb->dev = usblp->dev;
usblp->wcomplete = 0;
- err = usb_submit_urb(usblp->writeurb, GFP_KERNEL);
- if (err) {
+ if ((rv = usb_submit_urb(usblp->writeurb, GFP_KERNEL)) < 0) {
usblp->wcomplete = 1;
- if (err != -ENOMEM)
- count = -EIO;
- else
- count = writecount ? writecount : -ENOMEM;
+ usblp->wstatus = 0;
mutex_unlock (&usblp->mut);
- break;
+ return writecount ? writecount : -EIO;
}
mutex_unlock (&usblp->mut);
}
- return count;
+ return writecount;
}
-static ssize_t usblp_read(struct file *file, char __user *buffer, size_t
count, loff_t *ppos)
+/*
+ * Notice that we fail to restart in a few cases: on EFAULT, on restart
+ * error, etc. This is the historical behaviour. In all such cases we return
+ * EIO, and applications loop in order to get the new read going.
+ */
+static ssize_t usblp_read(struct file *file, char __user *buffer, size_t len,
loff_t *ppos)
{
struct usblp *usblp = file->private_data;
- int rv, intr;
+ ssize_t count;
+ ssize_t avail;
+ int rv;
if (!usblp->bidir)
return -EINVAL;
- intr = mutex_lock_interruptible (&usblp->mut);
- if (intr)
- return -EINTR;
- if (!usblp->present) {
- count = -ENODEV;
- goto done;
- }
-
- if (!usblp->rcomplete) {
- barrier();
-
- if (file->f_flags & O_NONBLOCK) {
- count = -EAGAIN;
- goto done;
- }
- mutex_unlock(&usblp->mut);
- rv = wait_event_interruptible(usblp->wait, usblp->rcomplete ||
!usblp->present);
- mutex_lock(&usblp->mut);
- if (rv < 0) {
- count = -EINTR;
- goto done;
- }
- }
-
- if (!usblp->present) {
- count = -ENODEV;
- goto done;
- }
-
- if (usblp->sleeping) {
- count = -ENODEV;
+ rv = usblp_rwait_and_lock(usblp, !!(file->f_flags & O_NONBLOCK));
+ if (rv < 0) {
+ count = rv;
goto done;
}
- if (usblp->readurb->status) {
- err("usblp%d: error %d reading from printer",
- usblp->minor, usblp->readurb->status);
+ if ((avail = usblp->rstatus) < 0) {
+ printk(KERN_ERR "usblp%d: error %d reading from printer\n",
+ usblp->minor, (int)avail);
usblp->readurb->dev = usblp->dev;
usblp->readcount = 0;
usblp->rcomplete = 0;
- if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
- dbg("error submitting urb");
+ if ((rv = usb_submit_urb(usblp->readurb, GFP_KERNEL)) < 0) {
+ dbg("error submitting urb (%d)", rv);
+ usblp->rcomplete = 1;
+ usblp->rstatus = rv;
+ }
count = -EIO;
goto done;
}
- count = count < usblp->readurb->actual_length - usblp->readcount ?
- count : usblp->readurb->actual_length - usblp->readcount;
-
- if (copy_to_user(buffer, usblp->readurb->transfer_buffer +
usblp->readcount, count)) {
+ count = len < avail - usblp->readcount ? len : avail - usblp->readcount;
+ if (count != 0 &&
+ copy_to_user(buffer, usblp->readurb->transfer_buffer +
usblp->readcount, count)) {
count = -EFAULT;
goto done;
}
- if ((usblp->readcount += count) == usblp->readurb->actual_length) {
+ if ((usblp->readcount += count) == avail) {
usblp->readcount = 0;
usblp->readurb->dev = usblp->dev;
usblp->rcomplete = 0;
- if (usb_submit_urb(usblp->readurb, GFP_KERNEL)) {
- count = -EIO;
+ if ((rv = usb_submit_urb(usblp->readurb, GFP_KERNEL)) < 0) {
+ dbg("error submitting urb (%d)", rv);
+ usblp->rcomplete = 1;
+ usblp->rstatus = rv;
+ /* We don't want to leak USB return codes into errno. */
+ if (count == 0)
+ count = -EIO;
goto done;
}
}
@@ -823,6 +796,122 @@ done:
}
/*
+ * Write for write URB to complete. Return with locked usblp on success.
+ *
+ * Our write path has a peculiar property: it does not buffer like a tty,
+ * but waits for the write to succeed. This allows our ->release to bug out
+ * without waiting for writes to drain. But it obviously does not work
+ * when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use
+ * select(2) or poll(2) to wait for the buffer to drain before closing.
+ * Alternatively, set blocking mode with fcntl and issue a zero-size write.
+ *
+ * Old v0.13 code had a non-functional timeout for wait_event(). Someone forgot
+ * to check the return code for timeout expiration, so it had no effect.
+ * But what was the intent of it? Timing out writes would be _very_ bad,
+ * because printouts would break every time when paper ran out.
+ */
+static int usblp_wwait_and_lock(struct usblp *usblp, int nonblock)
+{
+ DECLARE_WAITQUEUE(waita, current);
+ int rc;
+
+ add_wait_queue(&usblp->wwait, &waita);
+ for (;;) {
+ if (mutex_lock_interruptible(&usblp->mut)) {
+ rc = -EINTR;
+ break;
+ }
+ set_current_state(TASK_INTERRUPTIBLE);
+ if ((rc = usblp_wtest(usblp, nonblock)) < 0) {
+ mutex_unlock(&usblp->mut);
+ break;
+ }
+ if (rc == 0)
+ break;
+ mutex_unlock(&usblp->mut);
+ schedule();
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&usblp->wwait, &waita);
+ return rc;
+}
+
+static int usblp_wtest(struct usblp *usblp, int nonblock)
+{
+ unsigned long flags;
+
+ if (!usblp->present)
+ return -ENODEV;
+ if (signal_pending(current))
+ return -EINTR;
+ spin_lock_irqsave(&usblp->lock, flags);
+ if (usblp->wcomplete) {
+ spin_unlock_irqrestore(&usblp->lock, flags);
+ return 0;
+ }
+ spin_unlock_irqrestore(&usblp->lock, flags);
+ if (usblp->sleeping)
+ return -ENODEV;
+ if (nonblock)
+ return -EAGAIN;
+ return 1;
+}
+
+/*
+ * Wait for read bytes to become available. This probably should have been
+ * called usblp_r_lock_and_wait(), because we lock first. But it's a
traditional
+ * name for functions which lock and return.
+ *
+ * We do not use wait_event_interruptible because it makes locking iffy.
+ */
+static int usblp_rwait_and_lock(struct usblp *usblp, int nonblock)
+{
+ DECLARE_WAITQUEUE(waita, current);
+ int rc;
+
+ add_wait_queue(&usblp->rwait, &waita);
+ for (;;) {
+ if (mutex_lock_interruptible(&usblp->mut)) {
+ rc = -EINTR;
+ break;
+ }
+ set_current_state(TASK_INTERRUPTIBLE);
+ if ((rc = usblp_rtest(usblp, nonblock)) < 0) {
+ mutex_unlock(&usblp->mut);
+ break;
+ }
+ if (rc == 0) /* Keep it locked */
+ break;
+ mutex_unlock(&usblp->mut);
+ schedule();
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&usblp->rwait, &waita);
+ return rc;
+}
+
+static int usblp_rtest(struct usblp *usblp, int nonblock)
+{
+ unsigned long flags;
+
+ if (!usblp->present)
+ return -ENODEV;
+ if (signal_pending(current))
+ return -EINTR;
+ spin_lock_irqsave(&usblp->lock, flags);
+ if (usblp->rcomplete) {
+ spin_unlock_irqrestore(&usblp->lock, flags);
+ return 0;
+ }
+ spin_unlock_irqrestore(&usblp->lock, flags);
+ if (usblp->sleeping)
+ return -ENODEV;
+ if (nonblock)
+ return -EAGAIN;
+ return 1;
+}
+
+/*
* Checks for printers that have quirks, such as requiring unidirectional
* communication but reporting bidirectional; currently some HP printers
* have this flaw (HP 810, 880, 895, etc.), or needing an init string
@@ -893,23 +982,25 @@ static int usblp_probe(struct usb_interface *intf,
/* Malloc and start initializing usblp structure so we can use it
* directly. */
if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
- err("out of memory for usblp");
+ retval = -ENOMEM;
goto abort;
}
usblp->dev = dev;
mutex_init (&usblp->mut);
- init_waitqueue_head(&usblp->wait);
+ spin_lock_init(&usblp->lock);
+ init_waitqueue_head(&usblp->rwait);
+ init_waitqueue_head(&usblp->wwait);
usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
usblp->intf = intf;
usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL);
if (!usblp->writeurb) {
- err("out of memory");
+ retval = -ENOMEM;
goto abort;
}
usblp->readurb = usb_alloc_urb(0, GFP_KERNEL);
if (!usblp->readurb) {
- err("out of memory");
+ retval = -ENOMEM;
goto abort;
}
@@ -917,7 +1008,7 @@ static int usblp_probe(struct usb_interface *intf,
* since we can re-query it on an ioctl and a dynamic string
* could change in length. */
if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE,
GFP_KERNEL))) {
- err("out of memory for device_id_string");
+ retval = -ENOMEM;
goto abort;
}
@@ -929,19 +1020,19 @@ static int usblp_probe(struct usb_interface *intf,
* alternate setting can be changed later via an ioctl. */
if (!(usblp->writebuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
GFP_KERNEL, &usblp->writeurb->transfer_dma))) {
- err("out of memory for write buf");
+ retval = -ENOMEM;
goto abort;
}
if (!(usblp->readbuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
GFP_KERNEL, &usblp->readurb->transfer_dma))) {
- err("out of memory for read buf");
+ retval = -ENOMEM;
goto abort;
}
/* Allocate buffer for printer status */
usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
if (!usblp->statusbuf) {
- err("out of memory for statusbuf");
+ retval = -ENOMEM;
goto abort;
}
@@ -956,12 +1047,15 @@ static int usblp_probe(struct usb_interface *intf,
dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
+ retval = -ENODEV;
goto abort;
}
/* Setup the selected alternate setting and endpoints. */
- if (usblp_set_protocol(usblp, protocol) < 0)
+ if (usblp_set_protocol(usblp, protocol) < 0) {
+ retval = -ENODEV; /* ->probe isn't ->ioctl */
goto abort;
+ }
/* Retrieve and store the device ID string. */
usblp_cache_device_id_string(usblp);
@@ -979,12 +1073,14 @@ static int usblp_probe(struct usb_interface *intf,
retval = usb_register_dev(intf, &usblp_class);
if (retval) {
- err("Not able to get a minor for this device.");
+ printk(KERN_ERR "usblp: Not able to get a minor"
+ " (base %u, slice default).",
+ USBLP_MINOR_BASE);
goto abort_intfdata;
}
usblp->minor = intf->minor;
- info("usblp%d: USB %sdirectional printer dev %d "
- "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
+ printk(KERN_INFO "usblp%d: USB %sdirectional printer dev %d "
+ "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X\n",
usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
usblp->ifnum,
usblp->protocol[usblp->current_protocol].alt_setting,
@@ -1011,7 +1107,7 @@ abort:
usb_free_urb(usblp->readurb);
kfree(usblp);
}
- return -EIO;
+ return retval;
}
/*
@@ -1080,8 +1176,9 @@ static int usblp_select_alts(struct usblp *usblp)
if (ifd->desc.bInterfaceProtocol == 1) {
epread = NULL;
} else if (usblp->quirks & USBLP_QUIRK_BIDIR) {
- info("Disabling reads from problem bidirectional "
- "printer on usblp%d", usblp->minor);
+ printk(KERN_INFO "usblp%d: Disabling reads from "
+ "problematic bidirectional printer\n",
+ usblp->minor);
epread = NULL;
}
@@ -1121,7 +1218,7 @@ static int usblp_set_protocol(struct usblp *usblp, int
protocol)
return -EINVAL;
r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
if (r < 0) {
- err("can't set desired altsetting %d on interface %d",
+ printk(KERN_ERR "usblp: can't set desired altsetting %d on
interface %d\n",
alts, usblp->ifnum);
return r;
}
@@ -1253,12 +1350,7 @@ static struct usb_driver usblp_driver = {
static int __init usblp_init(void)
{
- int retval;
- retval = usb_register(&usblp_driver);
- if (!retval)
- info(DRIVER_VERSION ": " DRIVER_DESC);
-
- return retval;
+ return usb_register(&usblp_driver);
}
static void __exit usblp_exit(void)
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel