public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* USB gadget with drivers "on board"
@ 2010-04-26  8:29 Michał Nazarewicz
  2010-04-26 14:16 ` Daniel Mack
  0 siblings, 1 reply; 13+ messages in thread
From: Michał Nazarewicz @ 2010-04-26  8:29 UTC (permalink / raw)
  To: Marek Szyprowski

Hello everyone,

I need to create an USB gadget with drivers for Windows included
"on board".  In particular, when the gadget is connected to Windows
host it is detected as mass storage and mounted drive include the
drivers.  However, when the drivers are installed, it is detected
as some other device.

Now, it seems that a simple composite device with two configurations
is enough -- the first containing mass storage and the second other
functions.  My tests show that Windows manages to set the first
configuration and detect the mass storage interface.

Unfortunately, Linux does the same thing -- chooses the first
configuration and detects the mass storage interface.  What I'd
like to see is Linux choosing the second configuration which is
more functional.

Is there any way to accomplish that?

I came up with an idea of swapping bConfigurationValues (so that mass
storage configuration has it set to 2 and the other configuration
has it set to 1) but still retaining the order those are given to
host (a bit like with g_ether).

This however did not work, as Linux pretty much ignores those values
when choosing configuration.

So can it be done differently?

I think the following change would achieve the result I am seeking:

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index bdf87a8..38fd44e 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -121,21 +121,22 @@ int usb_choose_configuration(struct usb_device *udev)
                   		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)
+		else if (!best || best->desc.bConfigurationValue > c->desc.bConfigurationValue)
                   			best = c;
                   	}

                   	if (insufficient_power > 0)
                   		dev_info(&udev->dev, "rejected %d configuration%s "
                   			"due to insufficient available bus power\n",
                   			insufficient_power, plural(insufficient_power));

                   	if (best) {
                   		i = best->desc.bConfigurationValue;

Or maybe it'd be a good idea to prefer configurations with bigger
number of interfaces?

So what do you think? Does anyone know a (better) solution?

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2010-04-28 15:59 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-26  8:29 USB gadget with drivers "on board" Michał Nazarewicz
2010-04-26 14:16 ` Daniel Mack
2010-04-26 14:42   ` Michał Nazarewicz
2010-04-26 14:57     ` Daniel Mack
2010-04-26 15:45       ` Michał Nazarewicz
2010-04-26 17:37         ` Josua Dietze
2010-04-26 19:34           ` Alan Stern
2010-04-26 20:14             ` Josua Dietze
2010-04-28  8:46               ` Michał Nazarewicz
2010-04-28 11:31                 ` Michał Nazarewicz
2010-04-28 11:41                 ` Josua Dietze
2010-04-28 11:54                   ` Michał Nazarewicz
2010-04-28 15:59                 ` Alan Stern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox