Como atribuir driver USB ao dispositivo

29

Esta questão é dupla:

Primeiro, como você desanexa manualmente um driver de um dispositivo USB e anexa um diferente? Por exemplo, eu tenho um dispositivo que, quando conectado automaticamente, usa o driver de armazenamento usb.

saída 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
        ...

Eu não quero usar o driver usb-storage, então no meu aplicativo eu uso a biblioteca libusb para desanexar o driver usb-storage e então eu reivindico a interface. Eu então posso enviar dados de e para os aplicativos em execução no meu dispositivo USB e no meu sistema Linux host.

Como você desanexa um driver manualmente fora de um aplicativo?

Em segundo lugar, como atribuo automaticamente o driver para anexar no plug-in do dispositivo? Atualmente, tenho uma configuração de regra do udev para definir as permissões do dispositivo automaticamente:

SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"

Posso usar as regras do udev para atribuir drivers a interfaces específicas no dispositivo USB? Por exemplo, se eu quiser que o módulo usbnet seja usado automaticamente na interface 0 em vez de usb-storage, isso é possível no udev?

    
por linsek 05.12.2011 / 21:26

1 resposta

20

Para a primeira parte da questão, eu olhei e não consegui encontrar uma maneira melhor de desanexar um driver USB do que o que você já está fazendo com a libusb.

Quanto à segunda parte da questão, o udev pode reagir ao carregamento do driver, mas não forçar um driver específico a ser atribuído a um dispositivo.

Cada driver no kernel do Linux é responsável por um ou mais dispositivos. O próprio driver escolhe quais dispositivos ele suporta. Ele faz isso de forma programática, ou seja, verificando o fornecedor do dispositivo e o ID do produto ou, se não estiverem disponíveis (por exemplo, um dispositivo antigo), realizando algumas heurísticas de detecção automática e verificações de integridade. Uma vez que o motorista está confiante de que encontrou um dispositivo que ele suporta, ele se conecta a ele. Em suma, muitas vezes você não pode forçar um determinado driver a usar um dispositivo específico. Às vezes, no entanto, um driver de dispositivo é generoso com o que ele aceita, e um dispositivo pode funcionar que ele não conhece. Sua milhagem irá variar! No passado, tive que adicionar manualmente estranhas IDs de dispositivos / fornecedores PCI aos drivers que deveriam suportá-los, com sucesso e algumas falhas de kernel divertidas.

Agora, no caso dos módulos, há um passo extra. O carregador de módulo é despertado pelo kernel quando um novo dispositivo é detectado. Ele passou uma string de "modalias", que identifica o dispositivo e se parece com isso para dispositivos USB:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

Esta cadeia contém a classe de dispositivo ( usb ) e informações específicas da classe (fornecedor / dispositivo / número de série, classe de dispositivo, etc). Cada driver do kernel contém uma linha como:

MODULE_ALIAS("usb:...")

Qual deve combinar os usbalias (os curingas são usados para combinar dispositivos múltiplos). Se o modalias corresponder a um que o driver suporta, este driver é carregado (ou notificado do novo dispositivo, se já estiver lá).

Você pode ver os dispositivos compatíveis (por modalias) e seus módulos associados com

less /lib/modules/'uname -r'/modules.alias

Se você usar o driver de dispositivo de armazenamento usb, verá que ele possui alguns dispositivos específicos suportados pelo fornecedor e pelo ID do dispositivo e também tentará oferecer suporte a qualquer dispositivo com a classe certa (de armazenamento), independentemente da fornecedor / dispositivo.

Você pode influenciar isso usando mecanismos de espaço do usuário em seu sistema operacional ( /etc/modprobe.d/ no Debian e em seus amigos). Você pode colocar módulos em lista negra, ou você pode especificar módulos a serem carregados por modalias, assim como o arquivo modules.alias (e usando a mesma sintaxe). depmod -a regenerará os padrões do carregador do módulo.

No entanto, mesmo que você possa levar esse cavalo em particular para a água, você não pode fazê-lo beber. Se o driver não tiver suporte para o seu dispositivo, ele deverá ignorá-lo.

Esta é a teoria no caso geral.

Na prática, e no caso de USB, vejo que seu dispositivo parece ter duas interfaces , das quais o armazenamento é um. O kernel será anexado à interface de armazenamento do dispositivo geral. Se a outra interface tiver a classe correta, o driver usbnet poderá anexar a ela. Sim, você pode ter vários drivers conectados ao mesmo dispositivo físico , porque um dispositivo USB exporta várias interfaces (por exemplo, meu teclado Logitech G15 exporta dois porque tem um dispositivo de teclado e um ecrã LCD, cada um dos quais é manuseado por um controlador separado).

O fato de a segunda interface do seu dispositivo USB não ser detectada é indicativo de falta de suporte no kernel. Seja qual for o caso, você pode listar as interfaces de dispositivos / pontos de extremidade com detalhes excruciantes usando lsusb -v | less e, em seguida, deslocar para baixo para seu dispositivo específico (você pode limitar a saída por dispositivo: ID de fornecedor ou caminho USB se você estiver inclinado). / p>

Por favor, note: estou simplificando um pouco aqui com relação à estrutura lógica dos dispositivos USB. Culpe o consórcio USB. :)

    
por 24.01.2012 / 13:20