From: David Vrabel <david.vrabel@xxxxxxx> Check the return value of usb_hcd_link_urb_to_ep() and do not add the urb to the ASL/PZL if it returns an error. Omitting the check results in urbs that appear to be submitted successfully but then cannot be unliked (because usb_hcd_check_unlink_urb() returns an error). This can cause khubd (for example) to block forever in usb_kill_urb(). Signed-off-by: David Vrabel <david.vrabel@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx> --- drivers/usb/host/whci/asl.c | 12 +++++++++--- drivers/usb/host/whci/pzl.c | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index be753f6..c205078 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c @@ -255,23 +255,29 @@ int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags) spin_lock_irqsave(&whc->lock, flags); + err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); + if (err < 0) { + spin_unlock_irqrestore(&whc->lock, flags); + return err; + } + qset = get_qset(whc, urb, GFP_ATOMIC); if (qset == NULL) err = -ENOMEM; else err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); if (!err) { - usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); if (!qset->in_sw_list) asl_qset_insert_begin(whc, qset); - } + } else + usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb); spin_unlock_irqrestore(&whc->lock, flags); if (!err) queue_work(whc->workqueue, &whc->async_work); - return 0; + return err; } /** diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 0c40022..ff4ef9e 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c @@ -283,23 +283,29 @@ int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags) spin_lock_irqsave(&whc->lock, flags); + err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); + if (err < 0) { + spin_unlock_irqrestore(&whc->lock, flags); + return err; + } + qset = get_qset(whc, urb, GFP_ATOMIC); if (qset == NULL) err = -ENOMEM; else err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); if (!err) { - usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); if (!qset->in_sw_list) qset_insert_in_sw_list(whc, qset); - } + } else + usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb); spin_unlock_irqrestore(&whc->lock, flags); if (!err) queue_work(whc->workqueue, &whc->periodic_work); - return 0; + return err; } /** -- 1.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html