--- 1.68/drivers/usb/core/hcd.c Tue Jul 15 09:47:16 2003 +++ edited/drivers/usb/core/hcd.c Sun Jul 27 19:42:46 2003 @@ -1487,8 +1488,26 @@ static void hcd_panic (void *_hcd) { - struct usb_hcd *hcd = _hcd; - hcd->driver->stop (hcd); + struct usb_hcd *hcd = _hcd; + struct usb_device *hub = hcd->self.root_hub; + + hub = usb_get_dev (hub); + usb_disconnect (&hub); + + /* FIXME either try to restart, or arrange to clean up the + * hc-internal state, like usb_hcd_pci_remove() does + */ +} + +void mark_gone (struct usb_device *dev) +{ + unsigned i; + + dev->state = USB_STATE_NOTATTACHED; + for (i = 0; i < dev->maxchild; i++) { + if (dev->children [i]) + mark_gone (dev->children [i]); + } } /** @@ -1501,29 +1520,12 @@ */ void usb_hc_died (struct usb_hcd *hcd) { - struct list_head *devlist, *urblist; - struct hcd_dev *dev; - struct urb *urb; - unsigned long flags; - - /* flag every pending urb as done */ - spin_lock_irqsave (&hcd_data_lock, flags); - list_for_each (devlist, &hcd->dev_list) { - dev = list_entry (devlist, struct hcd_dev, dev_list); - list_for_each (urblist, &dev->urb_list) { - urb = list_entry (urblist, struct urb, urb_list); - dev_dbg (hcd->controller, "shutdown %s urb %p pipe %x, current status %d\n", - hcd->self.bus_name, urb, urb->pipe, urb->status); - if (urb->status == -EINPROGRESS) - urb->status = -ESHUTDOWN; - } - } - urb = (struct urb *) hcd->rh_timer.data; - if (urb) - urb->status = -ESHUTDOWN; - spin_unlock_irqrestore (&hcd_data_lock, flags); + dev_err (hcd->controller, "HC died; pending I/O will be aborted.\n"); - /* hcd->stop() needs a task context */ + /* prevent new submissions to devices in this tree */ + mark_gone (hcd->self.root_hub); + + /* then usb_disconnect() them all, in a task context */ INIT_WORK (&hcd->work, hcd_panic, hcd); (void) schedule_work (&hcd->work); } --- 1.12/drivers/usb/host/ohci-pci.c Mon Apr 14 02:51:40 2003 +++ edited/drivers/usb/host/ohci-pci.c Sun Jul 27 18:51:21 2003 @@ -199,6 +199,11 @@ int retval = 0; unsigned long flags; + if (hcd->state == USB_STATE_HALT) { + ohci_dbg (ohci, "USB restart of halted device\n"); + return -EL3HLT; + } + #ifdef CONFIG_PMAC_PBOOK { struct device_node *of_node;