mvp / uhubctl

uhubctl - USB hub per-port power control
Other
2.18k stars 227 forks source link

Notable projects using uhubctl... #138

Closed OutsourcedGuru closed 5 years ago

OutsourcedGuru commented 5 years ago

Just adding my own new OctoPrint-USBControl plugin now uses your executable.

mvp commented 5 years ago

Added in https://github.com/mvp/uhubctl/commit/f2a50dd4cb42f065c3113ac627ffc91b2b16cc15. Few tips:

  1. uhubctl does not require sudo access if you setup your udev rules properly.
  2. You cannot control all ports 2-5 on RPi separately, only controlling port 2 will turn off/on all 2-5. So there is no point to expose all 2-5 in your UI.

Regarding udev rules, I think this should be enough to add /etc/udev/rules.d/52-usb.rules:

SUBSYSTEM=="usb", ATTR{idVendor}=="0424", MODE="0666"
OutsourcedGuru commented 5 years ago

So... is USB Port 2 some sort of aggregate entity meaning (all four Type-A ports)?

If I plug a printer controller board into the Raspi3B and run sudo uhubctl it often shows me that the controller board is on USB Port 2. How would this then be toggled without affecting anything else plugged in?

Is this in your documentation somewhere because I must have missed this somehow?

"Raspberry Pi | Model B+, 2 B, 3 B (port 2 only) | 4 | 2.0 |   | 2011"

I take it that this means... there's some limitation of the 3B in which all four ports are (supposed to be) toggled at once? Having exercised this plugin I've written, I iteratively check with uhubctl and it seems to toggle each one uniquely.

mvp commented 5 years ago

Check this issue https://github.com/mvp/uhubctl/issues/119. Basically, this is quirk of Raspberry PI internal hardware design. USB port 1 is wired to control power on network (wifi+Ethernet), and USB port 2 is wired to control power on all remaining USB ports - 2,3,4,5. While uhubctl can show and change state for all ports, trying to control ports 3,4,5 separately won't do anything, unfortunately - this is Raspberry Pi hardware issue.

mvp commented 5 years ago

Note that this is slightly more complicated for RPi 3B+, which has 2 daisy-chained internal hubs (older models have only one 5-port hub). You will need to specify hub location and port properly for this to work.

OutsourcedGuru commented 5 years ago

That's a shame.

So to make this really useful on a 2B/3B is to add an external smart hub and refer to the bus/port. Thanks.

mvp commented 5 years ago

I checked your project page - good job! However, I didn't find any mention, acknowledgement or even a link to uhubctl anywhere. Do you mind adding some acknowledgement in README that your project is relying on uhubctl to work? Thanks!

OutsourcedGuru commented 5 years ago

My bad (I'm sure I was just trying to get the thing running). :laugh:

If you want to, give me a blurb that you'd like me to include in the README and the Settings page.

Oh... and I bought a Raspberry 3A+ and 3B+ for testing/support and was able to get something going for the latter.

mvp commented 5 years ago

I guess just put something like:

As for Raspberry Pi 3B+, I have never tried it myself and nobody reported how it works exactly. I wonder what is exact USB topology and whether it supports selective (per-port) power switching better than older Raspberry Pi models? If you can explore that on your 3B+, that would be great. Thanks!

OutsourcedGuru commented 5 years ago

Been there, done that. It's got a weird split hub. It presents 1-1.1 and 1-1. Toggling 1-1 Port 2 turns ON/OFF power to everything similar to the 3B. 1-1.1 only has three ports (networking and 2, 3 which may be individually toggled).

mvp commented 5 years ago

Hmm, interesting. Can you please post output from running uhubctl without options? 1-1 is root hub, 1-1.1 is daisy chained to 1-1, presumably via one of its ports (probably port 2 you mentioned).

Normally, you are not supposed to change power state for daisy-chaining port on any hub, as it may lead to undefined behavior: it technically detaches all slave hubs.

OutsourcedGuru commented 5 years ago

sudo uhubctl from 3B:

Current status for hub 1-1 [0424:9514, USB 2.00, 5 ports]
  Port 1: 0503 power highspeed enable connect [0424:ec00]
  Port 2: 0100 power
  Port 3: 0100 power
  Port 4: 0100 power
  Port 5: 0100 power

sudo uhubctl from 3B+:

Current status for hub 1-1.1 [0424:2514, USB 2.00, 3 ports]
  Port 1: 0503 power highspeed enable connect [0424:7800]
  Port 2: 0100 power
  Port 3: 0100 power
Current status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 1: 0503 power highspeed enable connect [0424:2514, USB 2.00, 3 ports]
  Port 2: 0100 power
  Port 3: 0100 power
  Port 4: 0100 power

sudo lsusb -t from 3B+:

/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 3, If 0, Class=Hub, Driver=hub/3p, 480M
            |__ Port 1: Dev 4, If 0, Class=Vendor Specific Class, Driver=lan78xx, 480M

sudo lsusb -vvv from 3B+:


Bus 001 Device 004: ID 0424:7800 Standard Microsystems Corp. 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.10
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass         0 
  bDeviceProtocol       255 
  bMaxPacketSize0        64
  idVendor           0x0424 Standard Microsystems Corp.
  idProduct          0x7800 
  bcdDevice            3.00
  iManufacturer           0 
  iProduct                0 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           39
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                2mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0 
      bInterfaceProtocol    255 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval               4
Binary Object Store Descriptor:
  bLength                 5
  bDescriptorType        15
  wTotalLength           22
  bNumDeviceCaps          2
  USB 2.0 Extension Device Capability:
    bLength                 7
    bDescriptorType        16
    bDevCapabilityType      2
    bmAttributes   0x00000006
      Link Power Management (LPM) Supported
  SuperSpeed USB Device Capability:
    bLength                10
    bDescriptorType        16
    bDevCapabilityType      3
    bmAttributes         0x00
    wSpeedsSupported   0x000e
      Device can operate at Full Speed (12Mbps)
      Device can operate at High Speed (480Mbps)
      Device can operate at SuperSpeed (5Gbps)
    bFunctionalitySupport   1
      Lowest fully-functional device speed is Full Speed (12Mbps)
    bU1DevExitLat          10 micro seconds
    bU2DevExitLat        1500 micro seconds
Device Status:     0x0001
  Self Powered

Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         2 TT per port
  bMaxPacketSize0        64
  idVendor           0x0424 Standard Microsystems Corp.
  idProduct          0x2514 USB 2.0 Hub
  bcdDevice            b.b3
  iManufacturer           0 
  iProduct                0 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                2mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      1 Single TT
      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     0x0001  1x 1 bytes
        bInterval              12
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      2 TT per port
      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     0x0001  1x 1 bytes
        bInterval              12
Hub Descriptor:
  bLength               9
  bDescriptorType      41
  nNbrPorts             3
  wHubCharacteristic 0x000d
    Per-port power switching
    Compound device
    Per-port overcurrent protection
    TT think time 8 FS bits
  bPwrOn2PwrGood       50 * 2 milli seconds
  bHubContrCurrent      1 milli Ampere
  DeviceRemovable    0x02
  PortPwrCtrlMask    0xff
 Hub Port Status:
   Port 1: 0000.0503 highspeed power enable connect
   Port 2: 0000.0100 power
   Port 3: 0000.0100 power
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0001
  Self Powered

Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         2 TT per port
  bMaxPacketSize0        64
  idVendor           0x0424 Standard Microsystems Corp.
  idProduct          0x2514 USB 2.0 Hub
  bcdDevice            b.b3
  iManufacturer           0 
  iProduct                0 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                2mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      1 Single TT
      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     0x0001  1x 1 bytes
        bInterval              12
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      2 TT per port
      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     0x0001  1x 1 bytes
        bInterval              12
Hub Descriptor:
  bLength               9
  bDescriptorType      41
  nNbrPorts             4
  wHubCharacteristic 0x000d
    Per-port power switching
    Compound device
    Per-port overcurrent protection
    TT think time 8 FS bits
  bPwrOn2PwrGood       50 * 2 milli seconds
  bHubContrCurrent      1 milli Ampere
  DeviceRemovable    0x02
  PortPwrCtrlMask    0xff
 Hub Port Status:
   Port 1: 0000.0503 highspeed power enable connect
   Port 2: 0000.0100 power
   Port 3: 0000.0100 power
   Port 4: 0000.0100 power
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0001
  Self Powered

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0 Unused
  bDeviceProtocol         1 Single TT
  bMaxPacketSize0        64
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0002 2.0 root hub
  bcdDevice            4.14
  iManufacturer           3 Linux 4.14.79-v7+ dwc_otg_hcd
  iProduct                2 DWC OTG Controller
  iSerial                 1 3f980000.usb
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           25
    bNumInterfaces          1
    bConfigurationValue     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     0x0004  1x 4 bytes
        bInterval              12
Hub Descriptor:
  bLength               9
  bDescriptorType      41
  nNbrPorts             1
  wHubCharacteristic 0x0008
    Ganged power switching
    Per-port overcurrent protection
    TT think time 8 FS bits
  bPwrOn2PwrGood        1 * 2 milli seconds
  bHubContrCurrent      0 milli Ampere
  DeviceRemovable    0x00
  PortPwrCtrlMask    0xff
 Hub Port Status:
   Port 1: 0000.0503 highspeed power enable connect
Device Status:     0x0001
  Self Powered
mvp commented 5 years ago

Thanks for the update.

Now I understand RPi USB topology as follows:

2B or 3B: have one USB hub 1-1, with port 1: Ethernet+wifi, and ports 2-5 ganged, controlled by port 2.

3B+: have 2 hubs - main is 1-1, all 4 ports power is controlled by port 2. Slave hub 1-1.1 is daisy-chained to port 1 of 1-1, and if 1-1 is turned off, it kills all ports of 1-1.1 as well. Looking at 1-1.1, all 3 ports seem to be truly independent (as it should be on compliant hubs), and Ethernet+wifi is permanently wired to port 1 of this hub.

SlySven commented 5 years ago

2B or 3B: have one USB hub 1-1, with port 1: Ethernet+wifi, and ports 2-5 ganged, controlled by port 2.

No WiFi on the 2B BTW...

OutsourcedGuru commented 5 years ago

I think you've got it.

The 3A+ was a disappointment. There's a single Type A that your uhubctl won't touch with a ten-foot pole.

mvp commented 5 years ago

Regarding RPi 3B+, I still don't quite understand how these ports are wired externally. Looking at specs, it has 4 USB 2.0 ports, but we see that internally 2+3=5 ports are available. It means 1 port is not wired at all? That also probably means that out of 4 USB ports available externally, 2 are "proper" (wired to slave hub, support PPPS as expected), and 2 are not (wired to root hub). It would be interesting to find actual mapping.

OutsourcedGuru commented 5 years ago

:laugh: Your guess is as good as mine.

And yet, it behaves like that 1-1.1 hub controls 1) networking devices, 2) the first smart USB device plugged in and 3) the second smart USB device plugged in. Of course, if they're both plugged in at startup it's probably prioritized by idProduct or similar. Toggling 1-1.1 #2 only toggles a single physical USB connection (not everything). Toggling 1-1 #2 toggles everything but networking devices.

You need to high-five me because I just hacked their site and found the Easter Egg you're looking for:

https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/rpi_SCH_3bplus_1p0_reduced.pdf

Okay, granted... it wasn't a hard filenaming standard to decypher. Hopefully that might help you. But of course the hubs are likely on that big Broadcom chip.

mvp commented 5 years ago

Thanks, but unfortunately, that schematic doesn't even have word USB anywhere :(

Note that USB ports are not dynamically allocated: each external physical port is fixed to certain port number from uhubctl output. You can find exact mapping by plugging in some unique device into all external ports one by one (e.g. USB stick) and checking uhubctl output where it appears connected.