Commit 73221b12ea55ae916b550e56d70743221ca3c886
1 parent
82d17978
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
Showing
1 changed file
with
8 additions
and
1 deletions
hw/usb-ohci.c
@@ -120,6 +120,8 @@ struct ohci_hcca { | @@ -120,6 +120,8 @@ struct ohci_hcca { | ||
120 | uint32_t done; | 120 | uint32_t done; |
121 | }; | 121 | }; |
122 | 122 | ||
123 | +static void ohci_bus_stop(OHCIState *ohci); | ||
124 | + | ||
123 | /* Bitfields for the first word of an Endpoint Desciptor. */ | 125 | /* Bitfields for the first word of an Endpoint Desciptor. */ |
124 | #define OHCI_ED_FA_SHIFT 0 | 126 | #define OHCI_ED_FA_SHIFT 0 |
125 | #define OHCI_ED_FA_MASK (0x7f<<OHCI_ED_FA_SHIFT) | 127 | #define OHCI_ED_FA_MASK (0x7f<<OHCI_ED_FA_SHIFT) |
@@ -344,11 +346,13 @@ static void ohci_attach(USBPort *port1, USBDevice *dev) | @@ -344,11 +346,13 @@ static void ohci_attach(USBPort *port1, USBDevice *dev) | ||
344 | } | 346 | } |
345 | 347 | ||
346 | /* Reset the controller */ | 348 | /* Reset the controller */ |
347 | -static void ohci_reset(OHCIState *ohci) | 349 | +static void ohci_reset(void *opaque) |
348 | { | 350 | { |
351 | + OHCIState *ohci = opaque; | ||
349 | OHCIPort *port; | 352 | OHCIPort *port; |
350 | int i; | 353 | int i; |
351 | 354 | ||
355 | + ohci_bus_stop(ohci); | ||
352 | ohci->ctl = 0; | 356 | ohci->ctl = 0; |
353 | ohci->old_ctl = 0; | 357 | ohci->old_ctl = 0; |
354 | ohci->status = 0; | 358 | ohci->status = 0; |
@@ -833,6 +837,7 @@ static void ohci_bus_stop(OHCIState *ohci) | @@ -833,6 +837,7 @@ static void ohci_bus_stop(OHCIState *ohci) | ||
833 | { | 837 | { |
834 | if (ohci->eof_timer) | 838 | if (ohci->eof_timer) |
835 | qemu_del_timer(ohci->eof_timer); | 839 | qemu_del_timer(ohci->eof_timer); |
840 | + ohci->eof_timer = NULL; | ||
836 | } | 841 | } |
837 | 842 | ||
838 | /* Sets a flag in a port status register but only set it if the port is | 843 | /* 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) | @@ -918,6 +923,7 @@ static void ohci_set_ctl(OHCIState *ohci, uint32_t val) | ||
918 | dprintf("usb-ohci: %s: USB Resume\n", ohci->name); | 923 | dprintf("usb-ohci: %s: USB Resume\n", ohci->name); |
919 | break; | 924 | break; |
920 | case OHCI_USB_RESET: | 925 | case OHCI_USB_RESET: |
926 | + ohci_reset(ohci); | ||
921 | dprintf("usb-ohci: %s: USB Reset\n", ohci->name); | 927 | dprintf("usb-ohci: %s: USB Reset\n", ohci->name); |
922 | break; | 928 | break; |
923 | } | 929 | } |
@@ -1291,6 +1297,7 @@ static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn, | @@ -1291,6 +1297,7 @@ static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn, | ||
1291 | } | 1297 | } |
1292 | 1298 | ||
1293 | ohci->async_td = 0; | 1299 | ohci->async_td = 0; |
1300 | + qemu_register_reset(ohci_reset, ohci); | ||
1294 | ohci_reset(ohci); | 1301 | ohci_reset(ohci); |
1295 | } | 1302 | } |
1296 | 1303 |