ブロックドライバには、次の buf 構造体メンバーが重要です。
int b_flags; /* Buffer status */ struct buf *av_forw; /* Driver work list link */ struct buf *av_back; /* Driver work list link */ size_t b_bcount; /* # of bytes to transfer */ union { caddr_t b_addr; /* Buffer's virtual address */ } b_un; daddr_t b_blkno; /* Block number on device */ diskaddr_t b_lblkno; /* Expanded block number on device */ size_t b_resid; /* # of bytes not transferred after error */ int b_error; /* Expanded error field */ void *b_private; /* "opaque" driver private area */ dev_t b_edev; /* expanded dev field */
ここでは:
ドライバでバッファーのリストを管理するためにドライバが使用できるポインタ。av_forw ポインタと av_back ポインタの説明については、Asynchronous Data Transfers (Block Drivers)を参照してください。
デバイスによって転送されるバイト数を指定します。
データバッファーのカーネル仮想アドレス。 bp_mapin(9F) の呼び出しのあとでのみ有効です。
512 バイトの DEV_BSIZE の単位で表された、データ転送用にデバイス上に存在する、先頭の 32 ビット論理ブロック番号。ドライバは、b_blkno と b_lblkno の両方ではなく、このどちらかを使用します。
512 バイトの DEV_BSIZE の単位で表された、データ転送用にデバイス上に存在する、先頭の 64 ビット論理ブロック番号。ドライバは、b_blkno と b_lblkno の両方ではなく、このどちらかを使用します。
エラーのために転送されなかったバイト数を示すためにドライバによって設定されます。b_resid の設定の例については、Example 16–7 を参照してください。b_resid メンバーはオーバーロードされます。b_resid はまた、 disksort(9F) によっても使用されます。
転送エラーが発生した場合、ドライバによってエラー番号が設定されます。b_error は、b_flags の B_ERROR ビットとともに設定されます。エラー値の詳細については、Intro (9E) のマニュアルページを参照してください。ドライバは、b_error を直接設定するのではなく、bioerror(9F) を使用します。
buf 構造体のステータスと転送の属性を含むフラグ。B_READ が設定されている場合、buf 構造体は、デバイスからメモリーへの転送を示します。それ以外の場合、この構造体はメモリーからデバイスへの転送を示します。データ転送中にドライバでエラーが発生した場合、ドライバは、b_flags メンバーの B_ERROR フィールドを設定します。さらに、ドライバは、b_error でより具体的なエラー値を提供します。ドライバは、B_ERROR を設定するのではなく、bioerror(9F) を使用します。
注意 - ドライバが b_flags をクリアしないようにしてください。 |
ドライバの非公開データを格納するために、ドライバによって排他的に使用されます。
転送で使用されたデバイスのデバイス番号が含まれています。
デバイスドライバの strategy(9E) ルーチンには、buf 構造体ポインタを渡すことができます。ただし、b_un.b_addr によって参照されるデータバッファーは、必ずしもカーネルのアドレス空間内にマッピングされるわけではありません。そのため、ドライバはデータに直接アクセスできません。ほとんどのブロック指向のデバイスは DMA 機能を備えているため、データバッファーに直接アクセスする必要はありません。代わりに、これらのデバイスは DMA マッピングルーチンを使用して、そのデバイスの DMA エンジンがデータ転送を実行できるようにします。DMA の使用の詳細については、Chapter 9, Direct Memory Access (DMA)を参照してください。
ドライバがデータバッファーに直接アクセスする必要がある場合、そのドライバはまず、bp_mapin(9F) を使用してそのバッファーをカーネルのアドレス空間内にマッピングする必要があります。ドライバがそのデータに直接アクセスする必要がなくなった場合は、bp_mapout(9F) を使用するべきです。
注意 - bp_mapout(9F) は、そのデバイスドライバによって割り当てられ、かつ所有されているバッファーに対してのみ呼び出すべきです。ファイルシステムなどの、strategy(9E) エントリポイントを介してドライバに渡されたバッファーに対しては bp_mapout() を呼び出してはいけません。 bp_mapin(9F) は参照カウントを保持しません。bp_mapout (9F) は、デバイスドライバ上のレイヤーが依存している可能性のあるカーネルマッピングをすべて削除します。 |