Этот вопрос двоякий:
Во-первых, как вручную отсоединить драйвер от USB-устройства и подключить другой? Например, у меня есть устройство, которое при подключении автоматически использует драйвер usb-хранилища.
вывод usbview
Vendor Id: xxxx
Product Id: xxxx
...
Number of Interfaces: 2
Interface Number: 0
Name: usb-storage
Number of Endpoints: 2
...
Interface Number: 1
Name: (none)
Number of Endpoints: 2
...
Я не хочу использовать драйвер usb-хранилища, поэтому в своем приложении я использую libusb
библиотеку, чтобы отключить драйвер usb-хранилища, а затем запрашиваю интерфейс. Затем я могу отправлять данные в и из приложений, работающих на моем USB-устройстве и в моей хост-системе Linux.
Как вручную отключить драйвер вне приложения?
Во-вторых, как мне автоматически назначить драйвер для подключения к плагину устройства? В настоящее время у меня есть настройка правила udev для автоматической установки разрешений устройства:
SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"
Могу ли я использовать правила udev для назначения драйверов определенным интерфейсам на устройстве USB? Например, если я хотел, чтобы модуль usbnet использовался автоматически на интерфейсе 0 вместо usb-storage, возможно ли это в udev?
usbnet
не загружается автоматически, потому что у него нет информации об оборудовании, которое может его использовать. Попробуйте найти подходящий драйвер и использовать, напримерmodinfo kalmia
,. Вalias
строках вы увидите идентификатор поставщика xxxx и идентификатор продукта yyyy asusb:vxxxxpyyyy
. Или вы можете отредактировать файл /lib/modules/kernel_version/modules.usbmap и для вашего HW вы можете удалить строку, где находится ваше HW-модуль usb-storage, или изменить usbstorage с помощью соответствующего сетевого драйвера. Но послеdepmod -a
этого изменения уйдут ...Ответы:
В первой части вопроса я посмотрел и не смог найти лучшего способа отсоединить драйвер USB, чем то, что вы уже делаете с libusb.
Что касается второй части вопроса, udev может реагировать на загрузку драйвера, но не может принудительно назначать конкретный драйвер устройству.
Каждый драйвер в ядре Linux отвечает за одно или несколько устройств. Драйвер сам выбирает, какие устройства он поддерживает. Это делается программно, т. Е. Путем проверки производителя устройства и идентификатора продукта или, если они недоступны (например, старое устройство), выполнения некоторых эвристических процедур автоматического обнаружения и проверки работоспособности. Как только водитель уверен, что нашел устройство, которое он поддерживает, он присоединяется к нему. Короче говоря, вы часто не можете заставить определенный драйвер использовать определенное устройство. Иногда, однако, драйвер устройства щедр в отношении того, что он принимает, и устройство может работать, о чем оно не знает. Ваш пробег будет меняться! В прошлом мне приходилось вручную добавлять странные идентификаторы устройств / поставщиков PCI в драйверы, которые должны их поддерживать, с неоднозначным успехом и несколькими забавными сбоями ядра.
Теперь, в случае модулей, есть дополнительный шаг. Модуль загрузчик пробуждается ядром , когда новое устройство обнаружено. Передается строка 'modalias', которая идентифицирует устройство и выглядит примерно так для USB-устройств:
Эта строка содержит класс устройства (
usb
) и информацию о классе (производитель / устройство / серийный номер, класс устройства и т. Д.). Каждый драйвер ядра содержит строку, такую как:Который должен соответствовать usbalias (подстановочные знаки используются для соответствия нескольким устройствам). Если
modalias
совпадает с поддерживаемым драйвером, этот драйвер загружается (или уведомляется о новом устройстве, если оно уже там).Вы можете увидеть поддерживаемые устройства (по модалиям) и связанные с ними модули с
Если вы воспользуетесь драйвером USB-устройства хранения данных, то увидите, что у него есть некоторые конкретные устройства, которые он поддерживает по поставщику и идентификатору устройства, а также попытаетесь поддержать любое устройство с правильным классом (хранилищем), независимо от поставщика / устройства. ,
Вы можете повлиять на это, используя механизмы пространства пользователя в вашей ОС (
/etc/modprobe.d/
в Debian и в друзьях). Вы можете занести в черный список модули или указать модули, которые будут загружаться с помощью modalias, точно так же какmodules.alias
файл (и используя тот же синтаксис).depmod -a
затем восстановит шаблоны загрузчика модуля.Тем не менее, даже если вы можете привести эту конкретную лошадь к воде, но вы не можете заставить его пить. Если драйвер не поддерживает ваше устройство, его следует игнорировать.
Это теория в общем случае.
На практике, и в случае с USB, я вижу, что ваше устройство имеет два интерфейса , один из которых - хранилище. Ядро подключится к интерфейсу хранилища всего устройства. Если другой интерфейс имеет правильный класс,
usbnet
драйвер может подключиться к нему. Да, вы можете иметь несколько драйверов, подключенных к одному физическому устройству, потому что устройство USB экспортирует несколько интерфейсов (например, моя клавиатура Logitech G15 экспортирует два интерфейса, потому что у нее есть устройство клавиатуры и ЖК-экран, каждый из которых обрабатывается отдельным драйвером) ,Тот факт, что второй интерфейс вашего USB-устройства не обнаружен, свидетельствует об отсутствии поддержки в ядре. В любом случае, вы можете перечислить интерфейсы / конечные точки устройства с помощью мучительных деталей
lsusb -v | less
, а затем прокрутить вниз до вашего конкретного устройства (вы можете ограничить вывод по устройству: идентификатор поставщика или путь USB, если вы так склонны).Пожалуйста, обратите внимание: я здесь немного упрощаю в отношении логической структуры USB-устройств. Виноват USB консорциум. :)
источник
static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);
в коде, это избыточно с модалиями?