编写适用于 Oracle® Solaris 11.2 的设备驱动程序

退出打印视图

更新时间: 2014 年 9 月
 
 

buf 结构

以下 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

驱动程序可用以管理其使用的一组缓冲区的指针。有关 av_forw 和 av_back 指针的讨论,请参见Asynchronous Data Transfers (Block Drivers)

b_bcount

指定要由设备传输的字节数。

b_un.b_addr

数据缓冲区的内核虚拟地址。仅在进行 bp_mapin(9F) 调用后有效。

b_blkno

设备上用于数据传输的起始 32 位逻辑块编号,以 DEV_BSIZE(512 字节)为单位。驱动程序应使用 b_blkno 或 b_lblkno,但不能同时使用两者。

b_lblkno

设备上用于数据传输的起始 64 位逻辑块编号,以 DEV_BSIZE(512 字节)为单位。驱动程序应使用 b_blkno 或 b_lblkno,但不能同时使用两者。

b_resid

由驱动程序设置的用于表明由于发生错误而未传输的字节数。有关设置 b_resid 的示例,请参见Example 16–7。b_resid 成员会过载。此外,disksort(9F) 也会使用 b_resid。

b_error

当发生传输错误时,由驱动程序设置为错误编号。b_error 应与 b_flags B_ERROR 位一起设置。有关错误值的详细信息,请参见 Intro(9E) 手册页。驱动程序应使用 bioerror(9F),而不是直接设置 b_error。

b_flags

表示 buf 结构的状态属性和传输属性的标志。如果设置了 B_READ,则 buf 结构指明从设备到内存的传输。否则,此结构指明从内存到设备的传输。如果在数据传输期间驱动程序遇到错误,则该驱动程序应设置 b_flags 成员中的 B_ERROR 字段。此外,该驱动程序还应在 b_error 中提供一个更明确的错误值。驱动程序应使用 bioerror(9F),而不是设置 B_ERROR


Caution

注意  - 驱动程序绝不能清除 b_flags


b_private

专供驱动程序存储驱动程序专用数据。

b_edev

包含用于传输的设备的设备编号。

bp_mapin 结构

可以将 buf 结构指针传递到设备驱动程序的 strategy(9E) 例程。但是,b_un.b_addr 引用的数据缓冲区不一定映射到内核地址空间中。因此,驱动程序无法直接访问数据。大多数面向块的设备具有 DMA 功能,因此不需要直接访问数据缓冲区。这些设备改为使用 DMA 映射例程以使设备的 DMA 引擎进行数据传输。有关使用 DMA 的详细信息,请参见Chapter 9, Direct Memory Access (DMA)

如果驱动程序需要直接访问数据缓冲区,则该驱动程序必须首先使用 bp_mapin(9F) 将缓冲区映射到内核地址空间。当驱动程序不再需要直接访问数据时,应使用 bp_mapout(9F)


Caution

注意  - 只应对已分配且由设备驱动程序拥有的缓冲区调用 bp_mapout(9F)。不得对通过 strategy(9E) 入口点传递到驱动程序的缓冲区(如文件系统)调用 bp_mapout()bp_mapin(9F) 不保留引用计数。bp_mapout(9F) 将删除设备驱动程序之上的层所依赖的任何内核映射。