mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 16:53:55 -06:00
usb: rework attach/detach workflow
Add separate detach callback to USBPortOps, split uhci/ohci/musb/usbhub attach functions into two. Move common code to the usb_attach() function, only the hardware-specific bits remain in the attach/detach callbacks. Keep track of the port it is attached to for each usb device. [ v3: fix tyops in usb-musb.c ] Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
0d86d2bebb
commit
618c169b57
6 changed files with 124 additions and 135 deletions
|
@ -307,8 +307,6 @@ static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token
|
|||
return match;
|
||||
}
|
||||
|
||||
static void uhci_attach(USBPort *port1, USBDevice *dev);
|
||||
|
||||
static void uhci_update_irq(UHCIState *s)
|
||||
{
|
||||
int level;
|
||||
|
@ -348,8 +346,9 @@ static void uhci_reset(void *opaque)
|
|||
for(i = 0; i < NB_PORTS; i++) {
|
||||
port = &s->ports[i];
|
||||
port->ctrl = 0x0080;
|
||||
if (port->port.dev)
|
||||
uhci_attach(&port->port, port->port.dev);
|
||||
if (port->port.dev) {
|
||||
usb_attach(&port->port, port->port.dev);
|
||||
}
|
||||
}
|
||||
|
||||
uhci_async_cancel_all(s);
|
||||
|
@ -593,50 +592,41 @@ static void uhci_resume (void *opaque)
|
|||
}
|
||||
}
|
||||
|
||||
static void uhci_attach(USBPort *port1, USBDevice *dev)
|
||||
static void uhci_attach(USBPort *port1)
|
||||
{
|
||||
UHCIState *s = port1->opaque;
|
||||
UHCIPort *port = &s->ports[port1->index];
|
||||
|
||||
if (dev) {
|
||||
if (port->port.dev) {
|
||||
usb_attach(port1, NULL);
|
||||
}
|
||||
/* set connect status */
|
||||
port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
|
||||
/* set connect status */
|
||||
port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
|
||||
|
||||
/* update speed */
|
||||
if (dev->speed == USB_SPEED_LOW)
|
||||
port->ctrl |= UHCI_PORT_LSDA;
|
||||
else
|
||||
port->ctrl &= ~UHCI_PORT_LSDA;
|
||||
|
||||
uhci_resume(s);
|
||||
|
||||
port->port.dev = dev;
|
||||
/* send the attach message */
|
||||
usb_send_msg(dev, USB_MSG_ATTACH);
|
||||
/* update speed */
|
||||
if (port->port.dev->speed == USB_SPEED_LOW) {
|
||||
port->ctrl |= UHCI_PORT_LSDA;
|
||||
} else {
|
||||
/* set connect status */
|
||||
if (port->ctrl & UHCI_PORT_CCS) {
|
||||
port->ctrl &= ~UHCI_PORT_CCS;
|
||||
port->ctrl |= UHCI_PORT_CSC;
|
||||
}
|
||||
/* disable port */
|
||||
if (port->ctrl & UHCI_PORT_EN) {
|
||||
port->ctrl &= ~UHCI_PORT_EN;
|
||||
port->ctrl |= UHCI_PORT_ENC;
|
||||
}
|
||||
|
||||
uhci_resume(s);
|
||||
|
||||
dev = port->port.dev;
|
||||
if (dev) {
|
||||
/* send the detach message */
|
||||
usb_send_msg(dev, USB_MSG_DETACH);
|
||||
}
|
||||
port->port.dev = NULL;
|
||||
port->ctrl &= ~UHCI_PORT_LSDA;
|
||||
}
|
||||
|
||||
uhci_resume(s);
|
||||
}
|
||||
|
||||
static void uhci_detach(USBPort *port1)
|
||||
{
|
||||
UHCIState *s = port1->opaque;
|
||||
UHCIPort *port = &s->ports[port1->index];
|
||||
|
||||
/* set connect status */
|
||||
if (port->ctrl & UHCI_PORT_CCS) {
|
||||
port->ctrl &= ~UHCI_PORT_CCS;
|
||||
port->ctrl |= UHCI_PORT_CSC;
|
||||
}
|
||||
/* disable port */
|
||||
if (port->ctrl & UHCI_PORT_EN) {
|
||||
port->ctrl &= ~UHCI_PORT_EN;
|
||||
port->ctrl |= UHCI_PORT_ENC;
|
||||
}
|
||||
|
||||
uhci_resume(s);
|
||||
}
|
||||
|
||||
static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
|
||||
|
@ -1103,6 +1093,7 @@ static void uhci_map(PCIDevice *pci_dev, int region_num,
|
|||
|
||||
static USBPortOps uhci_port_ops = {
|
||||
.attach = uhci_attach,
|
||||
.detach = uhci_detach,
|
||||
};
|
||||
|
||||
static int usb_uhci_common_initfn(UHCIState *s)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue