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>
This commit is contained in:
Родитель
7f0406db5f
Коммит
f720af91ec
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче