2010-07-22 14:08:04

by Michal Nazarewicz

[permalink] [raw]
Subject: [PATCH] USB: core: Choose configuration with lowest bConfigurationValue

This patch removes code from usb_choose_configuration()
responsible for ignoring the first USB device configuration if
its first interface is RNDIS. Instead,
usb_choose_configuration() chooses configuration with lowest
bConfigurationValue. Linux' Ethernet gadget uses a lower
bConfigurationValue for the second configuration which is
a CDC configuration so this code should choose configuration
that suits Linux better.

Signed-off-by: Michal Nazarewicz <[email protected]>
---
Just what I had in mind if anyone interested... Not that I have any
strong opinion about it. Also, not tested.

drivers/usb/core/generic.c | 47 +++++++++++++++++++++----------------------
1 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 9a34ccb..5b411af 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -46,6 +46,7 @@ int usb_choose_configuration(struct usb_device *udev)
int num_configs;
int insufficient_power = 0;
struct usb_host_config *c, *best;
+ int best_is_not_class = 1;

best = NULL;
c = udev->config;
@@ -102,33 +103,31 @@ int usb_choose_configuration(struct usb_device *udev)
continue;
}

- /* When the first config's first interface is one of Microsoft's
- * pet nonstandard Ethernet-over-USB protocols, ignore it unless
- * this kernel has enabled the necessary host side driver.
- */
- if (i == 0 && desc && (is_rndis(desc) || is_activesync(desc))) {
-#if !defined(CONFIG_USB_NET_RNDIS_HOST) && !defined(CONFIG_USB_NET_RNDIS_HOST_MODULE)
+ /* From the remaining configs, choose one whose first
+ * interface is for a non-vendor-specific class and
+ * has lowest bConfigurationValue. Reason for the
+ * former: Linux is more likely to have a class driver
+ * than a vendor-specific driver. Reason for the
+ * latter: Ethernet gadget use lower
+ * bConfigurationValue for configuration with CDC ECM
+ * which is preferred by Linux even though it's second
+ * configuration. */
+ if (udev->descriptor.bDeviceClass !=
+ USB_CLASS_VENDOR_SPEC &&
+ (desc && desc->bInterfaceClass !=
+ USB_CLASS_VENDOR_SPEC)) {
+ if (best_is_not_class ||
+ c->desc.bConfigurationValue <
+ best->desc.bConfigurationValue) {
+ best_is_not_class = 0;
+ best = c;
+ }
continue;
-#else
- best = c;
-#endif
- }
-
- /* From the remaining configs, choose the first one whose
- * first interface is for a non-vendor-specific class.
- * Reason: Linux is more likely to have a class driver
- * than a vendor-specific driver. */
- else if (udev->descriptor.bDeviceClass !=
- USB_CLASS_VENDOR_SPEC &&
- (desc && desc->bInterfaceClass !=
- USB_CLASS_VENDOR_SPEC)) {
- best = c;
- break;
}

/* If all the remaining configs are vendor-specific,
* choose the first one. */
- else if (!best)
+ if (!best)
best = c;
}

--
1.7.1


2010-07-22 14:22:41

by Alan Stern

[permalink] [raw]
Subject: Re: [PATCH] USB: core: Choose configuration with lowest bConfigurationValue

On Thu, 22 Jul 2010, Michal Nazarewicz wrote:

> This patch removes code from usb_choose_configuration()
> responsible for ignoring the first USB device configuration if
> its first interface is RNDIS. Instead,
> usb_choose_configuration() chooses configuration with lowest
> bConfigurationValue. Linux' Ethernet gadget uses a lower
> bConfigurationValue for the second configuration which is
> a CDC configuration so this code should choose configuration
> that suits Linux better.

I don't like this idea. Choosing configs is a sensitive topic, since
it is highly visible to users. It should be changed minimally, if at
all.

Alan Stern

2010-07-22 14:26:42

by Michal Nazarewicz

[permalink] [raw]
Subject: Re: [PATCH] USB: core: Choose configuration with lowest bConfigurationValue

> On Thu, 22 Jul 2010, Michal Nazarewicz wrote:
>> This patch removes code from usb_choose_configuration()
>> responsible for ignoring the first USB device configuration if
>> its first interface is RNDIS. Instead,
>> usb_choose_configuration() chooses configuration with lowest
>> bConfigurationValue. Linux' Ethernet gadget uses a lower
>> bConfigurationValue for the second configuration which is
>> a CDC configuration so this code should choose configuration
>> that suits Linux better.

On Thu, 22 Jul 2010 16:22:37 +0200, Alan Stern <[email protected]> wrote:
> I don't like this idea. Choosing configs is a sensitive topic, since
> it is highly visible to users. It should be changed minimally, if at
> all.

Fine by me. I've just posted it to show what I had in mind.

--
Best regards, _ _
| Humble Liege of Serenely Enlightened Majesty of o' \,=./ `o
| Computer Science, MichaƂ "mina86" Nazarewicz (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

2010-07-23 07:58:15

by Oliver Neukum

[permalink] [raw]
Subject: Re: [PATCH] USB: core: Choose configuration with lowest bConfigurationValue

Am Donnerstag, 22. Juli 2010, 16:09:10 schrieb Michal Nazarewicz:
> This patch removes code from usb_choose_configuration()
> responsible for ignoring the first USB device configuration if
> its first interface is RNDIS. Instead,
> usb_choose_configuration() chooses configuration with lowest
> bConfigurationValue. Linux' Ethernet gadget uses a lower
> bConfigurationValue for the second configuration which is
> a CDC configuration so this code should choose configuration
> that suits Linux better.

But what if the other side is not a Linux gadget? We need this code
to not select RNDIS on those devices. I am afraid we can't do this?

Regards
Oliver