All of lore.kernel.org
 help / color / mirror / Atom feed
* USB driver assignment with udev
@ 2009-03-11 23:20 Steve Calfee
  2009-03-11 23:37 ` Greg KH
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Steve Calfee @ 2009-03-11 23:20 UTC (permalink / raw)
  To: linux-hotplug

I am trying to understand how a USB driver gets assigned to a device.

Overview:

I have heard that the Apple OSX usb system does a probe and the probe
routine returns a "score", which is its rating of how close a match a
driver is to a device. This then lets the probing system decide which
driver is the best match and after all probing starts the binding of a
driver to a device.

Windows seems to assume that there is usually a specific driver for each
device, so it looks for a match in its registry for device allocation. It
only has storage and hid as class drivers which get devices if no special
driver is defined.

Linux assumes the opposite from windows, that there is a generic driver for
most devices. The first driver that matches a device grabs it.

Question:

It seems that a udev rule does a modprobe for a driver to handle a device.
In most cases the module is already in-kernel and this step does nothing.

The module/driver probe routine is called by the kernel, only if there is a
match in its registered usb_device_id table. If more than one driver
matches, the first one installed gets called first. In 2.6.16, if the probe
"failed" (returned non-zero), no more modules were probed. I think this is
broken, and I am now trying 2.6.28, maybe it does the right thing and
continues looking for a driver that wants a device.

I have a different situation, but a classic issue is if a user wants to
have ub handle one device and usb-storage handle others. How can this be
done? udev loads the driver, but the driver itself grabs the devices. The
first module loaded will hog all the devices. USBIP will also sooner or
later hit this problem, some devices might need to be local and some placed
remotely.  Presumably separate drivers will be needed.

So right now, a Linux USB driver will in-kernel determine if it wants to
bind to a particular device. This is weakly controlled by userspace by the
order of module registering (usually by order of insmod). But there is no
way for userspace to determine a mapping between devices and drivers. Is
there a udev solution for this?

Regards, Steve


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

* Re: USB driver assignment with udev
  2009-03-11 23:20 USB driver assignment with udev Steve Calfee
@ 2009-03-11 23:37 ` Greg KH
  2009-03-12  0:32 ` Steve Calfee
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2009-03-11 23:37 UTC (permalink / raw)
  To: linux-hotplug

On Wed, Mar 11, 2009 at 11:20:53PM +0000, Steve Calfee wrote:
> I am trying to understand how a USB driver gets assigned to a device.

Have you read the documentation on how this happens in the book, Linux
Device Drivers, third edition, which is free online?

> It seems that a udev rule does a modprobe for a driver to handle a device.
> In most cases the module is already in-kernel and this step does nothing.

Not really true, lots of times the module is not present.

> The module/driver probe routine is called by the kernel, only if there is a
> match in its registered usb_device_id table. If more than one driver
> matches, the first one installed gets called first. In 2.6.16, if the probe
> "failed" (returned non-zero), no more modules were probed. I think this is
> broken, and I am now trying 2.6.28, maybe it does the right thing and
> continues looking for a driver that wants a device.
> 
> I have a different situation, but a classic issue is if a user wants to
> have ub handle one device and usb-storage handle others. How can this be
> done? udev loads the driver, but the driver itself grabs the devices. The
> first module loaded will hog all the devices. USBIP will also sooner or
> later hit this problem, some devices might need to be local and some placed
> remotely.  Presumably separate drivers will be needed.

See the libusual code for how this is handled.

> So right now, a Linux USB driver will in-kernel determine if it wants to
> bind to a particular device. This is weakly controlled by userspace by the
> order of module registering (usually by order of insmod). But there is no
> way for userspace to determine a mapping between devices and drivers. Is
> there a udev solution for this?

Not really, but I fail to see the problem that you are trying to solve
here.

What exactly are you trying to do?

thanks,

greg k-h

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

* Re: USB driver assignment with udev
  2009-03-11 23:20 USB driver assignment with udev Steve Calfee
  2009-03-11 23:37 ` Greg KH
@ 2009-03-12  0:32 ` Steve Calfee
  2009-03-12  0:35 ` Kay Sievers
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Steve Calfee @ 2009-03-12  0:32 UTC (permalink / raw)
  To: linux-hotplug

Hi Greg, thanks for the quick response.

Greg KH <greg <at> kroah.com> writes:
> 
> On Wed, Mar 11, 2009 at 11:20:53PM +0000, Steve Calfee wrote:
> > I am trying to understand how a USB driver gets assigned to a device.
> 
> Have you read the documentation on how this happens in the book, Linux
> Device Drivers, third edition, which is free online?

Yes, excellent book.

> > It seems that a udev rule does a modprobe for a driver to handle a device.
> > In most cases the module is already in-kernel and this step does nothing.
> 
> Not really true, lots of times the module is not present.
> 
> > The module/driver probe routine is called by the kernel, only if there is a
> > match in its registered usb_device_id table. If more than one driver
> > matches, the first one installed gets called first. In 2.6.16, if the probe
> > "failed" (returned non-zero), no more modules were probed. I think this is
> > broken, and I am now trying 2.6.28, maybe it does the right thing and
> > continues looking for a driver that wants a device.
> > 
> > I have a different situation, but a classic issue is if a user wants to
> > have ub handle one device and usb-storage handle others. How can this be
> > done? udev loads the driver, but the driver itself grabs the devices. The
> > first module loaded will hog all the devices. USBIP will also sooner or
> > later hit this problem, some devices might need to be local and some placed
> > remotely.  Presumably separate drivers will be needed.
> 
> See the libusual code for how this is handled.

Excellent example of what I would like to do from udev.

I understand that the kernel needs to be able to do some of this for early boot
situations where maybe userspace is not up yet. However, doing the policy
decisions of mapping drivers to devices at module build time is difficult. That
is why libusual allows module parameters to be changed at run time. However,
that is a one driver solution to a generic problem. Udev would seem to be the
proper mechanism to map drivers to devices dynamically and under control of user
space.

> 
> > So right now, a Linux USB driver will in-kernel determine if it wants to
> > bind to a particular device. This is weakly controlled by userspace by the
> > order of module registering (usually by order of insmod). But there is no
> > way for userspace to determine a mapping between devices and drivers. Is
> > there a udev solution for this?
> 
> Not really, but I fail to see the problem that you are trying to solve
> here.
> 
> What exactly are you trying to do?
> 

OK, I understand. I cannot control exactly and dynamically the mapping of
drivers to devices. The mechanism does not exist.

I am trying to figure out how to do USB/IP. The problem is some devices should
be local to the client computer and some should be virtualized to the host
computer via TCP/IP. This means removing local drivers and adding a virtual
driver (and the opposite) dynamically under user control.

There is a module parameter new_id where devices can be assigned to a module,
but no "reject_id" parameter where a reserved device can be excluded from the
probe checking. And the problem with the parameters is there is no way to remove
one once set. 

Regards, Steve


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

* Re: USB driver assignment with udev
  2009-03-11 23:20 USB driver assignment with udev Steve Calfee
  2009-03-11 23:37 ` Greg KH
  2009-03-12  0:32 ` Steve Calfee
@ 2009-03-12  0:35 ` Kay Sievers
  2009-03-12  2:01 ` Greg KH
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kay Sievers @ 2009-03-12  0:35 UTC (permalink / raw)
  To: linux-hotplug

On Thu, Mar 12, 2009 at 00:37, Greg KH <greg@kroah.com> wrote:
> On Wed, Mar 11, 2009 at 11:20:53PM +0000, Steve Calfee wrote:
> Have you read the documentation on how this happens in the book, Linux
> Device Drivers, third edition, which is free online?
>
>> It seems that a udev rule does a modprobe for a driver to handle a device.
>> In most cases the module is already in-kernel and this step does nothing.
>
> Not really true, lots of times the module is not present.

And udev does call modprobe only for devices which are not bound to a
driver, so some of the modprobes end up doing nothing, yes, and
modprobe calls are very cheap these days, we just resolve with a
binary index a modalias string to a module name, and look if
/sys/$module exists, and exit if it's already there.

>> The module/driver probe routine is called by the kernel, only if there is a
>> match in its registered usb_device_id table. If more than one driver
>> matches, the first one installed gets called first. In 2.6.16, if the probe
>> "failed" (returned non-zero), no more modules were probed. I think this is
>> broken, and I am now trying 2.6.28, maybe it does the right thing and
>> continues looking for a driver that wants a device.
>>
>> I have a different situation, but a classic issue is if a user wants to
>> have ub handle one device and usb-storage handle others. How can this be
>> done? udev loads the driver, but the driver itself grabs the devices. The
>> first module loaded will hog all the devices. USBIP will also sooner or
>> later hit this problem, some devices might need to be local and some placed
>> remotely.  Presumably separate drivers will be needed.
>
> See the libusual code for how this is handled.
>
>> So right now, a Linux USB driver will in-kernel determine if it wants to
>> bind to a particular device. This is weakly controlled by userspace by the
>> order of module registering (usually by order of insmod). But there is no
>> way for userspace to determine a mapping between devices and drivers. Is
>> there a udev solution for this?
>
> Not really, but I fail to see the problem that you are trying to solve
> here.

None of the solutions are provided by default, but can be made working
today, with a bit of hacking.

You can use udev rules to unbind a driver, and rebind a different one
to a specific device.

Or you can disable kernel-driver-autobinding per bus, and let udev do
all the driver binding for this bus. A default rule would trigger the
in-kernel driver binding, and any custom rule added before that, could
bind a specific driver to a specific device. What's not covered with
disabled in-kernel driver binding is the device scanning at the time
of loading of a module, which would need to be implemented.

Both setups should work. We did not see a lot of interest in offering
any solution like that. We added:
/sys/bus/*/{drivers_autoprobe,drivers_probe} long ago, because we
thought it might be useful, but it's never got really used so far, and
the missing pieces never got added to the kernel and udev.

Kay

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

* Re: USB driver assignment with udev
  2009-03-11 23:20 USB driver assignment with udev Steve Calfee
                   ` (2 preceding siblings ...)
  2009-03-12  0:35 ` Kay Sievers
@ 2009-03-12  2:01 ` Greg KH
  2009-03-12 10:21 ` Scott James Remnant
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2009-03-12  2:01 UTC (permalink / raw)
  To: linux-hotplug

On Thu, Mar 12, 2009 at 12:32:02AM +0000, Steve Calfee wrote:
> I am trying to figure out how to do USB/IP.

You do realize this is already working for Linux with the code in the
main kernel tree?  Are you wanting to reimplement it, or does the
current solution somehow not work properly for you?

> The problem is some devices should be local to the client computer and
> some should be virtualized to the host computer via TCP/IP. This means
> removing local drivers and adding a virtual driver (and the opposite)
> dynamically under user control.

No, use a virtual USB host controller instead, like the current code
does.  Otherwise you would have to rewrite all usb drivers, which you
really don't want to do.

Please don't reinvent the wheel again :)

thanks,

greg k-h

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

* Re: USB driver assignment with udev
  2009-03-11 23:20 USB driver assignment with udev Steve Calfee
                   ` (3 preceding siblings ...)
  2009-03-12  2:01 ` Greg KH
@ 2009-03-12 10:21 ` Scott James Remnant
  2009-03-12 23:01 ` Steve Calfee
  2009-03-12 23:59 ` Kay Sievers
  6 siblings, 0 replies; 8+ messages in thread
From: Scott James Remnant @ 2009-03-12 10:21 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 1056 bytes --]

On Wed, 2009-03-11 at 23:20 +0000, Steve Calfee wrote:

> I have a different situation, but a classic issue is if a user wants to
> have ub handle one device and usb-storage handle others. How can this be
> done? udev loads the driver, but the driver itself grabs the devices. The
> first module loaded will hog all the devices. USBIP will also sooner or
> later hit this problem, some devices might need to be local and some placed
> remotely.  Presumably separate drivers will be needed.
> 
That's simple.

ub includes an alias for the specific device (ie. by vendor/device id as
well as class).

usb-storage includes the generic classful alias.

ub appears before usb-storage in the kernel link order, and thus appears
first in /lib/modules/$(uname -r)/modules.order

So the kernel will try that module first if it's a built-in, and
modprobe will try load module first if not.


If you want to do more complicated runtime decisions, you can use the
bind/unbind interface.

Scott
-- 
Scott James Remnant
scott@canonical.com

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

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

* Re: USB driver assignment with udev
  2009-03-11 23:20 USB driver assignment with udev Steve Calfee
                   ` (4 preceding siblings ...)
  2009-03-12 10:21 ` Scott James Remnant
@ 2009-03-12 23:01 ` Steve Calfee
  2009-03-12 23:59 ` Kay Sievers
  6 siblings, 0 replies; 8+ messages in thread
From: Steve Calfee @ 2009-03-12 23:01 UTC (permalink / raw)
  To: linux-hotplug

Kay Sievers <kay.sievers <at> vrfy.org> writes:
> You can use udev rules to unbind a driver, and rebind a different one
> to a specific device.
> 
> Or you can disable kernel-driver-autobinding per bus, and let udev do
> all the driver binding for this bus. A default rule would trigger the
> in-kernel driver binding, and any custom rule added before that, could
> bind a specific driver to a specific device. What's not covered with
> disabled in-kernel driver binding is the device scanning at the time
> of loading of a module, which would need to be implemented.
> 
> Both setups should work. We did not see a lot of interest in offering
> any solution like that. We added:
> /sys/bus/*/{drivers_autoprobe,drivers_probe} long ago, because we
> thought it might be useful, but it's never got really used so far, and
> the missing pieces never got added to the kernel and udev.
> 
> Kay

Hi Kay,

I tried your suggestion about manually binding and unbinding. That sort of
works, but I would like to avoid the handling by the first module until udev can
switch it out.

So I have been trying this manually. Turning off drivers_autoprobe sounded like
a good idea, the problem is that device id for a newly plugged in device is not
fully formed. IE usually in sys/.../1-1/1-1:1.0 the 1-1:1.0 is the number used
to bind and unbind a device, but the 1.0 which I guess is
configuration.interface does not appear in the /sys/..../1-1/ device directory.
So the bind fails because there is no proper device yet. I can echo 1-1 >
/sys/.../drivers_probe, but then the drivers are probed in their original order
and the wrong device binds.  I guess I could unbind this device and rebind it to
my desired driver, but it is starting to get pretty strange - and I suspect
buggy devices will not like all the activity.

All USB devices could potentially have two drivers, the local one and then the
one to remote the device. What I want is to have a text file giving the rules
for which driver gets which device. Then a gui can change the file and the next
udev add activity would connect things up by running a script over the file and
using the udev device info. 

Thanks for the info, Steve



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

* Re: USB driver assignment with udev
  2009-03-11 23:20 USB driver assignment with udev Steve Calfee
                   ` (5 preceding siblings ...)
  2009-03-12 23:01 ` Steve Calfee
@ 2009-03-12 23:59 ` Kay Sievers
  6 siblings, 0 replies; 8+ messages in thread
From: Kay Sievers @ 2009-03-12 23:59 UTC (permalink / raw)
  To: linux-hotplug

On Fri, Mar 13, 2009 at 00:01, Steve Calfee <nospamcalfee@yahoo.com> wrote:
> Kay Sievers <kay.sievers <at> vrfy.org> writes:
>> You can use udev rules to unbind a driver, and rebind a different one
>> to a specific device.
>>
>> Or you can disable kernel-driver-autobinding per bus, and let udev do
>> all the driver binding for this bus. A default rule would trigger the
>> in-kernel driver binding, and any custom rule added before that, could
>> bind a specific driver to a specific device. What's not covered with
>> disabled in-kernel driver binding is the device scanning at the time
>> of loading of a module, which would need to be implemented.
>>
>> Both setups should work. We did not see a lot of interest in offering
>> any solution like that. We added:
>> /sys/bus/*/{drivers_autoprobe,drivers_probe} long ago, because we
>> thought it might be useful, but it's never got really used so far, and
>> the missing pieces never got added to the kernel and udev.

> I tried your suggestion about manually binding and unbinding. That sort of
> works, but I would like to avoid the handling by the first module until udev can
> switch it out.
>
> So I have been trying this manually. Turning off drivers_autoprobe sounded like
> a good idea, the problem is that device id for a newly plugged in device is not
> fully formed. IE usually in sys/.../1-1/1-1:1.0 the 1-1:1.0 is the number used
> to bind and unbind a device, but the 1.0 which I guess is
> configuration.interface does not appear in the /sys/..../1-1/ device directory.
> So the bind fails because there is no proper device yet.

Oh, you will not need to know a device name in advance. You can just
hook into the event for "1-1" and trigger the binding with that name,
and the "1-1:1:0" will show up. If you disable autobinding, the
"usb_device" will need to be attached manually to the "usb" driver,
which will create the "usb_interface" devices.

In the events for the "usb_interface", which are the ones you are
interested in, you can plug your custom rules, which would look like
this for a device with vendor "1234", and a driver named "foo":
  ACTION="add", SUBSYSTEM="usb", \
     ENV{DEVTYPE}="usb_interface", \
     ATTRS{idVendor}="1234", ATTR{[drivers/usb:foo]bind}="$kernel"

And then you fall-back to a "default" rule, which will do what the
kernel does today, and which will also cover the interface creation.
It would look like:
  ACTION="add", SUBSYSTEM="usb", \
    ATTR{[subsystem/usb]drivers_probe}="$kernel"

As pointed out in the earlier mail, the missing piece is the case you
load a module later, and want to scan for devices which might be
interesting for the newly added driver. This is not covered at all and
will do nothing today with disabled autobinding.

Kay

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

end of thread, other threads:[~2009-03-12 23:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-11 23:20 USB driver assignment with udev Steve Calfee
2009-03-11 23:37 ` Greg KH
2009-03-12  0:32 ` Steve Calfee
2009-03-12  0:35 ` Kay Sievers
2009-03-12  2:01 ` Greg KH
2009-03-12 10:21 ` Scott James Remnant
2009-03-12 23:01 ` Steve Calfee
2009-03-12 23:59 ` Kay Sievers

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.