{"id":2273,"date":"2022-08-30T15:23:29","date_gmt":"2022-08-30T15:23:29","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/01\/05\/how-to-assign-usb-driver-to-device-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:23:29","modified_gmt":"2022-08-30T15:23:29","slug":"how-to-assign-usb-driver-to-device-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/how-to-assign-usb-driver-to-device-collection-of-common-programming-errors\/","title":{"rendered":"How to assign USB driver to device-Collection of common programming errors"},"content":{"rendered":"<p>For the first part of the question, I&#8217;ve looked and couldn&#8217;t find a better way to detach a USB driver than what you&#8217;re already doing with libusb.<\/p>\n<p>As for the second part of the question, udev can <em>react<\/em> to driver loading, but not <em>force<\/em> a specific driver to be assigned to a device.<\/p>\n<p>Every driver in the Linux kernel is responsible for one or more devices. The driver itself chooses what devices it supports. It does this programmatically, i.e. by checking the device&#8217;s vendor and product ID, or, if those aren&#8217;t available (e.g. an old device), performing some auto-detection heuristics and sanity checks. Once the driver is confident it&#8217;s found a device it supports, it attaches itself to it. In short, you often can&#8217;t force a particular driver to use a particular device. Sometimes, however, a device driver is generous with what it accepts, and a device <em>can<\/em> work that it doesn&#8217;t know about. Your mileage will vary! In the past, I&#8217;ve had to manually add weird PCI device\/vendor IDs to drivers that should support them, with mixed success and a few amusing kernel crashes.<\/p>\n<p>Now, in the case of modules, there&#8217;s an extra step. The <em>module loader<\/em> is woken up by the kernel when a new device is detected. It&#8217;s passed a &#8216;modalias&#8217; string, which identifies the device and looks something like this for USB devices:<\/p>\n<pre><code>usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00\n<\/code><\/pre>\n<p>This string contains the device class (<code>usb<\/code>) and class-specific information (vendor\/device\/serial number, device class, etc). Each kernel driver contains a line such as:<\/p>\n<pre><code>MODULE_ALIAS(\"usb:...\")\n<\/code><\/pre>\n<p>Which must match the usbalias (wildcards are used to match multiple devices). If the <code>modalias<\/code> matches one that the driver supports, this driver is loaded (or notified of the new device, if it&#8217;s there already).<\/p>\n<p>You can see the supported devices (by modalias) and their associated modules with<\/p>\n<pre><code>less \/lib\/modules\/`uname -r`\/modules.alias\n<\/code><\/pre>\n<p>If you grep for the usb-storage device driver, you&#8217;ll see it has some specific devices it supports by vendor and device ID, and will also attempt to support any device with the right (storage) class, no matter the vendor\/device.<\/p>\n<p>You can influence this using userspace mechanisms on your OS (<code>\/etc\/modprobe.d\/<\/code> on Debian and friends). You can blacklist modules, or you can specify modules to be loaded by modalias, just like the <code>modules.alias<\/code> file (and using the same syntax). <code>depmod -a<\/code> will then regenerate the module loader&#8217;s patterns.<\/p>\n<p>However, even though you can lead this particular horse to water, but you can&#8217;t make him drink. If the driver has no support for your device, it should ignore it.<\/p>\n<p>This is the theory in the general case.<\/p>\n<p>In practice, and in the case of USB, I see your device appears to have two <strong>endpoints<\/strong>, of which storage is one. The kernel will attach to the storage <strong>endpoint<\/strong> of the overall device. If the other endpoint has the right class, the <code>usbnet<\/code> driver <em>could<\/em> attach to it. Yes, you can have multiple drivers attached to the same <strong>physical<\/strong> device, because a USB device exports multiple <strong>endpoints<\/strong> (e.g. my Logitech G15 keyboard exports two because it has a keyboard device and an LCD screen, each of which is handled by a separate driver).<\/p>\n<p>The fact that the second endpoint of your USB device isn&#8217;t detected is indicative of lack of support in the kernel. Whatever the case, you can list the device endpoints in excruciating detail using <code>lsusb -v | less<\/code>, then scroll down to your particular device (you can limit the output by device:vendor ID or USB path if you&#8217;re so inclined).<\/p>\n<p>Please note: I&#8217;m oversimplifying a bit here with respect to the logical structure of USB devices. Blame the USB consortium. \ud83d\ude42<\/p>\n<p id=\"rop\"><small>Originally posted 2014-01-05 09:48:35. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>For the first part of the question, I&#8217;ve looked and couldn&#8217;t find a better way to detach a USB driver than what you&#8217;re already doing with libusb. As for the second part of the question, udev can react to driver loading, but not force a specific driver to be assigned to a device. Every driver [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2273","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2273","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=2273"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2273\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=2273"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=2273"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=2273"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}