One data point:
- 2.4.0-test1 on my laptop got OOPSen in OHCI if I sneezed.
(As in, simple usbdevfs calls to look at devices Oopsed.)
- 2.4.0-test1-ac7 with this patch and Johannes' hub patch
works reliably, like pre9 or so (light testing, though).
So far, so good; but I've not tried ac7 ohci without this patch.
And it does look like it'd affect code that doesn't use async
unlink.
Roman, do you know of anything else that'd have made the OHCI
driver become unstable?
- Dave
----- Original Message -----
From: "Cyrille Chepelov (home)" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Thursday, 1 June, 2000 2:25 PM
Subject: [linux-usb] (OHCI) nasty bug in sohci_unlink_urb() !
>
> 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]