mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
usb: Replace device_destroy bus op with a child_detach port op
Note this fixes 2 things in one go, first of all the device_destroy bus op should be a device_detach bus op, as pending async packets from the device should be cancelled on detach not on destroy. Secondly having this as a bus op won't work with companion controllers, since then there will be 1 bus driven by the ehci controller and thus 1 set of bus ops, but the device being detached may be downstream of a handed over port. Making the detach of a downstream device a port op allows the ehci controller to forward this to the companion controller port for handed over ports. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
d47e59b8b8
commit
4706ab6cc0
8 changed files with 69 additions and 29 deletions
|
@ -124,6 +124,7 @@ struct ohci_hcca {
|
|||
};
|
||||
|
||||
static void ohci_bus_stop(OHCIState *ohci);
|
||||
static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev);
|
||||
|
||||
/* Bitfields for the first word of an Endpoint Desciptor. */
|
||||
#define OHCI_ED_FA_SHIFT 0
|
||||
|
@ -351,6 +352,8 @@ static void ohci_detach(USBPort *port1)
|
|||
OHCIPort *port = &s->rhport[port1->index];
|
||||
uint32_t old_state = port->ctrl;
|
||||
|
||||
ohci_async_cancel_device(s, port1->dev);
|
||||
|
||||
/* set connect status */
|
||||
if (port->ctrl & OHCI_PORT_CCS) {
|
||||
port->ctrl &= ~OHCI_PORT_CCS;
|
||||
|
@ -392,6 +395,13 @@ static void ohci_wakeup(USBPort *port1)
|
|||
ohci_set_interrupt(s, intr);
|
||||
}
|
||||
|
||||
static void ohci_child_detach(USBPort *port1, USBDevice *child)
|
||||
{
|
||||
OHCIState *s = port1->opaque;
|
||||
|
||||
ohci_async_cancel_device(s, child);
|
||||
}
|
||||
|
||||
/* Reset the controller */
|
||||
static void ohci_reset(void *opaque)
|
||||
{
|
||||
|
@ -1673,10 +1683,8 @@ static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
static void ohci_device_destroy(USBBus *bus, USBDevice *dev)
|
||||
static void ohci_async_cancel_device(OHCIState *ohci, 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;
|
||||
|
@ -1700,12 +1708,12 @@ static CPUWriteMemoryFunc * const ohci_writefn[3]={
|
|||
static USBPortOps ohci_port_ops = {
|
||||
.attach = ohci_attach,
|
||||
.detach = ohci_detach,
|
||||
.child_detach = ohci_child_detach,
|
||||
.wakeup = ohci_wakeup,
|
||||
.complete = ohci_async_complete_packet,
|
||||
};
|
||||
|
||||
static USBBusOps ohci_bus_ops = {
|
||||
.device_destroy = ohci_device_destroy,
|
||||
};
|
||||
|
||||
static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue