Alan Stern wrote:
The idea is that the kernel now keeps track of USB power budgets. When a bus-powered device requires more current than its upstream hub is capable of providing, the kernel will not configure it.
Thanks for the explanation. I wrote a quick patch to make the reasoning visible to users. Any comments?
Index: linux/drivers/usb/core/hub.c =================================================================== --- linux.orig/drivers/usb/core/hub.c +++ linux/drivers/usb/core/hub.c @@ -1171,6 +1171,7 @@ static int choose_configuration(struct u u16 devstatus; int bus_powered; int num_configs; + int insufficient_power = 0; struct usb_host_config *c, *best; /* If this fails, assume the device is bus-powered */ @@ -1218,8 +1219,10 @@ static int choose_configuration(struct u */ /* Rule out configs that draw too much bus current */ - if (c->desc.bMaxPower * 2 > udev->bus_mA) + if (c->desc.bMaxPower * 2 > udev->bus_mA) { + insufficient_power++; continue; + } /* If the first config's first interface is COMM/2/0xff * (MSFT RNDIS), rule it out unless Linux has host-side @@ -1263,6 +1266,10 @@ static int choose_configuration(struct u dev_warn(&udev->dev, "no configuration chosen from %d choice%s\n", num_configs, plural(num_configs)); + if (insufficient_power > 0) + dev_info(&udev->dev, "rejected %d configuration%s " + "due to insufficient available bus power\n", + insufficient_power, plural(insufficient_power)); } return i; }