All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lonnie Mendez <lmendez19@austin.rr.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] Large USB patch
Date: Sun, 30 Apr 2006 15:56:52 -0500	[thread overview]
Message-ID: <44552494.3030908@austin.rr.com> (raw)
In-Reply-To: <445408D5.3060101@austin.rr.com>

[-- Attachment #1: Type: text/plain, Size: 447 bytes --]

   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.

[-- Attachment #2: lusb-upd6.diff --]
[-- Type: text/plain, Size: 4837 bytes --]

--- 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;

  reply	other threads:[~2006-04-30 20:57 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-20 19:59 [Qemu-devel] Large USB patch nix.wie.weg
2006-04-21  2:23 ` Lonnie Mendez
2006-04-21  5:59   ` nix.wie.weg
2006-04-21  7:04     ` Lonnie Mendez
2006-04-21 14:53 ` Lonnie Mendez
2006-04-21 15:00   ` Lonnie Mendez
2006-04-21 15:50   ` Lonnie Mendez
2006-04-21 16:19     ` Lonnie Mendez
2006-04-21 16:29       ` nix.wie.weg
2006-04-21 17:28         ` Lonnie Mendez
2006-04-21 18:06           ` Lonnie Mendez
2006-04-21 18:38             ` Lonnie Mendez
2006-04-21 20:50               ` Lonnie Mendez
2006-04-22  9:33                 ` nix.wie.weg
2006-04-22 14:36                   ` Lonnie Mendez
2006-04-22 15:36                     ` nix.wie.weg
2006-04-22 15:38                       ` nix.wie.weg
2006-04-22 16:00                     ` nix.wie.weg
2006-04-22 16:19                       ` Lonnie Mendez
2006-04-22 16:35                         ` nix.wie.weg
2006-04-23  3:38                           ` Lonnie Mendez
2006-04-23 21:54                             ` nix.wie.weg
2006-04-29  1:03                             ` Lonnie Mendez
2006-04-29  3:29                               ` Lonnie Mendez
2006-04-30  0:46                                 ` Lonnie Mendez
2006-04-30 20:56                                   ` Lonnie Mendez [this message]
2006-04-21 16:26     ` nix.wie.weg
2006-04-22 14:15 ` nix.wie.weg
2006-04-23 15:02 ` Fabrice Bellard
2006-04-23 16:11   ` nix.wie.weg
2006-04-24 23:50 ` [Qemu-devel] Update for cvs 2006-04-24 nix.wie.weg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44552494.3030908@austin.rr.com \
    --to=lmendez19@austin.rr.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.