WindowsGuestDrivers/viostor/documentation: Difference between revisions
No edit summary |
No edit summary |
||
(4 intermediate revisions by the same user not shown) | |||
Line 58: | Line 58: | ||
| Windows Server 2003 INF file. | | Windows Server 2003 INF file. | ||
|} | |} | ||
= Main Declarations and Data Structures = | |||
== VirtIO block device configuration descriptor == | |||
typedef struct virtio_blk_config { | |||
u64 capacity; /* The capacity (in 512-byte sectors). */ | |||
u32 size_max; /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */ | |||
u32 seg_max; /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ | |||
struct virtio_blk_geometry { /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ | |||
u16 cylinders; | |||
u8 heads; | |||
u8 sectors; | |||
} geometry; | |||
u32 blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ | |||
}blk_config, *pblk_config; | |||
== Miniport driver's per-HBA extension == | |||
typedef struct _ADAPTER_EXTENSION { | |||
ULONG_PTR device_base; /* device base address */ | |||
virtio_pci_vq_info pci_vq_info; /* pci virtual queue information block*/ | |||
vring_virtqueue* virtqueue; /* virtual queue pointer*/ | |||
INQUIRYDATA inquiry_data;/* inquiry data block */ | |||
blk_config info; /* block device configutation block */ | |||
ULONG breaks_number;/* number of phisical breaks to adjust the PORT_CONFIGURATION_INFORMATION */ | |||
ULONG transfer_size;/* maximum transfer size to adjust the PORT_CONFIGURATION_INFORMATION */ | |||
ULONG queue_depth; /* maximum depth of the device queue */ | |||
BOOLEAN dump_mode; /* runningin crash-dump mode*/ | |||
}ADAPTER_EXTENSION, *PADAPTER_EXTENSION; | |||
== VirtIO request header == | |||
typedef struct virtio_blk_outhdr { | |||
u32 type; /* VIRTIO_BLK_T* */ | |||
u32 ioprio; /* io priority. Always 0*/ | |||
u64 sector; /* Sector (ie. 512 byte offset) */ | |||
}blk_outhdr, *pblk_outhdr; | |||
== VirtIO request descriptor == | |||
typedef struct virtio_blk_req { | |||
struct list_head list; /* currently not in use*/ | |||
struct request *req; /* pointer to SRB*/ | |||
blk_outhdr out_hdr; /* runningin crash-dump mode*/ | |||
u8 status; /* request completion status */ | |||
VIO_SG sg[VIRTIO_MAX_SG]; /* buffer that holdes scatter-gather list*/ | |||
}blk_req, *pblk_req; | |||
== Miniport driver's per-SRB extension == | |||
typedef struct _RHEL_SRB_EXTENSION { | |||
blk_req vbr; /* request descriptor block */ | |||
ULONG out; /* number of OUT elements */ | |||
ULONG in; /* number of IN elements */ | |||
}RHEL_SRB_EXTENSION, *PRHEL_SRB_EXTENSION; | |||
= Functions = | |||
== VirtIO Storport miniport driver routines == | |||
=== VirtIoFindAdapter === | |||
The '''VirtIoFindAdapter''' routine uses the supplied configuration to determine whether a VirtIO HBA is supported and, if it is, to return configuration information about that adapter | |||
ULONG | |||
VirtIoFindAdapter( | |||
IN PVOID DeviceExtension, | |||
IN PVOID HwContext, | |||
IN PVOID BusInformation, | |||
IN PCHAR ArgumentString, | |||
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, | |||
OUT PBOOLEAN Again | |||
); | |||
=== VirtIoHwInitialize === | |||
The '''VirtIoHwInitialize''' routine initializes the miniport driver after system reboot or power failure occurs. It is called by StorPort after '''VirtIoFindAdapter''' successfully returns. '''VirtIoHwInitialize''' initializes the VirtIO HBA. | |||
BOOLEAN | |||
VirtIoHwInitialize( | |||
IN PVOID DeviceExtension | |||
); | |||
=== VirtIoBuildIo === | |||
The '''VirtIoBuildIo''' routine processes the SRB with unsynchronized access to shared system data structures before passing it to '''VirtIoStartIo'''. | |||
BOOLEAN | |||
VirtIoBuildIo( | |||
IN PVOID DeviceExtension, | |||
IN PSCSI_REQUEST_BLOCK Srb | |||
); | |||
=== VirtIoStartIo === | |||
The Storport driver calls the '''VirtIoStartIo''' routine one time for each incoming I/O request. | |||
BOOLEAN | |||
VirtIoStartIo( | |||
IN PVOID DeviceExtension, | |||
IN PSCSI_REQUEST_BLOCK Srb | |||
); | |||
=== VirtIoInterrupt === | |||
The Storport driver calls the '''VirtIoInterrupt''' routine after the VirtIO HBA generates an interrupt request. | |||
BOOLEAN | |||
VirtIoInterrupt( | |||
IN PVOID DeviceExtension | |||
); | |||
=== VirtIoResetBus === | |||
The '''VirtIoResetBus''' routine is called by the port driver to clear error conditions. | |||
BOOLEAN | |||
VirtIoResetBus( | |||
IN PVOID DeviceExtension, | |||
IN ULONG PathId | |||
); | |||
=== VirtIoAdapterControl === | |||
The '''VirtIoAdapterControl''' routine is called to perform synchronous operations to control the state or behavior of an adapter, such as stopping or restarting the VirtIO HBA for power management. | |||
SCSI_ADAPTER_CONTROL_STATUS | |||
VirtIoAdapterControl( | |||
IN PVOID DeviceExtension, | |||
IN SCSI_ADAPTER_CONTROL_TYPE ControlType, | |||
IN PVOID Parameters | |||
); | |||
== VirtIO support routines == | |||
=== VirtIODeviceReset === | |||
The '''VirtIODeviceReset''' routine is called from '''RhelShutDown''' routine to perform the VirtIO device reset. | |||
VOID | |||
VirtIODeviceReset( | |||
IN PVOID DeviceExtension); | |||
=== VirtIODeviceGetHostFeature === | |||
The '''VirtIODeviceGetHostFeature''' routine is called from '''VirtIoHwInitialize''' routine to obtain the VirtIO device feature. | |||
bool | |||
VirtIODeviceGetHostFeature( | |||
IN PVOID DeviceExtension, | |||
IN unsigned uFeature); | |||
=== VirtIODeviceGet === | |||
The '''VirtIODeviceGet''' routine is called from '''VirtIoHwInitialize''' routine to obtain a block of unformatted data by reading the VirtIO device PCI configuration space. | |||
void | |||
VirtIODeviceGet( | |||
IN PVOID DeviceExtension, | |||
unsigned offset, | |||
PVOID buf, | |||
unsigned len); | |||
=== VirtIODeviceISR === | |||
The '''VirtIODeviceISR''' routine is called from '''VirtIoInterrupt''' routine to obtain an interrupt status. | |||
UCHAR | |||
VirtIODeviceISR( | |||
IN PVOID DeviceExtension); | |||
=== VirtIODeviceFindVirtualQueue === | |||
The '''VirtIODeviceFindVirtualQueue''' routine is called from '''VirtIoFindAdapter''' and '''VirtIoAdapterControl''' routines to create or re-create a virtual queue. | |||
struct | |||
virtqueue* | |||
VirtIODeviceFindVirtualQueue( | |||
IN PVOID DeviceExtension, | |||
IN unsigned index); | |||
== Miscellaneous routines == | |||
=== RhelDoReadWrite === | |||
The '''RhelDoReadWrite''' routine is called from '''VirtIoStartIo''' routine. It passes an array of scatter gather elements to VirtIO queue by calling the '''add_buf''' and, if the above operation was ok, calls kick routines. | |||
BOOLEAN | |||
RhelDoReadWrite( | |||
IN PVOID DeviceExtension, | |||
PSCSI_REQUEST_BLOCK Srb | |||
); | |||
=== RhelShutDown === | |||
The '''RhelShutDown''' routine is called from '''VirtIoAdapterControl''' routine in response to ScsiStopAdapter request to delete a virtual queue and reset the underlying VirtIO device. | |||
VOID | |||
RhelShutDown( | |||
IN PVOID DeviceExtension | |||
); | |||
=== RhelDbgPrintToComPort === | |||
The '''RhelDbgPrintToComPort''' routine is called from everywhere to output debug print to COM1 port. | |||
ULONG | |||
_cdecl | |||
RhelDbgPrintToComPort( | |||
__in LPTSTR Format, | |||
... | |||
); | |||
= How to build = | |||
Run the appropriated WDK build environment. | |||
Go to the viostor project directory and run "build –cegZ" command. | |||
= Debugging = | |||
Even though live debugging is possible and sometimes highly desirable, in most cases debugging by printing is good enough to find a problem. | |||
Debug printing verbosity can be changed by adjusting RhelDbgLevel variable defined in virtio_stor.c file. | |||
Different levels of verbosity are defined in virtio_store_utilities.h file | |||
#define TRACE_LEVEL_NONE 0 // Tracing is not on | |||
#define TRACE_LEVEL_FATAL 1 // Abnormal exit or termination | |||
#define TRACE_LEVEL_ERROR 2 // Severe errors that need logging | |||
#define TRACE_LEVEL_WARNING 3 // Warnings such as allocation failure | |||
#define TRACE_LEVEL_INFORMATION 4 // Includes non-error cases(e.g.,Entry-Exit) | |||
#define TRACE_LEVEL_VERBOSE 5 // Detailed traces from intermediate steps | |||
Debug output to COM1 port can be turned on by uncommiting the following string in SOURCES file: | |||
#C_DEFINES = -DRHEL_COM_DEBUG=1 $(C_DEFINES) | |||
= Useful information = | |||
Find everything you need here: | |||
[http://msdn.microsoft.com/en-us/library/aa508893.aspx Storport Miniport Drivers] | |||
= VirtIO block for XP = | |||
An old style, SCSIPort driver, can be created by building the code in XP environment. However, due to the lack of resources SCSIPort driver has never been fully tested and currently is unsupported. |
Latest revision as of 04:19, 3 August 2009
STORPORT miniport driver for VIRTIO based SCSI controller
Scope
VirtIO miniport driver works together with the Storport driver. Storport miniport driver is a vendor-supplied driver used to access hardware. The following document describes VirtIO Storport miniport driver design goals and implementation. Detailed description of VirtIO itself is out of the scope and will not be covered in this document.
Code tour
File | Description |
virtio_store.c | Main source module for the miniport. |
virtio_store.h | Main include file for the miniport. |
virtio_store.rc | Resource definitions. |
virtio_store_utils.c | Source file for print to COM port routine. |
virtio_store_utils.h | Include file containing debugging and debugging print related definitions. |
virtio_store_hw_helper.c | Source file containing some "HW" related routines. |
virtio_store_hw_helper.h | Include file containing definitions for some "HW" related routines. |
osdep.h | Include OS dependent definitions. |
VirtIO.h | Include file containing VirtIO queue related definitions. |
virtio_pci.c | Source file for VirtIO PCI device routines. |
virtio_pci.h | Include file for VirtIO PCI device. |
virtio_ring.c | Source file for VirtIO ring routines. |
virtio_ring.h | Include file for VirtIO ring definitions. |
txtsetup.oem | Windows Server 2003 text-mode setup file. |
wlh.inf | Windows Server 2008 INF file. |
wnet.inf | Windows Server 2003 INF file. |
Main Declarations and Data Structures
VirtIO block device configuration descriptor
typedef struct virtio_blk_config {
u64 capacity; /* The capacity (in 512-byte sectors). */ u32 size_max; /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */ u32 seg_max; /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ struct virtio_blk_geometry { /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ u16 cylinders; u8 heads; u8 sectors; } geometry; u32 blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
}blk_config, *pblk_config;
Miniport driver's per-HBA extension
typedef struct _ADAPTER_EXTENSION {
ULONG_PTR device_base; /* device base address */ virtio_pci_vq_info pci_vq_info; /* pci virtual queue information block*/ vring_virtqueue* virtqueue; /* virtual queue pointer*/ INQUIRYDATA inquiry_data;/* inquiry data block */ blk_config info; /* block device configutation block */ ULONG breaks_number;/* number of phisical breaks to adjust the PORT_CONFIGURATION_INFORMATION */ ULONG transfer_size;/* maximum transfer size to adjust the PORT_CONFIGURATION_INFORMATION */ ULONG queue_depth; /* maximum depth of the device queue */ BOOLEAN dump_mode; /* runningin crash-dump mode*/
}ADAPTER_EXTENSION, *PADAPTER_EXTENSION;
VirtIO request header
typedef struct virtio_blk_outhdr {
u32 type; /* VIRTIO_BLK_T* */ u32 ioprio; /* io priority. Always 0*/ u64 sector; /* Sector (ie. 512 byte offset) */
}blk_outhdr, *pblk_outhdr;
VirtIO request descriptor
typedef struct virtio_blk_req {
struct list_head list; /* currently not in use*/ struct request *req; /* pointer to SRB*/ blk_outhdr out_hdr; /* runningin crash-dump mode*/ u8 status; /* request completion status */ VIO_SG sg[VIRTIO_MAX_SG]; /* buffer that holdes scatter-gather list*/
}blk_req, *pblk_req;
Miniport driver's per-SRB extension
typedef struct _RHEL_SRB_EXTENSION {
blk_req vbr; /* request descriptor block */ ULONG out; /* number of OUT elements */ ULONG in; /* number of IN elements */
}RHEL_SRB_EXTENSION, *PRHEL_SRB_EXTENSION;
Functions
VirtIO Storport miniport driver routines
VirtIoFindAdapter
The VirtIoFindAdapter routine uses the supplied configuration to determine whether a VirtIO HBA is supported and, if it is, to return configuration information about that adapter
ULONG VirtIoFindAdapter(
IN PVOID DeviceExtension, IN PVOID HwContext, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again );
VirtIoHwInitialize
The VirtIoHwInitialize routine initializes the miniport driver after system reboot or power failure occurs. It is called by StorPort after VirtIoFindAdapter successfully returns. VirtIoHwInitialize initializes the VirtIO HBA.
BOOLEAN VirtIoHwInitialize(
IN PVOID DeviceExtension );
VirtIoBuildIo
The VirtIoBuildIo routine processes the SRB with unsynchronized access to shared system data structures before passing it to VirtIoStartIo.
BOOLEAN VirtIoBuildIo(
IN PVOID DeviceExtension, IN PSCSI_REQUEST_BLOCK Srb );
VirtIoStartIo
The Storport driver calls the VirtIoStartIo routine one time for each incoming I/O request.
BOOLEAN VirtIoStartIo(
IN PVOID DeviceExtension, IN PSCSI_REQUEST_BLOCK Srb );
VirtIoInterrupt
The Storport driver calls the VirtIoInterrupt routine after the VirtIO HBA generates an interrupt request.
BOOLEAN VirtIoInterrupt(
IN PVOID DeviceExtension );
VirtIoResetBus
The VirtIoResetBus routine is called by the port driver to clear error conditions.
BOOLEAN VirtIoResetBus(
IN PVOID DeviceExtension, IN ULONG PathId );
VirtIoAdapterControl
The VirtIoAdapterControl routine is called to perform synchronous operations to control the state or behavior of an adapter, such as stopping or restarting the VirtIO HBA for power management.
SCSI_ADAPTER_CONTROL_STATUS VirtIoAdapterControl(
IN PVOID DeviceExtension, IN SCSI_ADAPTER_CONTROL_TYPE ControlType, IN PVOID Parameters );
VirtIO support routines
VirtIODeviceReset
The VirtIODeviceReset routine is called from RhelShutDown routine to perform the VirtIO device reset.
VOID VirtIODeviceReset(
IN PVOID DeviceExtension);
VirtIODeviceGetHostFeature
The VirtIODeviceGetHostFeature routine is called from VirtIoHwInitialize routine to obtain the VirtIO device feature.
bool VirtIODeviceGetHostFeature(
IN PVOID DeviceExtension, IN unsigned uFeature);
VirtIODeviceGet
The VirtIODeviceGet routine is called from VirtIoHwInitialize routine to obtain a block of unformatted data by reading the VirtIO device PCI configuration space.
void VirtIODeviceGet(
IN PVOID DeviceExtension, unsigned offset, PVOID buf, unsigned len);
VirtIODeviceISR
The VirtIODeviceISR routine is called from VirtIoInterrupt routine to obtain an interrupt status.
UCHAR VirtIODeviceISR(
IN PVOID DeviceExtension);
VirtIODeviceFindVirtualQueue
The VirtIODeviceFindVirtualQueue routine is called from VirtIoFindAdapter and VirtIoAdapterControl routines to create or re-create a virtual queue.
struct virtqueue* VirtIODeviceFindVirtualQueue(
IN PVOID DeviceExtension, IN unsigned index);
Miscellaneous routines
RhelDoReadWrite
The RhelDoReadWrite routine is called from VirtIoStartIo routine. It passes an array of scatter gather elements to VirtIO queue by calling the add_buf and, if the above operation was ok, calls kick routines.
BOOLEAN RhelDoReadWrite(
IN PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb );
RhelShutDown
The RhelShutDown routine is called from VirtIoAdapterControl routine in response to ScsiStopAdapter request to delete a virtual queue and reset the underlying VirtIO device.
VOID RhelShutDown(
IN PVOID DeviceExtension );
RhelDbgPrintToComPort
The RhelDbgPrintToComPort routine is called from everywhere to output debug print to COM1 port.
ULONG _cdecl RhelDbgPrintToComPort(
__in LPTSTR Format, ... );
How to build
Run the appropriated WDK build environment. Go to the viostor project directory and run "build –cegZ" command.
Debugging
Even though live debugging is possible and sometimes highly desirable, in most cases debugging by printing is good enough to find a problem. Debug printing verbosity can be changed by adjusting RhelDbgLevel variable defined in virtio_stor.c file. Different levels of verbosity are defined in virtio_store_utilities.h file
- define TRACE_LEVEL_NONE 0 // Tracing is not on
- define TRACE_LEVEL_FATAL 1 // Abnormal exit or termination
- define TRACE_LEVEL_ERROR 2 // Severe errors that need logging
- define TRACE_LEVEL_WARNING 3 // Warnings such as allocation failure
- define TRACE_LEVEL_INFORMATION 4 // Includes non-error cases(e.g.,Entry-Exit)
- define TRACE_LEVEL_VERBOSE 5 // Detailed traces from intermediate steps
Debug output to COM1 port can be turned on by uncommiting the following string in SOURCES file:
- C_DEFINES = -DRHEL_COM_DEBUG=1 $(C_DEFINES)
Useful information
Find everything you need here: Storport Miniport Drivers
VirtIO block for XP
An old style, SCSIPort driver, can be created by building the code in XP environment. However, due to the lack of resources SCSIPort driver has never been fully tested and currently is unsupported.