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
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel