summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2002-12-30 01:16:25 -0800
committerGreg Kroah-Hartman <greg@kroah.com>2002-12-30 01:16:25 -0800
commit4363e84803d40ba88336df3585b85dfaa88ff40d (patch)
tree0f31bfd1a0874d72936d7f5da08c568892be0818 /drivers
parenta08c2ca875535c30e407217c2f7e62099c50a721 (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.c12
-rw-r--r--drivers/usb/core/hcd.h1
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