Esta pergunta é dupla:
Primeiro, como você desanexa manualmente um driver de um dispositivo USB e conecta outro? Por exemplo, eu tenho um dispositivo que, quando conectado, usa automaticamente 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
...
Não quero usar o driver de armazenamento USB, portanto, no meu aplicativo, uso a libusb
biblioteca para desanexar o driver de armazenamento USB e, em seguida, reivindico a interface. Em seguida, posso enviar dados para e de aplicativos em execução no meu dispositivo USB e no meu sistema Linux host.
Como você desanexa um driver manualmente fora de um aplicativo?
Segundo, como atribuo automaticamente o driver para conectar 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 queria que o módulo usbnet fosse usado automaticamente na interface 0 em vez do armazenamento usb, isso é possível no udev?
usbnet
não será carregado automaticamente porque não possui informações sobre o hardware, o que pode ser usado. Tente encontrar o driver adequado e use, por exemplomodinfo kalmia
,. Nasalias
linhas, você verá a identificação do fornecedor xxxx e a identificação do produto aaaa comousb:vxxxxpyyyy
. Ou você pode editar o arquivo /lib/modules/kernel_version/modules.usbmap e, para o seu HW, você pode excluir a linha, onde é para você o módulo USB HW de armazenamento ou alterar o usbstorage com o driver de rede adequado. Mas depois quedepmod -a
essa mudança desaparecer ...Respostas:
Na primeira parte da pergunta, procurei e não consegui encontrar uma maneira melhor de desanexar um driver USB do que o que você já está fazendo com o libusb.
Quanto à segunda parte da pergunta, o udev pode reagir ao carregamento do driver, mas não força um driver específico a ser atribuído a um dispositivo.
Todo driver no kernel do Linux é responsável por um ou mais dispositivos. O próprio driver escolhe quais dispositivos ele suporta. Isso é feito 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), executando algumas heurísticas de detecção automática e verificações de sanidade. Quando o motorista está confiante de que encontrou um dispositivo compatível, ele se liga a ele. Em resumo, muitas vezes você não pode forçar um driver específico 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 varia! No passado, tive que adicionar manualmente identificações estranhas de dispositivos / fornecedores de PCI aos drivers que deveriam suportá-los, com sucesso misto e algumas falhas divertidas no kernel.
Agora, no caso de módulos, há uma etapa extra. O carregador de módulo é ativado pelo kernel quando um novo dispositivo é detectado. Ele passou uma string 'modalias', que identifica o dispositivo e se parece com isso com dispositivos USB:
Essa sequência contém a classe de dispositivo (
usb
) e informações específicas de classe (fornecedor / dispositivo / número de série, classe de dispositivo, etc.). Cada driver do kernel contém uma linha como:O qual deve corresponder às usbalias (caracteres curinga são usados para corresponder a vários dispositivos). Se
modalias
corresponder àquele suportado pelo driver, esse driver será carregado (ou notificado sobre o novo dispositivo, se já estiver lá).Você pode ver os dispositivos suportados (por modalidades) e seus módulos associados com
Se você solicitar o driver do dispositivo de armazenamento USB, verá que ele possui alguns dispositivos específicos compatíveis com o fornecedor e o ID do dispositivo e também tentará oferecer suporte a qualquer dispositivo com a classe correta (armazenamento), independentemente do fornecedor / dispositivo .
Você pode influenciar isso usando os mecanismos de espaço do usuário no seu sistema operacional (
/etc/modprobe.d/
no Debian e nos amigos). Você pode colocar módulos na lista negra ou especificar módulos a serem carregados pelas modalidades, assim como omodules.alias
arquivo (e usando a mesma sintaxe).depmod -a
irá regenerar os padrões do carregador de módulos.No entanto, mesmo que você possa levar esse cavalo em particular à água, mas não pode fazê-lo beber. Se o driver não tiver suporte para o seu dispositivo, ele deve ignorá-lo.
Esta é a teoria no caso geral.
Na prática, e no caso do 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
usbnet
driver poderá se conectar 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 possui um dispositivo de teclado e uma tela LCD, cada um dos quais é tratado por um driver 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 / pontos finais do dispositivo com detalhes excruciantes usando e
lsusb -v | less
, em seguida, role para baixo até o seu dispositivo específico (você pode limitar a saída por dispositivo: ID do fornecedor ou caminho USB, se desejar).Observe: estou simplificando um pouco aqui em relação à estrutura lógica dos dispositivos USB. Culpe o consórcio USB. :)
fonte
static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);
no código, é redundante com modalias?