キャプチャされたUSB通信に基づいて、既存のUSBデバイス用のLinuxドライバーを作成しようとしています。
デバイスには複数の構成があります。残念ながら、デバイスはUSB仕様に準拠していないようです。最初のSet ConfigurationRequestのみが機能します。 2番目のSetConfiguration Requestを発行すると、デバイスがロックされ、最終的にクラッシュします。 USBリセットまたは構成のリセット(0に設定)も何の役にも立ちません。
さて、Linux USB Coreは、何らかの理由でデバイスの構成を間違った値に設定することを決定したようです(最初の値を選択するだけです)。そうする前に私が介入する機会はありません。私はすでにカーネルモジュールとユーザースペースlibusbドライバーからそれを試しました。
カーネルのソースコードを読むと、構成を選択する関数は、 / drivers/usb/core/generic.c の汎用ドライバーのusb_choose_configuration()
のようです。 usb_device_is_owned()
がtrueを返した場合、関数がスキップされる可能性があることはわかりますが、その関数の結果にどのように影響を与えることができるかわかりません。
USBドライバーを追加するためだけにカーネル全体を再コンパイルする必要がないことを願っています。
したがって、ここに私の質問があります:
usb_choose_configuration
_関数をオーバーライドできる他の方法はありますか?usb_device_is_owned()
がすでにtrueを返すようにするにはどうすればよいですか?システムがデバイスの構成を設定しようとするのを防ぐ方法があるようで、ユーザースペースからでも機能します。 この機能をカーネルに追加したコミット に出くわしましたが、幸いなことに、サンプルコードも含まれています。
ユーザースペースプログラムは、デバイスファイルシステムを介してUSBハブの特定のポートの所有権を宣言でき、その結果、usb_device_is_owned()
がtrueを返します。
トリックは次のようです:
unsigned int port = 2; // Just as an example
// Send request 24 of type 'U' (USB), which returns an unsigned int
unsigned int ioctl_id = _IOR('U', 24, unsigned int);
// fd is a file descriptor to the hub's file in the devfs
ioctl(fd, ioctl_id, &port);
USBサブシステムのいくつかのioctl要求に関する情報は、 カーネルドキュメント で説明されています。完全なリストは カーネルソース にあります。 #definesは ここ です。
興味深いことに、システムは構成0(構成のリセット)に対して構成設定要求を送信します。