あらゆる種類の SCSI デバイスは、sg ドライバ経由でアクセスできます。つまり、 CD-ROM ドライブなら、sr と sg ドライバいずれでもアクセスできます。スキャナー のようなその他の SCSI デバイスは sg ドライバを使ってのみアクセスできます。 sg ドライバは、256 個の SCSI デバイスを認識できます。デバイスは sg ドライバ のロード後にいくつでも追加できます(ただし限度の 256 まで)。
SCSI 汎用(sg)ドライバのドキュメントはW4を参照 してください(sg_utils パッケージにも入っています)。 SCSI 規格については、W1や SCSI のプログラミングが 主題となっている書籍を参照してください。しくみを勉強したければ、 B3を参照してください。
カーネル 2.4 における sg ドライバは「バージョン 3」で、インタフェース機構の 追加と新しい ioctl() が加わりました。新規の ioctl() で一番おもしろいのは、 SG_IO で、SCSI コマンドを送り出し、その応答を待ちます。 Linux Documentation Project サイトにある www.tldp.org/HOWTO/SCSI-Generic-HOWTO/ には、sg ドライバについての完璧な解説があります。 このドキュメントの(おそらくより新しい)バージョンは、 www.torque.net/sg/p/sg_v3_ho.htmlにあります。
カーネル内で使用されている「sg」という略語には、SCSI 汎用ドライバを指す場合 と、最近の入出力デバイス(普通は DMA 対応)の多くが提供している、scatter-gather 機能を指す場合に使われています。どちらを意味するのかは、文脈次第です。 例えば、SG_GET_SG_TABLESIZE という分りにくい sg の ioctl()は、2 番目の 「SG」が scatter-gather を指しています。
sg の公開インタフェースは /usr/src/linux/include/scsi/sg.h にあります。ディストリビューションにもよりますが、これは GNU ライブラリのメンテナーが管理している /usr/include/scsi/sg.h と同じ内容かもしれませんし、違う かもしれません。この 2 つのファイルの内容が同じでなければ、前者のヘッダー ファイルを使ってください。 sg ベースでアプリケーションを書く場合は、sg の文書を見て、この問題をより 深く理解する方が良いでしょう。
sg ドライバは、現在ある SCSI デバイスすべてを登録しています(現状の最大数は、 256 個)。新しく登録する SCSI デバイスそれぞれに、次に利用可能なマイナー番号 が確保されます。少なくとも最初の内は、cat /proc/scsi/scsi で表示される中間レベルのものと同じ順番です。sg デバイスの マッピングは、cat /proc/scsi/sg/devices もしくは cat /proc/scsi/sg/device_strs でわかります。 cat /proc/scsi/scsi と sg の順序の違いが生じるのは、 低レベルのドライバが削除された時(例えば rmmod aha1542)や デバイスが remove-single-device で削除された時です。 sg ドライバは、残っている SCSI デバイスを変更すること無く、マイナー デバイス番号にマッピングし続けます。これは sg のマッピングに「欠番」を 残すことになります。 下記がその例です。
$ cat /proc/scsi/scsi Attached devices: Host: scsi0 Channel: 00 Id: 00 Lun: 00 Vendor: IBM Model: DNES-309170W Rev: SA30 Type: Direct-Access ANSI SCSI revision: 03 Host: scsi1 Channel: 00 Id: 02 Lun: 00 Vendor: PIONEER Model: DVD-ROM DVD-303 Rev: 1.10 Type: CD-ROM ANSI SCSI revision: 02 Host: scsi1 Channel: 00 Id: 06 Lun: 00 Vendor: YAMAHA Model: CRW4416S Rev: 1.0g Type: CD-ROM ANSI SCSI revision: 02 $ cat /proc/scsi/sg/device_strs IBM DNES-309170W SA30 PIONEER DVD-ROM DVD-303 1.10 YAMAHA CRW4416S 1.0g $ echo "scsi remove-single-device 1 0 2 0" > /proc/scsi/scsi $ cat /proc/scsi/scsi Attached devices: Host: scsi0 Channel: 00 Id: 00 Lun: 00 Vendor: IBM Model: DNES-309170W Rev: SA30 Type: Direct-Access ANSI SCSI revision: 03 Host: scsi1 Channel: 00 Id: 06 Lun: 00 Vendor: YAMAHA Model: CRW4416S Rev: 1.0g Type: CD-ROM ANSI SCSI revision: 02 $ cat /proc/scsi/sg/device_strs IBM DNES-309170W SA30 <no active device> YAMAHA CRW4416S 1.0g |
新しい sg_io_hdr インタフェースには、未転送データ量をカウントするための 「resid」というフィールドがあります。低レベルのアダプタのいくつかだけが この機能をサポートしており、その場合でのみこのフィールドに 0 以外が入ります。 このドキュメントの執筆時では、advansys、aha152x、sym53c8xx ドライバがこの機能 をサポートしています。
sg ドライバは、オープンしているファイルディスクリプタそれぞれに対して、 予約済みのバッファを管理しています。 この目的は、アプリケーションのデータ転送に際してカーネルのメモリが足りなく なっても、予約バッファの大きさに達するまでは転送が失敗しないことを保証する ことです。 これは、cdrecord のような ENOMEM エラーから簡単には復旧できない(CD-R なので) アプリケーションにとっては重要です。
ブート時のパラメタに「sg_def_reserved_size」がなかったり、sg モジュールの パラメタである「def_reserved_size」がなかったりすると、sg のファイル ディスクリプタがオープンする度に、include/linux/sg.h に定義してある SG_DEF_RESERVED_SIZE をそのまま使います。
SG_DEF_RESERVED_SIZE の値は、下記のカーネルブート時のオプションで変更可能 です。
sg_def_reserved_size=<n> |
sg モジュールがロードされる時、SG_DEF_RESERVED_SIZE で定義してある値は下記 のオプションで変更できます。
def_reserved_size=<n> |
次のファイルは誰もがすべて読み出し可能で、ASCII 形式で出力されます。 「def_reserved_size」は root が書き込み可能です。ASCII 出力は、人間と マシン両者が読める形式になっています(そのため読みやすさは犠牲に なっています)。表出力を見るには、 cat device_hdrs devices という Unix コマンドを使って ください。
/proc/scsi/sg/debug [sg ドライバの内部状態] /proc/scsi/sg/def_reserved_size [ブート時もしくはモジュールをロードした時の パラメタと同じ] /proc/scsi/sg/devices [数字表現のデバイスのデータテーブル] /proc/scsi/sg/device_hdr [sg と デバイスのカラムヘッダー] /proc/scsi/sg/device_strs [INQUIRY からの文字列のテーブル] /proc/scsi/sg/hosts [ホストデータ(数字)のテーブル] /proc/scsi/sg/host_hdr [sg と ホストのカラムヘッダー] /proc/scsi/sg/host_strs [ホスト ID(文字列)のテーブル] /proc/scsi/sg/version [sg のバージョン番号と日付] |