qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] PATCH: QEMU support for UHCI suspend / remote wake up
@ 2010-11-25 15:34 Marcelo Tosatti
  2010-11-25 16:15 ` [Qemu-devel] " Gerd Hoffmann
  0 siblings, 1 reply; 21+ messages in thread
From: Marcelo Tosatti @ 2010-11-25 15:34 UTC (permalink / raw)
  To: qemu-devel, kvm; +Cc: Matthew Garrett, Adam Jackson, Glauber de Oliveira Costa


This patch enables USB UHCI global suspend/resume feature. The OS will
stop the HC once all ports are suspended. If there is activity on the
port(s), an interrupt signalling remote wakeup will be triggered.

To enable autosuspend for the USB tablet on Linux guests:

echo auto > /sys/devices/pci0000:00/0000:00:01.2/usb1/1-1/power/level

It reduces CPU consumption of an idle FC12 guest from 2.7% to 0.3%.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 882d933..b7a4dc1 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -412,6 +412,9 @@ static void usb_hid_changed(USBHIDState *hs)
 
     if (hs->datain)
         hs->datain(hs->datain_opaque);
+
+    if (hs->dev.remote_wakeup)
+        usb_remote_wakeup(&hs->dev);
 }
 
 static void usb_mouse_event(void *opaque,
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 1d83400..674cb0c 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -59,6 +59,7 @@
 
 #define UHCI_PORT_RESET (1 << 9)
 #define UHCI_PORT_LSDA  (1 << 8)
+#define UHCI_PORT_RD    (1 << 6)
 #define UHCI_PORT_ENC   (1 << 3)
 #define UHCI_PORT_EN    (1 << 2)
 #define UHCI_PORT_CSC   (1 << 1)
@@ -501,6 +502,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
             port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
             /* some bits are reset when a '1' is written to them */
             port->ctrl &= ~(val & 0x000a);
+            port->ctrl &= ~(port->ctrl & 0x0040); /* clear port resume detected */
         }
         break;
     }
@@ -593,6 +595,43 @@ static void uhci_resume (void *opaque)
     }
 }
 
+static UHCIPort *find_port(UHCIState *s, USBDevice *d)
+{
+    int i;
+
+    for (i = 0; i < NB_PORTS; i++) {
+        UHCIPort *port = &s->ports[i];
+
+        if (d == port->port.dev) {
+            return port;
+        }
+    }
+
+    return NULL;
+}
+
+static void uhci_event(USBDevice *dev)
+{
+    USBBus *bus = usb_bus_from_device(dev);
+    UHCIState *s = container_of(bus, UHCIState, bus);
+
+    if (s->cmd & UHCI_CMD_EGSM) {
+        UHCIPort *port = find_port(s, dev);
+
+        if (!port) {
+            return;
+        }
+
+        if (port->ctrl & UHCI_PORT_RD) {
+            return;
+        }
+
+        port->ctrl |= UHCI_PORT_RD;
+
+        uhci_resume(s);
+    }
+}
+
 static void uhci_attach(USBPort *port1, USBDevice *dev)
 {
     UHCIState *s = port1->opaque;
@@ -602,6 +641,7 @@ static void uhci_attach(USBPort *port1, USBDevice *dev)
         if (port->port.dev) {
             usb_attach(port1, NULL);
         }
+        dev->info->remote_wakeup_cb = uhci_event;
         /* set connect status */
         port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
 
diff --git a/hw/usb.c b/hw/usb.c
index a326bcf..9b24d49 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -229,3 +229,9 @@ void usb_send_msg(USBDevice *dev, int msg)
 
     /* This _must_ be synchronous */
 }
+
+void usb_remote_wakeup(USBDevice *dev)
+{
+    if (dev->info->remote_wakeup_cb)
+        dev->info->remote_wakeup_cb(dev);
+}
diff --git a/hw/usb.h b/hw/usb.h
index 00d2802..16de1c9 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -189,6 +189,11 @@ struct USBDeviceInfo {
      */
     int (*handle_data)(USBDevice *dev, USBPacket *p);
 
+    /*
+     * Process remote wakeup request.
+     */
+    void (*remote_wakeup_cb)(USBDevice *dev);
+
     const char *product_desc;
 
     /* handle legacy -usbdevice command line options */
@@ -317,6 +322,7 @@ void usb_unregister_port(USBBus *bus, USBPort *port);
 int usb_device_attach(USBDevice *dev);
 int usb_device_detach(USBDevice *dev);
 int usb_device_delete_addr(int busnr, int addr);
+void usb_remote_wakeup(USBDevice *dev);
 
 static inline USBBus *usb_bus_from_device(USBDevice *d)
 {

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: PATCH: QEMU support for UHCI suspend / remote wake up
  2010-11-25 15:34 [Qemu-devel] PATCH: QEMU support for UHCI suspend / remote wake up Marcelo Tosatti
@ 2010-11-25 16:15 ` Gerd Hoffmann
  2010-11-25 17:04   ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Marcelo Tosatti
  0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2010-11-25 16:15 UTC (permalink / raw)
  To: Marcelo Tosatti
  Cc: Matthew Garrett, Adam Jackson, qemu-devel, kvm,
	Glauber de Oliveira Costa

   Hi,

> +        dev->info->remote_wakeup_cb = uhci_event;

> diff --git a/hw/usb.h b/hw/usb.h
> index 00d2802..16de1c9 100644
> --- a/hw/usb.h
> +++ b/hw/usb.h
> @@ -189,6 +189,11 @@ struct USBDeviceInfo {
>        */
>       int (*handle_data)(USBDevice *dev, USBPacket *p);
>
> +    /*
> +     * Process remote wakeup request.
> +     */
> +    void (*remote_wakeup_cb)(USBDevice *dev);
> +

No way.  DeviceInfo holds informations about the device 
*implementation*.  Multiple instances will share that, placing runtime 
data there is just plain wrong.

Also this is a callback from the usb device to the usb host adapter, not 
the other way around.  I'd suggest to create a USBBusOps for host 
adapter callbacks and and stick it into USBBus.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup
  2010-11-25 16:15 ` [Qemu-devel] " Gerd Hoffmann
@ 2010-11-25 17:04   ` Marcelo Tosatti
  2010-11-25 17:04     ` [Qemu-devel] [patch 1/2] add USBBusOps to USBBus Marcelo Tosatti
                       ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: Marcelo Tosatti @ 2010-11-25 17:04 UTC (permalink / raw)
  To: qemu-devel, kvm
  Cc: Matthew Garrett, Adam Jackson, Gerd Hoffmann,
	Glauber de Oliveira Costa

See patch 2 for details.

v2: 
- Add remote wakeup callback in USBBus, as suggested by Gerd.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [patch 1/2] add USBBusOps to USBBus
  2010-11-25 17:04   ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Marcelo Tosatti
@ 2010-11-25 17:04     ` Marcelo Tosatti
  2010-11-25 17:04     ` [Qemu-devel] [patch 2/2] support for UHCI suspend / remote wake up Marcelo Tosatti
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: Marcelo Tosatti @ 2010-11-25 17:04 UTC (permalink / raw)
  To: qemu-devel, kvm
  Cc: Matthew Garrett, Marcelo Tosatti, Adam Jackson, Gerd Hoffmann,
	Glauber de Oliveira Costa

[-- Attachment #1: usb-bus-ops --]
[-- Type: text/plain, Size: 4017 bytes --]

Needed for remote wakeup notification.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

Index: qemu-kvm/hw/usb-bus.c
===================================================================
--- qemu-kvm.orig/hw/usb-bus.c
+++ qemu-kvm/hw/usb-bus.c
@@ -14,11 +14,12 @@ static struct BusInfo usb_bus_info = {
 static int next_usb_bus = 0;
 static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
 
-void usb_bus_new(USBBus *bus, DeviceState *host)
+void usb_bus_new(USBBus *bus, DeviceState *host, USBBusOps *ops)
 {
     qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL);
     bus->busnr = next_usb_bus++;
     bus->qbus.allow_hotplug = 1; /* Yes, we can */
+    bus->ops = ops;
     QTAILQ_INIT(&bus->free);
     QTAILQ_INIT(&bus->used);
     QTAILQ_INSERT_TAIL(&busses, bus, next);
Index: qemu-kvm/hw/usb.c
===================================================================
--- qemu-kvm.orig/hw/usb.c
+++ qemu-kvm/hw/usb.c
@@ -229,3 +229,12 @@ void usb_send_msg(USBDevice *dev, int ms
 
     /* This _must_ be synchronous */
 }
+
+void usb_remote_wakeup(USBDevice *dev)
+{
+    USBBus *bus = usb_bus_from_device(dev);
+
+    if (bus->ops && bus->ops->remote_wakeup_cb) {
+        bus->ops->remote_wakeup_cb(bus, dev);
+    }
+}
Index: qemu-kvm/hw/usb.h
===================================================================
--- qemu-kvm.orig/hw/usb.h
+++ qemu-kvm/hw/usb.h
@@ -123,6 +123,7 @@
 #define USB_ENDPOINT_XFER_INT		3
 
 typedef struct USBBus USBBus;
+typedef struct USBBusOps USBBusOps;
 typedef struct USBPort USBPort;
 typedef struct USBDevice USBDevice;
 typedef struct USBDeviceInfo USBDeviceInfo;
@@ -294,8 +295,16 @@ void musb_set_size(MUSBState *s, int epn
 
 /* usb-bus.c */
 
+struct USBBusOps {
+    /*
+     * Process remote wakeup request.
+     */
+    void (*remote_wakeup_cb)(USBBus *bus, USBDevice *dev);
+};
+
 struct USBBus {
     BusState qbus;
+    USBBusOps *ops;
     int busnr;
     int nfree;
     int nused;
@@ -304,7 +313,7 @@ struct USBBus {
     QTAILQ_ENTRY(USBBus) next;
 };
 
-void usb_bus_new(USBBus *bus, DeviceState *host);
+void usb_bus_new(USBBus *bus, DeviceState *host, USBBusOps *ops);
 USBBus *usb_bus_find(int busnr);
 void usb_qdev_register(USBDeviceInfo *info);
 void usb_qdev_register_many(USBDeviceInfo *info);
@@ -317,6 +326,7 @@ void usb_unregister_port(USBBus *bus, US
 int usb_device_attach(USBDevice *dev);
 int usb_device_detach(USBDevice *dev);
 int usb_device_delete_addr(int busnr, int addr);
+void usb_remote_wakeup(USBDevice *dev);
 
 static inline USBBus *usb_bus_from_device(USBDevice *d)
 {
Index: qemu-kvm/hw/usb-musb.c
===================================================================
--- qemu-kvm.orig/hw/usb-musb.c
+++ qemu-kvm/hw/usb-musb.c
@@ -342,7 +342,7 @@ struct MUSBState {
         s->ep[i].epnum = i;
     }
 
-    usb_bus_new(&s->bus, NULL /* FIXME */);
+    usb_bus_new(&s->bus, NULL /* FIXME */, NULL);
     usb_register_port(&s->bus, &s->port, s, 0, musb_attach);
 
     return s;
Index: qemu-kvm/hw/usb-ohci.c
===================================================================
--- qemu-kvm.orig/hw/usb-ohci.c
+++ qemu-kvm/hw/usb-ohci.c
@@ -1702,7 +1702,7 @@ static void usb_ohci_init(OHCIState *ohc
 
     ohci->name = dev->info->name;
 
-    usb_bus_new(&ohci->bus, dev);
+    usb_bus_new(&ohci->bus, dev, NULL);
     ohci->num_ports = num_ports;
     for (i = 0; i < num_ports; i++) {
         usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, ohci_attach);
Index: qemu-kvm/hw/usb-uhci.c
===================================================================
--- qemu-kvm.orig/hw/usb-uhci.c
+++ qemu-kvm/hw/usb-uhci.c
@@ -1113,7 +1113,7 @@ static int usb_uhci_common_initfn(UHCISt
     pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3
     pci_conf[0x60] = 0x10; // release number
 
-    usb_bus_new(&s->bus, &s->dev.qdev);
+    usb_bus_new(&s->bus, &s->dev.qdev, NULL);
     for(i = 0; i < NB_PORTS; i++) {
         usb_register_port(&s->bus, &s->ports[i].port, s, i, uhci_attach);
     }

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [patch 2/2] support for UHCI suspend / remote wake up
  2010-11-25 17:04   ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Marcelo Tosatti
  2010-11-25 17:04     ` [Qemu-devel] [patch 1/2] add USBBusOps to USBBus Marcelo Tosatti
@ 2010-11-25 17:04     ` Marcelo Tosatti
  2010-12-01 15:12       ` [Qemu-devel] " Gerd Hoffmann
  2010-11-26  0:38     ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Paul Brook
  2010-12-01 16:47     ` [Qemu-devel] [patch 0/3] QEMU support for UHCI suspend / remote wake up (v3) Marcelo Tosatti
  3 siblings, 1 reply; 21+ messages in thread
From: Marcelo Tosatti @ 2010-11-25 17:04 UTC (permalink / raw)
  To: qemu-devel, kvm
  Cc: Matthew Garrett, Marcelo Tosatti, Adam Jackson, Gerd Hoffmann,
	Glauber de Oliveira Costa

[-- Attachment #1: usb-uhci-suspend --]
[-- Type: text/plain, Size: 3116 bytes --]

This patch enables USB UHCI global suspend/resume feature. The OS will
stop the HC once all ports are suspended. If there is activity on the
port(s), an interrupt signalling remote wakeup will be triggered.

To enable autosuspend for the USB tablet on Linux guests:

echo auto > /sys/devices/pci0000:00/0000:00:01.2/usb1/1-1/power/level

It reduces CPU consumption of an idle FC12 guest from 2.7% to 0.3%.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

Index: qemu-kvm/hw/usb-hid.c
===================================================================
--- qemu-kvm.orig/hw/usb-hid.c
+++ qemu-kvm/hw/usb-hid.c
@@ -412,6 +412,9 @@ static void usb_hid_changed(USBHIDState 
 
     if (hs->datain)
         hs->datain(hs->datain_opaque);
+
+    if (hs->dev.remote_wakeup)
+        usb_remote_wakeup(&hs->dev);
 }
 
 static void usb_mouse_event(void *opaque,
Index: qemu-kvm/hw/usb-uhci.c
===================================================================
--- qemu-kvm.orig/hw/usb-uhci.c
+++ qemu-kvm/hw/usb-uhci.c
@@ -59,6 +59,7 @@
 
 #define UHCI_PORT_RESET (1 << 9)
 #define UHCI_PORT_LSDA  (1 << 8)
+#define UHCI_PORT_RD    (1 << 6)
 #define UHCI_PORT_ENC   (1 << 3)
 #define UHCI_PORT_EN    (1 << 2)
 #define UHCI_PORT_CSC   (1 << 1)
@@ -501,6 +502,7 @@ static void uhci_ioport_writew(void *opa
             port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
             /* some bits are reset when a '1' is written to them */
             port->ctrl &= ~(val & 0x000a);
+            port->ctrl &= ~(port->ctrl & 0x0040); /* clear port resume detected */
         }
         break;
     }
@@ -593,6 +595,41 @@ static void uhci_resume (void *opaque)
     }
 }
 
+static UHCIPort *find_port(UHCIState *s, USBDevice *d)
+{
+    int i;
+
+    for (i = 0; i < NB_PORTS; i++) {
+        UHCIPort *port = &s->ports[i];
+
+        if (d == port->port.dev) {
+            return port;
+        }
+    }
+
+    return NULL;
+}
+
+static void uhci_event(USBBus *bus, USBDevice *dev)
+{
+    UHCIState *s = container_of(bus, UHCIState, bus);
+
+    if (s->cmd & UHCI_CMD_EGSM) {
+        UHCIPort *port = find_port(s, dev);
+
+        if (!port) {
+            return;
+        }
+
+        if (port->ctrl & UHCI_PORT_RD) {
+            return;
+        }
+
+        port->ctrl |= UHCI_PORT_RD;
+        uhci_resume(s);
+    }
+}
+
 static void uhci_attach(USBPort *port1, USBDevice *dev)
 {
     UHCIState *s = port1->opaque;
@@ -1101,6 +1138,10 @@ static void uhci_map(PCIDevice *pci_dev,
     register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
 }
 
+static USBBusOps uhci_bus_ops = {
+    .remote_wakeup_cb = uhci_event,
+};
+
 static int usb_uhci_common_initfn(UHCIState *s)
 {
     uint8_t *pci_conf = s->dev.config;
@@ -1113,7 +1154,7 @@ static int usb_uhci_common_initfn(UHCISt
     pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3
     pci_conf[0x60] = 0x10; // release number
 
-    usb_bus_new(&s->bus, &s->dev.qdev, NULL);
+    usb_bus_new(&s->bus, &s->dev.qdev, &uhci_bus_ops);
     for(i = 0; i < NB_PORTS; i++) {
         usb_register_port(&s->bus, &s->ports[i].port, s, i, uhci_attach);
     }

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup
  2010-11-25 17:04   ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Marcelo Tosatti
  2010-11-25 17:04     ` [Qemu-devel] [patch 1/2] add USBBusOps to USBBus Marcelo Tosatti
  2010-11-25 17:04     ` [Qemu-devel] [patch 2/2] support for UHCI suspend / remote wake up Marcelo Tosatti
@ 2010-11-26  0:38     ` Paul Brook
  2010-11-26  2:15       ` Marcelo Tosatti
  2010-12-01 16:47     ` [Qemu-devel] [patch 0/3] QEMU support for UHCI suspend / remote wake up (v3) Marcelo Tosatti
  3 siblings, 1 reply; 21+ messages in thread
From: Paul Brook @ 2010-11-26  0:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Matthew Garrett, kvm, Marcelo Tosatti, Glauber de Oliveira Costa,
	Adam Jackson, Gerd Hoffmann

> This patch enables USB UHCI global suspend/resume feature. The OS will
> stop the HC once all ports are suspended. If there is activity on the
> port(s), an interrupt signalling remote wakeup will be triggered.

I'm pretty sure this is wrong.  Suspend/resume works based on physical 
topology, i.e. the resume notification should go to the the port/hub to which 
the device is connected, not directly to the host controller.

Paul

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup
  2010-11-26  0:38     ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Paul Brook
@ 2010-11-26  2:15       ` Marcelo Tosatti
  2010-11-26  8:49         ` Gerd Hoffmann
  0 siblings, 1 reply; 21+ messages in thread
From: Marcelo Tosatti @ 2010-11-26  2:15 UTC (permalink / raw)
  To: Paul Brook
  Cc: Matthew Garrett, kvm, qemu-devel, Glauber de Oliveira Costa,
	Adam Jackson, Gerd Hoffmann

On Fri, Nov 26, 2010 at 12:38:28AM +0000, Paul Brook wrote:
> > This patch enables USB UHCI global suspend/resume feature. The OS will
> > stop the HC once all ports are suspended. If there is activity on the
> > port(s), an interrupt signalling remote wakeup will be triggered.
> 
> I'm pretty sure this is wrong.  Suspend/resume works based on physical 
> topology, i.e. the resume notification should go to the the port/hub to which 
> the device is connected, not directly to the host controller.

If the host controller is in global suspend state, and resume is
received on any of its root hub ports (given that remote wakeup is
enabled for the given port), the system will be interrupted if interrupt
enable bit is set.

2.1.2 USB STATUS REGISTER
I/O Address: Base + (02-03h)
Default Value: 0000h
Attribute: Read/Write Clear
size: 16 bits
This register indicates pending interrupts and various states of the
Host Controller

Resume Detect. The Host Controller sets this bit to 1 when it receives
a “RESUME” signal from a USB device. This is only valid if the Host
Controller is in a global suspend state (bit 3 of Command register = 1).

2.1.7.1 Behavior Under Global or Selective Suspend Scenarios

Resume will be recognized in the USBSTS register (bit 2) if resume is
received on a suspended or enabled port when the Host Controller is in
the global suspend state (USBCMD register bit 3 is set).

4.2.1 RESUME RECEIVED
This event indicates that the HC received a RESUME signal from a device
on the USB during a global suspend. If
this interrupt is enabled in the HC Interrupt Enable register, a
hardware interrupt will be signaled to the system
allowing the USB to be brought out of the suspend state and returned to
normal operation.

You are correct in that USB HUB emulation does not propagate resume, but
this does not make this patch incorrect.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup
  2010-11-26  2:15       ` Marcelo Tosatti
@ 2010-11-26  8:49         ` Gerd Hoffmann
  2010-11-26 12:09           ` Paul Brook
  0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2010-11-26  8:49 UTC (permalink / raw)
  To: Marcelo Tosatti
  Cc: Matthew Garrett, kvm, qemu-devel, Glauber de Oliveira Costa,
	Adam Jackson, Paul Brook

On 11/26/10 03:15, Marcelo Tosatti wrote:
> On Fri, Nov 26, 2010 at 12:38:28AM +0000, Paul Brook wrote:
>>> This patch enables USB UHCI global suspend/resume feature. The OS will
>>> stop the HC once all ports are suspended. If there is activity on the
>>> port(s), an interrupt signalling remote wakeup will be triggered.
>>
>> I'm pretty sure this is wrong.  Suspend/resume works based on physical
>> topology, i.e. the resume notification should go to the the port/hub to which
>> the device is connected, not directly to the host controller.

> You are correct in that USB HUB emulation does not propagate resume, but
> this does not make this patch incorrect.

Well, it does.  When the notification is port based our software model 
should better reflect that, so we have the chance to add resume 
propagation to the hub emulation later on.

I guess the Ops should be moved from the USBBus to the USBPort to 
reflect that.  This way the hub emulation and the uhci root hub can have 
different callbacks, which is needed to get this correct.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup
  2010-11-26  8:49         ` Gerd Hoffmann
@ 2010-11-26 12:09           ` Paul Brook
  0 siblings, 0 replies; 21+ messages in thread
From: Paul Brook @ 2010-11-26 12:09 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Matthew Garrett, kvm, Marcelo Tosatti, qemu-devel,
	Glauber de Oliveira Costa, Adam Jackson

> On 11/26/10 03:15, Marcelo Tosatti wrote:
> > On Fri, Nov 26, 2010 at 12:38:28AM +0000, Paul Brook wrote:
> >>> This patch enables USB UHCI global suspend/resume feature. The OS will
> >>> stop the HC once all ports are suspended. If there is activity on the
> >>> port(s), an interrupt signalling remote wakeup will be triggered.
> >> 
> >> I'm pretty sure this is wrong.  Suspend/resume works based on physical
> >> topology, i.e. the resume notification should go to the the port/hub to
> >> which the device is connected, not directly to the host controller.
> > 
> > You are correct in that USB HUB emulation does not propagate resume, but
> > this does not make this patch incorrect.
> 
> Well, it does.  When the notification is port based our software model
> should better reflect that, so we have the chance to add resume
> propagation to the hub emulation later on.

Exactly. The patch assumes the device is connected to a root hub port. This 
assumption is incorrect.

The device should be sending the resume signal to the port/hub to which it is 
connected. If that hub is still active it will reactivate the port, and flag a 
port change notification in the normal manner. If the hub is also suspended it 
will propagate the resume notification upstream (which may or may not be the 
root hub).

Paul

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: [patch 2/2] support for UHCI suspend / remote wake up
  2010-11-25 17:04     ` [Qemu-devel] [patch 2/2] support for UHCI suspend / remote wake up Marcelo Tosatti
@ 2010-12-01 15:12       ` Gerd Hoffmann
  2010-12-01 16:58         ` Marcelo Tosatti
  0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2010-12-01 15:12 UTC (permalink / raw)
  To: Marcelo Tosatti
  Cc: Matthew Garrett, Adam Jackson, qemu-devel, kvm,
	Glauber de Oliveira Costa

On 11/25/10 18:04, Marcelo Tosatti wrote:
> This patch enables USB UHCI global suspend/resume feature. The OS will
> stop the HC once all ports are suspended. If there is activity on the
> port(s), an interrupt signalling remote wakeup will be triggered.
>
> To enable autosuspend for the USB tablet on Linux guests:
>
> echo auto>  /sys/devices/pci0000:00/0000:00:01.2/usb1/1-1/power/level

Hmm, did you ever got this working sanely?

/me sees bus disconnects in the guest ...

>               port->ctrl&= ~(val&  0x000a);
> +            port->ctrl&= ~(port->ctrl&  0x0040); /* clear port resume detected */
>           }

This chunk looks suspicious ...

I suspect the port suspend/resume emulation isn't complete.

/me goes debugging,
   Gerd

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [patch 0/3] QEMU support for UHCI suspend / remote wake up (v3)
  2010-11-25 17:04   ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Marcelo Tosatti
                       ` (2 preceding siblings ...)
  2010-11-26  0:38     ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Paul Brook
@ 2010-12-01 16:47     ` Marcelo Tosatti
  2010-12-01 16:47       ` [Qemu-devel] [patch 1/3] add USBPortOps to USBPort Marcelo Tosatti
                         ` (2 more replies)
  3 siblings, 3 replies; 21+ messages in thread
From: Marcelo Tosatti @ 2010-12-01 16:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook, Gerd Hoffmann, Juan Quintela

v3:
- Move remote wakeup callback to USBPort
- Add subsection

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [patch 1/3] add USBPortOps to USBPort
  2010-12-01 16:47     ` [Qemu-devel] [patch 0/3] QEMU support for UHCI suspend / remote wake up (v3) Marcelo Tosatti
@ 2010-12-01 16:47       ` Marcelo Tosatti
  2010-12-01 17:10         ` [Qemu-devel] " Gerd Hoffmann
  2010-12-01 16:47       ` [Qemu-devel] [patch 2/3] support for UHCI suspend / remote wake up Marcelo Tosatti
  2010-12-01 16:47       ` [Qemu-devel] [patch 3/3] UHCI: Substate section for migration of remote wakeup feature Marcelo Tosatti
  2 siblings, 1 reply; 21+ messages in thread
From: Marcelo Tosatti @ 2010-12-01 16:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook, Marcelo Tosatti, Gerd Hoffmann, Juan Quintela

[-- Attachment #1: usb-bus-ops --]
[-- Type: text/plain, Size: 5446 bytes --]

Needed for remote wakeup notification.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

Index: qemu-kvm/hw/usb-bus.c
===================================================================
--- qemu-kvm.orig/hw/usb-bus.c
+++ qemu-kvm/hw/usb-bus.c
@@ -110,11 +110,11 @@ USBDevice *usb_create_simple(USBBus *bus
 }
 
 void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
-                       usb_attachfn attach)
+                       USBPortOps *ops)
 {
     port->opaque = opaque;
     port->index = index;
-    port->attach = attach;
+    port->ops = ops;
     QTAILQ_INSERT_TAIL(&bus->free, port, next);
     bus->nfree++;
 }
Index: qemu-kvm/hw/usb.c
===================================================================
--- qemu-kvm.orig/hw/usb.c
+++ qemu-kvm/hw/usb.c
@@ -28,7 +28,7 @@
 
 void usb_attach(USBPort *port, USBDevice *dev)
 {
-    port->attach(port, dev);
+    port->ops->attach(port, dev);
 }
 
 /**********************/
Index: qemu-kvm/hw/usb.h
===================================================================
--- qemu-kvm.orig/hw/usb.h
+++ qemu-kvm/hw/usb.h
@@ -124,6 +124,7 @@
 
 typedef struct USBBus USBBus;
 typedef struct USBPort USBPort;
+typedef struct USBPortOps USBPortOps;
 typedef struct USBDevice USBDevice;
 typedef struct USBDeviceInfo USBDeviceInfo;
 typedef struct USBPacket USBPacket;
@@ -196,12 +197,14 @@ struct USBDeviceInfo {
     USBDevice *(*usbdevice_init)(const char *params);
 };
 
-typedef void (*usb_attachfn)(USBPort *port, USBDevice *dev);
+struct USBPortOps {
+    void (*attach)(USBPort *port, USBDevice *dev);
+};
 
 /* USB port on which a device can be connected */
 struct USBPort {
     USBDevice *dev;
-    usb_attachfn attach;
+    USBPortOps *ops;
     void *opaque;
     int index; /* internal port index, may be used with the opaque */
     QTAILQ_ENTRY(USBPort) next;
@@ -312,7 +315,7 @@ USBDevice *usb_create(USBBus *bus, const
 USBDevice *usb_create_simple(USBBus *bus, const char *name);
 USBDevice *usbdevice_create(const char *cmdline);
 void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
-                       usb_attachfn attach);
+                       USBPortOps *ops);
 void usb_unregister_port(USBBus *bus, USBPort *port);
 int usb_device_attach(USBDevice *dev);
 int usb_device_detach(USBDevice *dev);
Index: qemu-kvm/hw/usb-musb.c
===================================================================
--- qemu-kvm.orig/hw/usb-musb.c
+++ qemu-kvm/hw/usb-musb.c
@@ -261,6 +261,10 @@
 
 static void musb_attach(USBPort *port, USBDevice *dev);
 
+static USBPortOps musb_port_ops = {
+    .attach = musb_attach,
+};
+
 typedef struct {
     uint16_t faddr[2];
     uint8_t haddr[2];
@@ -343,7 +347,7 @@ struct MUSBState {
     }
 
     usb_bus_new(&s->bus, NULL /* FIXME */);
-    usb_register_port(&s->bus, &s->port, s, 0, musb_attach);
+    usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops);
 
     return s;
 }
Index: qemu-kvm/hw/usb-ohci.c
===================================================================
--- qemu-kvm.orig/hw/usb-ohci.c
+++ qemu-kvm/hw/usb-ohci.c
@@ -1676,6 +1676,10 @@ static CPUWriteMemoryFunc * const ohci_w
     ohci_mem_write
 };
 
+static USBPortOps ohci_port_ops = {
+    .attach = ohci_attach,
+};
+
 static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
                           int num_ports, uint32_t localmem_base)
 {
@@ -1705,7 +1709,7 @@ static void usb_ohci_init(OHCIState *ohc
     usb_bus_new(&ohci->bus, dev);
     ohci->num_ports = num_ports;
     for (i = 0; i < num_ports; i++) {
-        usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, ohci_attach);
+        usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops);
     }
 
     ohci->async_td = 0;
Index: qemu-kvm/hw/usb-uhci.c
===================================================================
--- qemu-kvm.orig/hw/usb-uhci.c
+++ qemu-kvm/hw/usb-uhci.c
@@ -1101,6 +1101,10 @@ static void uhci_map(PCIDevice *pci_dev,
     register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
 }
 
+static USBPortOps uhci_port_ops = {
+    .attach = uhci_attach,
+};
+
 static int usb_uhci_common_initfn(UHCIState *s)
 {
     uint8_t *pci_conf = s->dev.config;
@@ -1115,7 +1119,7 @@ static int usb_uhci_common_initfn(UHCISt
 
     usb_bus_new(&s->bus, &s->dev.qdev);
     for(i = 0; i < NB_PORTS; i++) {
-        usb_register_port(&s->bus, &s->ports[i].port, s, i, uhci_attach);
+        usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops);
     }
     s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
     s->expire_time = qemu_get_clock(vm_clock) +
Index: qemu-kvm/hw/usb-hub.c
===================================================================
--- qemu-kvm.orig/hw/usb-hub.c
+++ qemu-kvm/hw/usb-hub.c
@@ -524,6 +524,10 @@ static void usb_hub_handle_destroy(USBDe
     }
 }
 
+static USBPortOps hub_port_ops = {
+    .attach = usb_hub_attach,
+};
+
 static int usb_hub_initfn(USBDevice *dev)
 {
     USBHubState *s = DO_UPCAST(USBHubState, dev, dev);
@@ -535,7 +539,7 @@ static int usb_hub_initfn(USBDevice *dev
     for (i = 0; i < s->nb_ports; i++) {
         port = &s->ports[i];
         usb_register_port(usb_bus_from_device(dev),
-                          &port->port, s, i, usb_hub_attach);
+                          &port->port, s, i, &hub_port_ops);
         port->wPortStatus = PORT_STAT_POWER;
         port->wPortChange = 0;
     }

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [patch 2/3] support for UHCI suspend / remote wake up
  2010-12-01 16:47     ` [Qemu-devel] [patch 0/3] QEMU support for UHCI suspend / remote wake up (v3) Marcelo Tosatti
  2010-12-01 16:47       ` [Qemu-devel] [patch 1/3] add USBPortOps to USBPort Marcelo Tosatti
@ 2010-12-01 16:47       ` Marcelo Tosatti
  2010-12-01 17:12         ` [Qemu-devel] " Gerd Hoffmann
  2010-12-01 16:47       ` [Qemu-devel] [patch 3/3] UHCI: Substate section for migration of remote wakeup feature Marcelo Tosatti
  2 siblings, 1 reply; 21+ messages in thread
From: Marcelo Tosatti @ 2010-12-01 16:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook, Marcelo Tosatti, Gerd Hoffmann, Juan Quintela

[-- Attachment #1: usb-uhci-suspend --]
[-- Type: text/plain, Size: 4129 bytes --]

This patch enables USB UHCI global suspend/resume feature. The OS will
stop the HC once all ports are suspended. If there is activity on the
port(s), an interrupt signalling remote wakeup will be triggered.

To enable autosuspend for the USB tablet on Linux guests:

echo auto > /sys/devices/pci0000:00/0000:00:01.2/usb1/1-1/power/level

It reduces CPU consumption of an idle FC12 guest from 2.7% to 0.3%.

To enable autosuspend in Windows:

1) Enable "Allow the computer to turn off this
device to save power" checkbox in "Power Management" tab of USB Root Hub 
properties. 

2) Create a REG_BINARY (XP) or REG_DWORD (Vista/2008) key named 
SelectiveSuspendEnabled under:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_0627&PID_0001\1\Device Parameters

With a value of 1.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

Index: qemu-kvm/hw/usb-hid.c
===================================================================
--- qemu-kvm.orig/hw/usb-hid.c
+++ qemu-kvm/hw/usb-hid.c
@@ -412,6 +412,9 @@ static void usb_hid_changed(USBHIDState 
 
     if (hs->datain)
         hs->datain(hs->datain_opaque);
+
+    if (hs->dev.remote_wakeup)
+        usb_remote_wakeup(&hs->dev);
 }
 
 static void usb_mouse_event(void *opaque,
Index: qemu-kvm/hw/usb-uhci.c
===================================================================
--- qemu-kvm.orig/hw/usb-uhci.c
+++ qemu-kvm/hw/usb-uhci.c
@@ -59,6 +59,7 @@
 
 #define UHCI_PORT_RESET (1 << 9)
 #define UHCI_PORT_LSDA  (1 << 8)
+#define UHCI_PORT_RD    (1 << 6)
 #define UHCI_PORT_ENC   (1 << 3)
 #define UHCI_PORT_EN    (1 << 2)
 #define UHCI_PORT_CSC   (1 << 1)
@@ -501,6 +502,7 @@ static void uhci_ioport_writew(void *opa
             port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
             /* some bits are reset when a '1' is written to them */
             port->ctrl &= ~(val & 0x000a);
+            port->ctrl &= ~(port->ctrl & 0x0040); /* clear port resume detected */
         }
         break;
     }
@@ -593,6 +595,23 @@ static void uhci_resume (void *opaque)
     }
 }
 
+static void uhci_event(USBPort *port, USBDevice *dev)
+{
+    USBBus *bus = usb_bus_from_device(dev);
+    UHCIState *s = container_of(bus, UHCIState, bus);
+
+    if (s->cmd & UHCI_CMD_EGSM) {
+        UHCIPort *uport = DO_UPCAST(UHCIPort, port, port);
+
+        if (uport->ctrl & UHCI_PORT_RD) {
+            return;
+        }
+
+        uport->ctrl |= UHCI_PORT_RD;
+        uhci_resume(s);
+    }
+}
+
 static void uhci_attach(USBPort *port1, USBDevice *dev)
 {
     UHCIState *s = port1->opaque;
@@ -1103,6 +1122,7 @@ static void uhci_map(PCIDevice *pci_dev,
 
 static USBPortOps uhci_port_ops = {
     .attach = uhci_attach,
+    .remote_wakeup = uhci_event,
 };
 
 static int usb_uhci_common_initfn(UHCIState *s)
Index: qemu-kvm/hw/usb.h
===================================================================
--- qemu-kvm.orig/hw/usb.h
+++ qemu-kvm/hw/usb.h
@@ -199,6 +199,7 @@ struct USBDeviceInfo {
 
 struct USBPortOps {
     void (*attach)(USBPort *port, USBDevice *dev);
+    void (*remote_wakeup)(USBPort *port, USBDevice *dev);
 };
 
 /* USB port on which a device can be connected */
@@ -253,6 +254,7 @@ static inline void usb_cancel_packet(USB
 }
 
 void usb_attach(USBPort *port, USBDevice *dev);
+void usb_remote_wakeup(USBDevice *dev);
 int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
 int set_usb_string(uint8_t *buf, const char *str);
 void usb_send_msg(USBDevice *dev, int msg);
Index: qemu-kvm/hw/usb.c
===================================================================
--- qemu-kvm.orig/hw/usb.c
+++ qemu-kvm/hw/usb.c
@@ -31,6 +31,21 @@ void usb_attach(USBPort *port, USBDevice
     port->ops->attach(port, dev);
 }
 
+void usb_remote_wakeup(USBDevice *dev)
+{
+    USBBus *bus = usb_bus_from_device(dev);
+    USBPort *port;
+
+    QTAILQ_FOREACH(port, &bus->used, next) {
+        if (port->dev == dev)
+            break;
+    }
+    assert(port != NULL);
+
+    if (port->ops->remote_wakeup)
+        port->ops->remote_wakeup(port, dev);
+}
+
 /**********************/
 
 /* generic USB device helpers (you are not forced to use them when

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [patch 3/3] UHCI: Substate section for migration of remote wakeup feature
  2010-12-01 16:47     ` [Qemu-devel] [patch 0/3] QEMU support for UHCI suspend / remote wake up (v3) Marcelo Tosatti
  2010-12-01 16:47       ` [Qemu-devel] [patch 1/3] add USBPortOps to USBPort Marcelo Tosatti
  2010-12-01 16:47       ` [Qemu-devel] [patch 2/3] support for UHCI suspend / remote wake up Marcelo Tosatti
@ 2010-12-01 16:47       ` Marcelo Tosatti
  2010-12-01 17:16         ` [Qemu-devel] " Gerd Hoffmann
  2 siblings, 1 reply; 21+ messages in thread
From: Marcelo Tosatti @ 2010-12-01 16:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook, Marcelo Tosatti, Gerd Hoffmann, Juan Quintela

[-- Attachment #1: usb-uhci-save --]
[-- Type: text/plain, Size: 1604 bytes --]

Use a subsection to migrate remote wakeup feature only when used by the guest. 

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

Index: qemu-kvm/hw/usb-uhci.c
===================================================================
--- qemu-kvm.orig/hw/usb-uhci.c
+++ qemu-kvm/hw/usb-uhci.c
@@ -363,6 +363,39 @@ static void uhci_pre_save(void *opaque)
     uhci_async_cancel_all(s);
 }
 
+static bool uhci_port_wakeup_state_needed(void *opaque)
+{
+    UHCIPort *port = opaque;
+
+    if (port->port.dev) {
+        return port->port.dev->remote_wakeup;
+    }
+
+    return false;
+}
+
+static int uhci_port_wakeup_post_load(void *opaque, int version_id)
+{
+    UHCIPort *port = opaque;
+
+    if (port->port.dev) {
+        port->port.dev->remote_wakeup = 1;
+    }
+
+    return 0;
+}
+
+const VMStateDescription vmstate_uhci_wakeup_state = {
+    .name = "uhci port/wakeup",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = uhci_port_wakeup_post_load,
+    .fields      = (VMStateField []) {
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_uhci_port = {
     .name = "uhci port",
     .version_id = 1,
@@ -371,6 +404,14 @@ static const VMStateDescription vmstate_
     .fields      = (VMStateField []) {
         VMSTATE_UINT16(ctrl, UHCIPort),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection []) {
+        {
+            .vmsd = &vmstate_uhci_wakeup_state,
+            .needed = uhci_port_wakeup_state_needed,
+        }, {
+            /* empty */
+        }
     }
 };
 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: [patch 2/2] support for UHCI suspend / remote wake up
  2010-12-01 15:12       ` [Qemu-devel] " Gerd Hoffmann
@ 2010-12-01 16:58         ` Marcelo Tosatti
  2010-12-01 17:17           ` Gerd Hoffmann
  0 siblings, 1 reply; 21+ messages in thread
From: Marcelo Tosatti @ 2010-12-01 16:58 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Matthew Garrett, Adam Jackson, qemu-devel, kvm,
	Glauber de Oliveira Costa

On Wed, Dec 01, 2010 at 04:12:14PM +0100, Gerd Hoffmann wrote:
> On 11/25/10 18:04, Marcelo Tosatti wrote:
> >This patch enables USB UHCI global suspend/resume feature. The OS will
> >stop the HC once all ports are suspended. If there is activity on the
> >port(s), an interrupt signalling remote wakeup will be triggered.
> >
> >To enable autosuspend for the USB tablet on Linux guests:
> >
> >echo auto>  /sys/devices/pci0000:00/0000:00:01.2/usb1/1-1/power/level
> 
> Hmm, did you ever got this working sanely?

Yes. Linux and Windows.

> /me sees bus disconnects in the guest ...

I was seeing bus disconnects when not clearing port resume bit properly.

> >              port->ctrl&= ~(val&  0x000a);
> >+            port->ctrl&= ~(port->ctrl&  0x0040); /* clear port resume detected */
> >          }
> 
> This chunk looks suspicious ...
> 
> I suspect the port suspend/resume emulation isn't complete.
> 
> /me goes debugging,
>   Gerd

CONFIG_USB_DEBUG helps.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: [patch 1/3] add USBPortOps to USBPort
  2010-12-01 16:47       ` [Qemu-devel] [patch 1/3] add USBPortOps to USBPort Marcelo Tosatti
@ 2010-12-01 17:10         ` Gerd Hoffmann
  0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2010-12-01 17:10 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Paul Brook, qemu-devel, Juan Quintela

On 12/01/10 17:47, Marcelo Tosatti wrote:
> Needed for remote wakeup notification.

Urks.  Crossover.  /me did this (and more) as part of the usb cleanup 
bits.  Current state:
   http://cgit.freedesktop.org/spice/qemu/log/?h=usb.1

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: [patch 2/3] support for UHCI suspend / remote wake up
  2010-12-01 16:47       ` [Qemu-devel] [patch 2/3] support for UHCI suspend / remote wake up Marcelo Tosatti
@ 2010-12-01 17:12         ` Gerd Hoffmann
  0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2010-12-01 17:12 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Paul Brook, qemu-devel, Juan Quintela

   Hi,

>               port->ctrl = (port->ctrl&  0x01fb) | (val&  ~0x01fb);
>               /* some bits are reset when a '1' is written to them */
>               port->ctrl&= ~(val&  0x000a);
> +            port->ctrl&= ~(port->ctrl&  0x0040); /* clear port resume detected */

Removing the port resume bit from the readonly mask works better than 
the clear-on-any-write hack ;)

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: [patch 3/3] UHCI: Substate section for migration of remote wakeup feature
  2010-12-01 16:47       ` [Qemu-devel] [patch 3/3] UHCI: Substate section for migration of remote wakeup feature Marcelo Tosatti
@ 2010-12-01 17:16         ` Gerd Hoffmann
  2010-12-01 19:14           ` Juan Quintela
  0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2010-12-01 17:16 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Paul Brook, qemu-devel, Juan Quintela

On 12/01/10 17:47, Marcelo Tosatti wrote:
> Use a subsection to migrate remote wakeup feature only when used by the guest.

Yea, right, this must be saved.  But certainly not by the UHCI adapter, 
it belongs into the usb devices.  Some of them don't save state at all 
today, which makes it a bit tricky to do this in a way that migration to 
older versions keeps working at least as long as remote wakeup isn't 
used ...

Juan, any idea?

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: [patch 2/2] support for UHCI suspend / remote wake up
  2010-12-01 16:58         ` Marcelo Tosatti
@ 2010-12-01 17:17           ` Gerd Hoffmann
  0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2010-12-01 17:17 UTC (permalink / raw)
  To: Marcelo Tosatti
  Cc: Matthew Garrett, Adam Jackson, qemu-devel, kvm,
	Glauber de Oliveira Costa

> I was seeing bus disconnects when not clearing port resume bit properly.
>
>>>               port->ctrl&= ~(val&   0x000a);
>>> +            port->ctrl&= ~(port->ctrl&   0x0040); /* clear port resume detected */
>>>           }
>>
>> This chunk looks suspicious ...
>>
>> I suspect the port suspend/resume emulation isn't complete.

The bug is that the port resume bit is masked out from guest writes, so 
the guest hasn't a chance to clear it ...

cheers,
   Gerd

PS: http://cgit.freedesktop.org/spice/qemu/log/?h=usb.1

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: [patch 3/3] UHCI: Substate section for migration of remote wakeup feature
  2010-12-01 17:16         ` [Qemu-devel] " Gerd Hoffmann
@ 2010-12-01 19:14           ` Juan Quintela
  2010-12-01 20:56             ` Marcelo Tosatti
  0 siblings, 1 reply; 21+ messages in thread
From: Juan Quintela @ 2010-12-01 19:14 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Marcelo Tosatti, qemu-devel, Paul Brook

Gerd Hoffmann <kraxel@redhat.com> wrote:
> On 12/01/10 17:47, Marcelo Tosatti wrote:
>> Use a subsection to migrate remote wakeup feature only when used by the guest.
>
> Yea, right, this must be saved.  But certainly not by the UHCI
> adapter, it belongs into the usb devices.  Some of them don't save
> state at all today, which makes it a bit tricky to do this in a way
> that migration to older versions keeps working at least as long as
> remote wakeup isn't used ...
>
> Juan, any idea?

Second thought.

Only to add sections for all devices that don't have one.  But the
problem is that we have optional subsections, not optional subsections
(it is not a way to not send a section because no value there).

Later, Juan.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] Re: [patch 3/3] UHCI: Substate section for migration of remote wakeup feature
  2010-12-01 19:14           ` Juan Quintela
@ 2010-12-01 20:56             ` Marcelo Tosatti
  0 siblings, 0 replies; 21+ messages in thread
From: Marcelo Tosatti @ 2010-12-01 20:56 UTC (permalink / raw)
  To: Juan Quintela; +Cc: Paul Brook, Gerd Hoffmann, qemu-devel

On Wed, Dec 01, 2010 at 08:14:22PM +0100, Juan Quintela wrote:
> Gerd Hoffmann <kraxel@redhat.com> wrote:
> > On 12/01/10 17:47, Marcelo Tosatti wrote:
> >> Use a subsection to migrate remote wakeup feature only when used by the guest.
> >
> > Yea, right, this must be saved.  But certainly not by the UHCI
> > adapter, it belongs into the usb devices.  Some of them don't save
> > state at all today, which makes it a bit tricky to do this in a way
> > that migration to older versions keeps working at least as long as
> > remote wakeup isn't used ...
> >
> > Juan, any idea?
> 
> Second thought.
> 
> Only to add sections for all devices that don't have one.  But the
> problem is that we have optional subsections, not optional subsections
> (it is not a way to not send a section because no value there).
> 
> Later, Juan.

Which breaks migration for older versions. Which lowers the
applicability of s/r.

Yes, remote_wakeup does not belong to UHCI, but i dont see another
solution. Or break migration upstream and use the hack for vendors.

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2010-12-01 23:34 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-25 15:34 [Qemu-devel] PATCH: QEMU support for UHCI suspend / remote wake up Marcelo Tosatti
2010-11-25 16:15 ` [Qemu-devel] " Gerd Hoffmann
2010-11-25 17:04   ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Marcelo Tosatti
2010-11-25 17:04     ` [Qemu-devel] [patch 1/2] add USBBusOps to USBBus Marcelo Tosatti
2010-11-25 17:04     ` [Qemu-devel] [patch 2/2] support for UHCI suspend / remote wake up Marcelo Tosatti
2010-12-01 15:12       ` [Qemu-devel] " Gerd Hoffmann
2010-12-01 16:58         ` Marcelo Tosatti
2010-12-01 17:17           ` Gerd Hoffmann
2010-11-26  0:38     ` [Qemu-devel] [patch 0/2] USB UHCI global suspend / remote wakeup Paul Brook
2010-11-26  2:15       ` Marcelo Tosatti
2010-11-26  8:49         ` Gerd Hoffmann
2010-11-26 12:09           ` Paul Brook
2010-12-01 16:47     ` [Qemu-devel] [patch 0/3] QEMU support for UHCI suspend / remote wake up (v3) Marcelo Tosatti
2010-12-01 16:47       ` [Qemu-devel] [patch 1/3] add USBPortOps to USBPort Marcelo Tosatti
2010-12-01 17:10         ` [Qemu-devel] " Gerd Hoffmann
2010-12-01 16:47       ` [Qemu-devel] [patch 2/3] support for UHCI suspend / remote wake up Marcelo Tosatti
2010-12-01 17:12         ` [Qemu-devel] " Gerd Hoffmann
2010-12-01 16:47       ` [Qemu-devel] [patch 3/3] UHCI: Substate section for migration of remote wakeup feature Marcelo Tosatti
2010-12-01 17:16         ` [Qemu-devel] " Gerd Hoffmann
2010-12-01 19:14           ` Juan Quintela
2010-12-01 20:56             ` Marcelo Tosatti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).