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;
}