2008年5月11日日曜日

FreeBSD 7.0-RELEASEでUSBキーボードを使ったら、キーを押すと変な記号がでたりで使い物にならなかった ~ キーボードのハードウェア依存な問題らしい

先日、自宅サーバをFreeBSD 7.0-RELEASEにアップグレードしたんですが、





そのときにも、USBキーボードのキーを押すと、変な記号やら表示されて、USBキーボードが使い物にならない問題がありました。なんかUSBキーボードの挙動がおかしいな、と気がついてはいたのですが、そのときは、気のせいだろう、ってことにして、見なかったことにしてました。



というのも、FreeBSDのインストール作業は、PS2キーボードを使って行うのが、個人的に一番いいと思ってて、また、ディスプレイもキーボードもマウスも接続しないで使うサーバなので、通常は、USBキーボードが使えなくてもまったく問題ないですし。



今日、ちょっと使ってみたくて、別のパソコンを、FreeBSD 7.0-RELEASEにアップグレードしたのですが、またしても、同じ問題が発生。



たとえば、以下は、USBキーボードのキー、A、B、Cを押したときの画面。



20080510



記号が表示されてます(笑)。いろいろキーを押すと、たまに、^A、^B、^Cと表示されることもありました。
なんだか、でたらめなキースキャンコードが返ってきているような雰囲気です。
6.2-STABLEのときは問題なく使えていたので、何か納得がいきません。



それに、仕事先のパソコンで、FreeBSD 7-STABLEで使っているものがあるのですが、それでは何の問題もなく、USBキーボードが使えています。これはいったいどういうことなんでしょうか。



きっとまたkbdmuxのせいだろ、とか思って、kbdmuxを無効にしてみたんですが、やっぱりダメ。
BIOSメニューで、USB Legacy Supportを無効にしてもダメ。
どうやら、USBキーボードのドライバであるukbd自体に問題があるっぽいようです。


とりあえず、障害の調査対象をukbdに絞込み、6.3-RELASEと、7.0-RELEASEとの間の差分をながめてみました。



http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/ukbd.c.diff?r1=1.72.2.2&r2=1.52.2.8&f=h



まずは、ukbdをカーネルから抜いて、カーネルモジュールとしてロードするようにしました。そして、ukbd.cを少し書き換えては、コンパイル、モジュールをロード、動作テスト、ダメならモジュールをアンロード、・・・以上の繰り返し、という手順で、試行錯誤をしてみたところ、見つかりました!



関数init_keyboardの中でやっていたらしい(quirkとされている)、usbd_set_protocol(state->ks_iface, 0);というのが、7.0-RELEASEになるときに消えてなくなっているのですが、これを付け加えたら、正常にUSBキーボードが使えるようになりました。



このあたりのコードがけっこう書き換えられてしまって、きれいなパッチにはならなかったのですが、暫定的に、こうしてみました。



--- /usr/src/sys/dev/usb/ukbd.c.ORG     2007-11-13 01:09:45.000000000 +0900
+++ /usr/src/sys/dev/usb/ukbd.c 2008-05-10 20:26:24.000000000 +0900
@@ -1458,6 +1458,15 @@
                return EINVAL;
        }



+       {
+         usbd_status err = usbd_set_protocol(state->ks_iface, 0);
+         DPRINTF(("ukbd:init_keyboard: protocol set\n"));
+         if (err) {
+           printf("ukbd: set protocol failed\n");
+           /*return EIO;  */
+         }
+       }
+
        /* Ignore if SETIDLE fails since it is not crucial. */
        usbd_set_idle(state->ks_iface, 0, 0);



上記の変更は、「私の使っているキーボードではこうすると動くようになる」ってだけで、誰の環境でも、必ずこうしなければいけない、というものではないはずです。注意してください。



上のコードは、ukbd.cがrevision 1.70になったときに、削除されたみたいです。



http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/ukbd.c.diff?r1=1.69&r2=1.70&f=h&f=u



以下のような、いくつかのファイルが関連していますが、



http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/ukbd.c?f=h
http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/usb_quirks.h?f=h
http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/usb_quirks.c?f=h



commitログをみていくと

o ukbd: Remove the NO_SET_PROTO quirk (fixes a PR 77940).  NetBSD removed
  their check and setting the proto a long time ago.

というのがあります。これのことです。



どうやら、キーボードの機種(ベンダー、モデル)によって、問題があるっぽいです。
このとき削除された処理が入っていると、動かなくなるキーボードがあったり、逆に、この処理を無くすと、私が使っているキーボードのように動かなくなることもある、ということでしょうか。



今回FreeBSD7でトラブルを起こした、私が自宅で使っているキーボードは、9年ほど前に、秋葉原で購入したもので、未使用の新品だけどジャンクとして売られていたキーボードです。もともとは、富士通製パソコンに付属のキーボードなのですが、なぜかキーボードだけでバラ売りされてました。値段はとても安かったです([E:happy01])



デバイスが認識されたとき、こんな風に表示されます。



ukbd0: <Fujitsu Fujitsu USB Comfort Keyboard, class 0/0, rev 1.00/1.00, addr 4> on uhub5



USBがWindowsでなんとか使えるようになったのは、たしかWindows 98SEくらいのころでしたが、これ、まさにそのころのキーボードです。つまり、初期のUSBキーボード、ってことでして、なんか微妙に変なところがある、ってことでしょうかねぇ・・・





昔問題になった、FreeBSD 6.1-RELEASE、6.2-RELEASEなどで、USB日本語106/109キーボードを使っていると、フルキーの右下あたりにある、アンダースコア(_)・・・「ろ」と書いてあるキー、が入力できない、という問題は、7.0-RELEASEでは直ってました。





0 件のコメント:

コメントを投稿