Re: USB power accounting at root hub level

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 25 Jul 2011, Thomas Petazzoni wrote:

> Hello,
> 
> I have an AT91-based platform which contains an OHCI USB root hub with
> two ports. However, due to hardware constraints, only a maximum of
> 700 mA can be consumed from both ports combined. This means that you
> can have one device at 500 mA and another at 200 mA, or two devices at
> 300 mA, but you cannot have two devices at 500 mA. The 700 mA is global
> for the two ports.
> 
> I tried to enforce such a limit by setting the hcd->power_budget field
> in the probe() function of the AT91 OHCI driver (through a nice
> platform_data field, as is done by the pxa27x OHCI driver), but I get
> results that don't make sense to me.
> 
> For testing purposes, if I set the power budget to 75 mA, then the
> first connected device (which requires 100 mA) is rejected, which is
> fine.
> 
> When I raise the power budget to 175 mA, I would expect the system to
> accept one 100 mA device, but not two devices. However, the kernel
> accepts both devices and only notices that :
> 
>  hub 1-0:1.0: 25mA over power budget!
> 
> When I add some debug prints at
> http://lxr.free-electrons.com/source/drivers/usb/core/generic.c#L99,
> what I get is :
> 
>  c->desc.bMaxPower * 2 == 100 mA for both device connections
>  udev->bus_mA == 175 mA for both device connections
> 
> I would have expected udev->bus_mA to be 75 mA for the second device,
> so that the 100 mA configuration gets rejected.

No.  The USB stack doesn't enforce any scheme for dividing up power 
among a hub's children.  All it does is log a warning if the devices 
want more power than the total available.

> However, looking at
> http://lxr.free-electrons.com/source/drivers/usb/core/hub.c#L1147, it
> appears that the hub->mA_per_port field is defined to hdev->bus_mA
> (i.e, the power budget). So it means that when we define a power budget
> of 175 mA, the USB core understands that it is 175 mA per port that is
> available, and not 175 mA globally for all ports of the root hub. I
> suspect this explains the behavior I'm seeing.
> 
> Unfortunately, this contradicts the computation done in
> hub_power_remaining() at
> http://lxr.free-electrons.com/source/drivers/usb/core/hub.c#L3014,
> which rightfully concludes that 25mA is missing. And this also seems to
> make it difficult to define a global root hub power limit.

There's no contradiction.  If 175 mA total are available, then one way
to apportion it is to plug in a single device requiring 175 mA.  In
other words, there really is up to 175 mA available for each port.

> Isn't there a contradiction here ? Shouldn't the hdev->bus_mA be
> understood as a global hub power budget, and not a per-port power
> budget ?

That _is_ how it is interpreted.

It looks like your real problem is in hcd.c line 2467 (in 
usb_add_hcd()):

	rhdev->bus_mA = min(500u, hcd->power_budget);

We probably shouldn't use the min() operation here, just set
rhdev->bus_mA to hcd->power_budget.  However, I'm not sure how the
various host controller drivers set the power_budget field; some of
them may set it to the total power divided by the number of ports
rather than the total power.  If they do, they will have to be fixed
when this change is made.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux