ヘッダファイル include/scsi/sg.h
はインターフェースの記述を
含んでいます(カーネルバージョン 1.3.98 に基づいています):
struct sg_header
{
int pack_len; /* やってくるパケット長 (ヘッダ込み) */
int reply_len; /* 期待される応答の最大長 */
int pack_id; /* パケットの id ナンバー */
int result; /* 0==ok, それ以外は errno コードを指示 */
unsigned int twelve_byte:1;
/* グループ 6 & 7 コマンドに対し 12 バイトコマンド長を強制 */
unsigned int other_flags:31; /* 将来用 */
unsigned char sense_buffer[16]; /* read によってのみ使用される */
/* コマンドに続いてコマンドのためのデータ(?) */
};
この構造体はどのように SCSI コマンドが処理され、また、コマンドの実行結果を 保持する空間を持っているかを表しています。 個々の構造体の構成要素については sec-header 章で後に議論します。
汎用デバイスとデータを交換する通常の方法は以下のようになります:
オープンした汎用デバイスに対しコマンドを送るために
次の三つの部分を含むブロックをデバイスに対して write()
します。
struct sg_header
SCSI コマンド
コマンドと一緒に送られるべきデータ
コマンドの結果を獲得するには、これ(と同様な)ブロック構造体を用いてブロックを
read()
します。
struct sg_header
デバイスからやって来るデータ
これが処理過程の通常の概要です。以降の章で各ステップをもっと詳しく 記述します。
注意:最近のカーネルバージョンに至るまで、SIGINT シグナルを
write()
と対応するread()
の呼び出しの間でブロックする必要があ
りました(つまり sigprocmask()
によって)。write()
部から結果
を取ってくるための read()
なしで復帰することは続いて起こるアクセ
スをブロックすることになります。このシグナルのブロックは見本のコードに
は含まれていません。ですからこれらの見本を走らせる際には SIGINT (a la
が訳せない^C )を発行するべきではありません。