On Fri, 2007-03-30 at 11:37, Harald Welte wrote:
> On Fri, Mar 30, 2007 at 12:19:30AM +0200, Stefan Schmidt wrote:
> > 
> > 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?
> 
> because the host will use the first configuration that "works".  So if
> you have any low_power config before having all high_power configs, then
> the low_power config will be chosen, unless some software/driver
> specifically selects a different one.

Makes sense. But there is still a problem with the fourth config. As
it is rndis_config_low it only appears if using the Neo on a bus
powered hub under windows.

This should be in mind for the person who tests this under windows and
other OSes.

> The same needs to be done for MacOS X at least, too.  

IIRC Koen already used it under MacOSX with RNDIS.

> I think I'll ask roh to look into this once he starts working for
> OpenMoko next week.

Good

> > 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.
> 
> sure, just merge the two patches.

The attached updated patch needs the highpower patch unapplied. If you
are fine with the changes just remove the highpower patch file and the
entry in series and apply this one.

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-30 15:10:57.000000000 +0200
+++ linux-2.6.20.2/drivers/usb/gadget/ether.c	2007-03-30 15:12:20.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,7 +459,20 @@
 	.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,
 };
 
@@ -473,7 +486,20 @@
 	.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 = &eth_config;
 		function = which_fn (eth);
+	} if ((device_desc.bNumConfigurations == 4 && index == 2) ||
+		(device_desc.bNumConfigurations == 2 && index == 1)) {
+		config = &eth_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
 	}
 

Attachment: signature.asc
Description: Digital signature

Reply via email to