もう4年ぐらい旅行先でTV放送を見たり,自宅で録画したりするのに活躍していたPX-W3U4だが,この前旅行から帰ってきて自宅の録画環境に接続したらなぜか動作しなくなっていた
PX-W3U4をUSBケーブルでPCに接続すると,本来はVID:PID=0511:083fで接続するはずなのだが,これがなぜかVID:PID=048d:9306(ITE Techでの標準)になっている。このためLinuxのpx4_drvデバイスドライバーが動作しなくなっていた。
試しにWindowsのNote PCに接続しても同様に動作しない。しょうがないんでWindowsのデバイスドライバー(WinUSB版px4_drv)のinfファイルをVID:PID=048d:9306に変更して,デジタル署名をし直した後デバイスドライバーをインストールし直したら,WindowsマシンでTV放送が視聴出来るようになった。
つまり動作しなくなったのはUSB接続時PX-W3U4のVID:PIDが変わっただけで,その他の機能は問題なく動作しているようだ。
Linuxマシンのデバイスドライバー(px4_drv)も,VID:PID=048d:9306にして(その他,EEPROMに入っているシリアル番号を取得する部分なども修正),動作するように出来た
PX-W3U4にはEEPROM(24C02WP)が実装されていて,そこにVIDやPID,シリアル番号,プロダクト名などが書き込まれている。VID:PID=048d:9306になってしまうということは,たぶんこのEEPROMがIT9305Eのboot時になんらかの理由で読み込めないのだと思うのだが,PX-W3U4をバラしてハードを詳しく確認しても特に問題はなさそうだった。
ただEEPROM(24C02WP)のWC端子がGNDに接続されているので,PX-W3U4の電源等が不安定な場合などで書き換わってしまうことがあるかもしれない。
実装されているEEPROM(24C02WP)に書き込まれているデータをダンプしてみた。書き込まれているデータ自体は,VID:PID=0511:083fになっているし他の情報も入っていて,特におかしくなっているようには思えないが(オリジナルの内容がわからないのでなんとも言えない),checksumとか先頭とかどこかが書き換わっているのかも?
dumpしたEEPROMのデータ:pxw3u4rom.bin
どなたか正常なPX-W3U4のEEPROMをdumpしてもらえないかな・・・
なんでIT9305Eがboot時にEEPROMを読み込まないのかは不明なのだが,もしかしたらソフトウェアで読まないように設定できるのかも?
PX-W3U4を本来のVID:PID=0511:083fに戻すべきなのだが,EEPROMの内容がダメなのかIT9305E側の問題なのか不明なので,このまま使用することにした
VID:PID=048d:9306を使うように修正した,Windows用のWinUSB版px4_drvデバイスドライバーとLinux用のchardev版px4_drvデバイスドライバー。
WinUSB版PX-W3U4用のinfファイルを,VID:PID=048d:9306に変更して,catファイルにデジタル署名(自己署名)をし直した。
px4_drv_patch.zip
Linux(Raspbian buster)マシンのpx4_drvデバイスドライバーをVID:PID=048d:9306で動作するように,一部のソースコードを修正して,ビルドしてインストールした。
以下は修正したソースファイル。
px4_device.c
} else if (!tmp) { dev_warn(dev, "EEPROM error.\n"); return ret; } ↓ } else if (!tmp) { //dev_warn(dev, "EEPROM error.\n"); //return ret; }
if (!px4 || !dev || !dev_serial || !chrdev_ctx || !quit_completion) ↓ if (!px4 || !dev || !chrdev_ctx || !quit_completion)
ret = px4_parse_serial_number(&px4->serial, dev_serial); if (ret) { dev_err(px4->dev, "px4_device_init: px4_parse_serial_number() failed. (ret: %d)\n", ret); goto fail; } dev_dbg(px4->dev, "px4_device_init: serial_number: %014llu\n", px4->serial.serial_number); dev_dbg(px4->dev, "px4_device_init: dev_id: %u\n", px4->serial.dev_id); if (!px4->serial.dev_id || px4->serial.dev_id > 2) dev_warn(px4->dev, "px4_device_init: Unexpected device id: %u\n", px4->serial.dev_id); ↓ /* ret = px4_parse_serial_number(&px4->serial, dev_serial); if (ret) { dev_err(px4->dev, "px4_device_init: px4_parse_serial_number() failed. (ret: %d)\n", ret); goto fail; } dev_dbg(px4->dev, "px4_device_init: serial_number: %014llu\n", px4->serial.serial_number); dev_dbg(px4->dev, "px4_device_init: dev_id: %u\n", px4->serial.dev_id); if (!px4->serial.dev_id || px4->serial.dev_id > 2) dev_warn(px4->dev, "px4_device_init: Unexpected device id: %u\n", px4->serial.dev_id); */
px4_usb.c
switch (id->idVendor) { case 0x0511: { ↓ switch (id->idVendor) { case 0x048d: case 0x0511: {
static const struct usb_device_id px4_usb_ids[] = { { USB_DEVICE(0x0511, USB_PID_PX_W3U4) }, { USB_DEVICE(0x0511, USB_PID_PX_Q3U4) }, ↓ static const struct usb_device_id px4_usb_ids[] = { { USB_DEVICE(0x048d, USB_PID_PX_W3U4) }, { USB_DEVICE(0x0511, USB_PID_PX_Q3U4) },
px4_usb.h
#define USB_PID_PX_W3U4 0x083f #define USB_PID_PX_Q3U4 0x084a ↓ #define USB_PID_PX_W3U4 0x9306 #define USB_PID_PX_Q3U4 0x084a
PX-W3U4のUSBがVID:PID=048d:9306になってしまうと,それに対応したデバイスドライバーdvb_usb_af9035を読み込もうとする
なので,読み込まないように/etc/modprobe.d/blacklist-dvb_usb_af9035.confファイルを以下の内容で作成した。
blacklist dvb_usb_af9035
これでPX-W3U4接続時に不要なデバイスドライバーの読み込みをしないように出来た。
新しくコメントをつける