CAM_CDBPARSE(3) FreeBSD ライブラリ関数マニュアル CAM_CDBPARSE(3)
名称
csio_build, csio_build_visit, csio_decode, csio_decode_visit, buff_decode, buff_decode_visit, csio_encode, csio_encode_visit, buff_encode_visit − CAM ユーザライブラリ SCSI バッファパーズルーチン |
ライブラリ
Common Access Method User Library (libcam, −lcam) |
書式
#include <stdio.h> int |
csio_build(struct ccb_scsiio *csio, u_int8_t *data_ptr,u_int32_t dxfer_len, u_int32_t flags, int retry_count,int timeout, char *cmd_spec, ...); int
csio_build_visit(struct ccb_scsiio *csio, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int32_t flags, int retry_count, int timeout, char *cmd_spec, int (*arg_get)(void *hook, char *field_name), void *gethook); int int int int int int int 解説 |
CAM バッファ /CDB エンコードおよびデコードルーチンは、古い FreeBSD SCSI レイヤの、類似した名前の scsireq_* 関数で書かれたユーザランド SCSI アプリ ケーションに対し、比較的簡単に新しいインタフェースへの移行できる道筋を提 供します。 これらの関数は、新しいアプリケーションで使っても構いませんが、ユーザは、 cam(3) ライブラリに組み入れられた関数を構築する各種 SCSI CCB 構築関数を使 用する方が簡単だということに気づくでしょう ( たとえば、 cam_fill_csio(), scsi_start_stop(), csi_read_write() です)。 csio_build() は、変数引数リストに提供された情報をもとにして ccb_scsiio 構 造体を構築します。この関数は、この関数に渡される NULL の data_ptrt 引数を 整然と処理します。 dxfer_len は、データフェーズの長さです。データ転送の方向は flags 引数に よって決まります。 data_ptr は、 SCSI データフェーズの間に使用されるデータバッファです。問題 の SCSI コマンドについてデータが転送されない場合は、これを NULL に設定す る必要があります。コマンドについて転送するデータがある場合は、このバッ ファは少なくとも dxfer_len の長さでなければなりません。 flags は 〈cam/cam_ccb.h〉 に定義されたフラグでなければなりません。 /* 共通の CCB ヘッダ */ /* CAM CCB フラグ */ typedef enum { CAM_CDB_POINTER = 0x00000001,/* CDB フィールドはポインタである */ CAM_QUEUE_ENABLE = 0x00000002,/* SIM 待ち行列処置は有効である */ CAM_CDB_LINKED = 0x00000004,/* CCB はリンクした CDB を含む */ CAM_SCATTER_VALID = 0x00000010,/* 分散/収集リストは有効である */ CAM_DIS_AUTOSENSE = 0x00000020,/* 自動探知機能を無効にする */ CAM_DIR_RESV = 0x00000000,/* データ方向 (00:予約済み) */ CAM_DIR_IN = 0x00000040,/* データ方向 (01:DATA IN) */ CAM_DIR_OUT = 0x00000080,/* データ方向 (10:DATA OUT) */ CAM_DIR_NONE = 0x000000C0,/* データ方向 (11:データなし) */ CAM_DIR_MASK = 0x000000C0,/* データ方向マスク */ CAM_SOFT_RST_OP = 0x00000100,/* 代わりにソフトリセットを使用する */ CAM_ENG_SYNC = 0x00000200,/* 完了時に剰余バイトをフラッシュする */ CAM_DEV_QFRZDIS = 0x00000400,/* DEV Q 凍結を無効にする */ CAM_DEV_QFREEZE = 0x00000800,/* 実行時に DEV Q を凍結する */ CAM_HIGH_POWER = 0x00001000,/* コマンドは大量の能力を得る */ CAM_SENSE_PTR = 0x00002000,/* センスデータはポインタである */ CAM_SENSE_PHYS = 0x00004000,/* センスポインタは物理的なアドレス */ CAM_TAG_ACTION_VALID = 0x00008000,/* この ccb 内ではタグ処置を使用する */ CAM_PASS_ERR_RECOVER = 0x00010000,/* 受け渡しドライバエラー。回復 */ CAM_DIS_DISCONNECT = 0x00020000,/* 切断を無効にする */ CAM_SG_LIST_PHYS = 0x00040000,/* SG リストに物理アドレスがある */ CAM_MSG_BUF_PHYS = 0x00080000,/* メッセージバッファ ptr が物理的である */ CAM_SNS_BUF_PHYS = 0x00100000,/* 自動探知データ ptr が物理的である */ CAM_DATA_PHYS = 0x00200000,/* SG/バッファデータ ptr が物理的である */ CAM_CDB_PHYS = 0x00400000,/* CDBポインタが物理的である */ CAM_ENG_SGLIST = 0x00800000,/* SG リストは HBA エンジン用である */ /* フェーズ認識モードフラグ */ CAM_DIS_AUTOSRP = 0x01000000,/* 自動保存/復元ポインタを無効にする */ CAM_DIS_AUTODISC = 0x02000000,/* 自動切断を無効にする */ CAM_TGT_CCB_AVAIL = 0x04000000,/* ターゲットの CCB が利用可能 */ CAM_TGT_PHASE_MODE = 0x08000000,/* SIM がフェーズモードで実行される */ CAM_MSGB_VALID = 0x20000000,/* メッセージバッファが有効 */ CAM_STATUS_VALID = 0x40000000,/* ステータスバッファが有効 */ CAM_DATAB_VALID = 0x80000000,/* データバッファが有効 */ /* ホストターゲットモードフラグ */ CAM_TERM_IO = 0x20000000,/* 入出力メッセージ補充を終了 */ CAM_DISCONNECT = 0x40000000,/* 切断は必須である */ CAM_SEND_STATUS = 0x80000000,/* データフェーズの後にステータスを送信 */ } ccb_flags; 複数のフラグを指定する場合、OR (論理和) を取る必要があります。どの CCB フ ラグを使用することもできます。以降の重要ないくつかのフラグについては特に 説明しておく価値があります。 |
CAM_DIR_IN
問題の操作が読み取り操作であることを示します。すな わち、データは SCSI デバイスからユーザ指定バッファ に読み取られています。 CAM_DIR_OUT CAM_DIR_NONE CAM_DEV_QFRZDIS CAM_PASS_ERR_RECOVER CAM_DATA_PHYS retry_count は、問題のコマンドを何回再試行するかをカーネルに通知します。 pass(4) ドライバが CAM_PASS_ERR_RECOVER フラグによって回復を有効にするよ う指示されていない限り、再試行カウントは無視されます。 timeout は、指定のコマンドが完了するまでどのくらい待機するかをカーネルに 通知します。時間が切れ、しかもコマンドが完了していないと、 CCB は、該当す るエラーステータスでカーネルから帰ります。 cmd_specis は SCSI CDB を構築するのに使用される CDB 形式指示子です。この テキストストリングは、フィールド指示子のリストで構成されます。フィールド 指示子は、各 CDB フィールド用の値 (値を変数引数リスト内の次の引数から取る べきことを示すことも含む)、フィールドの幅 (ビット単位またはバイト単位)、 およびオプションの名前を指定します。スペースは無視され、シャープ記号 (’#’) は、現在の行の末尾で終了するコメントの先頭を示します。 オプションの名前は、フィールド指定子の最初の部分であり、中括弧で囲まれま す。次の例で中括弧で囲まれたテキストは名前です。 {PS} v:b1 {Reserved} 0:b1 {Page Code} v:b6 # Mode select page このフィールド指定子には、3 つのフィールドがあります。 1 ビットのフィール ドが 2 つと 6 ビットのフィールドが 1 つです。 2 番めの 1 ビットフィールド は定数値 0 であり、最初の 1 ビットフィールドと 6 ビットフィールドは、変数 引数リストから取られます。複数バイトのフィールドは SCSI のバイト順序で CDB 内にスワップされ、スペースは無視されます。 フィールドが 16 進数値または文字 v のとき ( たとえば、 1A または v) 、 1 バイト値が CDB 中の次の未使用バイトにコピーされます。文字 v が使用されて いるとき、次の整数引数が変数引数リストから取られ、その値が使用されます。 定数の 16 進数値にフィールド幅の指定子、または文字 v にフィールド幅指定子 フィールドが続いたもの ( たとえば、 3:4, 3:b4, 3:i3, v:i3) は、指定のビッ トまたはバイト幅のフィールドを指定します。定数値、または (V 指定子の場合) 可変引数リストの次の整数値が、 CDB の次の未使用ビットまたはバイトにコピー されます。 10 進数または文字 b に 10 進数フィールド幅が続いたものは、その幅のビット フィールドを示します。ビットフィールドは、可能な限り緊密にパックされ、上 位ビットで開始し (SCSI 仕様と同じものを読み取られるようにです ) 、 1 バイ トが完全に一杯になるときはいつでも、または i フィールドが検出されたとき は、 CDB の新しいバイトが開始されます。 文字 i の後に 1, 2, 3, または 4 が続いたフィールド幅指示子は、 SCSI バイ ト順 (MSB が先頭) にスワップしなければならない 1, 2, 3, または 4 バイトの 整数値を示します。 v フィールド指示子については、次の整数引数が、変数引数リストから取られ、 その値が SCSI 順にスワップするのに使用されます。 csio_build_visit() は csio_build() と動作が類似していますが、 cmd_spec 内 の変数引数に置き換わる値が、 stdarg(3) によってではなく、 csio_build_visit() に渡される arg_get() 関数によって取り出される点が異な ります。 arg_get() 関数は次の 2 つの引数を取ります。 gethook field_name csio_decode() は、 SCSI 転送のフェーズでデータの情報をデコードするのに使 用されます。 デコードは、 csio_build() のコマンド指示子処理に類似していますが、 csio->data_ptr によって指されるデータからデータを取り出す点が異なります。 stdarg リストは、整数値ではなく整数を指すポインタです。シークフィールドタ イプと抑制修飾子が追加されます。 * 抑制修飾子 ( たとえば、 *i3 または *b4) は、フィールドからの割り当てを抑制し、データ内のバイトまたはビットを スキップするのに使用できます。これにより arg リスト内のダミー変数にコピー する必要がなくなります。 シークフィールドタイプ s によって、データをスキップできます。これは、’+’ 符号の存在の有無に基づき、データ内の絶対位置 (s3) または相対位置 (s+3) を 探します。シーク値は v として指定することができ、引数リストの次の整数値が シーク値として使用されます。 csio_decode_visit() は、 csio_decode() と同じように動作しますが、デコード したバッファの内容を可変長引数に配置する代わりに、デコードしたバッファの 内容は、渡された arg_put() 関数を通じてユーザに返される点が異なります。 arg_put() 関数は、次のいくつかの引数を取ります。 hook letter val count name buff_decode() は、 csio_decode() について前述した方式を使用して任意のデー タバッファをデコードします。 buff_decode_visit() は、 csio_decode_visit() について前述した方式を使用し て任意のデータバッファをデコードします。 csio_encode() は、 csio_build() について前述した方式を使用して、 ccb_scsiio の構造 data_ptr 部分 (CDB ではない ) をエンコードします。 csio_encode_visit() は、 csio_build_visit() について前述した方式を使用し て、 ccb_scsiio 構造の data_ptr 部分 (CDB ではない ) をエンコードします。 buff_encode_visit() は、 csio_build_visit() について前述した方式を使用し て、任意のデータポインタをエンコードします。 戻り値 |
csio_build(), csio_build_visit(), csio_encode(), csio_encode_visit() およ び buff_encode_visit() は、処理済みのフィールドの数を返します。 csio_decode(), csio_decode_visit(), buff_decode() および buff_decode_visit() は、実行された割り当ての数を返します。 |
関連項目
歴史
これらの関数の CAM バージョンは、古い FreeBSD の SCSI レイヤ用に実現され た類似の関数を基礎にしています。 SCSI の古いコード内のエンコード/デコード 関数は Peter Dufault が作成したものです。 多数のシステムに、ユーザ空間で SCSI コマンドをユーザが構築できる、これと 匹敵するインタフェースがあります。 古い scsireq データ構造は、SGI の /dev/scsi データ構造とほとんど同じでし た。作者の名前を知っている人はここに連絡してください。 Peter Dufault は、 1989 年の『Sun Expert』誌で、最初にこれについて読みました。 新しい CCB データ構造は、 CAM-2 および CAM-3 仕様に由来しています。 Peter Dufault は、 386BSD で SGI のインタフェースのクローンを実現しまし た。これがオリジナルの FreeBSD SCSI ライブラリと関連カーネル ioctl に至る ものになりました。互換性の必要がある場合は、dufault@hda.com に連絡してく ださい。 |
作者
Kenneth Merry が、これらのエンコードおよびデコードの関数の CAM バージョン を実現しました。この現在の作業は、Peter Dufault による以前の作業を基礎に しています。 |
バグ
CDB および SCSI CCB のデータバッファ部分の両方をエンコードする関数はおそ らく必要でしょう。 camcontrol(8) で任意のコマンド実行コードを実現している 間に私はこの必要性に気づきましたが、そのような関数を実現する時間がまだあ りません。 CCB フラグの説明には本当はここに属さないものがあります。それらは一般の CCB マニュアルページに属します。そのマニュアルページはまだ書かれていない ので、ここでの短い説明で間に合わせざるを得ません。 FreeBSD 10.0 October 13, 1998 FreeBSD 10.0 |