IOCTL_VPCI_INVALIDATE_BLOCK IOCTL (vpci.h)

PCI Express (PCIe) 虚拟函数的驱动程序 (VF) 发出 IOCTL_VPCI_INVALIDATE_BLOCK IOCTL 请求,以便通知一个或多个 VF 配置块中的数据发生更改。 IOCTL 完成后,驱动程序会收到有关这些更改的通知。 通知后,驱动程序应假定以前从指定的 VF 配置块读取的任何数据都已无效。 因此,驱动程序应通过再次读取配置块数据来更新其缓存。

驱动程序将此 IOCTL 颁发给驱动程序堆栈中下一个较低的驱动程序。

注意 此 IOCTL 请求由支持单根 I/O 虚拟化 (SR-IOV) 接口的设备上的 PCIe VF 的驱动程序发出。
 
当驱动程序发出 IOCTL_VPCI_INVALIDATE_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 创建和初始化例程,例如 IoAllocateIrpIoReuseIrpIoInitializeIrp。 有关 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

参数DeviceIoControlIoControlCode

IOCTL_VPCI_INVALIDATE_BLOCK

参数DeviceIoControlType3InputBuffer 指向 VPCI_INVALIDATE_BLOCK_OUTPUT 结构的指针。 驱动程序使用 IOCTL_VPCI_INVALIDATE_BLOCK I/O 请求的参数设置此结构的格式。
I参数DeviceIoControlInputBufferLength VPCI_INVALIDATE_BLOCK_OUTPUT结构的大小(以字节为单位)。
参数DeviceIoControlOutputBufferLength 调用方分配的缓冲区的大小(以字节为单位),该缓冲区将包含要读取的配置数据。
注意此值必须与 VPCI_INVALIDATE_BLOCK_OUTPUT 结构的 BytesRequested 成员的值相同。
 
 

发出 IOCTL 请求

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

IOCTL 请求完成结果

IOCTL_VPCI_INVALIDATE_BLOCK IOCTL 请求完成后,调用方分配IO_STATUS_BLOCK结构的成员将设置为下表中的值。

状态值
Status STATUS_SUCCESS
信息 零个
 

IOCTL_VPCI_INVALIDATE_BLOCK IOCTL 发布并完成时,VF 驱动程序会收到通知,指出 PF 驱动程序已更改 (一个或多个 VF 配置块中的) 数据 无效

注意 操作系统保留和管理成功完成此 IOCTL 所需的资源。
 
VF 配置块用于 PCIe PF 的驱动程序与支持 SR-IOV 接口的设备上的 VF 之间的反向通道通信。 VF 配置数据可以在以下驱动程序之间交换:
  • VF 驱动程序,在来宾操作系统中运行。 此操作系统在 Hyper-V 子分区中运行。
  • 在管理操作系统中运行的 PF 驱动程序。

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

从 NDIS 6.30 开始,VF 微型端口驱动程序不应发出 IOCTL_VPCI_INVALIDATE_BLOCK 请求。 相反,执行以下步骤是为了处理无效的 VF 配置块数据的通知。
  1. 在来宾 OS 中,NDIS 发出 IOCTL_VPCI_INVALIDATE_BLOCK 请求。
  2. 在管理 OS 中,将执行以下步骤:
    1. PF 微型端口驱动程序调用 NdisMInvalidateConfigBlock 函数,以通知 NDIS VF 配置数据已更改且不再有效。 驱动程序将 BlockMask 参数设置为 ULONGLONG 位掩码,该位掩码指定哪些 VF 配置块已更改。 位掩码中的每个位对应于一个 VF 配置块。 如果将位设置为 1,则相应 VF 配置块中的数据已更改。
    2. NDIS 向在管理 OS 中运行的虚拟化堆栈发出有关 VF 配置块数据更改的信号。 虚拟化堆栈缓存 BlockMask 参数数据。
      注意 每次 PF 微型端口驱动程序调用 NdisMInvalidateConfigBlock 时,虚拟化堆栈 BlockMask 参数数据与缓存中的当前值一起。
       
    3. 虚拟化堆栈会通知虚拟 PCI (VPCI) 驱动程序(在来宾 OS 中运行)VF 配置数据失效。 虚拟化堆栈将缓存的 BlockMask 参数数据发送到 VPCI 驱动程序。
  3. 在来宾 OS 中,将执行以下步骤:
    1. VPCI 驱动程序将缓存的 BlockMask 参数数据保存在与IOCTL_VPCI_INVALIDATE_BLOCK请求关联的VPCI_INVALIDATE_BLOCK_OUTPUT结构的 BlockMask 成员中。
    2. VPCI 驱动程序成功完成 IOCTL_VPCI_INVALIDATE_BLOCK 请求。 发生这种情况时,NDIS 会向 VF 微型端口驱动程序发出对象标识符 (OID ) OID_SRIOV_VF_INVALIDATE_CONFIG_BLOCK 请求。 指向 NDIS_SRIOV_VF_INVALIDATE_CONFIG_BLOCK_INFO 结构的指针在 OID 请求中传递。 此结构包含缓存的 BlockMask 参数数据。

      NDIS 还发出另一个 IOCTL_VPCI_INVALIDATE_BLOCK 请求,用于处理 VF 配置数据更改的连续通知。

    3. 当 VF 驱动程序处理 OID_SRIOV_VF_INVALIDATE_CONFIG_BLOCK 请求时,它会从指定的 VF 配置块读取数据。
注意 VF 配置块的用法及其配置数据的格式由设备的独立硬件供应商 (IHV) 定义。 配置数据仅由 PF 和 VF 的驱动程序使用。
 

要求

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

另请参阅

IO_STATUS_BLOCK

VPCI_INVALIDATE_BLOCK_OUTPUT

NdisMInvalidateConfigBlock

IRP_MJ_INTERNAL_DEVICE_CONTROL

在驱动程序中创建 IOCTL 请求

IRP

IO_STACK_LOCATION

IoCallDriver

OID_SRIOV_VF_INVALIDATE_CONFIG_BLOCK

NDIS_SRIOV_VF_INVALIDATE_CONFIG_BLOCK_INFO