mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 16:23:55 -06:00
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>
This commit is contained in:
parent
8e4faf3de9
commit
07771f6fce
7 changed files with 106 additions and 7 deletions
|
@ -685,6 +685,18 @@ static void ehci_queues_rip_unused(EHCIState *ehci)
|
|||
}
|
||||
}
|
||||
|
||||
static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev)
|
||||
{
|
||||
EHCIQueue *q, *tmp;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
|
||||
if (q->packet.owner != dev) {
|
||||
continue;
|
||||
}
|
||||
ehci_free_queue(q);
|
||||
}
|
||||
}
|
||||
|
||||
static void ehci_queues_rip_all(EHCIState *ehci)
|
||||
{
|
||||
EHCIQueue *q, *tmp;
|
||||
|
@ -2100,6 +2112,13 @@ static void ehci_map(PCIDevice *pci_dev, int region_num,
|
|||
cpu_register_physical_memory(addr, size, s->mem);
|
||||
}
|
||||
|
||||
static void ehci_device_destroy(USBBus *bus, USBDevice *dev)
|
||||
{
|
||||
EHCIState *s = container_of(bus, EHCIState, bus);
|
||||
|
||||
ehci_queues_rip_device(s, dev);
|
||||
}
|
||||
|
||||
static int usb_ehci_initfn(PCIDevice *dev);
|
||||
|
||||
static USBPortOps ehci_port_ops = {
|
||||
|
@ -2108,6 +2127,10 @@ static USBPortOps ehci_port_ops = {
|
|||
.complete = ehci_async_complete_packet,
|
||||
};
|
||||
|
||||
static USBBusOps ehci_bus_ops = {
|
||||
.device_destroy = ehci_device_destroy,
|
||||
};
|
||||
|
||||
static PCIDeviceInfo ehci_info = {
|
||||
.qdev.name = "usb-ehci",
|
||||
.qdev.size = sizeof(EHCIState),
|
||||
|
@ -2170,7 +2193,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
|
|||
|
||||
s->irq = s->dev.irq[3];
|
||||
|
||||
usb_bus_new(&s->bus, &s->dev.qdev);
|
||||
usb_bus_new(&s->bus, &ehci_bus_ops, &s->dev.qdev);
|
||||
for(i = 0; i < NB_PORTS; i++) {
|
||||
usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops,
|
||||
USB_SPEED_MASK_HIGH);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue