aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-07-25 16:50:37 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-07-25 16:50:37 +0000
commit73221b12ea55ae916b550e56d70743221ca3c886 (patch)
tree4a8932abdfb5ca055e8ca6c8d014429f0a4e3e9b /hw
parent82d179781bcd81b37e0213085087e1dbf1f6b7f9 (diff)
Fix memory corruption after OHCI reset, by Ed Swierk.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3086 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw')
-rw-r--r--hw/usb-ohci.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 99e072f875..2d5af7da07 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -120,6 +120,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)
@@ -344,11 +346,13 @@ static void ohci_attach(USBPort *port1, USBDevice *dev)
}
/* 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;
@@ -833,6 +837,7 @@ static void ohci_bus_stop(OHCIState *ohci)
{
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
@@ -918,6 +923,7 @@ static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
dprintf("usb-ohci: %s: USB Resume\n", ohci->name);
break;
case OHCI_USB_RESET:
+ ohci_reset(ohci);
dprintf("usb-ohci: %s: USB Reset\n", ohci->name);
break;
}
@@ -1291,6 +1297,7 @@ static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
}
ohci->async_td = 0;
+ qemu_register_reset(ohci_reset, ohci);
ohci_reset(ohci);
}