diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2011-05-23 17:37:12 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2011-06-14 12:56:49 +0200 |
commit | 07771f6fcebdb12de6dca537423f56299ed9b4b9 (patch) | |
tree | 374f2b5049bf5dc38984921b76250c590ab65403 /hw/usb-ohci.c | |
parent | 8e4faf3de9d1a8bd3289e5cc69d4ed206e2ed0cf (diff) | |
download | qemu-07771f6fcebdb12de6dca537423f56299ed9b4b9.zip |
usb: cancel async packets on unplug
This patch adds USBBusOps struct with (for now) only a single callback
which is called when a device is about to be destroyed. The USB Host
adapters are implementing this callback and use it to cancel any async
requests which might be in flight before the device actually goes away.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb-ohci.c')
-rw-r--r-- | hw/usb-ohci.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index 8b966f7907..401045a28f 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -1644,6 +1644,16 @@ static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) } } +static void ohci_device_destroy(USBBus *bus, USBDevice *dev) +{ + OHCIState *ohci = container_of(bus, OHCIState, bus); + + if (ohci->async_td && ohci->usb_packet.owner == dev) { + usb_cancel_packet(&ohci->usb_packet); + ohci->async_td = 0; + } +} + /* Only dword reads are defined on OHCI register space */ static CPUReadMemoryFunc * const ohci_readfn[3]={ ohci_mem_read, @@ -1664,6 +1674,10 @@ static USBPortOps ohci_port_ops = { .complete = ohci_async_complete_packet, }; +static USBBusOps ohci_bus_ops = { + .device_destroy = ohci_device_destroy, +}; + static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, int num_ports, uint32_t localmem_base) { @@ -1691,7 +1705,7 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, ohci->name = dev->info->name; - usb_bus_new(&ohci->bus, dev); + usb_bus_new(&ohci->bus, &ohci_bus_ops, dev); ohci->num_ports = num_ports; for (i = 0; i < num_ports; i++) { usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops, |