From: Greg KH To: linux-usb-devel@lists.sourceforge.net Subject: [PATCH] USB devio static urb removal Hi, And here's a patch against 2.5.3-pre2 that makes the devio code use usb_alloc_urb(). I tested this out with the pencam user space program (it uses libusb.) Any objections? thanks, greg k-h diff -Nru a/drivers/usb/devio.c b/drivers/usb/devio.c --- a/drivers/usb/devio.c Mon Jan 21 17:06:59 2002 +++ b/drivers/usb/devio.c Mon Jan 21 17:06:59 2002 @@ -53,7 +53,7 @@ unsigned int signr; void *userbuffer; void *userurb; - struct urb urb; + struct urb *urb; }; static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig) @@ -175,17 +175,21 @@ if (!as) return NULL; memset(as, 0, assize); - as->urb.number_of_packets = numisoframes; - spin_lock_init(&as->urb.lock); + as->urb = usb_alloc_urb(numisoframes); + if (!as->urb) { + kfree(as); + return NULL; + } return as; } static void free_async(struct async *as) { - if (as->urb.transfer_buffer) - kfree(as->urb.transfer_buffer); - if (as->urb.setup_packet) - kfree(as->urb.setup_packet); + if (as->urb->transfer_buffer) + kfree(as->urb->transfer_buffer); + if (as->urb->setup_packet) + kfree(as->urb->setup_packet); + usb_free_urb(as->urb); kfree(as); } @@ -259,7 +263,7 @@ wake_up(&ps->wait); if (as->signr) { sinfo.si_signo = as->signr; - sinfo.si_errno = as->urb.status; + sinfo.si_errno = as->urb->status; sinfo.si_code = SI_ASYNCIO; sinfo.si_addr = as->userurb; send_sig_info(as->signr, &sinfo, as->task); @@ -278,7 +282,7 @@ INIT_LIST_HEAD(&as->asynclist); spin_unlock_irqrestore(&ps->lock, flags); /* usb_unlink_urb calls the completion handler with status == -ENOENT */ - usb_unlink_urb(&as->urb); + usb_unlink_urb(as->urb); spin_lock_irqsave(&ps->lock, flags); } spin_unlock_irqrestore(&ps->lock, flags); @@ -862,7 +866,7 @@ kfree(dr); return -ENOMEM; } - if (!(as->urb.transfer_buffer = kmalloc(uurb.buffer_length, GFP_KERNEL))) { + if (!(as->urb->transfer_buffer = kmalloc(uurb.buffer_length, GFP_KERNEL))) { if (isopkt) kfree(isopkt); if (dr) @@ -870,19 +874,19 @@ free_async(as); return -ENOMEM; } - as->urb.next = NULL; - as->urb.dev = ps->dev; - as->urb.pipe = (uurb.type << 30) | __create_pipe(ps->dev, uurb.endpoint & 0xf) | (uurb.endpoint & USB_DIR_IN); - as->urb.transfer_flags = uurb.flags; - as->urb.transfer_buffer_length = uurb.buffer_length; - as->urb.setup_packet = (unsigned char*)dr; - as->urb.start_frame = uurb.start_frame; - as->urb.number_of_packets = uurb.number_of_packets; - as->urb.context = as; - as->urb.complete = async_completed; + as->urb->next = NULL; + as->urb->dev = ps->dev; + as->urb->pipe = (uurb.type << 30) | __create_pipe(ps->dev, uurb.endpoint & 0xf) | (uurb.endpoint & USB_DIR_IN); + as->urb->transfer_flags = uurb.flags; + as->urb->transfer_buffer_length = uurb.buffer_length; + as->urb->setup_packet = (unsigned char*)dr; + as->urb->start_frame = uurb.start_frame; + as->urb->number_of_packets = uurb.number_of_packets; + as->urb->context = as; + as->urb->complete = async_completed; for (totlen = u = 0; u < uurb.number_of_packets; u++) { - as->urb.iso_frame_desc[u].offset = totlen; - as->urb.iso_frame_desc[u].length = isopkt[u].length; + as->urb->iso_frame_desc[u].offset = totlen; + as->urb->iso_frame_desc[u].length = isopkt[u].length; totlen += isopkt[u].length; } if (isopkt) @@ -896,13 +900,13 @@ as->signr = uurb.signr; as->task = current; if (!(uurb.endpoint & USB_DIR_IN)) { - if (copy_from_user(as->urb.transfer_buffer, uurb.buffer, as->urb.transfer_buffer_length)) { + if (copy_from_user(as->urb->transfer_buffer, uurb.buffer, as->urb->transfer_buffer_length)) { free_async(as); return -EFAULT; } } async_newpending(as); - if ((ret = usb_submit_urb(&as->urb))) { + if ((ret = usb_submit_urb(as->urb))) { printk(KERN_DEBUG "usbdevfs: usb_submit_urb returned %d\n", ret); async_removepending(as); free_async(as); @@ -918,34 +922,35 @@ as = async_getpending(ps, arg); if (!as) return -EINVAL; - usb_unlink_urb(&as->urb); + usb_unlink_urb(as->urb); return 0; } static int processcompl(struct async *as) { + struct urb *urb = as->urb; unsigned int i; if (as->userbuffer) - if (copy_to_user(as->userbuffer, as->urb.transfer_buffer, as->urb.transfer_buffer_length)) + if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) return -EFAULT; - if (put_user(as->urb.status, + if (put_user(urb->status, &((struct usbdevfs_urb *)as->userurb)->status)) return -EFAULT; - if (put_user(as->urb.actual_length, + if (put_user(urb->actual_length, &((struct usbdevfs_urb *)as->userurb)->actual_length)) return -EFAULT; - if (put_user(as->urb.error_count, + if (put_user(urb->error_count, &((struct usbdevfs_urb *)as->userurb)->error_count)) return -EFAULT; - if (!(usb_pipeisoc(as->urb.pipe))) + if (!(usb_pipeisoc(urb->pipe))) return 0; - for (i = 0; i < as->urb.number_of_packets; i++) { - if (put_user(as->urb.iso_frame_desc[i].actual_length, + for (i = 0; i < urb->number_of_packets; i++) { + if (put_user(urb->iso_frame_desc[i].actual_length, &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length)) return -EFAULT; - if (put_user(as->urb.iso_frame_desc[i].status, + if (put_user(urb->iso_frame_desc[i].status, &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status)) return -EFAULT; }