mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 01:03: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
|
@ -322,52 +322,46 @@ static inline void ohci_set_interrupt(OHCIState *ohci, uint32_t intr)
|
|||
}
|
||||
|
||||
/* Attach or detach a device on a root hub port. */
|
||||
static void ohci_attach(USBPort *port1, USBDevice *dev)
|
||||
static void ohci_attach(USBPort *port1)
|
||||
{
|
||||
OHCIState *s = port1->opaque;
|
||||
OHCIPort *port = &s->rhport[port1->index];
|
||||
|
||||
/* set connect status */
|
||||
port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
|
||||
|
||||
/* update speed */
|
||||
if (port->port.dev->speed == USB_SPEED_LOW) {
|
||||
port->ctrl |= OHCI_PORT_LSDA;
|
||||
} else {
|
||||
port->ctrl &= ~OHCI_PORT_LSDA;
|
||||
}
|
||||
|
||||
/* notify of remote-wakeup */
|
||||
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
|
||||
ohci_set_interrupt(s, OHCI_INTR_RD);
|
||||
}
|
||||
|
||||
DPRINTF("usb-ohci: Attached port %d\n", port1->index);
|
||||
}
|
||||
|
||||
static void ohci_detach(USBPort *port1)
|
||||
{
|
||||
OHCIState *s = port1->opaque;
|
||||
OHCIPort *port = &s->rhport[port1->index];
|
||||
uint32_t old_state = port->ctrl;
|
||||
|
||||
if (dev) {
|
||||
if (port->port.dev) {
|
||||
usb_attach(port1, NULL);
|
||||
}
|
||||
/* set connect status */
|
||||
port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
|
||||
|
||||
/* update speed */
|
||||
if (dev->speed == USB_SPEED_LOW)
|
||||
port->ctrl |= OHCI_PORT_LSDA;
|
||||
else
|
||||
port->ctrl &= ~OHCI_PORT_LSDA;
|
||||
port->port.dev = dev;
|
||||
|
||||
/* notify of remote-wakeup */
|
||||
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND)
|
||||
ohci_set_interrupt(s, OHCI_INTR_RD);
|
||||
|
||||
/* send the attach message */
|
||||
usb_send_msg(dev, USB_MSG_ATTACH);
|
||||
DPRINTF("usb-ohci: Attached port %d\n", port1->index);
|
||||
} else {
|
||||
/* set connect status */
|
||||
if (port->ctrl & OHCI_PORT_CCS) {
|
||||
port->ctrl &= ~OHCI_PORT_CCS;
|
||||
port->ctrl |= OHCI_PORT_CSC;
|
||||
}
|
||||
/* disable port */
|
||||
if (port->ctrl & OHCI_PORT_PES) {
|
||||
port->ctrl &= ~OHCI_PORT_PES;
|
||||
port->ctrl |= OHCI_PORT_PESC;
|
||||
}
|
||||
dev = port->port.dev;
|
||||
if (dev) {
|
||||
/* send the detach message */
|
||||
usb_send_msg(dev, USB_MSG_DETACH);
|
||||
}
|
||||
port->port.dev = NULL;
|
||||
DPRINTF("usb-ohci: Detached port %d\n", port1->index);
|
||||
/* set connect status */
|
||||
if (port->ctrl & OHCI_PORT_CCS) {
|
||||
port->ctrl &= ~OHCI_PORT_CCS;
|
||||
port->ctrl |= OHCI_PORT_CSC;
|
||||
}
|
||||
/* disable port */
|
||||
if (port->ctrl & OHCI_PORT_PES) {
|
||||
port->ctrl &= ~OHCI_PORT_PES;
|
||||
port->ctrl |= OHCI_PORT_PESC;
|
||||
}
|
||||
DPRINTF("usb-ohci: Detached port %d\n", port1->index);
|
||||
|
||||
if (old_state != port->ctrl)
|
||||
ohci_set_interrupt(s, OHCI_INTR_RHSC);
|
||||
|
@ -413,8 +407,9 @@ static void ohci_reset(void *opaque)
|
|||
{
|
||||
port = &ohci->rhport[i];
|
||||
port->ctrl = 0;
|
||||
if (port->port.dev)
|
||||
ohci_attach(&port->port, port->port.dev);
|
||||
if (port->port.dev) {
|
||||
usb_attach(&port->port, port->port.dev);
|
||||
}
|
||||
}
|
||||
if (ohci->async_td) {
|
||||
usb_cancel_packet(&ohci->usb_packet);
|
||||
|
@ -1671,6 +1666,7 @@ static CPUWriteMemoryFunc * const ohci_writefn[3]={
|
|||
|
||||
static USBPortOps ohci_port_ops = {
|
||||
.attach = ohci_attach,
|
||||
.detach = ohci_detach,
|
||||
};
|
||||
|
||||
static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue