diff options
author | David Vrabel <david.vrabel@csr.com> | 2009-04-08 13:36:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-04-17 13:50:27 -0400 |
commit | f720af91ec2c67e9a1abbd935570f4b4e1f0dd54 (patch) | |
tree | af1dfd698dedced7944dcce7dcb84ed6fd8860aa /drivers/usb/host/whci/asl.c | |
parent | 7f0406db5fe4dd3ad3cbd53830239a87d68156fd (diff) |
USB: whci-hcd: check return value of usb_hcd_link_urb_to_ep()
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@csr.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/whci/asl.c')
-rw-r--r-- | drivers/usb/host/whci/asl.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index be753f664993..c2050785a819 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) | |||
255 | 255 | ||
256 | spin_lock_irqsave(&whc->lock, flags); | 256 | spin_lock_irqsave(&whc->lock, flags); |
257 | 257 | ||
258 | err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
259 | if (err < 0) { | ||
260 | spin_unlock_irqrestore(&whc->lock, flags); | ||
261 | return err; | ||
262 | } | ||
263 | |||
258 | qset = get_qset(whc, urb, GFP_ATOMIC); | 264 | qset = get_qset(whc, urb, GFP_ATOMIC); |
259 | if (qset == NULL) | 265 | if (qset == NULL) |
260 | err = -ENOMEM; | 266 | err = -ENOMEM; |
261 | else | 267 | else |
262 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); | 268 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); |
263 | if (!err) { | 269 | if (!err) { |
264 | usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
265 | if (!qset->in_sw_list) | 270 | if (!qset->in_sw_list) |
266 | asl_qset_insert_begin(whc, qset); | 271 | asl_qset_insert_begin(whc, qset); |
267 | } | 272 | } else |
273 | usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb); | ||
268 | 274 | ||
269 | spin_unlock_irqrestore(&whc->lock, flags); | 275 | spin_unlock_irqrestore(&whc->lock, flags); |
270 | 276 | ||
271 | if (!err) | 277 | if (!err) |
272 | queue_work(whc->workqueue, &whc->async_work); | 278 | queue_work(whc->workqueue, &whc->async_work); |
273 | 279 | ||
274 | return 0; | 280 | return err; |
275 | } | 281 | } |
276 | 282 | ||
277 | /** | 283 | /** |