もっとも基本的な SCSI コマンドの一つが INQUIRY
コマンドで、装置の
種類と構成を明らかにするために使用されます。以下はSCSI-2 仕様書からの
定義です(詳細は SCSI-2 標準規格を参照のこと)。
Table 44: INQUIRY Command
+=====-========-========-========-========-========-========-========-========+
| Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|Byte | | | | | | | | |
|=====+=======================================================================|
| 0 | Operation Code (12h) |
|-----+-----------------------------------------------------------------------|
| 1 | Logical Unit Number | Reserved | EVPD |
|-----+-----------------------------------------------------------------------|
| 2 | Page Code |
|-----+-----------------------------------------------------------------------|
| 3 | Reserved |
|-----+-----------------------------------------------------------------------|
| 4 | Allocation Length |
|-----+-----------------------------------------------------------------------|
| 5 | Control |
+=============================================================================+
出力データは以下の通り:
Table 45: Standard INQUIRY Data Format
+=====-========-========-========-========-========-========-========-========+
| Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|Byte | | | | | | | | |
|=====+==========================+============================================|
| 0 | Peripheral Qualifier | Peripheral Device Type |
|-----+-----------------------------------------------------------------------|
| 1 | RMB | Device-Type Modifier |
|-----+-----------------------------------------------------------------------|
| 2 | ISO Version | ECMA Version | ANSI-Approved Version |
|-----+-----------------+-----------------------------------------------------|
| 3 | AENC | TrmIOP | Reserved | Response Data Format |
|-----+-----------------------------------------------------------------------|
| 4 | Additional Length (n-4) |
|-----+-----------------------------------------------------------------------|
| 5 | Reserved |
|-----+-----------------------------------------------------------------------|
| 6 | Reserved |
|-----+-----------------------------------------------------------------------|
| 7 | RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe |
|-----+-----------------------------------------------------------------------|
| 8 | (MSB) |
|- - -+--- Vendor Identification ---|
| 15 | (LSB) |
|-----+-----------------------------------------------------------------------|
| 16 | (MSB) |
|- - -+--- Product Identification ---|
| 31 | (LSB) |
|-----+-----------------------------------------------------------------------|
| 32 | (MSB) |
|- - -+--- Product Revision Level ---|
| 35 | (LSB) |
|-----+-----------------------------------------------------------------------|
| 36 | |
|- - -+--- Vendor Specific ---|
| 55 | |
|-----+-----------------------------------------------------------------------|
| 56 | |
|- - -+--- Reserved ---|
| 95 | |
|=====+=======================================================================|
| | Vendor-Specific Parameters |
|=====+=======================================================================|
| 96 | |
|- - -+--- Vendor Specific ---|
| n | |
+=============================================================================+
次の例は低レベル関数 handle_SCSI_cmd
を Inquiry SCSI コマンドを
実行するために使用します。
最初に共通ヘッダにコマンド部を追加し、それから handle_SCSI_cmd
を呼び出します。handle_SCSI_cmd
の呼び出しに対する出力バッファサイズ
の引数は共通ヘッダのサイズを除外していることに注意してください。
エラーが発生しなかったならば、コマンドが完結した後に出力バッファは要求
されたデータを保有することになります。
#define INQUIRY_CMD 0x12
#define INQUIRY_CMDLEN 6
#define INQUIRY_REPLY_LEN 96
#define INQUIRY_VENDOR 8 /* 返答データ内のベンダ名のオフセット */
/* ベンダのブランドとモデルを要求 */
static unsigned char *Inquiry ( void )
{
static unsigned char Inqbuffer[ SCSI_OFF + INQUIRY_REPLY_LEN ];
unsigned char cmdblk [ INQUIRY_CMDLEN ] =
{ INQUIRY_CMD, /* command */
0, /* lun/reserved */
0, /* page code */
0, /* reserved */
INQUIRY_REPLY_LEN, /* allocation length */
0 };/* reserved/flag/link */
memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );
/*
* +------------------+
* | struct sg_header | <- cmd
* +------------------+
* | copy of cmdblk | <- cmd + SCSI_OFF
* +------------------+
*/
if (handle_SCSI_cmd(sizeof(cmdblk), 0, cmd,
sizeof(Inqbuffer) - SCSI_OFF, Inqbuffer )) {
fprintf( stderr, "Inquiry failed\n" );
exit(2);
}
return (Inqbuffer + SCSI_OFF);
}
上の例は次のような構造になっています。Inquiry 関数はそのコマンド部を
共通ヘッダのあと(SCSI_OFF
によって与えられます)にコピーします。
入力データはこのコマンドに対しては存在しません。
Handle_SCSI_cmd
がヘッダ構造体を定義します。
今や関数 main
を実装し、この作業中の見本プログラムを完成できます。
void main( void )
{
fd = open(DEVICE, O_RDWR);
if (fd < 0) {
fprintf( stderr, "Need read/write permissions for "DEVICE".\n" );
exit(1);
}
/* Inquiry の結果の一部のフィールドを表示 */
printf( "%s\n", Inquiry() + INQUIRY_VENDOR );
}
最初にデバイスオープンし、エラーをチェックしてから、高位のサブルーチン を呼び出します。その後、ベンダ、製品及びリビジョンなどの結果を人間が読 める形式で表示します。
注意: Inquiry の結果にはこの小さなプログラムが供するよりももっと多くの 情報があります。このプログラムをデバイスの種類や ANSI のバージョンなど を出すように拡張したくなるかもしれません。デバイスの種類には特別な重要 性があります。というのはこれがその装置に対する必須およびオプションのコ マンドセットを決定するからです。自分でこれをプログラムしたくないのであ れば、Eric Youngdale による scsiinfo プログラムを使用することもできま す。scsiinfo は SCSI 装置についてのほとんど全ての情報を要求するもので す。tsx-11.mit.edu の pub/Linux/ALPHA/scsi を見てください。