Re: a couple of USB related Oopses

From: Greg KH (greg@kroah.com)
Date: Thu Mar 07 2002 - 01:39:05 EST


On Tue, Mar 05, 2002 at 11:03:49PM -0600, James Curbo wrote:
> Ah, I tried it with 2.5.6-pre2 and usb-uhci.. still got a panic, when I
> tried to print to the printer (which is what I was doing before too)
> Also, got these in my kernel log...

Crud, missed another driver. Can you please try the patch below and let
me know if it fixes the problem for you?

thanks,

greg k-h

diff -Nru a/drivers/usb/printer.c b/drivers/usb/printer.c
--- a/drivers/usb/printer.c Wed Mar 6 22:46:17 2002
+++ b/drivers/usb/printer.c Wed Mar 6 22:46:17 2002
@@ -91,7 +91,7 @@
         struct usb_device *dev; /* USB device */
         devfs_handle_t devfs; /* devfs device */
         struct semaphore sem; /* locks this struct, especially "dev" */
- struct urb readurb, writeurb; /* The urbs */
+ struct urb *readurb, *writeurb; /* The urbs */
         wait_queue_head_t wait; /* Zzzzz ... */
         int readcount; /* Counter for reads */
         int ifnum; /* Interface number */
@@ -253,15 +253,15 @@
         usblp->used = 1;
         file->private_data = usblp;
 
- usblp->writeurb.transfer_buffer_length = 0;
- usblp->writeurb.status = 0;
+ usblp->writeurb->transfer_buffer_length = 0;
+ usblp->writeurb->status = 0;
         usblp->wcomplete = 1; /* we begin writeable */
         usblp->rcomplete = 0;
 
         if (usblp->bidir) {
                 usblp->readcount = 0;
- usblp->readurb.dev = usblp->dev;
- if (usb_submit_urb(&usblp->readurb, GFP_KERNEL) < 0) {
+ usblp->readurb->dev = usblp->dev;
+ if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) {
                         retval = -EIO;
                         usblp->used = 0;
                         file->private_data = NULL;
@@ -278,8 +278,10 @@
         usblp_table [usblp->minor] = NULL;
         info ("usblp%d: removed", usblp->minor);
 
- kfree (usblp->writeurb.transfer_buffer);
+ kfree (usblp->writeurb->transfer_buffer);
         kfree (usblp->device_id_string);
+ usb_free_urb(usblp->writeurb);
+ usb_free_urb(usblp->readurb);
         kfree (usblp);
 }
 
@@ -292,8 +294,8 @@
         usblp->used = 0;
         if (usblp->dev) {
                 if (usblp->bidir)
- usb_unlink_urb(&usblp->readurb);
- usb_unlink_urb(&usblp->writeurb);
+ usb_unlink_urb(usblp->readurb);
+ usb_unlink_urb(usblp->writeurb);
                 up(&usblp->sem);
         } else /* finish cleanup from disconnect */
                 usblp_cleanup (usblp);
@@ -306,8 +308,8 @@
 {
         struct usblp *usblp = file->private_data;
         poll_wait(file, &usblp->wait, wait);
- return ((!usblp->bidir || usblp->readurb.status == -EINPROGRESS) ? 0 : POLLIN | POLLRDNORM)
- | (usblp->writeurb.status == -EINPROGRESS ? 0 : POLLOUT | POLLWRNORM);
+ return ((!usblp->bidir || usblp->readurb->status == -EINPROGRESS) ? 0 : POLLIN | POLLRDNORM)
+ | (usblp->writeurb->status == -EINPROGRESS ? 0 : POLLOUT | POLLWRNORM);
 }
 
 static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -423,12 +425,12 @@
                         return -ENODEV;
                 }
 
- if (usblp->writeurb.status != 0) {
+ 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;
+ usblp->minor, usblp->writeurb->status);
+ err = usblp->writeurb->status;
                         } else
                                 err = usblp_check_status(usblp, err);
                         up (&usblp->sem);
@@ -440,23 +442,23 @@
                         continue;
                 }
 
- writecount += usblp->writeurb.transfer_buffer_length;
- usblp->writeurb.transfer_buffer_length = 0;
+ writecount += usblp->writeurb->transfer_buffer_length;
+ usblp->writeurb->transfer_buffer_length = 0;
 
                 if (writecount == count) {
                         up (&usblp->sem);
                         break;
                 }
 
- usblp->writeurb.transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ?
- (count - writecount) : USBLP_BUF_SIZE;
+ usblp->writeurb->transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ?
+ (count - writecount) : USBLP_BUF_SIZE;
 
- if (copy_from_user(usblp->writeurb.transfer_buffer, buffer + writecount,
- usblp->writeurb.transfer_buffer_length)) return -EFAULT;
+ if (copy_from_user(usblp->writeurb->transfer_buffer, buffer + writecount,
+ usblp->writeurb->transfer_buffer_length)) return -EFAULT;
 
- usblp->writeurb.dev = usblp->dev;
+ usblp->writeurb->dev = usblp->dev;
                 usblp->wcomplete = 0;
- if (usb_submit_urb(&usblp->writeurb, GFP_KERNEL)) {
+ if (usb_submit_urb(usblp->writeurb, GFP_KERNEL)) {
                         count = -EIO;
                         up (&usblp->sem);
                         break;
@@ -516,29 +518,29 @@
                 goto done;
         }
 
- if (usblp->readurb.status) {
+ if (usblp->readurb->status) {
                 err("usblp%d: error %d reading from printer",
- usblp->minor, usblp->readurb.status);
- usblp->readurb.dev = usblp->dev;
+ usblp->minor, usblp->readurb->status);
+ usblp->readurb->dev = usblp->dev;
                  usblp->readcount = 0;
- usb_submit_urb(&usblp->readurb, GFP_KERNEL);
+ usb_submit_urb(usblp->readurb, GFP_KERNEL);
                 count = -EIO;
                 goto done;
         }
 
- count = count < usblp->readurb.actual_length - usblp->readcount ?
- count : usblp->readurb.actual_length - usblp->readcount;
+ 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)) {
+ if (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) == usblp->readurb->actual_length) {
                 usblp->readcount = 0;
- usblp->readurb.dev = usblp->dev;
+ usblp->readurb->dev = usblp->dev;
                 usblp->rcomplete = 0;
- if (usb_submit_urb(&usblp->readurb, GFP_KERNEL)) {
+ if (usb_submit_urb(usblp->readurb, GFP_KERNEL)) {
                         count = -EIO;
                         goto done;
                 }
@@ -668,24 +670,42 @@
 
         init_waitqueue_head(&usblp->wait);
 
+ usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!usblp->writeurb) {
+ err("out of memory");
+ kfree(usblp);
+ return NULL;
+ }
+ usblp->readurb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!usblp->readurb) {
+ err("out of memory");
+ usb_free_urb(usblp->writeurb);
+ kfree(usblp);
+ return NULL;
+ }
+
         if (!(buf = kmalloc(USBLP_BUF_SIZE * (bidir ? 2 : 1), GFP_KERNEL))) {
                 err("out of memory");
+ usb_free_urb(usblp->writeurb);
+ usb_free_urb(usblp->readurb);
                 kfree(usblp);
                 return NULL;
         }
 
         if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) {
                 err("out of memory");
+ usb_free_urb(usblp->writeurb);
+ usb_free_urb(usblp->readurb);
                 kfree(usblp);
                 kfree(buf);
                 return NULL;
         }
 
- FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
+ FILL_BULK_URB(usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
                 buf, 0, usblp_bulk_write, usblp);
 
         if (bidir)
- FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
+ FILL_BULK_URB(usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
                         buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, usblp_bulk_read, usblp);
 
         /* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */
@@ -737,9 +757,9 @@
         lock_kernel();
         usblp->dev = NULL;
 
- usb_unlink_urb(&usblp->writeurb);
+ usb_unlink_urb(usblp->writeurb);
         if (usblp->bidir)
- usb_unlink_urb(&usblp->readurb);
+ usb_unlink_urb(usblp->readurb);
 
         if (!usblp->used)
                 usblp_cleanup (usblp);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Mar 07 2002 - 21:00:59 EST