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

Reply via email to