PSM(4)

名称
psm - PS/2 マウス方式のポインティングデバイス用ドライバ

書式
options "PSM_HOOKAPM" options "PSM_RESETAFTERSUSPEND" options "KBD_RESETDELAY=N" options "KBD_MAXWAIT=N" options "PSM_DEBUG=N" options "KBDIO_DEBUG=N" device psm0 at isa? tty irq 12

解説
psm ドライバは PS/2 方式のポインティングデバイスについての サポートを行ないます。 現在、システムには唯ひとつの psm デバイスノードをおくことができます。 PS/2 マウスポートはキーボードコントローラの補助ポートに配置されているので、 キーボードコントローラ用のドライバである atkbdc も一緒にカーネルに組み込まれていなければなりません。 なお現時点では irq 番号を変更することはできないので注意して下さい。

基本的な PS/2 方式のポインティングデバイスには 2 個または 3 個の ボタンがあります。 中にはローラ又はホイールやボタンが幾つか追加されている デバイスもあります。

  デバイス分解能
通常 PS/2 方式のポインティングデバイスは何段階かの分解能、即ち、 移動についての感度を持っています。 これらの分解能は一般に、1 インチあたり 25、50、100、200 パルス となっています。 デバイスによってはより細密な分解能を有しているものもあります。 現在の分解能は実行時に変更できます。 psm ドライバでは、ユーザは予めドライバフラグを用いて分解能を 設定する (ドライバの設定 を参照) か、または後で ioctl(2) コマンドの MOUSE_SETMODE (IOCTL を参照) を用いて分解能を変更することができます。

  通知レート
デバイスがホストシステムに移動とボタン状態の報告を行なう 頻度、即ち通知レートの設定も変更可能です。 一般的にいって PS/2 方式のポインティングデバイスは 毎秒 10、20、40、60、80、100、200 回 の報告を送信することができます。 60 回または 100 回毎秒の通知レートが多数のデバイスについてのデフォルト値であると 思われます。 何の移動もなく、且つどのボタンもその状態を変更していない時は、 そのデバイスはホストシステムに何も通知しないということに注意してください。 通知レートは ioctl コールを用いて変更できます。

  動作レベル
psm ドライバには 3 段階の動作レベルがあります。 現在の動作レベルは ioctl コールを用いて設定できます。

レベル 0 では基本的なサポートが行なわれます。 即ち、デバイスドライバは接続されたデバイスの水平方向と垂直方向の移動 及び最高 3 個までのボタンの状態を報告します。 移動とボタンの状態は一連の固定長データパケット ( データパケット形式 参照) に符号化されます。 レベル 0 はデフォルトの動作レベルであって、ユーザプログラム がドライバをオープンしたとき、 最初はこのレベルにあります。

動作レベル 1、即ち「拡張」レベルでは、もし存在するならローラ (又はホイール)、 及び最高 11 個迄のボタンがサポートされます。 ローラによる移動は Z 軸に沿った移動として報告されます。 このレベルでは 8 バイトのデータパケットがユーザプログラムに送られます。

動作レベル 2 では、ポインティングデバイスからのデータはそのままユーザプログラム に渡されます。 最新の PS/2 方式のポインティングデバイスはしばしば固有のデータ形式を 用いています。 その為、ユーザプログラムではこのレベルでドライバを操作するときに 特殊なデバイスからのデータ形式に関する知識に精通していることが 求められます。 このレベルを「ネイティブ」レベルといいます。

  データパケット形式
psm ドライバから引き渡されるデータパケットは動作レベルによって異なった形式 になっています。

PS/2 マウス方式のポインティングデバイスからのデータパケットは、 動作レベル 0 では 3 バイトあります:

Byte 1
    bit 7
        1 は垂直移動カウントの算術あふれを示します。
    bit 6
        1 は水平移動カウントの算術あふれを示します。
    bit 5
        垂直移動カウントが負の場合にセットされます。
    bit 4
        水平移動カウントが負の場合にセットされます。
    bit 3
        常に 1 です。
    bit 2
        中ボタンの状態; 押下されていればセットされます。中ボタンがないデバイス では、このビットは常に 0 です。
    bit 1
        右ボタンの状態; 押下されていればセットされます。
    bit 0
        左ボタンの状態; 押下されていればセットされます。
Byte 2
    2 の補数での水平移動カウント; -256 から 255 まで。 符号ビットは第 1 バイトにあることに注意してください。
Byte 3
    2 の補数での垂直移動カウント; -256 から 255 まで。 符号ビットは第 1 バイトにあることに注意して下さい。

レベル 1 では、 mouse(4) に定義されている標準形式である MOUSE_PROTO_SYSMOUSE 形式が用いられます。

レベル 2、即ちネイティブレベルでは、データパケットの長さと形式には標準が ありません。

  加速
psm ドライバはポインティングデバイスの移動をある程度「加速」することができます。 デバイスを速く動かすほど、ポインタは画面上をより遠くまで移動します。 ドライバには加速の効果を支配する内部変数があります。 その変数の値はドライバフラグを用いるか又は ioctl コールを用いて 変更できます。

  デバイス番号
psm のマイナデバイス番号は次式により生成されます。

    minor = (`unit' << 1) | `non-blocking'

ここで、「unit」とはデバイス番号 (通常 0) です。 そして「非ブロッキング」ビットがセットされるのは 「プロセスブロックを行なうことでマウス入力があるまでウェイトせずに、 直ちに復帰する」ことを示す為です。 「非ブロッキング」ビットは XFree86 については セットされなければならず、 その為 XFree86 について通常用いられるマイナデバイス番号は 1 です。 デバイスノード名については 関連ファイル を参照して下さい。

ドライバの設定

  カーネル設定オプション
psm ドライバを制御する為に以下のようなカーネル設定オプションがあります。 これらオプションはカーネル設定ファイル (config(8) を参照) に設定できます。

PSM_HOOKAPM
    ラップトップコンピュータの中には、システムが省電力モードから 「レジューム」した直後、どういう訳か 組み込まれた PS/2 ポインティングデバイスが操作不能になっているものがあります。 もっとも、結局は使用可能にはなります。 入出力操作を実行してデバイスを刺激すればデバイスを早く目覚めさせる ことができるらしいという報告があります。 このオプションは、一連のコードを psm ドライバに追加してAPM「レジューム」イベントをフックし、デバイスに 無害な入出力操作を施します。

PSM_RESETAFTERSUSPEND
    このオプションにより上述の問題に対しもっと強力な動作を加えます。 このオプションを指定すると、APM レジュームイベントの後 psm ドライバはデバイスをリセットします。 このオプションを使うには PSM_HOOKAPM オプションもまた一緒に指定して下さい。

KBD_RESETDELAY=X, KBD_MAXWAIT=Y
    psm ドライバは起動の過程でポインティングデバイスをリセットしようとします。 時々リセット後にデバイスが応答するまで時間がかかることがあります。 これらのオプションによりドライバがどのくらいの時間待つべきかを制御します。 ドライバは最高で X * Y ミリ秒の間ウェイトします。 ドライバがユーザのポインティングデバイスを検出できないように見える場合には、 ユーザはこれらの値を増加させたいと考えるかも知れません。 デフォルト値は X に対しては 200 ミリ秒で Y に対しては 5 です。

PSM_DEBUG=N, KBDIO_DEBUG=N
    これはデバッグレベルを N に設定します。 デフォルトのデバッグレベルは 0 です。 デバッグログについては 診断 を参照して下さい。

  ドライバフラグ
psm ドライバは以下のようなフラグを受け付けます。 カーネル設定ファイルの中かまたは起動時のユーザ設定メニュー ( boot(8) を参照) でこれらのフラグを 設定して下さい。

bit 0..3 RESOLUTION
    このフラグはポインティングデバイスの分解能を指定します。 0 から 4 迄でなければなりません。 この値が大きければ大きいほど、デバイスは分解能が高くなります。 このフィールドにより指定される実際の分解能はデバイスのモデルにより 異なります。 一般的な分解能は以下の通りです。

    1 (low)
        25 パルス毎インチ (ppi)
    2 (medium low)
        50 ppi
    3 (medium high)
        100 ppi
    4 (high)
        200 ppi

    このフラグを 0 のままにしておけば、(それが何であれ) デバイスのデフォルトの分解能となります。

bit 4..7 ACCELERATION
    このフラグは加速効果の程度を加減します。 このフラグの値が小さければ小さいほど、移動の感度は上がります。 許容される最小値は 1 であり、この値で最も感度が高い設定となります。 このフラグを 0 に設定すれば完全に加速効果を無効にします。

bit 8 NOCHECKSYNC
    psm ドライバはデータパケットの第 1 バイトの検出を そのバイトのビットパターンを検査することにより行なおうとします。 このやり方は大抵の PS/2 ポインティングデバイスでは旨く行きます。 しかし既知のデバイスとあまり互換性のないデバイスの中には このやり方と相容れないものがあるかも知れません。 もし、あなたのポインティングデバイスが期待通りには機能していないと考えられ、 且つカーネルが頻繁に

        psmintr: out of sync (xxxx != yyyy).

    のようなメッセージをコンソールに表示する場合には、 同期検査を無効にする為にこのフラグをセットして 効果があるかどうかを調べて下さい。

bit 9 NOIDPROBE
    このフラグが指定されると、 psm ドライバはポインティングデバイスのモデルを調査しようとしたり モデル固有の初期化をしません。 その場合、デバイスは標準的な PS/2 マウスのように振舞うはずです。 ホイールや追加されたボタンのような特別な機能は psm ドライバには認識されないでしょう。

bit 10 NORESET
    このフラグがセットされていれば、 デバイスを初期化するときに psm ドライバはポインティングデバイスをリセットしません。 もし FreeBSD カーネルが他の OS の起動した後に立ち上がったなら、 ポインティングデバイスは以前の OS の設定を継承することになります。 しかし、 psm ドライバにはその設定を知る為の方法がないので、 デバイスとドライバは正しく動作しないかも知れません。 このフラグは正常な環境下では決して必要とはならないはずです。

bit 11 FORCETAP
    パッドデバイスの中には、デバイスの表面をユーザが「軽く叩く(タップする)」と、 あたかも 4 番目のボタンが押されたかのように報告するものがあります ( 警告 参照) 。 このフラグにより psm ドライバはデバイスがこのように振舞うと仮定します。 このフラグがなければ、 本ドライバは ALPS GlidePoint モデルに対してのみ このような振舞いを仮定します。

bit 12 IGNOREPORTERROR
    このフラグによって、PS/2 マウスポートを検査するときに psm ドライバは若干のエラー状態を無視します。 これは正常な環境下では決して必要にはならないはずです。

IOCTL
マウスドライバにはいくつかの ioctl(2) コマンドがあります。 これらのコマンドと関連する構造体及び定数は <machine/mouse.h> に定義されています。 コマンドの一般的な解説は mouse(4) に与えられています。 このセクションでは psm ドライバに固有の機能について解説します。

MOUSE_GETLEVEL int *level
MOUSE_SETLEVEL int *level
    これらのコマンドで psm ドライバの動作レベルを操作します。

MOUSE_GETHWINFO mousehw_t *hw
    これは接続されたデバイスのハードウェア情報を以下の構造体で返します。

        typedef struct mousehw {
            int buttons;    /* ボタンの数 */
            int iftype;     /* I/F の種類 */
            int type;       /* マウス/トラックボール/パッド... */
            int model;      /* I/F に固有のモデル ID */
            int hwid;       /* I/F に固有のハードウェア ID */
        } mousehw_t;

    buttons フィールドはデバイスにあるボタンの数を保持します。 現在 psm ドライバは Logitech 製の 3 ボタンマウスを検出して そのように報告することができます。 他のメーカ製の 3 ボタンマウスについては正しく報告されるかどうかは 分かりません。 しかし、 ボタンの数が正しく検出されてもされなくてもドライバの運用には影響しません。

    iftype フィールドは常に MOUSE_IF_PS2 です。

    type フィールドは次のようなデバイスの種類を示します。即ち MOUSE_MOUSE, MOUSE_TRACKBALL, MOUSE_STICK, MOUSE_PAD, MOUSE_UNKNOW です。 ユーザはこのフィールドに頼り過ぎてはいけません。 というのは、ドライバは必ずしも常に デバイスの種類を識別できる訳ではないからです。 実際のところデバイスの種類を識別できることは稀なのです。

    model フィールドは動作レベル 0 では常に MOUSE_MODEL_GENERIC です。 これはより高次の動作レベルでは MOUSE_MODEL_GENERIC かまたは MOUSE_MODEL_XXX のうちのどれか 1 つになるかも知れません。 この場合にも psm ドライバがこのフィールドに適切な値をセットするかどうかは分かりません。

    hwid フィールドはデバイスにより返された ID の値です。 一般的な ID は以下の通りです。

    0   マウス (Microsoft, Logitech 及び他の多数のメーカ)
    2   Microsoft Ballpoint mouse
    3   Microsoft IntelliMouse

MOUSE_GETMODE mousemode_t *mode
    このコマンドによりマウスドライバの現在の動作パラメータを得ます。

        typedef struct mousemode {
            int protocol;    /* MOUSE_PROTO_XXX */
            int rate;        /* 通知レート (毎秒)、不明の時は -1 */
            int resolution;  /* MOUSE_RES_XXX、不明の時は -1 */
            int accelfactor; /* 加速因子 */
            int level;       /* ドライバの動作レベル */
            int packetsize;  /* データパケットの長さ */
            unsigned char syncmask[2]; /* 同期ビット */
        } mousemode_t;

    protocol フィールドは動作レベル 0 と 2 では MOUSE_PROTO_PS2 です。 動作レベル 1 では、 MOUSE_PROTO_SYSMOUSE です。

    rate フィールドは状態を通知する頻度 (1 秒当りに報告する回数) で、 この頻度でデバイスはホストコンピュータに移動の報告を送ります。 サポートされている一般的な値は、10, 20, 40, 60, 80, 100, 200 です。 中には他の任意の値をも受容するマウスもあるでしょう。

    resolution フィールドはポインティングデバイスの分解能で、定数 MOUSE_RES_XXX の中のいずれかひとつの値かまたはある正の値です。 この値が大きいほど、マウスは分解能が細密になります。 定数 MOUSE_RES_XXX によって指定される実際の分解能はマウスのモデルによって異なります。 一般的な分解能は次の通りです:

    MOUSE_RES_LOW
        25 ppi
    MOUSE_RES_MEDIUMLOW
        50 ppi
    MOUSE_RES_MEDIUMHIGH
        100 ppi
    MOUSE_RES_HIGH
        200 ppi

    accelfactor フィールドは加速機能 (加速 を参照) を管理する為の値を保持します。 この値は 0 か正でなければなりません。 もしこの値が 0 であれば、加速は無効となります。

    packetsize フィールドはデータパケットの長さを示します。 これは動作レベルやポインティングデバイスのモデルによって変わります。

    level 0
        3 バイト
    level 1
        8 バイト
    level 2
        デバイスのモデルで決まります

    配列である syncmask フィールドはデータパケットの第 1 バイトを検出する為の ビットマスクとビットパターンを保持します。 syncmask[0] フィールドは各バイトと AND をとるためのビットマスクです。 その結果が syncmask[1] フィールドに等しい場合には、恐らくそのバイトはデータパケットの第 1 バイト であろう思われます。 注意すべきことは、この検出方法は 100% 信頼できるものではなく、そのため、 単に参考となる手段でしかないと見なすべきことです。

MOUSE_SETMODE mousemode_t *mode
    このコマンドはマウスドライバの現在の動作パラメータを mode フィールドに指定された通りに変更します。 rate, resolution, level, accelfactor の各フィールドだけが変更できます。 その他のフィールドに値をセットしても エラーを生成しませんし効果もありません。

    あるフィールドの現在の設定を変更したくない場合には、 そのフィールドに -1 を入れて下さい。 resolution フィールドと rate フィールドには 0 を入れることもでき、この場合にはそのフィールドのデフォルト値 が設定されます。

MOUSE_READDATA mousedata_t *data
MOUSE_READSTATE mousedata_t *state
    これらのコマンドについては、現在 psm ドライバはサポートしていません。

MOUSE_GETSTATE mousestatus_t *status
    このコマンドは mouse(4) に記述されているようにボタンの現在の状態と移動カウントを返します。

関連ファイル
/dev/psm0
    「非ブロッキング」型デバイスノード
/dev/bpsm0
    devfs での「ブロッキング」型デバイスノード。

使用例
    options "PSM_HOOKAPM"
    device psm0 at isa? tty irq 12

「レジューム」イベント後にポインティングデバイスを刺激するための オプションのコードとともに psm ドライバをカーネルに組み込みます。

    device psm0 at isa? tty flags 0x024 irq 12

デバイス分解能を高く (4) セットし、加速因子を 2 にセットします。

診断

デバッグレベル 0 では、起動過程での以下のような行以外には 殆ど情報はログされません:

    psm0: device ID X

ここで X は発見されたポインティングデバイスから返されたデバイス ID コードです。 既知の ID については MOUSE_GETINFO を参照して下さい。

デバッグレベル 1 ではドライバが補助ポート (マウスポート) を検査している間により多くの情報がログされます。 メッセージは LOG_DEBUG の level で LOG_KERN を facility として (syslogd(8) を参照) ログされます。

    psm0: current command byte:xxxx
    kbdio: TEST_AUX_PORT status:0000
    kbdio: RESET_AUX return code:00fa
    kbdio: RESET_AUX status:00aa
    kbdio: RESET_AUX ID:0000
    [...]
    psm: status 00 02 64
    psm0 irq 12 on isa
    psm0: model AAAA, device ID X, N buttons
    psm0: config:00000www, flags:0000uuuu, packet size:M
    psm0: syncmask:xx, syncbits:yy

第 1 行目は補助ポートが検査される直前のキーボードコントローラの コマンドバイトの値を示します。 これは通常は、4D, 45, 47, 65 のいずれかで、通電時にマザーボード BIOS が キーボードコントローラを初期化した方法により決まります。

第 2 行目は補助ポートインタフェースに対してキーボードコントローラが テストした結果を示し、0 でエラーが無いことを示します。 しかしながら、たとえシステムにポートが存在しなくてもエラーが無いと 報告するコントローラも中にはあることに注意して下さい。

第 3 行目から第 5 行目まではポインティングデバイスのリセット状態を示します。 機能しているデバイスであれば FA AA <ID> という順序に並んだデータ を返すはずです。 この ID コードは上で解説したものです。

第 7 行目は現在のハードウェアの設定を示します。 これらのバイトは次のようにフォーマットされます:

Byte 1
    bit 7
        予約済み。
    bit 6
        0 - ストリームモード、1 - リモートモード。 ストリームモードでは、ポインティングデバイスはその状態が変わる度に デバイス状態を送ります。 リモートモードでは、ホストコンピュータはデバイスの状態が送られるように 要求しなければなりません。 psm ドライバはデバイスをストリームモードにします。
    bit 5
        ポインティングデバイスが現在有効であればセットされます。 有効でなければ 0 です。
    bit 4
        0 - 1:1 スケーリング、1 - 2:1 スケーリング。 1:1 スケーリングがデフォルトです。
    bit 3
        予約済み。
    bit 2
        左ボタン状態; 押下されていればセット。
    bit 1
        中ボタン状態; 押下されていればセット。
    bit 0
        右ボタン状態; 押下されていればセット。
Byte 2
    bit 7
        予約済み。
    bit 6..0
        分解能コード: 0 から 3 迄。 分解能コードに対応する実際の分解能はデバイスにより異なります。
Byte 3
    状態通知レート (1 秒当りに報告する回数) で、この頻度でデバイスは 移動報告をホストコンピュータに送ります。

psm ドライバがユーザプログラムによりオープンされるまでは ポインティングデバイスは有効にならないことに注意して下さい。

残りの行についてはデバイス ID コード、検出されたボタンの数、及び 内部変数を表示します。

デバッグレベル 2 では、ずっと多くの詳細な情報がログされます。

警告
多くのパッドデバイスは、ユーザがパッドの表面を「軽く叩いた(タップした)」時に、 まるで第 1 (左) ボタンが 押下されたかのように振舞います。 これに対し、ALPS GlidePoint のパッドモデルの中には、軽く叩く(タッピング)動作を 第 4 番目のボタンのイベントとして処理するものがあります。

MouseSystems 製の PS/2 マウスの中には、正しく機能させるために 高分解能モードにする必要があるものがあります。 ドライバフラグを用いて分解能を設定して下さい。

一旦データストリームの同期がずれた場合には、 パケットの第 1 バイトに再び同期することを保証する方法はありません。 しかしながら、X サーバが moused(1) を用いてマウスにアクセスしていない場合には、 ユーザが XFree86 サーバを使用中に問題が生じても、 仮想端末に切り替えてから X サーバに戻れば X サーバを マウスと同期させることができるかも知れません。 マウスを移動させないでいずれかのボタンをクリックすれば やはり効果があるかも知れません。

バグ
ioctl コマンドの MOUSEIOCREAD は削除されました。 どのみち、これは機能していなかったのです。

関連項目
ioctl(2), syslog(3), atkbdc(4), mouse(4), mse(4), sysmouse(4), moused(8), syslogd(8)

作者
psm ドライバは非常に多くの人々によりなされた仕事に基づいています。 これらの人々の中から少数の方々を挙げれば Eric Forsberg, Sandi Donno, Rick Macklem, Andrew Herbert, Charles Hannum, Shoji Yuen, Kazutaka Yokota がいます。

このマニュアルページは Kazutaka Yokota <yokota@FreeBSD.org> が書きました。