VMWare PVSCSI Device Interface
This document describes the VMWare PVSCSI device interface specification, based on the source code of the PVSCSI Linux driver from kernel 3.0.4.
Overview
The interface is based on a memory area shared between hypervisor and VM.
The memory area is obtained by driver as a device IO memory resource of
PVSCSI_MEM_SPACE_SIZE
length.
The shared memory consists of a registers area and a rings area.
The registers area is used to raise hypervisor interrupts and issue device
commands. The rings area is used to transfer data descriptors and SCSI
commands from VM to hypervisor and to transfer messages produced by
hypervisor to VM. Data itself is transferred via virtual scatter-gather DMA.
PVSCSI Device Registers
The length of the registers area is 1 page
(PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES
). The structure of the
registers area is described by the PVSCSIRegOffset
enum. There
are registers to issue device commands (with optional short data),
issue device interrupts, and control interrupt masking.
PVSCSI Device Rings
There are three rings in shared memory:
- Request ring (
struct PVSCSIRingReqDesc *req_ring
) ring for OS to device requests
- Completion ring (
struct PVSCSIRingCmpDesc *cmp_ring
) ring for device request completions
- Message ring (
struct PVSCSIRingMsgDesc *msg_ring
) ring for messages from device. This ring is optional and the guest might not configure it.
There is a control area (struct PVSCSIRingsState *rings_state
)
used to control rings operation.
PVSCSI Device to Host Interrupts
The following interrupt types are supported by the PVSCSI device:
Completion interrupts (completion ring notifications):
PVSCSI_INTR_CMPL_0
PVSCSI_INTR_CMPL_1
Message interrupts (message ring notifications):
PVSCSI_INTR_MSG_0
PVSCSI_INTR_MSG_1
Interrupts are controlled via the PVSCSI_REG_OFFSET_INTR_MASK
register. If a bit is set it means the interrupt is enabled, and if
it is clear then the interrupt is disabled.
The interrupt modes supported are legacy, MSI and MSI-X.
In the case of legacy interrupts, the PVSCSI_REG_OFFSET_INTR_STATUS
register is used to check which interrupt has arrived. Interrupts are
acknowledged when the corresponding bit is written to the interrupt
status register.
PVSCSI Device Operation Sequences
Startup sequence
Issue
PVSCSI_CMD_ADAPTER_RESET
commandWindows driver reads interrupt status register here
Issue
PVSCSI_CMD_SETUP_MSG_RING
command with no additional data, check status and disable device messages if error returned (Omitted if device messages disabled by driver configuration)Issue
PVSCSI_CMD_SETUP_RINGS
command, provide rings configuration asstruct PVSCSICmdDescSetupRings
Issue
PVSCSI_CMD_SETUP_MSG_RING
command again, provide rings configuration asstruct PVSCSICmdDescSetupMsgRing
Unmask completion and message (if device messages enabled) interrupts
Shutdown sequence
Mask interrupts
Flush request ring using
PVSCSI_REG_OFFSET_KICK_NON_RW_IO
Issue
PVSCSI_CMD_ADAPTER_RESET
command
Send request
Fill next free request ring descriptor
Issue
PVSCSI_REG_OFFSET_KICK_RW_IO
for R/W operations orPVSCSI_REG_OFFSET_KICK_NON_RW_IO
for other operations
Abort command
Issue
PVSCSI_CMD_ABORT_CMD
command
Request completion processing
Upon completion interrupt arrival process completion and message (if enabled) rings