From d28f4e2d86317f7ef7398651e8a1d493e4bf8c88 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 6 Jan 2012 15:23:10 +0100 Subject: usb: kill USB_MSG_RESET The USB subsystem pipes internal reset notifications through usb_handle_packet() with a special magic PID. This indirection is a pretty pointless excercise as it ends up being handled by usb_generic_handle_packet anyway. Replace the USB_MSG_RESET with a usb_device_reset() function which can be called directly. Also rename the existing usb_reset() function to usb_port_reset() to avoid confusion. Signed-off-by: Gerd Hoffmann --- hw/usb-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/usb-hub.c') diff --git a/hw/usb-hub.c b/hw/usb-hub.c index 956b020eed..0f3b2dda0e 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -305,7 +305,7 @@ static int usb_hub_handle_control(USBDevice *dev, USBPacket *p, break; case PORT_RESET: if (dev && dev->attached) { - usb_send_msg(dev, USB_MSG_RESET); + usb_device_reset(dev); port->wPortChange |= PORT_STAT_C_RESET; /* set enable bit */ port->wPortStatus |= PORT_STAT_ENABLE; -- cgit v1.2.3 From 06c750888c57bdc374feaa097f6cbc720210b834 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 10 Jan 2012 17:08:13 +0100 Subject: usb-hub: implement find_device Implement the find_device callback for the usb hub. It'll loop over all ports, calling usb_find_device for all enabled ports until it finds a matching device. Signed-off-by: Gerd Hoffmann --- hw/usb-hub.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'hw/usb-hub.c') diff --git a/hw/usb-hub.c b/hw/usb-hub.c index 0f3b2dda0e..bd7641c4bf 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -220,6 +220,26 @@ static void usb_hub_complete(USBPort *port, USBPacket *packet) s->dev.port->ops->complete(s->dev.port, packet); } +static USBDevice *usb_hub_find_device(USBDevice *dev, uint8_t addr) +{ + USBHubState *s = DO_UPCAST(USBHubState, dev, dev); + USBHubPort *port; + USBDevice *downstream; + int i; + + for (i = 0; i < NUM_PORTS; i++) { + port = &s->ports[i]; + if (!(port->wPortStatus & PORT_STAT_ENABLE)) { + continue; + } + downstream = usb_find_device(&port->port, addr); + if (downstream != NULL) { + return downstream; + } + } + return NULL; +} + static void usb_hub_handle_reset(USBDevice *dev) { USBHubState *s = DO_UPCAST(USBHubState, dev, dev); @@ -541,6 +561,7 @@ static void usb_hub_class_initfn(ObjectClass *klass, void *data) uc->init = usb_hub_initfn; uc->product_desc = "QEMU USB Hub"; uc->usb_desc = &desc_hub; + uc->find_device = usb_hub_find_device; uc->handle_packet = usb_hub_handle_packet; uc->handle_reset = usb_hub_handle_reset; uc->handle_control = usb_hub_handle_control; -- cgit v1.2.3 From 7f74a56b1416a759c1da0a280e99242662f350c5 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 11 Jan 2012 11:16:20 +0100 Subject: usb: kill handle_packet callback All drivers except usb-hub use usb_generic_handle_packet. The only reason the usb hub has its own function is that it used to be called with packets which are intended for downstream devices. With the new, separate device lookup step this doesn't happen any more, so the need for a different handle_packet callback is gone. So we can kill the handle_packet callback and just call usb_generic_handle_packet directly. The special hub handling in usb_handle_packet() can go away for the same reason. Signed-off-by: Gerd Hoffmann --- hw/usb-hub.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) (limited to 'hw/usb-hub.c') diff --git a/hw/usb-hub.c b/hw/usb-hub.c index bd7641c4bf..22562565c7 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -455,44 +455,6 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p) return ret; } -static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p) -{ - USBHubPort *port; - USBDevice *dev; - int i, ret; - - for(i = 0; i < NUM_PORTS; i++) { - port = &s->ports[i]; - dev = port->port.dev; - if (dev && dev->attached && (port->wPortStatus & PORT_STAT_ENABLE)) { - ret = usb_handle_packet(dev, p); - if (ret != USB_RET_NODEV) { - return ret; - } - } - } - return USB_RET_NODEV; -} - -static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p) -{ - USBHubState *s = (USBHubState *)dev; - -#if defined(DEBUG) && 0 - printf("usb_hub: pid=0x%x\n", pid); -#endif - if (dev->state == USB_STATE_DEFAULT && - dev->addr != 0 && - p->devaddr != dev->addr && - (p->pid == USB_TOKEN_SETUP || - p->pid == USB_TOKEN_OUT || - p->pid == USB_TOKEN_IN)) { - /* broadcast the packet to the devices */ - return usb_hub_broadcast_packet(s, p); - } - return usb_generic_handle_packet(dev, p); -} - static void usb_hub_handle_destroy(USBDevice *dev) { USBHubState *s = (USBHubState *)dev; @@ -562,7 +524,6 @@ static void usb_hub_class_initfn(ObjectClass *klass, void *data) uc->product_desc = "QEMU USB Hub"; uc->usb_desc = &desc_hub; uc->find_device = usb_hub_find_device; - uc->handle_packet = usb_hub_handle_packet; uc->handle_reset = usb_hub_handle_reset; uc->handle_control = usb_hub_handle_control; uc->handle_data = usb_hub_handle_data; -- cgit v1.2.3 From 079d0b7f1eedcc634c371fe05b617fdc55c8b762 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 12 Jan 2012 13:23:01 +0100 Subject: usb: Set USBEndpoint in usb_packet_setup(). With the separation of the device lookup (via usb_find_device) and packet processing we can lookup device and endpoint before setting up the usb packet. So we can initialize USBPacket->ep early and keep it valid for the whole lifecycle of the USBPacket. Also the devaddr and devep fields are not needed any more. Signed-off-by: Gerd Hoffmann --- hw/usb-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/usb-hub.c') diff --git a/hw/usb-hub.c b/hw/usb-hub.c index 22562565c7..940e211d13 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -416,7 +416,7 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p) switch(p->pid) { case USB_TOKEN_IN: - if (p->devep == 1) { + if (p->ep->nr == 1) { USBHubPort *port; unsigned int status; uint8_t buf[4]; -- cgit v1.2.3 From 7567b51fbe92e1300a672eaddd413c4a7e807d90 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 17 Jan 2012 13:25:46 +0100 Subject: usb: pass USBEndpoint to usb_wakeup Devices must specify which endpoint has data to transfer now. The plan is to use the usb_wakeup() not only for remove wakeup support, but for "data ready" signaling in general, so we can move away from constant polling to event driven usb device emulation. Signed-off-by: Gerd Hoffmann --- hw/usb-hub.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'hw/usb-hub.c') diff --git a/hw/usb-hub.c b/hw/usb-hub.c index 940e211d13..6d1ce065d9 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -37,6 +37,7 @@ typedef struct USBHubPort { typedef struct USBHubState { USBDevice dev; + USBEndpoint *intr; USBHubPort ports[NUM_PORTS]; } USBHubState; @@ -163,7 +164,7 @@ static void usb_hub_attach(USBPort *port1) } else { port->wPortStatus &= ~PORT_STAT_LOW_SPEED; } - usb_wakeup(&s->dev); + usb_wakeup(s->intr); } static void usb_hub_detach(USBPort *port1) @@ -171,7 +172,7 @@ static void usb_hub_detach(USBPort *port1) USBHubState *s = port1->opaque; USBHubPort *port = &s->ports[port1->index]; - usb_wakeup(&s->dev); + usb_wakeup(s->intr); /* Let upstream know the device on this port is gone */ s->dev.port->ops->child_detach(s->dev.port, port1->dev); @@ -199,7 +200,7 @@ static void usb_hub_wakeup(USBPort *port1) if (port->wPortStatus & PORT_STAT_SUSPEND) { port->wPortChange |= PORT_STAT_C_SUSPEND; - usb_wakeup(&s->dev); + usb_wakeup(s->intr); } } @@ -481,6 +482,7 @@ static int usb_hub_initfn(USBDevice *dev) int i; usb_desc_init(dev); + s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); for (i = 0; i < NUM_PORTS; i++) { port = &s->ports[i]; usb_register_port(usb_bus_from_device(dev), -- cgit v1.2.3