From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1FaIyW-0000Ws-4k for qemu-devel@nongnu.org; Sun, 30 Apr 2006 16:57:04 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1FaIyU-0000Wb-Ax for qemu-devel@nongnu.org; Sun, 30 Apr 2006 16:57:03 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FaIyU-0000WY-52 for qemu-devel@nongnu.org; Sun, 30 Apr 2006 16:57:02 -0400 Received: from [24.93.47.44] (helo=ms-smtp-05.texas.rr.com) by monty-python.gnu.org with esmtp (Exim 4.52) id 1FaJ29-0000Bj-2K for qemu-devel@nongnu.org; Sun, 30 Apr 2006 17:00:49 -0400 Received: from [192.168.0.11] (cpe-67-9-160-120.austin.res.rr.com [67.9.160.120]) by ms-smtp-05.texas.rr.com (8.13.4/8.13.4) with ESMTP id k3UKuxvj011298 for ; Sun, 30 Apr 2006 15:57:00 -0500 (CDT) Message-ID: <44552494.3030908@austin.rr.com> Date: Sun, 30 Apr 2006 15:56:52 -0500 From: Lonnie Mendez MIME-Version: 1.0 Subject: Re: [Qemu-devel] Large USB patch References: <4447E811.1040403@gmx.de> <4448F1F6.4090609@austin.rr.com> <4448FF3F.3030009@austin.rr.com> <44490614.50406@austin.rr.com> <44490852.2080608@gmx.de> <44491659.30804@austin.rr.com> <44491F0A.2090608@austin.rr.com> <444926AC.3070104@austin.rr.com> <44494596.3070808@austin.rr.com> <4449F860.1060809@gmx.de> <444A3F7E.6070107@austin.rr.com> <444A5336.4040102@gmx.de> <444A578E.6000702@austin.rr.com> <444A5B65.8010104@gmx.de> <444AF6B7.1030606@austin.rr.com> <4452BB67.8080902@austin.rr.com> <4452DD84.8090707@austin.rr.com> <445408D5.3060101@austin.rr.com> In-Reply-To: <445408D5.3060101@austin.rr.com> Content-Type: multipart/mixed; boundary="------------030306080708040200020104" Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------030306080708040200020104 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Attached is another patch to implement the said resume code. With this patch, devices attached to windows xp guest are able to resume the controller when necessary. Before, if a device was attached to the usbhub and windows had the root hub set for power savings then the bus would stay suspended. It implements the function usb_wakeup_controller which can be called with a USBDevice handle for the device that is causing the event. --------------030306080708040200020104 Content-Type: text/plain; name="lusb-upd6.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="lusb-upd6.diff" --- a/qemu/hw/usb-uhci.c 2006-04-30 14:32:43.000000000 -0500 +++ b/qemu/hw/usb-uhci.c 2006-04-30 15:03:46.000000000 -0500 @@ -102,6 +102,7 @@ } UHCI_QH; static int uhci_attach (USBDevice *hub, USBDevice *dev, int portnum); +static void uhci_resume (void *opaque); static void uhci_update_irq (UHCIState *s) { @@ -338,13 +339,6 @@ UHCIPort *port; int i; - // wakeup the controller if suspended - if (s->cmd & UHCI_CMD_EGSM) { - s->cmd |= UHCI_CMD_FGR; - s->status |= UHCI_STS_RD; - uhci_update_irq(s); - } - if (dev) { if( portnum >= NB_PORTS ) { #ifdef DEBUG @@ -385,6 +379,9 @@ port->ctrl |= UHCI_PORT_LSDA; else port->ctrl &= ~UHCI_PORT_LSDA; + + uhci_resume(s); + /* send the attach message */ port->dev= dev; port->dev->handle_msg (port->dev, USB_MSG_ATTACH); @@ -401,6 +398,9 @@ port->ctrl &= ~UHCI_PORT_EN; port->ctrl |= UHCI_PORT_ENC; } + + uhci_resume(s); + if (port->dev) { /* send the detach message */ port->dev->handle_msg(port->dev, USB_MSG_DETACH); @@ -412,6 +412,21 @@ } } +/* signal resume if controller suspended */ +static void uhci_resume (void *opaque) +{ + UHCIState *s = (UHCIState *)opaque; + + if (!s) + return; + + if (s->cmd & UHCI_CMD_EGSM) { + s->cmd |= UHCI_CMD_FGR; + s->status |= UHCI_STS_RD; + uhci_update_irq(s); + } +} + static int uhci_broadcast_packet(UHCIState *s, uint8_t pid, uint8_t devaddr, uint8_t devep, uint8_t *data, int len) @@ -732,6 +738,7 @@ dev->speed= USB_SPEED_FULL; dev->state= USB_STATE_ATTACHED; dev->handle_attach= &uhci_attach; + dev->handle_resume= &uhci_resume; for(i = 0; i < NB_PORTS; i++) { s->ports[i].dev= NULL; } --- a/qemu/hw/usb.h 2006-04-30 14:32:43.000000000 -0500 +++ b/qemu/hw/usb.h 2006-04-30 15:14:23.000000000 -0500 @@ -187,6 +187,7 @@ int (*handle_data) (USBDevice *dev, int pid, uint8_t devep, uint8_t *data, int len); int (*handle_attach) (USBDevice *hub, USBDevice *dev, int portnum); + void (*handle_resume) (void *opaque); }; /* Maximum of simultaneous USB Devices including all USB Controllers */ @@ -212,6 +213,9 @@ USBDevice* usb_find_device (char *path); char* usb_find_name (USBDevice *device); +/* resumes a suspended controller that given device is attached to */ +void usb_wakeup_controller(USBDevice *dev); + /* function which adds or removes the usb devices according to usb_tree */ int usb_update_devices (PCIBus *pci_bus); /* functions which show info on the available usb devices - used by monitor.c*/ --- a/qemu/hw/usb.c 2006-04-30 14:32:43.000000000 -0500 +++ b/qemu/hw/usb.c 2006-04-30 15:14:35.000000000 -0500 @@ -401,6 +408,27 @@ } } +/* communicate resume to host controller */ +void usb_wakeup_controller(USBDevice *dev) +{ + USBTree *tree = usb_tree; + USBDevice *controller = NULL; + char bus_path[5]; + + if (dev == NULL) + return; + + for (; tree != NULL; tree= tree->next) { + if (tree->dev == dev) { // have match - next find root controller + strncpy(bus_path, tree->path, 3); + controller = usb_find_device(bus_path); + if (controller && controller->handle_resume) // send resume if implemented + controller->handle_resume(controller->opaque); + break; + } + } +} + /* remove a usb device, the following steps are taken: 1. find the device 2. let his father know @@ -608,6 +636,7 @@ dev->handle_msg= &usb_dummy_handle_msg; dev->handle_data= &usb_dummy_handle_data; dev->handle_attach= &usb_dummy_handle_attach; + dev->handle_resume= NULL; } return dev; } --- a/qemu/hw/usb-hub.c 2006-04-30 14:33:29.000000000 -0500 +++ b/qemu/hw/usb-hub.c 2006-04-30 15:13:22.000000000 -0500 @@ -212,12 +212,20 @@ port->wPortStatus |= PORT_STAT_LOW_SPEED; else port->wPortStatus &= ~PORT_STAT_LOW_SPEED; + + if (hub->remote_wakeup) + usb_wakeup_controller(dev); + port->dev = dev; port->dev->handle_msg (port->dev, USB_MSG_ATTACH); return portnum; } else { port = &s->ports[portnum]; dev = port->dev; + + if (hub->remote_wakeup) + usb_wakeup_controller(dev); + if (dev) { port->wPortStatus &= ~PORT_STAT_CONNECTION; port->wPortChange |= PORT_STAT_C_CONNECTION; --------------030306080708040200020104--