IOCTL_VPCI_WRITE_BLOCK IOCTL (IOCTL_VPCI_WRITE_BLOCK IOCTL_VPCI_WRITE_BLOCK

PCI Express(PCIe)虚拟函数(VF)的驱动程序发出 IOCTL_VPCI_WRITE_BLOCK I/O 控制代码(IOCTL),以便将数据写入 VF 配置块。 驱动程序将此 IOCTL 颁发给驱动程序堆栈中的下一个较低驱动程序。

注意 此 IOCTL 请求是由支持单个根 I/O 虚拟化(SR-IOV)接口的设备上的 PCIe VF 驱动程序颁发的。
 
当驱动程序发出 IOCTL_VPCI_WRITE_BLOCK IOCTL 时,驱动程序必须执行以下步骤:
准备 I/O 请求数据包结构
准备 I/O 堆栈位置结构
发出 IOCTL 请求
IOCTL 请求完成结果
有关在内核模式驱动程序之间发出 IOCTL 的详细信息,请参阅 在驱动程序中创建 IOCTL 请求

主要代码

IRP_MJ_DEVICE_CONTROL

状态块

Irp->IoStatus.Status 设置为STATUS_SUCCESS(如果请求成功)。

否则,状态为相应的错误条件作为 NTSTATUS 代码。

有关详细信息,请参阅 [XREF-LINK:NTSTATUS 值]。

言论

准备 I/O 请求数据包结构

驱动程序必须首先分配或重复使用 I/O 请求数据包(IRP)。 可以使用 IoBuildDeviceIoControlRequest 例程专门分配 IOCTL IRP。 还可以使用常规用途 IRP 创建和初始化例程,例如 IoAllocateIrpIoReuseIrp,或 IoInitializeIrp。 有关 IRP 分配的详细信息,请参阅 为 Lower-Level 驱动程序创建 IRP

然后,驱动程序必须设置 IRP 结构的成员,如下表所述。

IRP 成员 价值
UserBuffer NULL
UserEvent 调用 KeInitializeEvent 例程时初始化的事件对象的地址。
注意 如果不需要异步完成 IOCTL 请求,则应将此成员设置为 NULL。 有关详细信息,请参阅 在驱动程序中创建 IOCTL 请求
 
UserIosb 调用方分配 IO_STATUS_BLOCK 结构的地址。 此结构由较低驱动程序更新,以指示 I/O 请求的最终状态。
 

准备 I/O 堆栈位置结构

驱动程序调用 IoGetNextIrpStackLocation 例程来访问较低驱动程序的 I/O 堆栈位置。 此函数返回指向包含 I/O 堆栈位置参数的 IO_STACK_LOCATION 结构的指针。

然后,驱动程序必须在 IO_STACK_LOCATION 结构中设置成员,如下表所述:

IO_STACK_LOCATION成员 价值
MajorFunction

IRP_MJ_INTERNAL_DEVICE_CONTROL

Parameters.DeviceIoControl.IoControlCode

IOCTL_VPCI_WRITE_BLOCK

Parameters.DeviceIoControl.Type3InputBuffer 指向 VPCI_WRITE_BLOCK_INPUT 结构的指针。 驱动程序使用 IOCTL_VPCI_WRITE_BLOCK I/O 请求的参数设置此结构的格式。
IParameters.DeviceIoControl.InputBufferLength VPCI_WRITE_BLOCK_INPUT 结构的大小(以字节为单位)。
Parameters.DeviceIoControl.OutputBufferLength
 

发出 IOCTL 请求

若要发出此 IOCTL 请求,驱动程序调用 IoCallDriver 例程,以将请求传递到驱动程序堆栈中的下一个较低驱动程序。 驱动程序设置 IoCallDriver 的参数,如下表所述。
IoCallDriver 参数 价值
DeviceObject 较低驱动程序的设备对象。
Irp 以前分配和初始化的 IRP 的地址。 有关详细信息,请参阅 准备 I/O 请求数据包(IRP)结构
 

IOCTL 请求完成结果

IOCTL_VPCI_WRITE_BLOCK IOCTL 请求完成后,调用方分配 IO_STATUS_BLOCK 结构的 状态 成员设置为下表中的值之一:
状态值 描述
STATUS_SUCCESS IOCTL 已成功完成。
STATUS_PENDING IOCTL 尚未完成。 驱动程序必须调用 KeWaitForSingleObject 例程才能将当前线程置于等待状态。 驱动程序将 Object 参数设置为调用 KeInitializeEvent 例程时初始化的事件对象的地址。

当 IOCTL 请求完成时,会发出该事件信号。 发出事件信号后,线程将恢复执行。

STATUS_BUFFER_TOO_SMALL Parameters.DeviceIoControl.InputBufferLength 成员设置为小于 VPCI_WRITE_BLOCK_INPUT 结构的大小(以字节为单位)的值。
 

如果请求成功完成,则 IO_STATUS_BLOCK 结构的 信息 成员设置为写入的字节数。 否则,信息 成员设置为零。

发出 IOCTL_VPCI_WRITE_BLOCK IOCTL 时,系统会通知 PCIe 物理函数(PF)的驱动程序将数据写入指定的 VF 配置块。

注意作系统保留和管理成功完成此 IOCTL 所需的资源。
 
VF 配置块用于 PCIe PF 的驱动程序与支持 SR-IOV 接口的设备上的 VF 之间的反向通道通信。 PF 驱动程序在设备的 PCI 配置空间未使用的块内为每个 VF 分配配置块。

分配 VF 配置块后,可以在以下驱动程序之间以受保护的方式交换 VF 配置数据:

  • 在来宾作系统中运行的 VF 驱动程序。 此作系统在 Hyper-V 子分区中运行。
  • 在管理作系统中运行的 PF 驱动程序。

    此作系统在 Hyper-V 父分区中运行。

VF 配置块的用法及其配置数据的格式由设备的独立硬件供应商(IHV)定义。 配置数据仅由 PF 和 VF 的驱动程序使用。
注释IOCTL_VPCI_WRITE_BLOCK IOCTL 提供 WriteVfConfigBlock 例程的异步替代方法。
 

要求

要求 价值
最低支持的客户端 在 Windows Server 2012 及更高版本的 Windows 中可用。
标头 hpi.h (包括 Wdm.h)
IRQL DISPATCH_LEVEL

另请参阅

IO_STATUS_BLOCK

IRP_MJ_INTERNAL_DEVICE_CONTROL

WriteVfConfigBlock

在驱动程序中创建 IOCTL 请求

IRP

VPCI_WRITE_BLOCK_INPUT

IO_STACK_LOCATION

IoCallDriver