Loading Documentation/usb/URB.txt +22 −0 Original line number Diff line number Diff line Loading @@ -168,6 +168,28 @@ that if the completion handler or anyone else tries to resubmit it they will get a -EPERM error. Thus you can be sure that when usb_kill_urb() returns, the URB is totally idle. There is a lifetime issue to consider. An URB may complete at any time, and the completion handler may free the URB. If this happens while usb_unlink_urb or usb_kill_urb is running, it will cause a memory-access violation. The driver is responsible for avoiding this, which often means some sort of lock will be needed to prevent the URB from being deallocated while it is still in use. On the other hand, since usb_unlink_urb may end up calling the completion handler, the handler must not take any lock that is held when usb_unlink_urb is invoked. The general solution to this problem is to increment the URB's reference count while holding the lock, then drop the lock and call usb_unlink_urb or usb_kill_urb, and then decrement the URB's reference count. You increment the reference count by calling struct urb *usb_get_urb(struct urb *urb) (ignore the return value; it is the same as the argument) and decrement the reference count by calling usb_free_urb. Of course, none of this is necessary if there's no danger of the URB being freed by the completion handler. 1.7. What about the completion handler? Loading Documentation/usb/usbmon.txt +3 −3 Original line number Diff line number Diff line Loading @@ -183,10 +183,10 @@ An input control transfer to get a port status. d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 < d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000 An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper to a storage device at address 5: An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte Bulk wrapper to a storage device at address 5: dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000 dd65f0e8 4128379808 C Bo:1:005:2 0 31 > * Raw binary format and API Loading drivers/usb/Kconfig +8 −8 Original line number Diff line number Diff line Loading @@ -2,14 +2,6 @@ # USB device configuration # menuconfig USB_SUPPORT bool "USB support" depends on HAS_IOMEM default y ---help--- This option adds core support for Universal Serial Bus (USB). You will also need drivers from the following menu to make use of it. # many non-PCI SOC chips embed OHCI config USB_ARCH_HAS_OHCI boolean Loading Loading @@ -63,6 +55,14 @@ config USB_ARCH_HAS_XHCI boolean default PCI menuconfig USB_SUPPORT bool "USB support" depends on HAS_IOMEM default y ---help--- This option adds core support for Universal Serial Bus (USB). You will also need drivers from the following menu to make use of it. if USB_SUPPORT config USB_COMMON Loading drivers/usb/core/message.c +6 −5 Original line number Diff line number Diff line Loading @@ -308,7 +308,8 @@ static void sg_complete(struct urb *urb) retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -ENODEV && retval != -EBUSY) retval != -EBUSY && retval != -EIDRM) dev_err(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); Loading @@ -317,7 +318,6 @@ static void sg_complete(struct urb *urb) } spin_lock(&io->lock); } urb->dev = NULL; /* on the last completion, signal usb_sg_wait() */ io->bytes += urb->actual_length; Loading Loading @@ -524,7 +524,6 @@ void usb_sg_wait(struct usb_sg_request *io) case -ENXIO: /* hc didn't queue this one */ case -EAGAIN: case -ENOMEM: io->urbs[i]->dev = NULL; retval = 0; yield(); break; Loading @@ -542,7 +541,6 @@ void usb_sg_wait(struct usb_sg_request *io) /* fail any uncompleted urbs */ default: io->urbs[i]->dev = NULL; io->urbs[i]->status = retval; dev_dbg(&io->dev->dev, "%s, submit --> %d\n", __func__, retval); Loading Loading @@ -593,7 +591,10 @@ void usb_sg_cancel(struct usb_sg_request *io) if (!io->urbs [i]->dev) continue; retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -EBUSY) if (retval != -EINPROGRESS && retval != -ENODEV && retval != -EBUSY && retval != -EIDRM) dev_warn(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); } Loading drivers/usb/core/urb.c +12 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,10 @@ EXPORT_SYMBOL_GPL(usb_submit_urb); * never submitted, or it was unlinked before, or the hardware is already * finished with it), even if the completion handler has not yet run. * * The URB must not be deallocated while this routine is running. In * particular, when a driver calls this routine, it must insure that the * completion handler cannot deallocate the URB. * * Unlinking and Endpoint Queues: * * [The behaviors and guarantees described below do not apply to virtual Loading Loading @@ -603,6 +607,10 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * * The URB must not be deallocated while this routine is running. In * particular, when a driver calls this routine, it must insure that the * completion handler cannot deallocate the URB. * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). Loading Loading @@ -640,6 +648,10 @@ EXPORT_SYMBOL_GPL(usb_kill_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * * The URB must not be deallocated while this routine is running. In * particular, when a driver calls this routine, it must insure that the * completion handler cannot deallocate the URB. * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). Loading Loading
Documentation/usb/URB.txt +22 −0 Original line number Diff line number Diff line Loading @@ -168,6 +168,28 @@ that if the completion handler or anyone else tries to resubmit it they will get a -EPERM error. Thus you can be sure that when usb_kill_urb() returns, the URB is totally idle. There is a lifetime issue to consider. An URB may complete at any time, and the completion handler may free the URB. If this happens while usb_unlink_urb or usb_kill_urb is running, it will cause a memory-access violation. The driver is responsible for avoiding this, which often means some sort of lock will be needed to prevent the URB from being deallocated while it is still in use. On the other hand, since usb_unlink_urb may end up calling the completion handler, the handler must not take any lock that is held when usb_unlink_urb is invoked. The general solution to this problem is to increment the URB's reference count while holding the lock, then drop the lock and call usb_unlink_urb or usb_kill_urb, and then decrement the URB's reference count. You increment the reference count by calling struct urb *usb_get_urb(struct urb *urb) (ignore the return value; it is the same as the argument) and decrement the reference count by calling usb_free_urb. Of course, none of this is necessary if there's no danger of the URB being freed by the completion handler. 1.7. What about the completion handler? Loading
Documentation/usb/usbmon.txt +3 −3 Original line number Diff line number Diff line Loading @@ -183,10 +183,10 @@ An input control transfer to get a port status. d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 < d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000 An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper to a storage device at address 5: An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte Bulk wrapper to a storage device at address 5: dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000 dd65f0e8 4128379808 C Bo:1:005:2 0 31 > * Raw binary format and API Loading
drivers/usb/Kconfig +8 −8 Original line number Diff line number Diff line Loading @@ -2,14 +2,6 @@ # USB device configuration # menuconfig USB_SUPPORT bool "USB support" depends on HAS_IOMEM default y ---help--- This option adds core support for Universal Serial Bus (USB). You will also need drivers from the following menu to make use of it. # many non-PCI SOC chips embed OHCI config USB_ARCH_HAS_OHCI boolean Loading Loading @@ -63,6 +55,14 @@ config USB_ARCH_HAS_XHCI boolean default PCI menuconfig USB_SUPPORT bool "USB support" depends on HAS_IOMEM default y ---help--- This option adds core support for Universal Serial Bus (USB). You will also need drivers from the following menu to make use of it. if USB_SUPPORT config USB_COMMON Loading
drivers/usb/core/message.c +6 −5 Original line number Diff line number Diff line Loading @@ -308,7 +308,8 @@ static void sg_complete(struct urb *urb) retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -ENODEV && retval != -EBUSY) retval != -EBUSY && retval != -EIDRM) dev_err(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); Loading @@ -317,7 +318,6 @@ static void sg_complete(struct urb *urb) } spin_lock(&io->lock); } urb->dev = NULL; /* on the last completion, signal usb_sg_wait() */ io->bytes += urb->actual_length; Loading Loading @@ -524,7 +524,6 @@ void usb_sg_wait(struct usb_sg_request *io) case -ENXIO: /* hc didn't queue this one */ case -EAGAIN: case -ENOMEM: io->urbs[i]->dev = NULL; retval = 0; yield(); break; Loading @@ -542,7 +541,6 @@ void usb_sg_wait(struct usb_sg_request *io) /* fail any uncompleted urbs */ default: io->urbs[i]->dev = NULL; io->urbs[i]->status = retval; dev_dbg(&io->dev->dev, "%s, submit --> %d\n", __func__, retval); Loading Loading @@ -593,7 +591,10 @@ void usb_sg_cancel(struct usb_sg_request *io) if (!io->urbs [i]->dev) continue; retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -EBUSY) if (retval != -EINPROGRESS && retval != -ENODEV && retval != -EBUSY && retval != -EIDRM) dev_warn(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); } Loading
drivers/usb/core/urb.c +12 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,10 @@ EXPORT_SYMBOL_GPL(usb_submit_urb); * never submitted, or it was unlinked before, or the hardware is already * finished with it), even if the completion handler has not yet run. * * The URB must not be deallocated while this routine is running. In * particular, when a driver calls this routine, it must insure that the * completion handler cannot deallocate the URB. * * Unlinking and Endpoint Queues: * * [The behaviors and guarantees described below do not apply to virtual Loading Loading @@ -603,6 +607,10 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * * The URB must not be deallocated while this routine is running. In * particular, when a driver calls this routine, it must insure that the * completion handler cannot deallocate the URB. * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). Loading Loading @@ -640,6 +648,10 @@ EXPORT_SYMBOL_GPL(usb_kill_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * * The URB must not be deallocated while this routine is running. In * particular, when a driver calls this routine, it must insure that the * completion handler cannot deallocate the URB. * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). Loading