Patchwork [1/3] usb-hub: wakeup on attach

login
register
mail settings
Submitter Gerd Hoffmann
Date Nov. 1, 2011, 2:56 p.m.
Message ID <1320159390-29797-2-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/123080/
State New
Headers show

Comments

Gerd Hoffmann - Nov. 1, 2011, 2:56 p.m.
When attaching a new device we must send a wakeup request to the root
hub, otherwise the guest will not notice the new device in case the
usb hub is suspended.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb-hub.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
hkran - Nov. 2, 2011, 9:38 a.m.
On 11/01/2011 10:56 PM, Gerd Hoffmann wrote:
> When attaching a new device we must send a wakeup request to the root
> hub, otherwise the guest will not notice the new device in case the
> usb hub is suspended.
>
> Signed-off-by: Gerd Hoffmann<kraxel@redhat.com>
> ---
>   hw/usb-hub.c |    1 +
>   1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/hw/usb-hub.c b/hw/usb-hub.c
> index 09c6516..7b47079 100644
> --- a/hw/usb-hub.c
> +++ b/hw/usb-hub.c
> @@ -163,6 +163,7 @@ static void usb_hub_attach(USBPort *port1)
>       } else {
>           port->wPortStatus&= ~PORT_STAT_LOW_SPEED;
>       }
> +    usb_wakeup(&s->dev);
>   }
>
>   static void usb_hub_detach(USBPort *port1)
pulled, In what cases, the usb hub will be suspended? and how to tell it 
happened? thanks.
Gerd Hoffmann - Nov. 2, 2011, 12:56 p.m.
Hi,

>>   static void usb_hub_detach(USBPort *port1)
> pulled, In what cases, the usb hub will be suspended? and how to tell it
> happened? thanks.

The guest enables the remote-wakeup feature.  'lspci -v' (within the
guest) shows it.

cheers,
  Gerd
hkran - Nov. 3, 2011, 6:01 a.m.
On 11/02/2011 08:56 PM, Gerd Hoffmann wrote:
>    Hi,
>
>>>    static void usb_hub_detach(USBPort *port1)
>> pulled, In what cases, the usb hub will be suspended? and how to tell it
>> happened? thanks.
> The guest enables the remote-wakeup feature.  'lspci -v' (within the
> guest) shows it.
>
> cheers,
>    Gerd
>
I use the param "-usb -usbdevice tablet" to start qemu  and then usb_del 
tablet via monitor console after getting qemu up.
I saw this by entering lsusb -v

Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Device Descriptor:
   bLength                18
   bDescriptorType         1
   bcdUSB               1.10
   bDeviceClass            9 Hub
   bDeviceSubClass         0 Unused
   bDeviceProtocol         0 Full speed (or root) hub
   bMaxPacketSize0        64
   idVendor           0x1d6b Linux Foundation
   idProduct          0x0001 1.1 root hub
   bcdDevice            2.06
   iManufacturer           3 Linux 2.6.32-131.0.15.el6.x86_64 uhci_hcd
   iProduct                2 UHCI Host Controller
   iSerial                 1 0000:00:01.2
..........................
Hub Descriptor:
   bLength               9
   bDescriptorType      41
   nNbrPorts             2
   wHubCharacteristic 0x000a
     No power switching (usb 1.0)
     Per-port overcurrent protection
   bPwrOn2PwrGood        1 * 2 milli seconds
   bHubContrCurrent      0 milli Ampere
   DeviceRemovable    0x00
   PortPwrCtrlMask    0xff
  Hub Port Status:
    Port 1: 0000.0100 power
    Port 2: 0000.0100 power
Device Status:     0x0003
   Self Powered
   Remote Wakeup Enabled

(It seems that the Remote-wakeup feature has been enabled)
There are two ports with the status "power",  and I do not know how to 
make it suspended yet. Can you help more ?
Gerd Hoffmann - Nov. 3, 2011, 8:41 a.m.
On 11/03/11 07:01, hkran wrote:
> On 11/02/2011 08:56 PM, Gerd Hoffmann wrote:
>>    Hi,
>>
>>>>    static void usb_hub_detach(USBPort *port1)
>>> pulled, In what cases, the usb hub will be suspended? and how to tell it
>>> happened? thanks.
>> The guest enables the remote-wakeup feature.  'lspci -v' (within the
>> guest) shows it.
>>
>> cheers,
>>    Gerd
>>
> I use the param "-usb -usbdevice tablet" to start qemu  and then usb_del
> tablet via monitor console after getting qemu up.
> I saw this by entering lsusb -v
> 
> Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
> Device Descriptor:
>   bLength                18
>   bDescriptorType         1
>   bcdUSB               1.10
>   bDeviceClass            9 Hub
>   bDeviceSubClass         0 Unused
>   bDeviceProtocol         0 Full speed (or root) hub
>   bMaxPacketSize0        64
>   idVendor           0x1d6b Linux Foundation
>   idProduct          0x0001 1.1 root hub
>   bcdDevice            2.06
>   iManufacturer           3 Linux 2.6.32-131.0.15.el6.x86_64 uhci_hcd
>   iProduct                2 UHCI Host Controller
>   iSerial                 1 0000:00:01.2
> ..........................
> Hub Descriptor:
>   bLength               9
>   bDescriptorType      41
>   nNbrPorts             2
>   wHubCharacteristic 0x000a
>     No power switching (usb 1.0)
>     Per-port overcurrent protection
>   bPwrOn2PwrGood        1 * 2 milli seconds
>   bHubContrCurrent      0 milli Ampere
>   DeviceRemovable    0x00
>   PortPwrCtrlMask    0xff
>  Hub Port Status:
>    Port 1: 0000.0100 power
>    Port 2: 0000.0100 power
> Device Status:     0x0003
>   Self Powered
>   Remote Wakeup Enabled
> 
> (It seems that the Remote-wakeup feature has been enabled)
> There are two ports with the status "power",  and I do not know how to
> make it suspended yet. Can you help more ?

That is the root hub created by the linux kernel, not the hub emulated
by qemu.  If you hook up just a single device no hob is needed.

cheers,
  Gerd
hkran - Nov. 3, 2011, 9:20 a.m.
On 11/03/2011 04:41 PM, Gerd Hoffmann wrote:
> On 11/03/11 07:01, hkran wrote:
>> On 11/02/2011 08:56 PM, Gerd Hoffmann wrote:
>>>     Hi,
>>>
>>>>>     static void usb_hub_detach(USBPort *port1)
>>>> pulled, In what cases, the usb hub will be suspended? and how to tell it
>>>> happened? thanks.
>>> The guest enables the remote-wakeup feature.  'lspci -v' (within the
>>> guest) shows it.
>>>
>>> cheers,
>>>     Gerd
>>>
>> I use the param "-usb -usbdevice tablet" to start qemu  and then usb_del
>> tablet via monitor console after getting qemu up.
>> I saw this by entering lsusb -v
>>
>> Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
>> Device Descriptor:
>>    bLength                18
>>    bDescriptorType         1
>>    bcdUSB               1.10
>>    bDeviceClass            9 Hub
>>    bDeviceSubClass         0 Unused
>>    bDeviceProtocol         0 Full speed (or root) hub
>>    bMaxPacketSize0        64
>>    idVendor           0x1d6b Linux Foundation
>>    idProduct          0x0001 1.1 root hub
>>    bcdDevice            2.06
>>    iManufacturer           3 Linux 2.6.32-131.0.15.el6.x86_64 uhci_hcd
>>    iProduct                2 UHCI Host Controller
>>    iSerial                 1 0000:00:01.2
>> ..........................
>> Hub Descriptor:
>>    bLength               9
>>    bDescriptorType      41
>>    nNbrPorts             2
>>    wHubCharacteristic 0x000a
>>      No power switching (usb 1.0)
>>      Per-port overcurrent protection
>>    bPwrOn2PwrGood        1 * 2 milli seconds
>>    bHubContrCurrent      0 milli Ampere
>>    DeviceRemovable    0x00
>>    PortPwrCtrlMask    0xff
>>   Hub Port Status:
>>     Port 1: 0000.0100 power
>>     Port 2: 0000.0100 power
>> Device Status:     0x0003
>>    Self Powered
>>    Remote Wakeup Enabled
>>
>> (It seems that the Remote-wakeup feature has been enabled)
>> There are two ports with the status "power",  and I do not know how to
>> make it suspended yet. Can you help more ?
> That is the root hub created by the linux kernel, not the hub emulated
> by qemu.  If you hook up just a single device no hob is needed.
>
> cheers,
>    Gerd
>
Yes, it is. After I usb_add a storage a 8-port hub emulated is added :

lsusb
Bus 001 Device 004: ID 0000:7777
Bus 001 Device 003: ID 0000:0000
Bus 001 Device 002: ID 0627:0001 Adomax Technology Co., Ltd
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Device 003 is the hub and Device 004 is my storage

lsusb -s 3 -v:

Bus 001 Device 003: ID 0000:0000
Device Descriptor:
   bLength                18
   bDescriptorType         1
   bcdUSB               1.10
   bDeviceClass            9 Hub
   bDeviceSubClass         0 Unused
   bDeviceProtocol         0 Full speed (or root) hub
   bMaxPacketSize0         8
   idVendor           0x0000
   idProduct          0x0000
   bcdDevice            1.01
   iManufacturer           1 QEMU 0.15.50
   iProduct                2 QEMU USB Hub
   iSerial                 3 314159
   bNumConfigurations      1
...........................................
     iConfiguration          0
     bmAttributes         0xe0
       Self Powered
       Remote Wakeup
     MaxPower                0mA
     Interface Descriptor:
       bLength                 9
       bDescriptorType         4
       bInterfaceNumber        0
       bAlternateSetting       0
       bNumEndpoints           1
       bInterfaceClass         9 Hub
       bInterfaceSubClass      0 Unused
       bInterfaceProtocol      0 Full speed (or root) hub
       iInterface              0
       Endpoint Descriptor:
         bLength                 7
         bDescriptorType         5
         bEndpointAddress     0x81  EP 1 IN
         bmAttributes            3
           Transfer Type            Interrupt
           Synch Type               None
           Usage Type               Data
         wMaxPacketSize     0x0002  1x 2 bytes
         bInterval             255
Hub Descriptor:
   bLength              10
   bDescriptorType      41
   nNbrPorts             8
   wHubCharacteristic 0x000a
     No power switching (usb 1.0)
     Per-port overcurrent protection
   bPwrOn2PwrGood        1 * 2 milli seconds
   bHubContrCurrent      0 milli Ampere
   DeviceRemovable    0x00 0x00
   PortPwrCtrlMask    0xff 0x00
  Hub Port Status:
    Port 1: 0000.0103 power enable connect
    Port 2: 0000.0100 power
    Port 3: 0000.0100 power
    Port 4: 0000.0100 power
    Port 5: 0000.0100 power
    Port 6: 0000.0100 power
    Port 7: 0000.0100 power
    Port 8: 0000.0100 power
Device Status:     0x0001
   Self Powered

my storage is connected to the port 1.

after usb_del, all the hub port status will turn to power. how should i 
do next to get it to be suspended?thanks.
hkran - Nov. 10, 2011, 3:45 a.m.
On 11/01/2011 10:56 PM, Gerd Hoffmann wrote:
> When attaching a new device we must send a wakeup request to the root
> hub, otherwise the guest will not notice the new device in case the
> usb hub is suspended.
>
> Signed-off-by: Gerd Hoffmann<kraxel@redhat.com>
> ---
>   hw/usb-hub.c |    1 +
>   1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/hw/usb-hub.c b/hw/usb-hub.c
> index 09c6516..7b47079 100644
> --- a/hw/usb-hub.c
> +++ b/hw/usb-hub.c
> @@ -163,6 +163,7 @@ static void usb_hub_attach(USBPort *port1)
>       } else {
>           port->wPortStatus&= ~PORT_STAT_LOW_SPEED;
>       }
> +    usb_wakeup(&s->dev);
>   }
>
>   static void usb_hub_detach(USBPort *port1)
It seems "attach" works. But the "detach" did not work.
I added over two usbdevice "tablet" and usb_del them. I found sometimes 
the guest did not know that the tablet had been deleted in host when the 
port
's status changed to "suspend".

After I add usb_wake like this in the function usb_hub_detach. the 
problem can be fixed.

static void usb_hub_detach(USBPort *port1)
{
     USBHubState *s = port1->opaque;
     USBHubPort *port = &s->ports[port1->index];

     usb_wakeup(&s->dev);                 
---------------------------------->wakeup when detach
     /* Let upstream know the device on this port is gone */
     s->dev.port->ops->child_detach(s->dev.port, port1->dev);

     port->wPortStatus &= ~PORT_STAT_CONNECTION;
     port->wPortChange |= PORT_STAT_C_CONNECTION;
     if (port->wPortStatus & PORT_STAT_ENABLE) {
         port->wPortStatus &= ~PORT_STAT_ENABLE;
         port->wPortChange |= PORT_STAT_C_ENABLE;
     }
}
Gerd Hoffmann - Nov. 22, 2011, 12:23 p.m.
Hi,

> After I add usb_wake like this in the function usb_hub_detach. the
> problem can be fixed.
> 
> static void usb_hub_detach(USBPort *port1)
> {
>     USBHubState *s = port1->opaque;
>     USBHubPort *port = &s->ports[port1->index];
> 
>     usb_wakeup(&s->dev);                
> ---------------------------------->wakeup when detach

Fix added to usb patch queue.

thanks,
  Gerd

Patch

diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 09c6516..7b47079 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -163,6 +163,7 @@  static void usb_hub_attach(USBPort *port1)
     } else {
         port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
     }
+    usb_wakeup(&s->dev);
 }
 
 static void usb_hub_detach(USBPort *port1)