2011/07/16

libusb_open()でLIBUSB_ERROR_NOT_SUPPORTEDが返ってくるが、わからん

わからんシリーズ。
cygwinで、libusb-1.0を使ったサンプルを書いていた。
まあ、本当はサンプルではないのだが・・・うまくいかんのでね。

libusb_init();
libusb_get_device_list();
while() {
 libusb_get_device_descriptor();
 目的のVID/PIDだったらbreak;
}
libusb_open();
libusb_free_device_list();


だいたい、こんな感じ。

その中の libusb_open() で -12が返ってくる。
ヘッダを見ると、

/** Operation not supported or unimplemented on this platform */
LIBUSB_ERROR_NOT_SUPPORTED = -12,


となっている。

そっか、cygwinではlibusb_open()はサポートされてないんだな。
うんうん。

いやいや、ちょっと待て。
libusb_open()ができんかったら、libusbは使えないも同然やん!
現在の最新版はlibusb-1.0.8なのだが、cygwinでは1.0.7+となっている。
おそらくcygwin用のパッチが当ててあるのだろう。
そんなわけで、ソースファイルはcygwinのsetup.exeを使って落としてきた。
cygwinのソースファイルは初めてなのだが、今回は/usr/srcに落とされていた。
bz2とpatchとshの3ファイル。
使い方がわからん・・・。

スクリプトをちょっと眺めると「help」というのがあった。

$ ./libusb1.0-1.0.7+gitbd62c472-1.sh help
This is the cygwin packaging script for libusb1.0-1.0.7+gitbd62c472-1.
Usage: ./libusb1.0-1.0.7+gitbd62c472-1.sh [
Options are:
 help, --help Print this message
 version, --version Print the version message
 with_logs, --logs Create logs of remaining steps
Actions are:
 prep Unpack and patch into /usr/src/libusb1.0-1.0.7+gitbd62c472
 mkdirs Make hidden directories needed during build

 conf, configure Configure the package (./configure)
 reconf Rerun configure
 build, make Build the package (make)
 check, test Run the testsuite (make check)
 clean Remove built files (make clean)
 install Install package to staging area (make install)
 list List package contents
 depend List package dependencies
 strip Strip package executables
 pkg, package Prepare the binary package libusb1.0-1.0.7+gitbd62c472-1.tar.bz2
 mkpatch Prepare the patch file libusb1.0-1.0.7+gitbd62c472-1.patch
 acceptpatch Copy patch file libusb1.0-1.0.7+gitbd62c472-1.patch to /usr/src
 spkg, src-package Prepare the source package libusb1.0-1.0.7+gitbd62c472-1-src.tar.bz2
 finish Remove source directory /usr/src/libusb1.0-1.0.7+gitbd62c472
 checksig Validate GPG signatures (requires gpg)
 first Full run for spkg (mkdirs, spkg, finish)
 almostall Full run for bin pkg, except for finish
 all Full run for bin pkg


prepを使うと、カレントディレクトリにファイルが展開された。


LIBUSB_ERROR_NOT_SUPPORTEDをgrepしてみると、何箇所かあった。
さて、このうちのどこなのか・・・。
いつもならログを埋め込んでいくところだが、ソースを見ていると既にある。
usbi_dbg()というものだが、これはログ有効ビルドをしていないと出ないらしい。

$ ./configure --enable-debug-log
$ make
$ make install


libusbのAPIにも、libusb_set_debug()というデバッグ出力を有効にするものがある。
だが、ここまでのログはさすがにビルドし直さないと出ないようだ。
大量のログが出て、libusb_open()のときにはこんなのが出ていた。

libusb:debug [libusb_open] open 3.1
libusb:debug [unsupported_open] unsupported API call for 'open' (unrecognized device driver)

ほほう。
検索すると、os/windows_usb.hにマクロがあった。

#define PRINT_UNSUPPORTED_API(fname) \
 usbi_dbg("unsupported API call for '" \
 #fname "' (unrecognized device driver)" #line); \
 return LIBUSB_ERROR_NOT_SUPPORTED;


ふんふん、引数でopenが渡されているのだな。
では「PRINT_UNSUPPORTED_API(open)」で検索。
os/windows_usb.cにあった。

static int unsupported_open(struct libusb_device_handle *dev_handle) {
 PRINT_UNSUPPORTED_API(open);
}

えっ・・・。
なんか、嫌な感じだ。
unsupported_open()は、usb_api_backend[0]の中にあった。
このusb_api_backend[0]は、unsupported_XXX()だけだ。

usb_api_backend[]は4つあって、
 usb_api_backend[0] = unsupported_XXX()
 usb_api_backend[1] = composite_XXX()
 usb_api_backend[2] = winusb_XXX()
 usb_api_backend[3] = hid_xxx()
という割り当てになっている。
まあ、関数テーブルだな。
デバイスの種類に応じて添字が決まるのだろう。

つまり、libusbでopenするデバイスはどれでも同じ処理をするのではなく、デバイスの種類に応じた処理をするということがわかる。

libusb:debug [libusb_open] open 3.1
この「3.1」は、バス番号(bus_number)とデバイス番号(device_address)なので、意味はない。



0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。