diff options
| author | David Brownell <david-b@pacbell.net> | 2002-12-30 01:16:25 -0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <greg@kroah.com> | 2002-12-30 01:16:25 -0800 |
| commit | 4363e84803d40ba88336df3585b85dfaa88ff40d (patch) | |
| tree | 0f31bfd1a0874d72936d7f5da08c568892be0818 /drivers | |
| parent | a08c2ca875535c30e407217c2f7e62099c50a721 (diff) | |
[PATCH] cleanup after dead hc needs task context
Simple patch to invoke hcd->stop() in task context, as
required. When Cardbus works again (broken in 2.5.53
unless it's just me), this will get rid of some oopsing
when folk physically eject the device, with no shutdown.
As well as making other "hc died" faults behave better.
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/usb/core/hcd.c | 12 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.h | 1 |
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 624beac700b4..ab3ac53d7b6a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1339,6 +1339,12 @@ EXPORT_SYMBOL (usb_hcd_irq); /*-------------------------------------------------------------------------*/ +static void hcd_panic (void *_hcd) +{ + struct usb_hcd *hcd = _hcd; + hcd->driver->stop (hcd); +} + /** * usb_hc_died - report abnormal shutdown of a host controller (bus glue) * @hcd: pointer to the HCD representing the controller @@ -1371,9 +1377,9 @@ void usb_hc_died (struct usb_hcd *hcd) urb->status = -ESHUTDOWN; spin_unlock_irqrestore (&hcd_data_lock, flags); - if (urb) - usb_rh_status_dequeue (hcd, urb); - hcd->driver->stop (hcd); + /* hcd->stop() needs a task context */ + INIT_WORK (&hcd->work, hcd_panic, hcd); + (void) schedule_work (&hcd->work); } EXPORT_SYMBOL (usb_hc_died); diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 99cb0f4b2c84..a3d924e2e34c 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -67,6 +67,7 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */ struct timer_list rh_timer; /* drives root hub */ struct list_head dev_list; /* devices on this bus */ + struct work_struct work; /* * hardware info/state |
