Hello. This patch fixes #260.
The main idea is to provide the same usb device config twice. One with 500mA MaxPower and one with 100mA. This allows charging the battery faster on a powered hub or host and have it also available on bus powered hubs for example debug board v2. Normally g_ether provides one config with cdc_ether only and a second one if RNDIS is enabled. With this patch it provides 2 or 4 configs. In cdc_ether only mode all works fine. On host the high power config is choosen and on debug board the low power config. Enabling RNDIS makes it a bit more tricky. A special order of the configs is needed: rndis_config eth_config eth_config_low rndis_config_low Anybody know offhand why this is needed? With this order I'm able to connect to the Neo1973 directly connected to my host or through the debug board. On the debug board rejecting of the two 500mA configs works fine: usb 2-1.3: rejected 2 configurations due to insufficient available bus power The one remaining problem is that the RNDIS, windows compatible, support is untested. It seems I have to search such a box to test it. :( At the moment this patch applies on top of the current quilt set. I would suggest to remove g_ether-highpower.patch and let this one base on the vanilla g_ether driver once we like to apply this one. If you agree I can take care off it. regards Stefan Schmidt
Index: linux-2.6.20.2/drivers/usb/gadget/ether.c
===================================================================
--- linux-2.6.20.2.orig/drivers/usb/gadget/ether.c 2007-03-29 22:40:21.000000000 +0200
+++ linux-2.6.20.2/drivers/usb/gadget/ether.c 2007-03-30 00:06:24.000000000 +0200
@@ -133,7 +133,7 @@
u16 cdc_filter;
unsigned long todo;
#define WORK_RX_MEMORY 0
- int rndis_config;
+ int rndis_config, rndis_config_low;
u8 host_mac [ETH_ALEN];
};
@@ -416,13 +416,13 @@
*
* NOTE: Controllers like superh_udc should probably be able to use
* an RNDIS-only configuration.
- *
- * FIXME define some higher-powered configurations to make it easier
- * to recharge batteries ...
*/
#define DEV_CONFIG_VALUE 1 /* cdc or subset */
#define DEV_RNDIS_CONFIG_VALUE 2 /* rndis; optional */
+#define DEV_CONFIG_VALUE_LOW 3 /* cdc or subset; low power */
+#define DEV_RNDIS_CONFIG_VALUE_LOW 4 /* rndis; optional; low power */
+
static struct usb_device_descriptor
device_desc = {
@@ -439,7 +439,7 @@
.idProduct = __constant_cpu_to_le16 (CDC_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
- .bNumConfigurations = 1,
+ .bNumConfigurations = 2,
};
static struct usb_otg_descriptor
@@ -459,10 +459,23 @@
.bNumInterfaces = 2,
.bConfigurationValue = DEV_CONFIG_VALUE,
.iConfiguration = STRING_CDC,
- .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+ .bmAttributes = USB_CONFIG_ATT_ONE,
.bMaxPower = 250,
};
+static struct usb_config_descriptor
+eth_config_low = {
+ .bLength = sizeof eth_config_low,
+ .bDescriptorType = USB_DT_CONFIG,
+
+ /* compute wTotalLength on the fly */
+ .bNumInterfaces = 2,
+ .bConfigurationValue = DEV_CONFIG_VALUE_LOW,
+ .iConfiguration = STRING_CDC,
+ .bmAttributes = USB_CONFIG_ATT_ONE,
+ .bMaxPower = 50,
+};
+
#ifdef CONFIG_USB_ETH_RNDIS
static struct usb_config_descriptor
rndis_config = {
@@ -473,9 +486,22 @@
.bNumInterfaces = 2,
.bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
.iConfiguration = STRING_RNDIS,
- .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+ .bmAttributes = USB_CONFIG_ATT_ONE,
.bMaxPower = 250,
};
+
+static struct usb_config_descriptor
+rndis_config_low = {
+ .bLength = sizeof rndis_config_low,
+ .bDescriptorType = USB_DT_CONFIG,
+
+ /* compute wTotalLength on the fly */
+ .bNumInterfaces = 2,
+ .bConfigurationValue = DEV_RNDIS_CONFIG_VALUE_LOW,
+ .iConfiguration = STRING_RNDIS,
+ .bmAttributes = USB_CONFIG_ATT_ONE,
+ .bMaxPower = 50,
+};
#endif
/*
@@ -800,7 +826,7 @@
.bcdUSB = __constant_cpu_to_le16 (0x0200),
.bDeviceClass = USB_CLASS_COMM,
- .bNumConfigurations = 1,
+ .bNumConfigurations = 2,
};
static const struct usb_descriptor_header *hs_eth_function [11] = {
@@ -935,14 +961,23 @@
/* list the RNDIS config first, to make Microsoft's drivers
* happy. DOCSIS 1.0 needs this too.
*/
- if (device_desc.bNumConfigurations == 2 && index == 0) {
+ if (device_desc.bNumConfigurations == 4 && index == 0) {
config = &rndis_config;
function = which_fn (rndis);
- } else
+ } if (device_desc.bNumConfigurations == 4 && index == 3) {
+ config = &rndis_config_low;
+ function = which_fn (rndis);
+ }
#endif
- {
+ /* Index of the cdc_ether configs is important */
+ if ((device_desc.bNumConfigurations == 4 && index == 1) ||
+ (device_desc.bNumConfigurations == 2 && index == 0)) {
config = ð_config;
function = which_fn (eth);
+ } if ((device_desc.bNumConfigurations == 4 && index == 2) ||
+ (device_desc.bNumConfigurations == 2 && index == 1)) {
+ config = ð_config_low;
+ function = which_fn (eth);
}
/* for now, don't advertise srp-only devices */
@@ -1120,10 +1155,12 @@
switch (number) {
case DEV_CONFIG_VALUE:
+ case DEV_CONFIG_VALUE_LOW:
result = set_ether_config (dev, gfp_flags);
break;
#ifdef CONFIG_USB_ETH_RNDIS
case DEV_RNDIS_CONFIG_VALUE:
+ case DEV_RNDIS_CONFIG_VALUE_LOW:
dev->rndis = 1;
result = set_ether_config (dev, gfp_flags);
break;
@@ -2151,6 +2188,7 @@
DEBUG (dev, "unbind\n");
rndis_deregister (dev->rndis_config);
+ rndis_deregister (dev->rndis_config_low);
rndis_exit ();
/* we've already been disconnected ... no i/o is active */
@@ -2349,6 +2387,8 @@
if (!cdc) {
eth_config.bNumInterfaces = 1;
eth_config.iConfiguration = STRING_SUBSET;
+ eth_config_low.bNumInterfaces = 1;
+ eth_config_low.iConfiguration = STRING_SUBSET;
fs_subset_descriptors();
hs_subset_descriptors();
}
@@ -2356,13 +2396,13 @@
device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
usb_gadget_set_selfpowered (gadget);
- /* For now RNDIS is always a second config */
+ /* For now RNDIS is always a second set of configs */
if (rndis)
- device_desc.bNumConfigurations = 2;
+ device_desc.bNumConfigurations = 4;
#ifdef CONFIG_USB_GADGET_DUALSPEED
if (rndis)
- dev_qualifier.bNumConfigurations = 2;
+ dev_qualifier.bNumConfigurations = 4;
else if (!cdc)
dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC;
@@ -2383,9 +2423,13 @@
otg_descriptor.bmAttributes |= USB_OTG_HNP,
eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
eth_config.bMaxPower = 4;
+ eth_config_low.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ eth_config_low.bMaxPower = 4;
#ifdef CONFIG_USB_ETH_RNDIS
rndis_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
rndis_config.bMaxPower = 4;
+ rndis_config_low.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ rndis_config_low.bMaxPower = 4;
#endif
}
signature.asc
Description: Digital signature
