JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
デバイスドライバの記述     Oracle Solaris 10 8/11 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

パート I Solaris プラットフォーム用デバイスドライバの設計

1.  Solaris デバイスドライバの概要

2.  Solaris カーネルとデバイスツリー

3.  マルチスレッド

4.  プロパティー

5.  イベントの管理とタスクのキュー

6.  ドライバの自動設定

7.  デバイスアクセス: プログラム式入出力

8.  割り込みハンドラ

9.  ダイレクトメモリーアクセス (DMA)

10.  デバイスメモリーおよびカーネルメモリーのマッピング

11.  デバイスコンテキスト管理

12.  電源管理

13.  Solaris ドライバの強化

14.  階層化ドライバインタフェース (LDI)

パート II 特定の種類のデバイスドライバの設計

15.  文字デバイスのドライバ

16.  ブロックデバイスのドライバ

17.  SCSI ターゲットドライバ

18.  SCSI ホストバスアダプタドライバ

19.  ネットワークデバイスのドライバ

20.  USB ドライバ

Solaris 環境での USB

USBA 2.0 フレームワーク

USB クライアントドライバ

クライアントドライバのバインド

USB デバイスがシステムからどのように見えるか

USB デバイスと Solaris デバイスツリー

互換デバイス名

複数のインタフェースを備えたデバイス

デバイスドライバのバインディングのチェック

基本的なデバイスアクセス

クライアントドライバが接続される前

記述子ツリー

デバイスアクセスを取得するためのドライバの登録

デバイス通信

USB エンドポイント

デフォルトパイプ

パイプの状態

パイプのオープン

パイプのクローズ

データ転送

同期および非同期転送とコールバック

要求

パイプのフラッシュ

デバイス状態管理

USB デバイスのホットプラグ

ホットプラグコールバック

電源を入れたまま挿入

電源を入れたまま取り外し

電源を入れたまま再挿入

電源管理

デバイス電源管理

システム電源管理

直列化

ユーティリティー関数

デバイス設定機能

インタフェース番号の取得

デバイス全体の管理

複数の設定を持つデバイス

代替設定の変更または取得

その他のユーティリティー関数

文字列記述子の取得

パイプの非公開データ機能

USB 状態のクリア

デバイス、インタフェース、エンドポイントの各状態の取得

デバイスのバスアドレスの取得

サンプル USB デバイスドライバ

パート III デバイスドライバの構築

21.  ドライバのコンパイル、ロード、パッケージ化、およびテスト

22.  デバイスドライバのデバッグ、テスト、およびチューニング

23.  推奨されるコーティング方法

パート IV 付録

A.  ハードウェアの概要

B.  Solaris DDI/DKI サービスの概要

C.  64 ビットデバイスドライバの準備

D.  コンソールフレームバッファードライバ

索引

基本的なデバイスアクセス

この節では、USB デバイスへのアクセス方法やクライアントドライバの登録方法について説明します。また、記述子ツリーについても説明します。

クライアントドライバが接続される前

クライアントドライバが接続される前に、次のイベントが発生します。

  1. 最初のクライアントドライバが接続される前に、PROM (OBP/BIOS) と USBA フレームワークがデバイスにアクセスします。

  2. ハブドライバが、ハブの各ポート上のデバイスでアイデンティティーと構成を調べます。

  3. 各デバイスへのデフォルト制御パイプが開かれ、各デバイスのデバイス記述子が調べられます。

  4. デバイスごとに、そのデバイス記述子とインタフェース記述子に基づいて互換名プロパティーが構築されます。

互換名プロパティーは、クライアントドライバに個別にバインド可能なデバイスのさまざまな部分を定義します。クライアントドライバは、デバイス全体にバインドすることも、1 つのインタフェースだけにバインドすることもできます。「クライアントドライバのバインド」を参照してください。

記述子ツリー

記述子の解析時には、構造体のメンバーが自然な境界に位置合わせされたあと、ホストの CPU のエンディアンに変換されます。解析後の標準 USB 構成記述子、インタフェース記述子、およびエンドポイント記述子は、各構成の階層ツリーの形でクライアントドライバから使用可能となります。クラス固有またはベンダー固有の raw 記述子情報もすべて、同じ階層ツリー内でクライアントドライバから使用可能となります。

階層記述子ツリーを取得するには、usb_get_dev_data(9F) 関数を呼び出します。usb_get_dev_data (9F) のマニュアルページの「関連項目」節には、各標準 USB 記述子のマニュアルページの一覧が含まれています。raw 記述子情報を解析するには、usb_parse_data(9F) 関数を使用します。

2 つの構成を含むデバイスの記述子ツリーは、次の図に示すようなツリーになります。

図 20-3 階層 USB 記述子ツリー

image:図は、2 つの構成を含むデバイスの各インタフェースの記述子ペアのツリーを示しています。

上図に示した dev_cfg 配列には、構成に対応するノードが含まれています。各ノードに含まれる情報は次のとおりです。

2 番目のインデックスで指定された構成の 2 番目のインタフェースを表すノードは、図で dev_cfg[1].cfg_if[1] の位置にあります。そのノードには、そのインタフェースの代替設定を表すノードの配列が含まれています。USB 記述子の階層はツリーの全体にわたって伝播されます。文字列記述子データに含まれる ASCII 文字列は、USB 仕様でこれらの文字列が存在するとされている場所に接続されます。

構成の配列は間が空いておらず、構成インデックスでインデックス指定されます。最初の有効な構成 (構成 1) は、dev_cfg[0] です。インタフェースと代替設定のインデックスは、それらの個数に対応した値になります。各代替設定のエンドポイントは連続的にインデックス指定されます。各代替設定の最初のエンドポイントはインデックス 0 です。

この採番方式によりツリーのトラバースが容易に行えます。たとえば、エンドポイントインデックス 0、代替 0、インタフェース 1、構成インデックス 1 の raw 記述子データは、次のパスで定義されるノードの位置にあります。

dev_cfg[1].cfg_if[1].if_alt[0].altif_ep[0].ep_descr

記述子ツリーを直接使用する代わりに usb_lookup_ep_data(9F) 関数を使用することもできます。usb_lookup_ep_data(9F) 関数は、引数としてインタフェース、代替設定、エンドポイント、エンドポイントタイプ、および向きを取ります。usb_lookup_ep_data(9F) 関数を使用すると、記述子ツリーをたどって特定のエンドポイントを取得できます。詳細については、usb_get_dev_data(9F) のマニュアルページを参照してください。

デバイスアクセスを取得するためのドライバの登録

クライアントドライバからの USBA 2.0 フレームワーク への最初の 2 つの呼び出しは、usb_client_attach(9F) 関数と usb_get_dev_data(9F) 関数の呼び出しです。これら 2 つの呼び出しは、クライアントドライバの attach(9E) エントリポイントから行われます。usb_get_dev_data(9F) 関数を呼び出す前に usb_client_attach(9F) 関数を呼び出す必要があります。

usb_client_attach(9F) 関数は、USBA 2.0 フレームワーク にクライアントドライバを登録します。usb_client_attach(9F) 関数ではバージョン管理が実行されます。クライアントドライバのソースファイルは必ず、次の行で始まっている必要があります。

#define USBDRV_MAJOR_VER        2
#define USBDRV_MINOR_VER        minor-version
#include <sys/usb/usba.h>

minor-version の値は USBA_MINOR_VER 以下である必要があります。シンボル USBA_MINOR_VER<sys/usb/usbai.h> ヘッダーファイル内で定義されています。<sys/usb/usbai.h> ヘッダーファイルは <sys/usb/usba.h> ヘッダーファイルによってインクルードされます。

USBDRV_VERSION は、USBDRV_MAJOR_VERSIONUSBDRV_MINOR_VERSION からバージョン番号を生成するマクロです。usb_client_attach() の第 2 引数は USBDRV_VERSION である必要があります。この第 2 引数が USBDRV_VERSION でない場合や USBDRV_VERSION が無効なバージョンを反映している場合には、usb_client_attach() 関数が失敗します。この制限により、プログラミングインタフェースの互換性が確保されます。

usb_get_dev_data() 関数は、適切な USB デバイス管理に必要な情報を返します。たとえば、usb_get_dev_data() 関数から次の情報が返されます。

usb_get_dev_data() 関数の呼び出しは必須です。usb_get_dev_data() を呼び出すことが、デフォルト制御パイプを取得したり mutex の初期化に必要な iblock_cookie を取得したりするための唯一の方法です。

クライアントドライバの attach(9E) ルーチンは通常、usb_get_dev_data() を呼び出したあとで、必要な記述子やデータを記述子ツリーからドライバのソフト状態にコピーします。ソフト状態にコピーされたエンドポイント記述子は、あとでそれらのエンドポイントへのパイプを開く際に使用されます。attach(9E) ルーチンは通常、記述子をコピーしたあとで、usb_free_descr_tree(9F) を呼び出して記述子ツリーを解放します。あるいは記述子ツリーを保持し、記述子をコピーしないようにしてもかまいません。

次の 3 つの解析レベルのいずれかを usb_get_dev_data(9F) 関数に指定することで、返される記述子ツリーの範囲を決定します。ドライバがデバイスのより広い範囲にバインドする必要がある場合、より広い範囲のツリーが必要となります。

クライアントドライバの detach(9E) ルーチンは、usb_free_dev_data(9F) 関数を呼び出すことで、usb_get_dev_data() 関数によって割り当てられたリソースをすべて解放する必要があります。usb_free_dev_data() 関数はハンドルを受け取りますが、そのハンドルでは、記述子ツリーがすでに usb_free_descr_tree() 関数で解放されています。さらにクライアントドライバの detach() ルーチンは、usb_client_detach(9F) 関数も呼び出すことで、usb_client_attach(9F) 関数によって割り当てられたリソースをすべて解放する必要があります。