--- qemu/hw/usb.c 2018/04/24 16:53:35 1.1.1.5 +++ qemu/hw/usb.c 2018/04/24 18:39:17 1.1.1.7 @@ -28,7 +28,32 @@ void usb_attach(USBPort *port, USBDevice *dev) { - port->attach(port, dev); + if (dev != NULL) { + /* attach */ + if (port->dev) { + usb_attach(port, NULL); + } + dev->port = port; + port->dev = dev; + port->ops->attach(port); + usb_send_msg(dev, USB_MSG_ATTACH); + } else { + /* detach */ + dev = port->dev; + port->ops->detach(port); + if (dev) { + usb_send_msg(dev, USB_MSG_DETACH); + dev->port = NULL; + port->dev = NULL; + } + } +} + +void usb_wakeup(USBDevice *dev) +{ + if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) { + dev->port->ops->wakeup(dev); + } } /**********************/ @@ -59,8 +84,8 @@ static int do_token_setup(USBDevice *s, index = (s->setup_buf[5] << 8) | s->setup_buf[4]; if (s->setup_buf[0] & USB_DIR_IN) { - ret = s->handle_control(s, request, value, index, - s->setup_len, s->data_buf); + ret = s->info->handle_control(s, request, value, index, + s->setup_len, s->data_buf); if (ret < 0) return ret; @@ -83,7 +108,7 @@ static int do_token_in(USBDevice *s, USB int ret = 0; if (p->devep != 0) - return s->handle_data(s, p); + return s->info->handle_data(s, p); request = (s->setup_buf[0] << 8) | s->setup_buf[1]; value = (s->setup_buf[3] << 8) | s->setup_buf[2]; @@ -93,8 +118,8 @@ static int do_token_in(USBDevice *s, USB case SETUP_STATE_ACK: if (!(s->setup_buf[0] & USB_DIR_IN)) { s->setup_state = SETUP_STATE_IDLE; - ret = s->handle_control(s, request, value, index, - s->setup_len, s->data_buf); + ret = s->info->handle_control(s, request, value, index, + s->setup_len, s->data_buf); if (ret > 0) return 0; return ret; @@ -126,7 +151,7 @@ static int do_token_in(USBDevice *s, USB static int do_token_out(USBDevice *s, USBPacket *p) { if (p->devep != 0) - return s->handle_data(s, p); + return s->info->handle_data(s, p); switch(s->setup_state) { case SETUP_STATE_ACK: @@ -169,6 +194,9 @@ int usb_generic_handle_packet(USBDevice switch(p->pid) { case USB_MSG_ATTACH: s->state = USB_STATE_ATTACHED; + if (s->info->handle_attach) { + s->info->handle_attach(s); + } return 0; case USB_MSG_DETACH: @@ -179,7 +207,9 @@ int usb_generic_handle_packet(USBDevice s->remote_wakeup = 0; s->addr = 0; s->state = USB_STATE_DEFAULT; - s->handle_reset(s); + if (s->info->handle_reset) { + s->info->handle_reset(s); + } return 0; } @@ -225,7 +255,7 @@ void usb_send_msg(USBDevice *dev, int ms USBPacket p; memset(&p, 0, sizeof(p)); p.pid = msg; - dev->handle_packet(dev, &p); + dev->info->handle_packet(dev, &p); /* This _must_ be synchronous */ }