aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2009-04-08 13:36:31 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-04-17 13:50:27 -0400
commitf720af91ec2c67e9a1abbd935570f4b4e1f0dd54 (patch)
treeaf1dfd698dedced7944dcce7dcb84ed6fd8860aa /drivers
parent7f0406db5fe4dd3ad3cbd53830239a87d68156fd (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')
-rw-r--r--drivers/usb/host/whci/asl.c12
-rw-r--r--drivers/usb/host/whci/pzl.c12
2 files changed, 18 insertions, 6 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/**
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index 0c40022a6b2f..ff4ef9e910d9 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)
283 283
284 spin_lock_irqsave(&whc->lock, flags); 284 spin_lock_irqsave(&whc->lock, flags);
285 285
286 err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
287 if (err < 0) {
288 spin_unlock_irqrestore(&whc->lock, flags);
289 return err;
290 }
291
286 qset = get_qset(whc, urb, GFP_ATOMIC); 292 qset = get_qset(whc, urb, GFP_ATOMIC);
287 if (qset == NULL) 293 if (qset == NULL)
288 err = -ENOMEM; 294 err = -ENOMEM;
289 else 295 else
290 err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); 296 err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
291 if (!err) { 297 if (!err) {
292 usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
293 if (!qset->in_sw_list) 298 if (!qset->in_sw_list)
294 qset_insert_in_sw_list(whc, qset); 299 qset_insert_in_sw_list(whc, qset);
295 } 300 } else
301 usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);
296 302
297 spin_unlock_irqrestore(&whc->lock, flags); 303 spin_unlock_irqrestore(&whc->lock, flags);
298 304
299 if (!err) 305 if (!err)
300 queue_work(whc->workqueue, &whc->periodic_work); 306 queue_work(whc->workqueue, &whc->periodic_work);
301 307
302 return 0; 308 return err;
303} 309}
304 310
305/** 311/**