All of lore.kernel.org
 help / color / mirror / Atom feed
* port power is on again after turning off by user space
@ 2020-12-15  3:31 Peter Chen
  2020-12-15  5:02 ` Jun Li
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Chen @ 2020-12-15  3:31 UTC (permalink / raw)
  To: Alan Stern; +Cc: linux-usb

Hi Alan,

I use one HUB power control application (https://github.com/mvp/uhubctl) to investigate power switchable HUB, and
find the kernel turns port power on again at drivers/usb/core/hub.c, after port power is turned off by user space.

5122                 if (hub_is_port_power_switchable(hub)
5123                                 && !port_is_power_on(hub, portstatus)
5124                                 && !port_dev->port_owner)
5125                         set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);

The main sequence for testing turn port power off like below:

- uhubctl sends command to turn specifc port (eg, 2-1.4) power off.
- devio at kernel gets that command, and send to hub.
- port power is off, the hub_event is triggered due to port status is changed.
- usb_disconnect is called, but port power is on again by kernel at function hub_port_connect.

I can't find the code history why the port power needs to turn on after device is disconnected, do you know why?
Any sugguestions to fix it? Thanks.

Best regards,
Peter Chen
 


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

* Re: port power is on again after turning off by user space
  2020-12-15  3:31 port power is on again after turning off by user space Peter Chen
@ 2020-12-15  5:02 ` Jun Li
  2020-12-15  5:14   ` Peter Chen
  0 siblings, 1 reply; 11+ messages in thread
From: Jun Li @ 2020-12-15  5:02 UTC (permalink / raw)
  To: Peter Chen; +Cc: Alan Stern, linux-usb

Peter Chen <peter.chen@nxp.com> 于2020年12月15日周二 上午11:33写道:
>
> Hi Alan,
>
> I use one HUB power control application (https://github.com/mvp/uhubctl) to investigate power switchable HUB, and
> find the kernel turns port power on again at drivers/usb/core/hub.c, after port power is turned off by user space.
>
> 5122                 if (hub_is_port_power_switchable(hub)
> 5123                                 && !port_is_power_on(hub, portstatus)
> 5124                                 && !port_dev->port_owner)
> 5125                         set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
>
> The main sequence for testing turn port power off like below:
>
> - uhubctl sends command to turn specifc port (eg, 2-1.4) power off.
> - devio at kernel gets that command, and send to hub.
> - port power is off, the hub_event is triggered due to port status is changed.
> - usb_disconnect is called, but port power is on again by kernel at function hub_port_connect.
>
> I can't find the code history why the port power needs to turn on after device is disconnected, do you know why?
> Any sugguestions to fix it? Thanks.

Seems in this case the port need claimed by user app, I am seeing this commit

commit fbaecff06a7db4defa899a664fe2758e5161b39d
Author: Deepak Das <deepakdas.linux@gmail.com>
Date:   Wed Jan 21 23:39:58 2015 +0530

    usb: core: hub: modify hub reset logic in hub driver

    Currently if port power is turned off by user on hub port
    using USBDEVFS then port power is turned back ON
    by hub driver.
    This commit modifies hub reset logic in hub_port_connect() to prevent
    hub driver from turning back the port power ON if port is not owned
    by kernel.

    Signed-off-by: Deepak Das <deepakdas.linux@gmail.com>
    Acked-by: Alan Stern <stern@rowland.harvard.edu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b4bfa3a..3e9c4d4 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4655,9 +4655,13 @@ static void hub_port_connect(struct usb_hub
*hub, int port1, u16 portstatus,
        if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
                        test_bit(port1, hub->removed_bits)) {

-               /* maybe switch power back on (e.g. root hub was reset) */
+               /*
+                * maybe switch power back on (e.g. root hub was reset)
+                * but only if the port isn't owned by someone else.
+                */
                if (hub_is_port_power_switchable(hub)
-                               && !port_is_power_on(hub, portstatus))
+                               && !port_is_power_on(hub, portstatus)
+                               && !port_dev->port_owner)
                        set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);

                if (portstatus & USB_PORT_STAT_ENABLE)

Li Jun
>
>
> Best regards,
> Peter Chen
>
>

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

* Re: port power is on again after turning off by user space
  2020-12-15  5:02 ` Jun Li
@ 2020-12-15  5:14   ` Peter Chen
  2020-12-15  9:57     ` Peter Chen
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Chen @ 2020-12-15  5:14 UTC (permalink / raw)
  To: Jun Li; +Cc: Alan Stern, linux-usb

On 20-12-15 13:02:03, Jun Li wrote:
> Peter Chen <peter.chen@nxp.com> 于2020年12月15日周二 上午11:33写道:
> >
> > Hi Alan,
> >
> > I use one HUB power control application (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmvp%2Fuhubctl&amp;data=04%7C01%7Cpeter.chen%40nxp.com%7C736ece19bc7a430c98b808d8a0b6975c%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637436053362151022%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=lptf1XO5yeb6lQbAFlKUrZ%2BEX5ATXQRftGwm26WowFA%3D&amp;reserved=0) to investigate power switchable HUB, and
> > find the kernel turns port power on again at drivers/usb/core/hub.c, after port power is turned off by user space.
> >
> > 5122                 if (hub_is_port_power_switchable(hub)
> > 5123                                 && !port_is_power_on(hub, portstatus)
> > 5124                                 && !port_dev->port_owner)
> > 5125                         set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
> >
> > The main sequence for testing turn port power off like below:
> >
> > - uhubctl sends command to turn specifc port (eg, 2-1.4) power off.
> > - devio at kernel gets that command, and send to hub.
> > - port power is off, the hub_event is triggered due to port status is changed.
> > - usb_disconnect is called, but port power is on again by kernel at function hub_port_connect.
> >
> > I can't find the code history why the port power needs to turn on after device is disconnected, do you know why?
> > Any sugguestions to fix it? Thanks.
> 
> Seems in this case the port need claimed by user app, I am seeing this commit
> 
> commit fbaecff06a7db4defa899a664fe2758e5161b39d
> Author: Deepak Das <deepakdas.linux@gmail.com>
> Date:   Wed Jan 21 23:39:58 2015 +0530
> 
>     usb: core: hub: modify hub reset logic in hub driver
> 
>     Currently if port power is turned off by user on hub port
>     using USBDEVFS then port power is turned back ON
>     by hub driver.
>     This commit modifies hub reset logic in hub_port_connect() to prevent
>     hub driver from turning back the port power ON if port is not owned
>     by kernel.
> 
>     Signed-off-by: Deepak Das <deepakdas.linux@gmail.com>
>     Acked-by: Alan Stern <stern@rowland.harvard.edu>
>     Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index b4bfa3a..3e9c4d4 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -4655,9 +4655,13 @@ static void hub_port_connect(struct usb_hub
> *hub, int port1, u16 portstatus,
>         if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
>                         test_bit(port1, hub->removed_bits)) {
> 
> -               /* maybe switch power back on (e.g. root hub was reset) */
> +               /*
> +                * maybe switch power back on (e.g. root hub was reset)
> +                * but only if the port isn't owned by someone else.
> +                */
>                 if (hub_is_port_power_switchable(hub)
> -                               && !port_is_power_on(hub, portstatus))
> +                               && !port_is_power_on(hub, portstatus)
> +                               && !port_dev->port_owner)
>                         set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
> 
>                 if (portstatus & USB_PORT_STAT_ENABLE)
> 

Yes, I saw this commit. But the port is owned by kernel, the device on the
port could be enumerated by kernel, just the power on the port could be
changed by user space.

-- 

Thanks,
Peter Chen

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

* RE: port power is on again after turning off by user space
  2020-12-15  5:14   ` Peter Chen
@ 2020-12-15  9:57     ` Peter Chen
  2020-12-15 15:55       ` Alan Stern
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Chen @ 2020-12-15  9:57 UTC (permalink / raw)
  To: Jun Li, Alan Stern; +Cc: linux-usb

 
> > > Hi Alan,
> > >
> > > I use one HUB power control application
> > >
> (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.
> com%2Fmvp%2Fuhubctl&amp;data=04%7C01%7Cpeter.chen%40nxp.com%7C
> 736ece19bc7a430c98b808d8a0b6975c%7C686ea1d3bc2b4c6fa92cd99c5c3016
> 35%7C0%7C0%7C637436053362151022%7CUnknown%7CTWFpbGZsb3d8eyJ
> WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7
> C1000&amp;sdata=lptf1XO5yeb6lQbAFlKUrZ%2BEX5ATXQRftGwm26WowFA%
> 3D&amp;reserved=0) to investigate power switchable HUB, and find the kernel
> turns port power on again at drivers/usb/core/hub.c, after port power is turned
> off by user space.
> > >
> > > 5122                 if (hub_is_port_power_switchable(hub)
> > > 5123                                 && !port_is_power_on(hub,
> portstatus)
> > > 5124                                 && !port_dev->port_owner)
> > > 5125                         set_port_feature(hdev, port1,
> USB_PORT_FEAT_POWER);
> > >
> > > The main sequence for testing turn port power off like below:
> > >
> > > - uhubctl sends command to turn specifc port (eg, 2-1.4) power off.
> > > - devio at kernel gets that command, and send to hub.
> > > - port power is off, the hub_event is triggered due to port status is changed.
> > > - usb_disconnect is called, but port power is on again by kernel at function
> hub_port_connect.
> > >
> > > I can't find the code history why the port power needs to turn on after
> device is disconnected, do you know why?
> > > Any sugguestions to fix it? Thanks.
> >
> > Seems in this case the port need claimed by user app, I am seeing this
> > commit
> >
> > commit fbaecff06a7db4defa899a664fe2758e5161b39d
> > Author: Deepak Das <deepakdas.linux@gmail.com>
> > Date:   Wed Jan 21 23:39:58 2015 +0530
> >
> >     usb: core: hub: modify hub reset logic in hub driver
> >
> >     Currently if port power is turned off by user on hub port
> >     using USBDEVFS then port power is turned back ON
> >     by hub driver.
> >     This commit modifies hub reset logic in hub_port_connect() to prevent
> >     hub driver from turning back the port power ON if port is not owned
> >     by kernel.
> >
> >     Signed-off-by: Deepak Das <deepakdas.linux@gmail.com>
> >     Acked-by: Alan Stern <stern@rowland.harvard.edu>
> >     Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> >
> > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index
> > b4bfa3a..3e9c4d4 100644
> > --- a/drivers/usb/core/hub.c
> > +++ b/drivers/usb/core/hub.c
> > @@ -4655,9 +4655,13 @@ static void hub_port_connect(struct usb_hub
> > *hub, int port1, u16 portstatus,
> >         if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
> >                         test_bit(port1, hub->removed_bits)) {
> >
> > -               /* maybe switch power back on (e.g. root hub was reset)
> */
> > +               /*
> > +                * maybe switch power back on (e.g. root hub was reset)
> > +                * but only if the port isn't owned by someone else.
> > +                */
> >                 if (hub_is_port_power_switchable(hub)
> > -                               && !port_is_power_on(hub,
> portstatus))
> > +                               && !port_is_power_on(hub,
> portstatus)
> > +                               && !port_dev->port_owner)
> >                         set_port_feature(hdev, port1,
> > USB_PORT_FEAT_POWER);
> >
> >                 if (portstatus & USB_PORT_STAT_ENABLE)
> >
> 
> Yes, I saw this commit. But the port is owned by kernel, the device on the port
> could be enumerated by kernel, just the power on the port could be changed by
> user space.
> 

I find this issue has discussed there, but I can't open the URL: https://bit.ly/2JzczjZ
Below the description from: https://github.com/mvp/uhubctl.
Their workarounds are not good.

Power comes back on after few seconds on Linux

Some device drivers in kernel are surprised by USB device
being turned off and automatically try to power it back on.

You can use option -r N where N is some number from 10 to 1000
to fix this - uhubctl will try to turn power off many times in quick
succession, and it should suppress that. This may be eventually fixed
in kernel, see more discussion here.

Disabling USB authorization for device in question before
turning power off with uhubctl should help:

echo 0 > sudo tee /sys/bus/usb/devices/${location}.${port}/authorized
If your device is USB mass storage, invoking udisksctl before calling uhubctl
should help too:

sudo udisksctl power-off --block-device /dev/disk/...`
sudo uhubctl -a off ...
 
Peter

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

* Re: port power is on again after turning off by user space
  2020-12-15  9:57     ` Peter Chen
@ 2020-12-15 15:55       ` Alan Stern
  2020-12-16  2:56         ` Peter Chen
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Stern @ 2020-12-15 15:55 UTC (permalink / raw)
  To: Peter Chen; +Cc: Jun Li, linux-usb

On Tue, Dec 15, 2020 at 09:57:53AM +0000, Peter Chen wrote:
>  
> > > > Hi Alan,
> > > >
> > > > I use one HUB power control application
> > > >
> > (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.
> > com%2Fmvp%2Fuhubctl&amp;data=04%7C01%7Cpeter.chen%40nxp.com%7C
> > 736ece19bc7a430c98b808d8a0b6975c%7C686ea1d3bc2b4c6fa92cd99c5c3016
> > 35%7C0%7C0%7C637436053362151022%7CUnknown%7CTWFpbGZsb3d8eyJ
> > WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7
> > C1000&amp;sdata=lptf1XO5yeb6lQbAFlKUrZ%2BEX5ATXQRftGwm26WowFA%
> > 3D&amp;reserved=0) to investigate power switchable HUB, and find the kernel
> > turns port power on again at drivers/usb/core/hub.c, after port power is turned
> > off by user space.
> > > >
> > > > 5122                 if (hub_is_port_power_switchable(hub)
> > > > 5123                                 && !port_is_power_on(hub,
> > portstatus)
> > > > 5124                                 && !port_dev->port_owner)
> > > > 5125                         set_port_feature(hdev, port1,
> > USB_PORT_FEAT_POWER);
> > > >
> > > > The main sequence for testing turn port power off like below:
> > > >
> > > > - uhubctl sends command to turn specifc port (eg, 2-1.4) power off.
> > > > - devio at kernel gets that command, and send to hub.
> > > > - port power is off, the hub_event is triggered due to port status is changed.
> > > > - usb_disconnect is called, but port power is on again by kernel at function
> > hub_port_connect.
> > > >
> > > > I can't find the code history why the port power needs to turn on after
> > device is disconnected, do you know why?
> > > > Any sugguestions to fix it? Thanks.
> > >
> > > Seems in this case the port need claimed by user app, I am seeing this
> > > commit
> > >
> > > commit fbaecff06a7db4defa899a664fe2758e5161b39d
> > > Author: Deepak Das <deepakdas.linux@gmail.com>
> > > Date:   Wed Jan 21 23:39:58 2015 +0530
> > >
> > >     usb: core: hub: modify hub reset logic in hub driver
> > >
> > >     Currently if port power is turned off by user on hub port
> > >     using USBDEVFS then port power is turned back ON
> > >     by hub driver.
> > >     This commit modifies hub reset logic in hub_port_connect() to prevent
> > >     hub driver from turning back the port power ON if port is not owned
> > >     by kernel.
> > >
> > >     Signed-off-by: Deepak Das <deepakdas.linux@gmail.com>
> > >     Acked-by: Alan Stern <stern@rowland.harvard.edu>
> > >     Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > >
> > > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index
> > > b4bfa3a..3e9c4d4 100644
> > > --- a/drivers/usb/core/hub.c
> > > +++ b/drivers/usb/core/hub.c
> > > @@ -4655,9 +4655,13 @@ static void hub_port_connect(struct usb_hub
> > > *hub, int port1, u16 portstatus,
> > >         if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
> > >                         test_bit(port1, hub->removed_bits)) {
> > >
> > > -               /* maybe switch power back on (e.g. root hub was reset)
> > */
> > > +               /*
> > > +                * maybe switch power back on (e.g. root hub was reset)
> > > +                * but only if the port isn't owned by someone else.
> > > +                */
> > >                 if (hub_is_port_power_switchable(hub)
> > > -                               && !port_is_power_on(hub,
> > portstatus))
> > > +                               && !port_is_power_on(hub,
> > portstatus)
> > > +                               && !port_dev->port_owner)
> > >                         set_port_feature(hdev, port1,
> > > USB_PORT_FEAT_POWER);
> > >
> > >                 if (portstatus & USB_PORT_STAT_ENABLE)
> > >
> > 
> > Yes, I saw this commit. But the port is owned by kernel, the device on the port
> > could be enumerated by kernel, just the power on the port could be changed by
> > user space.

You've got the general idea.

Normally ports are owned by the hub driver.  If one of them loses power 
for some reason (for example, the user turns it off), the hub driver 
will turn the power back on.  This is because the hub driver wants 
ports to be powered at all times unless they are in runtime suspend.

The way to prevent the hub driver from managing the port power is to 
claim the port for the user, by issuing the USBDEVFS_CLAIM_PORT ioctl.  
Also, when that is done, the kernel wno't try to manage a device 
attached to the port -- that is, the kernel won't automatically install 
a configuration for a new device and it won't try to probe drivers for 
the device's interfaces if the user installs a config.

> I find this issue has discussed there, but I can't open the URL: https://bit.ly/2JzczjZ
> Below the description from: https://github.com/mvp/uhubctl.
> Their workarounds are not good.
> 
> Power comes back on after few seconds on Linux
> 
> Some device drivers in kernel are surprised by USB device
> being turned off and automatically try to power it back on.
> 
> You can use option -r N where N is some number from 10 to 1000
> to fix this - uhubctl will try to turn power off many times in quick
> succession, and it should suppress that. This may be eventually fixed
> in kernel, see more discussion here.
> 
> Disabling USB authorization for device in question before
> turning power off with uhubctl should help:
> 
> echo 0 > sudo tee /sys/bus/usb/devices/${location}.${port}/authorized
> If your device is USB mass storage, invoking udisksctl before calling uhubctl
> should help too:
> 
> sudo udisksctl power-off --block-device /dev/disk/...`
> sudo uhubctl -a off ...

Yes, this certainly indicates that they don't understand the real 
problem or the appropriate solution.  You could file a bug report for 
the github project to tell them.

Alan Stern

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

* Re: port power is on again after turning off by user space
  2020-12-15 15:55       ` Alan Stern
@ 2020-12-16  2:56         ` Peter Chen
  2020-12-16 15:51           ` Alan Stern
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Chen @ 2020-12-16  2:56 UTC (permalink / raw)
  To: Alan Stern; +Cc: Jun Li, linux-usb

On 20-12-15 10:55:41, Alan Stern wrote:
> On Tue, Dec 15, 2020 at 09:57:53AM +0000, Peter Chen wrote:
> >  
> > > > > Hi Alan,
> > > > >
> > > > > I use one HUB power control application
> > > > >
> > > (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.
> > > com%2Fmvp%2Fuhubctl&amp;data=04%7C01%7Cpeter.chen%40nxp.com%7C
> > > 736ece19bc7a430c98b808d8a0b6975c%7C686ea1d3bc2b4c6fa92cd99c5c3016
> > > 35%7C0%7C0%7C637436053362151022%7CUnknown%7CTWFpbGZsb3d8eyJ
> > > WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7
> > > C1000&amp;sdata=lptf1XO5yeb6lQbAFlKUrZ%2BEX5ATXQRftGwm26WowFA%
> > > 3D&amp;reserved=0) to investigate power switchable HUB, and find the kernel
> > > turns port power on again at drivers/usb/core/hub.c, after port power is turned
> > > off by user space.
> > > > >
> > > > > 5122                 if (hub_is_port_power_switchable(hub)
> > > > > 5123                                 && !port_is_power_on(hub,
> > > portstatus)
> > > > > 5124                                 && !port_dev->port_owner)
> > > > > 5125                         set_port_feature(hdev, port1,
> > > USB_PORT_FEAT_POWER);
> > > > >
> > > > > The main sequence for testing turn port power off like below:
> > > > >
> > > > > - uhubctl sends command to turn specifc port (eg, 2-1.4) power off.
> > > > > - devio at kernel gets that command, and send to hub.
> > > > > - port power is off, the hub_event is triggered due to port status is changed.
> > > > > - usb_disconnect is called, but port power is on again by kernel at function
> > > hub_port_connect.
> > > > >
> > > > > I can't find the code history why the port power needs to turn on after
> > > device is disconnected, do you know why?
> > > > > Any sugguestions to fix it? Thanks.
> > > >
> > > > Seems in this case the port need claimed by user app, I am seeing this
> > > > commit
> > > >
> > > > commit fbaecff06a7db4defa899a664fe2758e5161b39d
> > > > Author: Deepak Das <deepakdas.linux@gmail.com>
> > > > Date:   Wed Jan 21 23:39:58 2015 +0530
> > > >
> > > >     usb: core: hub: modify hub reset logic in hub driver
> > > >
> > > >     Currently if port power is turned off by user on hub port
> > > >     using USBDEVFS then port power is turned back ON
> > > >     by hub driver.
> > > >     This commit modifies hub reset logic in hub_port_connect() to prevent
> > > >     hub driver from turning back the port power ON if port is not owned
> > > >     by kernel.
> > > >
> > > >     Signed-off-by: Deepak Das <deepakdas.linux@gmail.com>
> > > >     Acked-by: Alan Stern <stern@rowland.harvard.edu>
> > > >     Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > >
> > > > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index
> > > > b4bfa3a..3e9c4d4 100644
> > > > --- a/drivers/usb/core/hub.c
> > > > +++ b/drivers/usb/core/hub.c
> > > > @@ -4655,9 +4655,13 @@ static void hub_port_connect(struct usb_hub
> > > > *hub, int port1, u16 portstatus,
> > > >         if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
> > > >                         test_bit(port1, hub->removed_bits)) {
> > > >
> > > > -               /* maybe switch power back on (e.g. root hub was reset)
> > > */
> > > > +               /*
> > > > +                * maybe switch power back on (e.g. root hub was reset)
> > > > +                * but only if the port isn't owned by someone else.
> > > > +                */
> > > >                 if (hub_is_port_power_switchable(hub)
> > > > -                               && !port_is_power_on(hub,
> > > portstatus))
> > > > +                               && !port_is_power_on(hub,
> > > portstatus)
> > > > +                               && !port_dev->port_owner)
> > > >                         set_port_feature(hdev, port1,
> > > > USB_PORT_FEAT_POWER);
> > > >
> > > >                 if (portstatus & USB_PORT_STAT_ENABLE)
> > > >
> > > 
> > > Yes, I saw this commit. But the port is owned by kernel, the device on the port
> > > could be enumerated by kernel, just the power on the port could be changed by
> > > user space.
> 
> You've got the general idea.
> 
> Normally ports are owned by the hub driver.  If one of them loses power 
> for some reason (for example, the user turns it off), the hub driver 
> will turn the power back on.  This is because the hub driver wants 
> ports to be powered at all times unless they are in runtime suspend.
> 
> The way to prevent the hub driver from managing the port power is to 
> claim the port for the user, by issuing the USBDEVFS_CLAIM_PORT ioctl.  
> Also, when that is done, the kernel wno't try to manage a device 
> attached to the port -- that is, the kernel won't automatically install 
> a configuration for a new device and it won't try to probe drivers for 
> the device's interfaces if the user installs a config.
> 

Alan, we have several use cases for power switchable HUB, one of the use
cases is USB port is managed by kernel (eg, needs mass storage
class), but needs to toggle port power, is it reasonable we add a sysfs
entry to support it?

-- 

Thanks,
Peter Chen

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

* Re: port power is on again after turning off by user space
  2020-12-16  2:56         ` Peter Chen
@ 2020-12-16 15:51           ` Alan Stern
  2020-12-21  5:37             ` Peter Chen
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Stern @ 2020-12-16 15:51 UTC (permalink / raw)
  To: Peter Chen; +Cc: Jun Li, linux-usb

On Wed, Dec 16, 2020 at 02:56:20AM +0000, Peter Chen wrote:
> On 20-12-15 10:55:41, Alan Stern wrote:
> > You've got the general idea.
> > 
> > Normally ports are owned by the hub driver.  If one of them loses power 
> > for some reason (for example, the user turns it off), the hub driver 
> > will turn the power back on.  This is because the hub driver wants 
> > ports to be powered at all times unless they are in runtime suspend.
> > 
> > The way to prevent the hub driver from managing the port power is to 
> > claim the port for the user, by issuing the USBDEVFS_CLAIM_PORT ioctl.  
> > Also, when that is done, the kernel wno't try to manage a device 
> > attached to the port -- that is, the kernel won't automatically install 
> > a configuration for a new device and it won't try to probe drivers for 
> > the device's interfaces if the user installs a config.
> > 
> 
> Alan, we have several use cases for power switchable HUB, one of the use
> cases is USB port is managed by kernel (eg, needs mass storage
> class), but needs to toggle port power, is it reasonable we add a sysfs
> entry to support it?

Can you give more information about your use cases?  After all, if the 
port power is turned off then the port can't possibly handle 
mass-storage devices -- or anything else.

On the other hand, if the port is managed by the kernel then the kernel 
(not the user) should be responsible for deciding whether or not to 
turn off the port's power.

If there's some real reason for turning the port power off for an 
extended period of time, the user can claim the port and turn off the 
power.  Then later on, the user can release the port and turn the power 
back on.

Alternatively, if you only need to turn off the port power for a short 
time, what you're already doing should be okay.

I can't explain it any better than this unless I understand your use 
cases more fully.

Alan Stern

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

* Re: port power is on again after turning off by user space
  2020-12-16 15:51           ` Alan Stern
@ 2020-12-21  5:37             ` Peter Chen
  2020-12-21 16:25               ` Alan Stern
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Chen @ 2020-12-21  5:37 UTC (permalink / raw)
  To: Alan Stern; +Cc: Jun Li, linux-usb

On 20-12-16 10:51:44, Alan Stern wrote:
> On Wed, Dec 16, 2020 at 02:56:20AM +0000, Peter Chen wrote:
> > On 20-12-15 10:55:41, Alan Stern wrote:
> > > You've got the general idea.
> > > 
> > > Normally ports are owned by the hub driver.  If one of them loses power 
> > > for some reason (for example, the user turns it off), the hub driver 
> > > will turn the power back on.  This is because the hub driver wants 
> > > ports to be powered at all times unless they are in runtime suspend.
> > > 
> > > The way to prevent the hub driver from managing the port power is to 
> > > claim the port for the user, by issuing the USBDEVFS_CLAIM_PORT ioctl.  
> > > Also, when that is done, the kernel wno't try to manage a device 
> > > attached to the port -- that is, the kernel won't automatically install 
> > > a configuration for a new device and it won't try to probe drivers for 
> > > the device's interfaces if the user installs a config.
> > > 
> > 
> > Alan, we have several use cases for power switchable HUB, one of the use
> > cases is USB port is managed by kernel (eg, needs mass storage
> > class), but needs to toggle port power, is it reasonable we add a sysfs
> > entry to support it?
> 
> Can you give more information about your use cases?  After all, if the 
> port power is turned off then the port can't possibly handle 
> mass-storage devices -- or anything else.

Sorry, Alan. Due to holiday season, the U.S team doesn't reply me the
use case. I think the basic use cases are emulate the hot-plug test for
USB devices, the USB devices could be Flash Drive on market or DUT (Device
Under test) for the same controller works at device mode. Assume one
typical test case:

Plug in Flash Drive at port 1-1.1 during the boots up:

while (1) {
- Check Flash Drive is there (eg, cat /proc/partitions)
- Turn port 1 at 1-1 off
- Check Flash Drive is gone
- Turn port 1 at 1-1 on
}

> 
> On the other hand, if the port is managed by the kernel then the kernel 
> (not the user) should be responsible for deciding whether or not to 
> turn off the port's power.
> 
> If there's some real reason for turning the port power off for an 
> extended period of time, the user can claim the port and turn off the 
> power.  Then later on, the user can release the port and turn the power 
> back on.
> 

Yes, I think this is one of the use cases. We want power power control
at one application (A), but different with our test application(B), it means
if the user claims the port, and power off using A, then the A will end.
After the B finished running, A runs again for power on, but at this time,
the port owner has changed.

-- 

Thanks,
Peter Chen

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

* Re: port power is on again after turning off by user space
  2020-12-21  5:37             ` Peter Chen
@ 2020-12-21 16:25               ` Alan Stern
  2020-12-22  2:02                 ` Peter Chen
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Stern @ 2020-12-21 16:25 UTC (permalink / raw)
  To: Peter Chen; +Cc: Jun Li, linux-usb

On Mon, Dec 21, 2020 at 05:37:29AM +0000, Peter Chen wrote:
> On 20-12-16 10:51:44, Alan Stern wrote:
> > On Wed, Dec 16, 2020 at 02:56:20AM +0000, Peter Chen wrote:
> > > On 20-12-15 10:55:41, Alan Stern wrote:
> > > > You've got the general idea.
> > > > 
> > > > Normally ports are owned by the hub driver.  If one of them loses power 
> > > > for some reason (for example, the user turns it off), the hub driver 
> > > > will turn the power back on.  This is because the hub driver wants 
> > > > ports to be powered at all times unless they are in runtime suspend.
> > > > 
> > > > The way to prevent the hub driver from managing the port power is to 
> > > > claim the port for the user, by issuing the USBDEVFS_CLAIM_PORT ioctl.  
> > > > Also, when that is done, the kernel wno't try to manage a device 
> > > > attached to the port -- that is, the kernel won't automatically install 
> > > > a configuration for a new device and it won't try to probe drivers for 
> > > > the device's interfaces if the user installs a config.
> > > > 
> > > 
> > > Alan, we have several use cases for power switchable HUB, one of the use
> > > cases is USB port is managed by kernel (eg, needs mass storage
> > > class), but needs to toggle port power, is it reasonable we add a sysfs
> > > entry to support it?
> > 
> > Can you give more information about your use cases?  After all, if the 
> > port power is turned off then the port can't possibly handle 
> > mass-storage devices -- or anything else.
> 
> Sorry, Alan. Due to holiday season, the U.S team doesn't reply me the
> use case. I think the basic use cases are emulate the hot-plug test for
> USB devices, the USB devices could be Flash Drive on market or DUT (Device
> Under test) for the same controller works at device mode. Assume one
> typical test case:
> 
> Plug in Flash Drive at port 1-1.1 during the boots up:
> 
> while (1) {
> - Check Flash Drive is there (eg, cat /proc/partitions)
> - Turn port 1 at 1-1 off
> - Check Flash Drive is gone
> - Turn port 1 at 1-1 on
> }

Okay.  This can be done as follows:

while (1) {
- Check Flash Drive is there (eg, cat /proc/partitions)
- Claim port 1 on 1-1
- Turn port 1 at 1-1 off
- Check Flash Drive is gone
- Release port 1 on 1-1
- Turn port 1 at 1-1 on
- Delay for 10 seconds (time for device probing)
}


> > On the other hand, if the port is managed by the kernel then the kernel 
> > (not the user) should be responsible for deciding whether or not to 
> > turn off the port's power.
> > 
> > If there's some real reason for turning the port power off for an 
> > extended period of time, the user can claim the port and turn off the 
> > power.  Then later on, the user can release the port and turn the power 
> > back on.
> > 
> 
> Yes, I think this is one of the use cases. We want power power control
> at one application (A), but different with our test application(B), it means
> if the user claims the port, and power off using A, then the A will end.
> After the B finished running, A runs again for power on, but at this time,
> the port owner has changed.

Yes, that won't work.  If you want to keep the port power turned off 
then you have to keep the usbfs device file open -- which means your 
program A must not end and then restart.

(Acutally, I'm not certain about that.  If you claim a port, turn off 
its power, and then release the port, I don't remember whether the hub 
driver will then turn the power back on right away.  It might not.  
But in any case, it isn't good programming to release a port without 
turning its power back on.)

Can A be rewritten so that it doesn't end when B is running?

ALan Stern

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

* Re: port power is on again after turning off by user space
  2020-12-21 16:25               ` Alan Stern
@ 2020-12-22  2:02                 ` Peter Chen
  2020-12-22  2:35                   ` Alan Stern
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Chen @ 2020-12-22  2:02 UTC (permalink / raw)
  To: Alan Stern; +Cc: Jun Li, linux-usb, Frank Li

On 20-12-21 11:25:51, Alan Stern wrote:
> On Mon, Dec 21, 2020 at 05:37:29AM +0000, Peter Chen wrote:
> > On 20-12-16 10:51:44, Alan Stern wrote:
> > > On Wed, Dec 16, 2020 at 02:56:20AM +0000, Peter Chen wrote:
> > > > On 20-12-15 10:55:41, Alan Stern wrote:
> > > > > You've got the general idea.
> > > > > 
> > > > > Normally ports are owned by the hub driver.  If one of them loses power 
> > > > > for some reason (for example, the user turns it off), the hub driver 
> > > > > will turn the power back on.  This is because the hub driver wants 
> > > > > ports to be powered at all times unless they are in runtime suspend.
> > > > > 
> > > > > The way to prevent the hub driver from managing the port power is to 
> > > > > claim the port for the user, by issuing the USBDEVFS_CLAIM_PORT ioctl.  
> > > > > Also, when that is done, the kernel wno't try to manage a device 
> > > > > attached to the port -- that is, the kernel won't automatically install 
> > > > > a configuration for a new device and it won't try to probe drivers for 
> > > > > the device's interfaces if the user installs a config.
> > > > > 
> > > > 
> > > > Alan, we have several use cases for power switchable HUB, one of the use
> > > > cases is USB port is managed by kernel (eg, needs mass storage
> > > > class), but needs to toggle port power, is it reasonable we add a sysfs
> > > > entry to support it?
> > > 
> > > Can you give more information about your use cases?  After all, if the 
> > > port power is turned off then the port can't possibly handle 
> > > mass-storage devices -- or anything else.
> > 
> > Sorry, Alan. Due to holiday season, the U.S team doesn't reply me the
> > use case. I think the basic use cases are emulate the hot-plug test for
> > USB devices, the USB devices could be Flash Drive on market or DUT (Device
> > Under test) for the same controller works at device mode. Assume one
> > typical test case:
> > 
> > Plug in Flash Drive at port 1-1.1 during the boots up:
> > 
> > while (1) {
> > - Check Flash Drive is there (eg, cat /proc/partitions)
> > - Turn port 1 at 1-1 off
> > - Check Flash Drive is gone
> > - Turn port 1 at 1-1 on
> > }
> 
> Okay.  This can be done as follows:
> 
> while (1) {
> - Check Flash Drive is there (eg, cat /proc/partitions)
> - Claim port 1 on 1-1
> - Turn port 1 at 1-1 off
> - Check Flash Drive is gone
> - Release port 1 on 1-1
> - Turn port 1 at 1-1 on
> - Delay for 10 seconds (time for device probing)
> }
> 
> 
> > > On the other hand, if the port is managed by the kernel then the kernel 
> > > (not the user) should be responsible for deciding whether or not to 
> > > turn off the port's power.
> > > 
> > > If there's some real reason for turning the port power off for an 
> > > extended period of time, the user can claim the port and turn off the 
> > > power.  Then later on, the user can release the port and turn the power 
> > > back on.
> > > 
> > 
> > Yes, I think this is one of the use cases. We want power power control
> > at one application (A), but different with our test application(B), it means
> > if the user claims the port, and power off using A, then the A will end.
> > After the B finished running, A runs again for power on, but at this time,
> > the port owner has changed.
> 
> Yes, that won't work.  If you want to keep the port power turned off 
> then you have to keep the usbfs device file open -- which means your 
> program A must not end and then restart.
> 
> (Acutally, I'm not certain about that.  If you claim a port, turn off 
> its power, and then release the port, I don't remember whether the hub 
> driver will then turn the power back on right away.  It might not.  
> But in any case, it isn't good programming to release a port without 
> turning its power back on.)
> 
> Can A be rewritten so that it doesn't end when B is running?
> 

Of course. I think the similar use case like below:

Program A (Port power control program)

while (1) {
	- Wait "turn off" command;
	- Claim requested port;
	- Turn off requested port;
	- Wait "turn on" command;
	- Turn on requested port
	- Release requested port;
};

Program B actually is a script:

{
while [ "$i" -lt 10000 ];
do
- Check Flash Drive is there (eg, cat /proc/partitions);
- Send "turn off" command;
- Wait 5 seconds, and check if Flash Drive has gone;
- Send "turn on" command;
- i=`expr $i + 1`;
done
terminate program A;
};

I need to find communication solution between program A and script B.
Or would you have any suggestions to design such kinds of test case?

-- 

Thanks,
Peter Chen

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

* Re: port power is on again after turning off by user space
  2020-12-22  2:02                 ` Peter Chen
@ 2020-12-22  2:35                   ` Alan Stern
  0 siblings, 0 replies; 11+ messages in thread
From: Alan Stern @ 2020-12-22  2:35 UTC (permalink / raw)
  To: Peter Chen; +Cc: Jun Li, linux-usb, Frank Li

On Tue, Dec 22, 2020 at 02:02:44AM +0000, Peter Chen wrote:
> On 20-12-21 11:25:51, Alan Stern wrote:
> > Okay.  This can be done as follows:
> > 
> > while (1) {
> > - Check Flash Drive is there (eg, cat /proc/partitions)
> > - Claim port 1 on 1-1
> > - Turn port 1 at 1-1 off
> > - Check Flash Drive is gone
> > - Release port 1 on 1-1
> > - Turn port 1 at 1-1 on
> > - Delay for 10 seconds (time for device probing)
> > }
> > 
> > 
> > > > On the other hand, if the port is managed by the kernel then the kernel 
> > > > (not the user) should be responsible for deciding whether or not to 
> > > > turn off the port's power.
> > > > 
> > > > If there's some real reason for turning the port power off for an 
> > > > extended period of time, the user can claim the port and turn off the 
> > > > power.  Then later on, the user can release the port and turn the power 
> > > > back on.
> > > > 
> > > 
> > > Yes, I think this is one of the use cases. We want power power control
> > > at one application (A), but different with our test application(B), it means
> > > if the user claims the port, and power off using A, then the A will end.
> > > After the B finished running, A runs again for power on, but at this time,
> > > the port owner has changed.
> > 
> > Yes, that won't work.  If you want to keep the port power turned off 
> > then you have to keep the usbfs device file open -- which means your 
> > program A must not end and then restart.
> > 
> > (Acutally, I'm not certain about that.  If you claim a port, turn off 
> > its power, and then release the port, I don't remember whether the hub 
> > driver will then turn the power back on right away.  It might not.  
> > But in any case, it isn't good programming to release a port without 
> > turning its power back on.)
> > 
> > Can A be rewritten so that it doesn't end when B is running?
> > 
> 
> Of course. I think the similar use case like below:
> 
> Program A (Port power control program)
> 
> while (1) {
> 	- Wait "turn off" command;
> 	- Claim requested port;
> 	- Turn off requested port;
> 	- Wait "turn on" command;
> 	- Turn on requested port
> 	- Release requested port;

You have to be a little careful about this.  Let's say you turn on the 
port power.  THen the device will connect and be enumerated.

But if you haven't released the port at this point, the kernel won't 
select a configuration for the device; it will leave the device in the 
unconfigured state.  Perhaps the code in usb_hub_release_port() and 
usb_hub_release_all_ports() needs to be changed; perhaps these routines 
should select and install a configuration if the child device isn't 
already configured.

For the time being, the safest approach is to release the port first 
and then turn on the power.  Of course, that's not ideal either because 
it would mean changing the power setting for a port you don't own.  But 
right now that's the best you can do.

> };
> 
> Program B actually is a script:
> 
> {
> while [ "$i" -lt 10000 ];
> do
> - Check Flash Drive is there (eg, cat /proc/partitions);
> - Send "turn off" command;
> - Wait 5 seconds, and check if Flash Drive has gone;
> - Send "turn on" command;
> - i=`expr $i + 1`;
> done
> terminate program A;
> };
> 
> I need to find communication solution between program A and script B.
> Or would you have any suggestions to design such kinds of test case?

Normally programs like this would communicate by a pipe or a Unix 
socket.  One way to make this work is for program B to run A in the 
background before the "while" loop starts, so that B could control 
the standard input and output files that A uses.  That's probably the 
approach I would take.

Alan Stern

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

end of thread, other threads:[~2020-12-22  2:35 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-15  3:31 port power is on again after turning off by user space Peter Chen
2020-12-15  5:02 ` Jun Li
2020-12-15  5:14   ` Peter Chen
2020-12-15  9:57     ` Peter Chen
2020-12-15 15:55       ` Alan Stern
2020-12-16  2:56         ` Peter Chen
2020-12-16 15:51           ` Alan Stern
2020-12-21  5:37             ` Peter Chen
2020-12-21 16:25               ` Alan Stern
2020-12-22  2:02                 ` Peter Chen
2020-12-22  2:35                   ` Alan Stern

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.