This patchlet fixes a BUG() when using async unlink on OHCI. Basically, an
error in refcounting led to a schedule()-hungry sohci_free_dev call, even
when in_interrupt().
It's been against 2.4.0-test1-ac7, which includes Roman's last
visible patch (22/5).
-- Cyrille
------------------------------------------------------------------------------
Grumpf.
--- drivers/usb/usb-ohci.romans.c Thu Jun 1 22:12:35 2000
+++ drivers/usb/usb-ohci.c Thu Jun 1 22:19:18 2000
@@ -527,12 +527,12 @@
#ifdef DEBUG
urb_print (urb, "UNLINK", 1);
#endif
-
- usb_dec_dev_use (urb->dev);
- if (usb_pipedevice (urb->pipe) == ohci->rh.devnum)
+ if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) {
+ usb_dec_dev_use(urb->dev);
return rh_unlink_urb (urb); /* a request to the virtual root hub */
-
+ }
+
if (urb->hcpriv) {
/* URB active? */
if (urb->status == USB_ST_URB_PENDING && !ohci->disabled) {
@@ -548,15 +548,19 @@
urb_priv->ed->state |= ED_URB_DEL;
spin_unlock_irqrestore (&usb_ed_lock, flags);
if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) {
+ usb_dec_dev_use (urb->dev);
add_wait_queue (&op_wakeup, &wait);
current->state = TASK_UNINTERRUPTIBLE;
if (!schedule_timeout (HZ / 10)) /* wait until all TDs
are deleted */
err("unlink URB timeout!");
remove_wait_queue (&op_wakeup, &wait);
urb->status = -ENOENT;
- } else
+ } else {
+ /* usb_dec_dev_use done in dl_del_list() */
urb->status = -EINPROGRESS;
+ }
} else {
+ usb_dec_dev_use (urb->dev);
urb_rm_priv (urb);
if (urb->complete && (urb->transfer_flags & USB_ASYNC_UNLINK))
{
urb->complete (urb);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]