When the USB OHCI controller starts, a periodic end-of-frame routine
writes to a chunk of memory set aside by the device driver. If the
machine reboots or the OS kexecs, the controller continues writing
even though the memory is no longer owned by the device driver,
causing random, mysterious corruption, until the new OS reinitializes
the OHCI controller.

The attached patch fixes this by resetting the controller whenever the
machine reboots or the device driver issues a reset command, and
disabling the timer when the controller resets.

--Ed
Index: qemu-snapshot-2007-02-09_05/hw/usb-ohci.c
===================================================================
--- qemu-snapshot-2007-02-09_05.orig/hw/usb-ohci.c
+++ qemu-snapshot-2007-02-09_05/hw/usb-ohci.c
@@ -106,6 +106,8 @@ struct ohci_hcca {
     uint32_t done;
 };
 
+static void ohci_bus_stop(OHCIState *ohci);
+
 /* Bitfields for the first word of an Endpoint Desciptor.  */
 #define OHCI_ED_FA_SHIFT  0
 #define OHCI_ED_FA_MASK   (0x7f<<OHCI_ED_FA_SHIFT)
@@ -323,11 +325,13 @@ static void ohci_attach(USBPort *port1, 
 }
 
 /* Reset the controller */
-static void ohci_reset(OHCIState *ohci)
+static void ohci_reset(void *opaque)
 {
+    OHCIState *ohci = opaque;
     OHCIPort *port;
     int i;
 
+    ohci_bus_stop(ohci);
     ohci->ctl = 0;
     ohci->old_ctl = 0;
     ohci->status = 0;
@@ -813,6 +817,7 @@ static void ohci_bus_stop(OHCIState *ohc
 {
     if (ohci->eof_timer)
         qemu_del_timer(ohci->eof_timer);
+    ohci->eof_timer = NULL;
 }
 
 /* Sets a flag in a port status register but only set it if the port is
@@ -898,6 +903,7 @@ static void ohci_set_ctl(OHCIState *ohci
         dprintf("usb-ohci: %s: USB Resume\n", ohci->pci_dev.name);
         break;
     case OHCI_USB_RESET:
+        ohci_reset(ohci);
         dprintf("usb-ohci: %s: USB Reset\n", ohci->pci_dev.name);
         break;
     }
@@ -1266,5 +1272,6 @@ void usb_ohci_init(struct PCIBus *bus, i
     }
 
     ohci->async_td = 0;
+    qemu_register_reset(ohci_reset, ohci);
     ohci_reset(ohci);
 }

Reply via email to