On Mon, 10 Jan 2005, Matthias Urlichs wrote:

> Hi,
> 
> I observed a few crashes in rh_report_status recently.
> 
> Three problems:
> - The timer is not always disabled when the data value is zeroed.
> - If the root hub has vanished (somebody unplugged the PCMCIA card with
>   the USB adapter at exactly the wrong time), hcd->self.root_hub may be
>   zero.
> 
> These seem to be fixed by the patch appended below.
> Please propagate to Linus' kernel.

None of these changes should be needed.  That's not to say there aren't 
any remaining problems -- there may well be, but they should be fixed 
another way.

> ===== drivers/usb/core/hcd.c 1.104 vs edited =====
> --- 1.104/drivers/usb/core/hcd.c      2004-11-07 23:31:07 +01:00
> +++ edited/drivers/usb/core/hcd.c     2005-01-10 13:07:13 +01:00
> @@ -538,6 +543,8 @@
>               length = hcd->driver->hub_status_data (
>                                       hcd, urb->transfer_buffer);
>               if (length > 0) {
> +                     if (hcd->rh_timer.data)
> +                             del_timer_sync (&hcd->rh_timer);

There's no point in deleting the timer here.  This section of code is in
the timer callback, so whenever it runs the timer has already been turned
off.

>                       hcd->rh_timer.data = 0;
>                       urb->actual_length = length;
>                       urb->status = 0;
> @@ -1623,8 +1632,11 @@
>       dev_err (hcd->self.controller, "HC died; cleaning up\n");
>  
>       /* make khubd clean up old urbs and devices */
> -     usb_set_device_state(hcd->self.root_hub, USB_STATE_NOTATTACHED);
> -     mod_timer(&hcd->rh_timer, jiffies);
> +
> +     if(hcd->self.root_hub) {
> +             usb_set_device_state(hcd->self.root_hub, USB_STATE_NOTATTACHED);
> +             mod_timer(&hcd->rh_timer, jiffies);
> +     }

I'm not sure about this test.  A better approach might be to change the
host controller drivers instead so that they don't call this routine after
the root hub has been removed.  I suppose that this test won't hurt,
however.

If you're running into races with unexpected device removal, this is 
probably the place where they occur.

>  }
>  EXPORT_SYMBOL (usb_hc_died);
>  
> @@ -1635,6 +1648,8 @@
>       struct usb_hcd *hcd;
>  
>       hcd = container_of (bus, struct usb_hcd, self);
> +     if(hcd->rh_timer.data)
> +             del_timer_sync (&hcd->rh_timer);

By the time this code runs, the root hub should already have been removed.  
Removing it will automatically cancel the status URB and hence will delete 
the timer; there's no need to delete it again.

>       kfree(hcd);
>  }
>  EXPORT_SYMBOL (usb_hcd_release);

Alan Stern



-------------------------------------------------------
The SF.Net email is sponsored by: Beat the post-holiday blues
Get a FREE limited edition SourceForge.net t-shirt from ThinkGeek.
It's fun and FREE -- well, almost....http://www.thinkgeek.com/sfshirt
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to