From: Vadim Rozenfeld <vrozenfe@redhat.com>
To: kvm@vger.kernel.org
Subject: [PATCH] viostor driver. Add MSI-X support
Date: Sun, 25 Oct 2009 13:16:51 +0200 [thread overview]
Message-ID: <4AE433A3.6000106@redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 25697 bytes --]
repository: /home/vadimr/shares/kvm-guest-drivers-windows
branch: master
commit 8d7431f1080345c06abdb2ec334fb654da2a59fa
Author: Vadim Rozenfeld<vrozenfe@redhat.com>
Date: Sun Oct 25 13:04:09 2009 +0200
[PATCH] Add MSI-X support
Signed-off-by: Vadim Rozenfeld<vrozenfe@redhat.com>
diff --git a/viostor/SOURCES b/viostor/SOURCES
index 561cfc0..1352710 100644
--- a/viostor/SOURCES
+++ b/viostor/SOURCES
@@ -6,6 +6,7 @@ C_DEFINES = -DUSE_STORPORT=1 $(C_DEFINES)
TARGETLIBS=$(SDK_LIB_PATH)\storport.lib
!elseif "$(DDK_TARGET_OS)" == "WinLH"
C_DEFINES = -DUSE_STORPORT=1 $(C_DEFINES)
+C_DEFINES = -DMSI_SUPPORTED=1 $(C_DEFINES)
TARGETLIBS=$(SDK_LIB_PATH)\storport.lib
!else
TARGETLIBS=$(SDK_LIB_PATH)\scsiport.lib
diff --git a/viostor/virtio_pci.c b/viostor/virtio_pci.c
index 6bf26cc..9d47763 100644
--- a/viostor/virtio_pci.c
+++ b/viostor/virtio_pci.c
@@ -86,7 +86,7 @@ VirtIODeviceGet(
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s\n", __FUNCTION__));
- ioaddr = adaptExt->device_base + VIRTIO_PCI_CONFIG + offset;
+ ioaddr = adaptExt->device_base + VIRTIO_PCI_CONFIG((adaptExt->msix_vectors> 0)) + offset;
for (i = 0; i< len; i++) {
ptr[i] = ScsiPortReadPortUchar((PUCHAR)(ioaddr + i));
@@ -125,7 +125,8 @@ struct
virtqueue*
VirtIODeviceFindVirtualQueue(
IN PVOID DeviceExtension,
- IN unsigned index)
+ IN unsigned index,
+ IN unsigned vector)
{
virtio_pci_vq_info *info;
struct virtqueue *vq;
@@ -133,9 +134,20 @@ VirtIODeviceFindVirtualQueue(
ULONG dummy;
PHYSICAL_ADDRESS pa;
ULONG pageNum;
+ unsigned res;
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s\n", __FUNCTION__));
+ RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s index = %d, vector = %d\n", __FUNCTION__, index, vector));
+
+ if(vector) {
+ ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_MSI_CONFIG_VECTOR),(USHORT)0);
+ res = ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_MSI_CONFIG_VECTOR));
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> VIRTIO_MSI_CONFIG_VECTOR res = 0x%x\n", __FUNCTION__, res));
+ if(res == VIRTIO_MSI_NO_VECTOR) {
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> Cannot find config vector res = 0x%x\n", __FUNCTION__, res));
+ return NULL;
+ }
+ }
// Select the queue we're interested in
ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_PCI_QUEUE_SEL),(USHORT)index);
@@ -144,7 +156,7 @@ VirtIODeviceFindVirtualQueue(
num = ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_PCI_QUEUE_NUM));
RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>>> [vp_dev->addr + VIRTIO_PCI_QUEUE_NUM] = %x\n", __FUNCTION__, num) );
- if (!num || ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_PCI_QUEUE_PFN)))
+ if (!num || ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + VIRTIO_PCI_QUEUE_PFN)))
return NULL;
// allocate and fill out our structure the represents an active queue
@@ -174,7 +186,18 @@ VirtIODeviceFindVirtualQueue(
pageNum = (ULONG)(pa.QuadPart>> PAGE_SHIFT);
RhelDbgPrint(TRACE_LEVEL_FATAL, ("[%s] queue phys.address %08lx:%08lx, pfn %lx\n", __FUNCTION__, pa.u.HighPart, pa.u.LowPart, pageNum));
ScsiPortWritePortUlong((PULONG)(adaptExt->device_base + VIRTIO_PCI_QUEUE_PFN),(ULONG)(pageNum));
-
+
+ if(vector) {
+ ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_MSI_QUEUE_VECTOR),(USHORT)vector);
+ res = ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_MSI_QUEUE_VECTOR));
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> VIRTIO_MSI_QUEUE_VECTOR vector = %d, res = 0x%x\n", __FUNCTION__, vector, res));
+ if(res == VIRTIO_MSI_NO_VECTOR) {
+ ScsiPortWritePortUlong((PULONG)(adaptExt->device_base + VIRTIO_PCI_QUEUE_PFN),(ULONG)0);
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> Cannot create vq vector\n", __FUNCTION__));
+ return NULL;
+ }
+ }
+
return vq;
}
diff --git a/viostor/virtio_pci.h b/viostor/virtio_pci.h
index fc31163..8f99e18 100644
--- a/viostor/virtio_pci.h
+++ b/viostor/virtio_pci.h
@@ -52,7 +52,15 @@
/* The remaining space is defined by each driver as the per-driver
* configuration space */
-#define VIRTIO_PCI_CONFIG 20
+#define VIRTIO_PCI_CONFIG(msix_enabled) (msix_enabled ? 24 : 20)
+
+/* MSI-X registers: only enabled if MSI-X is enabled. */
+/* A 16-bit vector for configuration changes. */
+#define VIRTIO_MSI_CONFIG_VECTOR 20
+/* A 16-bit vector for selected queue notifications. */
+#define VIRTIO_MSI_QUEUE_VECTOR 22
+/* Vector value used to disable MSI for queue */
+#define VIRTIO_MSI_NO_VECTOR 0xffff
typedef struct virtio_pci_vq_info
{
@@ -98,7 +106,8 @@ struct
virtqueue*
VirtIODeviceFindVirtualQueue(
IN PVOID DeviceExtension,
- IN unsigned index);
+ IN unsigned index,
+ IN unsigned vector);
void
VirtIODeviceDeleteVirtualQueue(
diff --git a/viostor/virtio_stor.c b/viostor/virtio_stor.c
index b972dd2..4c9fe27 100644
--- a/viostor/virtio_stor.c
+++ b/viostor/virtio_stor.c
@@ -38,6 +38,13 @@ CompleteDpcRoutine(
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
) ;
+#ifdef MSI_SUPPORTED
+BOOLEAN
+VirtIoMSInterruptRoutine (
+ IN PVOID DeviceExtension,
+ IN ULONG MessageID
+ );
+#endif
#endif
BOOLEAN
@@ -103,7 +110,8 @@ VOID
FORCEINLINE
CompleteDPC(
IN PVOID DeviceExtension,
- IN pblk_req vbr
+ IN pblk_req vbr,
+ IN ULONG MessageID
);
ULONG
@@ -210,6 +218,10 @@ VirtIoFindAdapter(
#ifdef USE_STORPORT
ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
+#ifdef MSI_SUPPORTED
+ ConfigInfo->HwMSInterruptRoutine = VirtIoMSInterruptRoutine;
+ ConfigInfo->InterruptSynchronizationMode=InterruptSynchronizePerMessage;//InterruptSynchronizeAll;//
+#endif
#else
ConfigInfo->MapBuffers = TRUE;
#endif
@@ -325,20 +337,6 @@ VirtIoFindAdapter(
adaptExt->pci_vq_info.queue = PAGE_ALIGN(ptr);
adaptExt->virtqueue = (vring_virtqueue*)((ULONG_PTR)(adaptExt->pci_vq_info.queue) + vr_sz);
- adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0);
- if (!adaptExt->pci_vq_info.vq) {
- ScsiPortLogError(DeviceExtension,
- NULL,
- 0,
- 0,
- 0,
- SP_INTERNAL_ADAPTER_ERROR,
- __LINE__);
-
- RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find snd virtual queue\n"));
- return SP_RETURN_ERROR;
- }
-
InitializeListHead(&adaptExt->list_head);
InitializeListHead(&adaptExt->complete_list);
@@ -372,11 +370,47 @@ VirtIoHwInitialize(
u64 cap;
u32 v;
struct virtio_blk_geometry vgeo;
+#ifdef MSI_SUPPORTED
+ MESSAGE_INTERRUPT_INFORMATION msi_info;
+#endif
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s (%d)\n", __FUNCTION__, KeGetCurrentIrql()));
adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+#ifdef MSI_SUPPORTED
+ while(StorPortGetMSIInfo(DeviceExtension, adaptExt->msix_vectors,&msi_info) == STOR_STATUS_SUCCESS) {
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageId = %x\n", msi_info.MessageId));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageData = %x\n", msi_info.MessageData));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptVector = %x\n", msi_info.InterruptVector));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptLevel = %x\n", msi_info.InterruptLevel));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptMode = %s\n", msi_info.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageAddress = %p\n\n", msi_info.MessageAddress));
+ ++adaptExt->msix_vectors;
+ }
+
+ if(!adaptExt->dump_mode&& (adaptExt->msix_vectors> 1)) {
+ RhelDbgPrint(TRACE_LEVEL_ERROR, ("xru dump_mode = %x\n", adaptExt->dump_mode));
+ adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, adaptExt->msix_vectors - 1);
+ }
+#endif
+
+ if(!adaptExt->pci_vq_info.vq) {
+ adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, 0);
+ }
+ if (!adaptExt->pci_vq_info.vq) {
+ ScsiPortLogError(DeviceExtension,
+ NULL,
+ 0,
+ 0,
+ 0,
+ SP_INTERNAL_ADAPTER_ERROR,
+ __LINE__);
+
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find snd virtual queue\n"));
+ return FALSE;
+ }
+
if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_BARRIER)) {
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_BARRIER\n"));
}
@@ -612,7 +646,7 @@ VirtIoInterrupt(
Srb->SrbStatus = SRB_STATUS_ERROR;
break;
}
- CompleteDPC(DeviceExtension, vbr);
+ CompleteDPC(DeviceExtension, vbr, 0);
}
}
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s isInterruptServiced = %d\n", __FUNCTION__, isInterruptServiced));
@@ -671,8 +705,15 @@ VirtIoAdapterControl(
}
case ScsiRestartAdapter: {
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("ScsiRestartAdapter\n"));
-
- adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0);
+ adaptExt->pci_vq_info.vq = NULL;
+#ifdef MSI_SUPPORTED
+ if(!adaptExt->dump_mode& adaptExt->msix_vectors) {
+ adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, adaptExt->msix_vectors);
+ }
+#endif
+ if(!adaptExt->pci_vq_info.vq) {
+ adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, 0);
+ }
if (!adaptExt->pci_vq_info.vq)
{
RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find snd virtual queue\n"));
@@ -765,6 +806,45 @@ VirtIoBuildIo(
return TRUE;
}
+
+#ifdef MSI_SUPPORTED
+BOOLEAN
+VirtIoMSInterruptRoutine (
+ IN PVOID DeviceExtension,
+ IN ULONG MessageID
+ )
+{
+ pblk_req vbr;
+ unsigned int len;
+ unsigned long flags;
+ PADAPTER_EXTENSION adaptExt;
+ PSCSI_REQUEST_BLOCK Srb;
+
+ adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+
+ RhelDbgPrint(TRACE_LEVEL_VERBOSE,
+ ("<--->%s : MessageID 0x%x\n", __FUNCTION__, MessageID));
+
+ while((vbr = adaptExt->pci_vq_info.vq->vq_ops->get_buf(adaptExt->pci_vq_info.vq,&len)) != NULL) {
+ Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
+ switch (vbr->status) {
+ case VIRTIO_BLK_S_OK:
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ break;
+ case VIRTIO_BLK_S_UNSUPP:
+ Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
+ break;
+ default:
+ Srb->SrbStatus = SRB_STATUS_ERROR;
+ break;
+ }
+ CompleteDPC(DeviceExtension, vbr, MessageID);
+ }
+
+ return TRUE;
+}
+#endif
+
#endif
UCHAR
@@ -1031,7 +1111,8 @@ VOID
FORCEINLINE
CompleteDPC(
IN PVOID DeviceExtension,
- IN pblk_req vbr
+ IN pblk_req vbr,
+ IN ULONG MessageID
)
{
PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
@@ -1044,7 +1125,7 @@ CompleteDPC(
InsertTailList(&adaptExt->complete_list,&vbr->list_entry);
StorPortIssueDpc(DeviceExtension,
&adaptExt->completion_dpc,
- NULL,
+ (PVOID)MessageID,
NULL);
return;
}
@@ -1063,26 +1144,41 @@ CompleteDpcRoutine(
{
STOR_LOCK_HANDLE LockHandle;
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)Context;
+ ULONG MessageID = (ULONG)SystemArgument1;
+ ULONG OldIrql;
- StorPortAcquireSpinLock ( Context, InterruptLock , NULL,&LockHandle);
-
+ if(adaptExt->msix_vectors) {
+ StorPortAcquireMSISpinLock (Context, MessageID,&OldIrql);
+ } else {
+ StorPortAcquireSpinLock ( Context, InterruptLock , NULL,&LockHandle);
+ }
while (!IsListEmpty(&adaptExt->complete_list)) {
PSCSI_REQUEST_BLOCK Srb;
pblk_req vbr;
vbr = (pblk_req) RemoveHeadList(&adaptExt->complete_list);
Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
- StorPortReleaseSpinLock (Context,&LockHandle);
-
+ if(adaptExt->msix_vectors) {
+ StorPortReleaseMSISpinLock (Context, MessageID, OldIrql);
+ } else {
+ StorPortReleaseSpinLock (Context,&LockHandle);
+ }
+
ScsiPortNotification(RequestComplete,
Context,
Srb);
- StorPortAcquireSpinLock ( Context, InterruptLock , NULL,&LockHandle);
-
+ if(adaptExt->msix_vectors) {
+ StorPortAcquireMSISpinLock (Context, MessageID,&OldIrql);
+ } else {
+ StorPortAcquireSpinLock ( Context, InterruptLock , NULL,&LockHandle);
+ }
}
- StorPortReleaseSpinLock (Context,&LockHandle);
-
+ if(adaptExt->msix_vectors) {
+ StorPortReleaseMSISpinLock (Context, MessageID, OldIrql);
+ } else {
+ StorPortReleaseSpinLock (Context,&LockHandle);
+ }
return;
}
diff --git a/viostor/virtio_stor.h b/viostor/virtio_stor.h
index dd4728e..221c653 100644
--- a/viostor/virtio_stor.h
+++ b/viostor/virtio_stor.h
@@ -105,6 +105,7 @@ typedef struct _ADAPTER_EXTENSION {
LIST_ENTRY complete_list;
STOR_DPC completion_dpc;
BOOLEAN has_sn;
+ ULONG msix_vectors;
}ADAPTER_EXTENSION, *PADAPTER_EXTENSION;
typedef struct _RHEL_SRB_EXTENSION {
diff --git a/viostor/virtio_stor_hw_helper.c b/viostor/virtio_stor_hw_helper.c
index 3c09259..893b40f 100644
--- a/viostor/virtio_stor_hw_helper.c
+++ b/viostor/virtio_stor_hw_helper.c
@@ -40,7 +40,7 @@ BOOLEAN
RhelDoReadWrite(PVOID DeviceExtension,
PSCSI_REQUEST_BLOCK Srb)
{
- return StorPortSynchronizeAccess(DeviceExtension,SynchronizedAccessRoutine, (PVOID)Srb);
+ return StorPortSynchronizeAccess(DeviceExtension, SynchronizedAccessRoutine, (PVOID)Srb);
}
#else
BOOLEAN
diff --git a/viostor/wlh.inf b/viostor/wlh.inf
index aae425a..286aca2 100644
--- a/viostor/wlh.inf
+++ b/viostor/wlh.inf
@@ -1,108 +1,117 @@
-; Copyright (c) 2009, Red Hat Inc.
-[Version]
-Signature="$Windows NT$"
-Provider=%RHEL%
-ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
-Class=SCSIAdapter
-DriverVer = 05/05/2009,4.3.0.17241
-CatalogFile=viostor.cat
-
-;
-; Source file information
-;
-
-[SourceDisksNames]
-1 = %DiskId1%,,,""
-
-[SourceDisksFiles]
-viostor.sys = 1,,
-
-[ControlFlags]
-;ExcludeFromSelect = *
-
-[DestinationDirs]
-DefaultDestDir = 10
-viostor_Files_Driver = 12
-
-;
-; Driver information
-;
-
-[Manufacturer]
-%RHEL% = RHEL,NTx86,NTamd64
-
-[RHEL]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-[RHEL.NTx86]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-[RHEL.NTamd64]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-;
-; General installation section
-;
-
-[viostor_Files_Driver]
-viostor.sys,,,2
-
-[rhelscsi_inst]
-CopyFiles=viostor_Files_Driver
-
-
-
-;
-; Service Installation
-;
-
-[rhelscsi_inst.Services]
-AddService = viostor, 0x00000002 , rhelscsi_Service_Inst, rhelscsi_EventLog_Inst
-
-[rhelscsi_Service_Inst]
-ServiceType = %SERVICE_KERNEL_DRIVER%
-StartType = %SERVICE_BOOT_START%
-ErrorControl = %SERVICE_ERROR_NORMAL%
-ServiceBinary = %12%\viostor.sys
-LoadOrderGroup = SCSI miniport
-AddReg = pnpsafe_pci_addreg
-
-
-[rhelscsi_EventLog_Inst]
-AddReg = rhelscsi_EventLog_AddReg
-
-[rhelscsi_EventLog_AddReg]
-HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
-HKR,,TypesSupported,%REG_DWORD%,7
-
-
-[pnpsafe_pci_addreg]
-HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001
-HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000001
-
-[Strings]
-;
-; Localizable Strings
-;
-diskId1 = "Red Hat VirtIO SCSI controller Installation Disk"
-RHELScsi.DeviceDesc = "Red Hat VirtIO SCSI controller"
-RHEL = "Red Hat, Inc."
-
-;
-; Non-Localizable Strings
-;
-
-REG_EXPAND_SZ = 0x00020000
-REG_DWORD = 0x00010001
-SERVICE_KERNEL_DRIVER = 1
-SERVICE_BOOT_START = 0
-SERVICE_ERROR_NORMAL = 1
-
-
-
+; Copyright (c) 2009, Red Hat Inc.
+[Version]
+Signature="$Windows NT$"
+Provider=%RHEL%
+ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
+Class=SCSIAdapter
+DriverVer = 10/10/2009,5.3.0.17241
+CatalogFile=viostor.cat
+
+;
+; Source file information
+;
+
+[SourceDisksNames]
+1 = %DiskId1%,,,""
+
+[SourceDisksFiles]
+viostor.sys = 1,,
+
+[ControlFlags]
+;ExcludeFromSelect = *
+
+[DestinationDirs]
+DefaultDestDir = 10
+viostor_Files_Driver = 12
+
+;
+; Driver information
+;
+
+[Manufacturer]
+%RHEL% = RHEL,NTx86,NTamd64
+
+[RHEL]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+[RHEL.NTx86]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+[RHEL.NTamd64]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+;
+; General installation section
+;
+
+[viostor_Files_Driver]
+viostor.sys,,,2
+
+[rhelscsi_inst]
+CopyFiles=viostor_Files_Driver
+
+;
+; Service Installation
+;
+
+[rhelscsi_inst.Services]
+AddService = viostor, 0x00000002 , rhelscsi_Service_Inst, rhelscsi_EventLog_Inst
+
+[rhelscsi_Service_Inst]
+ServiceType = %SERVICE_KERNEL_DRIVER%
+StartType = %SERVICE_BOOT_START%
+ErrorControl = %SERVICE_ERROR_NORMAL%
+ServiceBinary = %12%\viostor.sys
+LoadOrderGroup = SCSI miniport
+AddReg = pnpsafe_pci_addreg
+
+[rhelscsi_inst.HW]
+AddReg = pnpsafe_pci_addreg_msix
+
+[rhelscsi_EventLog_Inst]
+AddReg = rhelscsi_EventLog_AddReg
+
+[rhelscsi_EventLog_AddReg]
+HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
+HKR,,TypesSupported,%REG_DWORD%,7
+
+
+[pnpsafe_pci_addreg]
+HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001
+HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000001
+
+[pnpsafe_pci_addreg_msix]
+HKR, "Interrupt Management",, 0x00000010
+HKR, "Interrupt Management\MessageSignaledInterruptProperties",, 0x00000010
+HKR, "Interrupt Management\MessageSignaledInterruptProperties", MSISupported, 0x00010001, 0
+HKR, "Interrupt Management\MessageSignaledInterruptProperties", MessageNumberLimit, 0x00010001, 2
+HKR, "Interrupt Management\Affinity Policy",, 0x00000010
+HKR, "Interrupt Management\Affinity Policy", DevicePolicy, 0x00010001, 5
+
+
+[Strings]
+;
+; Localizable Strings
+;
+diskId1 = "Red Hat VirtIO SCSI controller Installation Disk"
+RHELScsi.DeviceDesc = "Red Hat VirtIO SCSI controller"
+RHEL = "Red Hat, Inc."
+
+;
+; Non-Localizable Strings
+;
+
+REG_EXPAND_SZ = 0x00020000
+REG_DWORD = 0x00010001
+SERVICE_KERNEL_DRIVER = 1
+SERVICE_BOOT_START = 0
+SERVICE_ERROR_NORMAL = 1
+
+
+
diff --git a/viostor/wnet.inf b/viostor/wnet.inf
index aae425a..81d61be 100644
--- a/viostor/wnet.inf
+++ b/viostor/wnet.inf
@@ -1,108 +1,104 @@
-; Copyright (c) 2009, Red Hat Inc.
-[Version]
-Signature="$Windows NT$"
-Provider=%RHEL%
-ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
-Class=SCSIAdapter
-DriverVer = 05/05/2009,4.3.0.17241
-CatalogFile=viostor.cat
-
-;
-; Source file information
-;
-
-[SourceDisksNames]
-1 = %DiskId1%,,,""
-
-[SourceDisksFiles]
-viostor.sys = 1,,
-
-[ControlFlags]
-;ExcludeFromSelect = *
-
-[DestinationDirs]
-DefaultDestDir = 10
-viostor_Files_Driver = 12
-
-;
-; Driver information
-;
-
-[Manufacturer]
-%RHEL% = RHEL,NTx86,NTamd64
-
-[RHEL]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-[RHEL.NTx86]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-[RHEL.NTamd64]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-;
-; General installation section
-;
-
-[viostor_Files_Driver]
-viostor.sys,,,2
-
-[rhelscsi_inst]
-CopyFiles=viostor_Files_Driver
-
-
-
-;
-; Service Installation
-;
-
-[rhelscsi_inst.Services]
-AddService = viostor, 0x00000002 , rhelscsi_Service_Inst, rhelscsi_EventLog_Inst
-
-[rhelscsi_Service_Inst]
-ServiceType = %SERVICE_KERNEL_DRIVER%
-StartType = %SERVICE_BOOT_START%
-ErrorControl = %SERVICE_ERROR_NORMAL%
-ServiceBinary = %12%\viostor.sys
-LoadOrderGroup = SCSI miniport
-AddReg = pnpsafe_pci_addreg
-
-
-[rhelscsi_EventLog_Inst]
-AddReg = rhelscsi_EventLog_AddReg
-
-[rhelscsi_EventLog_AddReg]
-HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
-HKR,,TypesSupported,%REG_DWORD%,7
-
-
-[pnpsafe_pci_addreg]
-HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001
-HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000001
-
-[Strings]
-;
-; Localizable Strings
-;
-diskId1 = "Red Hat VirtIO SCSI controller Installation Disk"
-RHELScsi.DeviceDesc = "Red Hat VirtIO SCSI controller"
-RHEL = "Red Hat, Inc."
-
-;
-; Non-Localizable Strings
-;
-
-REG_EXPAND_SZ = 0x00020000
-REG_DWORD = 0x00010001
-SERVICE_KERNEL_DRIVER = 1
-SERVICE_BOOT_START = 0
-SERVICE_ERROR_NORMAL = 1
-
-
-
+; Copyright (c) 2009, Red Hat Inc.
+[Version]
+Signature="$Windows NT$"
+Provider=%RHEL%
+ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
+Class=SCSIAdapter
+DriverVer = 10/10/2009,5.3.0.17241
+CatalogFile=viostor.cat
+
+;
+; Source file information
+;
+
+[SourceDisksNames]
+1 = %DiskId1%,,,""
+
+[SourceDisksFiles]
+viostor.sys = 1,,
+
+[ControlFlags]
+;ExcludeFromSelect = *
+
+[DestinationDirs]
+DefaultDestDir = 10
+viostor_Files_Driver = 12
+
+;
+; Driver information
+;
+
+[Manufacturer]
+%RHEL% = RHEL,NTx86,NTamd64
+
+[RHEL]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+[RHEL.NTx86]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+[RHEL.NTamd64]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+;
+; General installation section
+;
+
+[viostor_Files_Driver]
+viostor.sys,,,2
+
+[rhelscsi_inst]
+CopyFiles=viostor_Files_Driver
+
+;
+; Service Installation
+;
+
+[rhelscsi_inst.Services]
+AddService = viostor, 0x00000002 , rhelscsi_Service_Inst, rhelscsi_EventLog_Inst
+
+[rhelscsi_Service_Inst]
+ServiceType = %SERVICE_KERNEL_DRIVER%
+StartType = %SERVICE_BOOT_START%
+ErrorControl = %SERVICE_ERROR_NORMAL%
+ServiceBinary = %12%\viostor.sys
+LoadOrderGroup = SCSI miniport
+AddReg = pnpsafe_pci_addreg
+
+[rhelscsi_EventLog_Inst]
+AddReg = rhelscsi_EventLog_AddReg
+
+[rhelscsi_EventLog_AddReg]
+HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
+HKR,,TypesSupported,%REG_DWORD%,7
+
+[pnpsafe_pci_addreg]
+HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001
+HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000001
+
+[Strings]
+;
+; Localizable Strings
+;
+diskId1 = "Red Hat VirtIO SCSI controller Installation Disk"
+RHELScsi.DeviceDesc = "Red Hat VirtIO SCSI controller"
+RHEL = "Red Hat, Inc."
+
+;
+; Non-Localizable Strings
+;
+
+REG_EXPAND_SZ = 0x00020000
+REG_DWORD = 0x00010001
+SERVICE_KERNEL_DRIVER = 1
+SERVICE_BOOT_START = 0
+SERVICE_ERROR_NORMAL = 1
+
+
+
--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[-- Attachment #2: add_msix_support.patch --]
[-- Type: text/plain, Size: 25374 bytes --]
diff --git a/viostor/SOURCES b/viostor/SOURCES
index 561cfc0..1352710 100644
--- a/viostor/SOURCES
+++ b/viostor/SOURCES
@@ -6,6 +6,7 @@ C_DEFINES = -DUSE_STORPORT=1 $(C_DEFINES)
TARGETLIBS=$(SDK_LIB_PATH)\storport.lib
!elseif "$(DDK_TARGET_OS)" == "WinLH"
C_DEFINES = -DUSE_STORPORT=1 $(C_DEFINES)
+C_DEFINES = -DMSI_SUPPORTED=1 $(C_DEFINES)
TARGETLIBS=$(SDK_LIB_PATH)\storport.lib
!else
TARGETLIBS=$(SDK_LIB_PATH)\scsiport.lib
diff --git a/viostor/virtio_pci.c b/viostor/virtio_pci.c
index 6bf26cc..9d47763 100644
--- a/viostor/virtio_pci.c
+++ b/viostor/virtio_pci.c
@@ -86,7 +86,7 @@ VirtIODeviceGet(
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s\n", __FUNCTION__));
- ioaddr = adaptExt->device_base + VIRTIO_PCI_CONFIG + offset;
+ ioaddr = adaptExt->device_base + VIRTIO_PCI_CONFIG((adaptExt->msix_vectors > 0)) + offset;
for (i = 0; i < len; i++) {
ptr[i] = ScsiPortReadPortUchar((PUCHAR)(ioaddr + i));
@@ -125,7 +125,8 @@ struct
virtqueue*
VirtIODeviceFindVirtualQueue(
IN PVOID DeviceExtension,
- IN unsigned index)
+ IN unsigned index,
+ IN unsigned vector)
{
virtio_pci_vq_info *info;
struct virtqueue *vq;
@@ -133,9 +134,20 @@ VirtIODeviceFindVirtualQueue(
ULONG dummy;
PHYSICAL_ADDRESS pa;
ULONG pageNum;
+ unsigned res;
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s\n", __FUNCTION__));
+ RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s index = %d, vector = %d\n", __FUNCTION__, index, vector));
+
+ if(vector) {
+ ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_MSI_CONFIG_VECTOR),(USHORT)0);
+ res = ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_MSI_CONFIG_VECTOR));
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> VIRTIO_MSI_CONFIG_VECTOR res = 0x%x\n", __FUNCTION__, res));
+ if(res == VIRTIO_MSI_NO_VECTOR) {
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> Cannot find config vector res = 0x%x\n", __FUNCTION__, res));
+ return NULL;
+ }
+ }
// Select the queue we're interested in
ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_PCI_QUEUE_SEL),(USHORT)index);
@@ -144,7 +156,7 @@ VirtIODeviceFindVirtualQueue(
num = ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_PCI_QUEUE_NUM));
RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>>> [vp_dev->addr + VIRTIO_PCI_QUEUE_NUM] = %x\n", __FUNCTION__, num) );
- if (!num || ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_PCI_QUEUE_PFN)))
+ if (!num || ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + VIRTIO_PCI_QUEUE_PFN)))
return NULL;
// allocate and fill out our structure the represents an active queue
@@ -174,7 +186,18 @@ VirtIODeviceFindVirtualQueue(
pageNum = (ULONG)(pa.QuadPart >> PAGE_SHIFT);
RhelDbgPrint(TRACE_LEVEL_FATAL, ("[%s] queue phys.address %08lx:%08lx, pfn %lx\n", __FUNCTION__, pa.u.HighPart, pa.u.LowPart, pageNum));
ScsiPortWritePortUlong((PULONG)(adaptExt->device_base + VIRTIO_PCI_QUEUE_PFN),(ULONG)(pageNum));
-
+
+ if(vector) {
+ ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_MSI_QUEUE_VECTOR),(USHORT)vector);
+ res = ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_MSI_QUEUE_VECTOR));
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> VIRTIO_MSI_QUEUE_VECTOR vector = %d, res = 0x%x\n", __FUNCTION__, vector, res));
+ if(res == VIRTIO_MSI_NO_VECTOR) {
+ ScsiPortWritePortUlong((PULONG)(adaptExt->device_base + VIRTIO_PCI_QUEUE_PFN),(ULONG)0);
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("%s>> Cannot create vq vector\n", __FUNCTION__));
+ return NULL;
+ }
+ }
+
return vq;
}
diff --git a/viostor/virtio_pci.h b/viostor/virtio_pci.h
index fc31163..8f99e18 100644
--- a/viostor/virtio_pci.h
+++ b/viostor/virtio_pci.h
@@ -52,7 +52,15 @@
/* The remaining space is defined by each driver as the per-driver
* configuration space */
-#define VIRTIO_PCI_CONFIG 20
+#define VIRTIO_PCI_CONFIG(msix_enabled) (msix_enabled ? 24 : 20)
+
+/* MSI-X registers: only enabled if MSI-X is enabled. */
+/* A 16-bit vector for configuration changes. */
+#define VIRTIO_MSI_CONFIG_VECTOR 20
+/* A 16-bit vector for selected queue notifications. */
+#define VIRTIO_MSI_QUEUE_VECTOR 22
+/* Vector value used to disable MSI for queue */
+#define VIRTIO_MSI_NO_VECTOR 0xffff
typedef struct virtio_pci_vq_info
{
@@ -98,7 +106,8 @@ struct
virtqueue*
VirtIODeviceFindVirtualQueue(
IN PVOID DeviceExtension,
- IN unsigned index);
+ IN unsigned index,
+ IN unsigned vector);
void
VirtIODeviceDeleteVirtualQueue(
diff --git a/viostor/virtio_stor.c b/viostor/virtio_stor.c
index b972dd2..4c9fe27 100644
--- a/viostor/virtio_stor.c
+++ b/viostor/virtio_stor.c
@@ -38,6 +38,13 @@ CompleteDpcRoutine(
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
) ;
+#ifdef MSI_SUPPORTED
+BOOLEAN
+VirtIoMSInterruptRoutine (
+ IN PVOID DeviceExtension,
+ IN ULONG MessageID
+ );
+#endif
#endif
BOOLEAN
@@ -103,7 +110,8 @@ VOID
FORCEINLINE
CompleteDPC(
IN PVOID DeviceExtension,
- IN pblk_req vbr
+ IN pblk_req vbr,
+ IN ULONG MessageID
);
ULONG
@@ -210,6 +218,10 @@ VirtIoFindAdapter(
#ifdef USE_STORPORT
ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
+#ifdef MSI_SUPPORTED
+ ConfigInfo->HwMSInterruptRoutine = VirtIoMSInterruptRoutine;
+ ConfigInfo->InterruptSynchronizationMode=InterruptSynchronizePerMessage;//InterruptSynchronizeAll;//
+#endif
#else
ConfigInfo->MapBuffers = TRUE;
#endif
@@ -325,20 +337,6 @@ VirtIoFindAdapter(
adaptExt->pci_vq_info.queue = PAGE_ALIGN(ptr);
adaptExt->virtqueue = (vring_virtqueue*)((ULONG_PTR)(adaptExt->pci_vq_info.queue) + vr_sz);
- adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0);
- if (!adaptExt->pci_vq_info.vq) {
- ScsiPortLogError(DeviceExtension,
- NULL,
- 0,
- 0,
- 0,
- SP_INTERNAL_ADAPTER_ERROR,
- __LINE__);
-
- RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find snd virtual queue\n"));
- return SP_RETURN_ERROR;
- }
-
InitializeListHead(&adaptExt->list_head);
InitializeListHead(&adaptExt->complete_list);
@@ -372,11 +370,47 @@ VirtIoHwInitialize(
u64 cap;
u32 v;
struct virtio_blk_geometry vgeo;
+#ifdef MSI_SUPPORTED
+ MESSAGE_INTERRUPT_INFORMATION msi_info;
+#endif
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s (%d)\n", __FUNCTION__, KeGetCurrentIrql()));
adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+#ifdef MSI_SUPPORTED
+ while(StorPortGetMSIInfo(DeviceExtension, adaptExt->msix_vectors, &msi_info) == STOR_STATUS_SUCCESS) {
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageId = %x\n", msi_info.MessageId));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageData = %x\n", msi_info.MessageData));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptVector = %x\n", msi_info.InterruptVector));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptLevel = %x\n", msi_info.InterruptLevel));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("InterruptMode = %s\n", msi_info.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"));
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("MessageAddress = %p\n\n", msi_info.MessageAddress));
+ ++adaptExt->msix_vectors;
+ }
+
+ if(!adaptExt->dump_mode && (adaptExt->msix_vectors > 1)) {
+ RhelDbgPrint(TRACE_LEVEL_ERROR, ("xru dump_mode = %x\n", adaptExt->dump_mode));
+ adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, adaptExt->msix_vectors - 1);
+ }
+#endif
+
+ if(!adaptExt->pci_vq_info.vq) {
+ adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, 0);
+ }
+ if (!adaptExt->pci_vq_info.vq) {
+ ScsiPortLogError(DeviceExtension,
+ NULL,
+ 0,
+ 0,
+ 0,
+ SP_INTERNAL_ADAPTER_ERROR,
+ __LINE__);
+
+ RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find snd virtual queue\n"));
+ return FALSE;
+ }
+
if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_BARRIER)) {
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_BARRIER\n"));
}
@@ -612,7 +646,7 @@ VirtIoInterrupt(
Srb->SrbStatus = SRB_STATUS_ERROR;
break;
}
- CompleteDPC(DeviceExtension, vbr);
+ CompleteDPC(DeviceExtension, vbr, 0);
}
}
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s isInterruptServiced = %d\n", __FUNCTION__, isInterruptServiced));
@@ -671,8 +705,15 @@ VirtIoAdapterControl(
}
case ScsiRestartAdapter: {
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("ScsiRestartAdapter\n"));
-
- adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0);
+ adaptExt->pci_vq_info.vq = NULL;
+#ifdef MSI_SUPPORTED
+ if(!adaptExt->dump_mode & adaptExt->msix_vectors) {
+ adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, adaptExt->msix_vectors);
+ }
+#endif
+ if(!adaptExt->pci_vq_info.vq) {
+ adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, 0);
+ }
if (!adaptExt->pci_vq_info.vq)
{
RhelDbgPrint(TRACE_LEVEL_FATAL, ("Cannot find snd virtual queue\n"));
@@ -765,6 +806,45 @@ VirtIoBuildIo(
return TRUE;
}
+
+#ifdef MSI_SUPPORTED
+BOOLEAN
+VirtIoMSInterruptRoutine (
+ IN PVOID DeviceExtension,
+ IN ULONG MessageID
+ )
+{
+ pblk_req vbr;
+ unsigned int len;
+ unsigned long flags;
+ PADAPTER_EXTENSION adaptExt;
+ PSCSI_REQUEST_BLOCK Srb;
+
+ adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+
+ RhelDbgPrint(TRACE_LEVEL_VERBOSE,
+ ("<--->%s : MessageID 0x%x\n", __FUNCTION__, MessageID));
+
+ while((vbr = adaptExt->pci_vq_info.vq->vq_ops->get_buf(adaptExt->pci_vq_info.vq, &len)) != NULL) {
+ Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
+ switch (vbr->status) {
+ case VIRTIO_BLK_S_OK:
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ break;
+ case VIRTIO_BLK_S_UNSUPP:
+ Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
+ break;
+ default:
+ Srb->SrbStatus = SRB_STATUS_ERROR;
+ break;
+ }
+ CompleteDPC(DeviceExtension, vbr, MessageID);
+ }
+
+ return TRUE;
+}
+#endif
+
#endif
UCHAR
@@ -1031,7 +1111,8 @@ VOID
FORCEINLINE
CompleteDPC(
IN PVOID DeviceExtension,
- IN pblk_req vbr
+ IN pblk_req vbr,
+ IN ULONG MessageID
)
{
PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
@@ -1044,7 +1125,7 @@ CompleteDPC(
InsertTailList(&adaptExt->complete_list, &vbr->list_entry);
StorPortIssueDpc(DeviceExtension,
&adaptExt->completion_dpc,
- NULL,
+ (PVOID)MessageID,
NULL);
return;
}
@@ -1063,26 +1144,41 @@ CompleteDpcRoutine(
{
STOR_LOCK_HANDLE LockHandle;
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)Context;
+ ULONG MessageID = (ULONG)SystemArgument1;
+ ULONG OldIrql;
- StorPortAcquireSpinLock ( Context, InterruptLock , NULL, &LockHandle);
-
+ if(adaptExt->msix_vectors) {
+ StorPortAcquireMSISpinLock (Context, MessageID, &OldIrql);
+ } else {
+ StorPortAcquireSpinLock ( Context, InterruptLock , NULL, &LockHandle);
+ }
while (!IsListEmpty(&adaptExt->complete_list)) {
PSCSI_REQUEST_BLOCK Srb;
pblk_req vbr;
vbr = (pblk_req) RemoveHeadList(&adaptExt->complete_list);
Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
- StorPortReleaseSpinLock (Context, &LockHandle);
-
+ if(adaptExt->msix_vectors) {
+ StorPortReleaseMSISpinLock (Context, MessageID, OldIrql);
+ } else {
+ StorPortReleaseSpinLock (Context, &LockHandle);
+ }
+
ScsiPortNotification(RequestComplete,
Context,
Srb);
- StorPortAcquireSpinLock ( Context, InterruptLock , NULL, &LockHandle);
-
+ if(adaptExt->msix_vectors) {
+ StorPortAcquireMSISpinLock (Context, MessageID, &OldIrql);
+ } else {
+ StorPortAcquireSpinLock ( Context, InterruptLock , NULL, &LockHandle);
+ }
}
- StorPortReleaseSpinLock (Context, &LockHandle);
-
+ if(adaptExt->msix_vectors) {
+ StorPortReleaseMSISpinLock (Context, MessageID, OldIrql);
+ } else {
+ StorPortReleaseSpinLock (Context, &LockHandle);
+ }
return;
}
diff --git a/viostor/virtio_stor.h b/viostor/virtio_stor.h
index dd4728e..221c653 100644
--- a/viostor/virtio_stor.h
+++ b/viostor/virtio_stor.h
@@ -105,6 +105,7 @@ typedef struct _ADAPTER_EXTENSION {
LIST_ENTRY complete_list;
STOR_DPC completion_dpc;
BOOLEAN has_sn;
+ ULONG msix_vectors;
}ADAPTER_EXTENSION, *PADAPTER_EXTENSION;
typedef struct _RHEL_SRB_EXTENSION {
diff --git a/viostor/virtio_stor_hw_helper.c b/viostor/virtio_stor_hw_helper.c
index 3c09259..893b40f 100644
--- a/viostor/virtio_stor_hw_helper.c
+++ b/viostor/virtio_stor_hw_helper.c
@@ -40,7 +40,7 @@ BOOLEAN
RhelDoReadWrite(PVOID DeviceExtension,
PSCSI_REQUEST_BLOCK Srb)
{
- return StorPortSynchronizeAccess(DeviceExtension,SynchronizedAccessRoutine, (PVOID)Srb);
+ return StorPortSynchronizeAccess(DeviceExtension, SynchronizedAccessRoutine, (PVOID)Srb);
}
#else
BOOLEAN
diff --git a/viostor/wlh.inf b/viostor/wlh.inf
index aae425a..286aca2 100644
--- a/viostor/wlh.inf
+++ b/viostor/wlh.inf
@@ -1,108 +1,117 @@
-; Copyright (c) 2009, Red Hat Inc.
-[Version]
-Signature="$Windows NT$"
-Provider=%RHEL%
-ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
-Class=SCSIAdapter
-DriverVer = 05/05/2009,4.3.0.17241
-CatalogFile=viostor.cat
-
-;
-; Source file information
-;
-
-[SourceDisksNames]
-1 = %DiskId1%,,,""
-
-[SourceDisksFiles]
-viostor.sys = 1,,
-
-[ControlFlags]
-;ExcludeFromSelect = *
-
-[DestinationDirs]
-DefaultDestDir = 10
-viostor_Files_Driver = 12
-
-;
-; Driver information
-;
-
-[Manufacturer]
-%RHEL% = RHEL,NTx86,NTamd64
-
-[RHEL]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-[RHEL.NTx86]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-[RHEL.NTamd64]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-;
-; General installation section
-;
-
-[viostor_Files_Driver]
-viostor.sys,,,2
-
-[rhelscsi_inst]
-CopyFiles=viostor_Files_Driver
-
-
-
-;
-; Service Installation
-;
-
-[rhelscsi_inst.Services]
-AddService = viostor, 0x00000002 , rhelscsi_Service_Inst, rhelscsi_EventLog_Inst
-
-[rhelscsi_Service_Inst]
-ServiceType = %SERVICE_KERNEL_DRIVER%
-StartType = %SERVICE_BOOT_START%
-ErrorControl = %SERVICE_ERROR_NORMAL%
-ServiceBinary = %12%\viostor.sys
-LoadOrderGroup = SCSI miniport
-AddReg = pnpsafe_pci_addreg
-
-
-[rhelscsi_EventLog_Inst]
-AddReg = rhelscsi_EventLog_AddReg
-
-[rhelscsi_EventLog_AddReg]
-HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
-HKR,,TypesSupported,%REG_DWORD%,7
-
-
-[pnpsafe_pci_addreg]
-HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001
-HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000001
-
-[Strings]
-;
-; Localizable Strings
-;
-diskId1 = "Red Hat VirtIO SCSI controller Installation Disk"
-RHELScsi.DeviceDesc = "Red Hat VirtIO SCSI controller"
-RHEL = "Red Hat, Inc."
-
-;
-; Non-Localizable Strings
-;
-
-REG_EXPAND_SZ = 0x00020000
-REG_DWORD = 0x00010001
-SERVICE_KERNEL_DRIVER = 1
-SERVICE_BOOT_START = 0
-SERVICE_ERROR_NORMAL = 1
-
-
-
+; Copyright (c) 2009, Red Hat Inc.
+[Version]
+Signature="$Windows NT$"
+Provider=%RHEL%
+ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
+Class=SCSIAdapter
+DriverVer = 10/10/2009,5.3.0.17241
+CatalogFile=viostor.cat
+
+;
+; Source file information
+;
+
+[SourceDisksNames]
+1 = %DiskId1%,,,""
+
+[SourceDisksFiles]
+viostor.sys = 1,,
+
+[ControlFlags]
+;ExcludeFromSelect = *
+
+[DestinationDirs]
+DefaultDestDir = 10
+viostor_Files_Driver = 12
+
+;
+; Driver information
+;
+
+[Manufacturer]
+%RHEL% = RHEL,NTx86,NTamd64
+
+[RHEL]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+[RHEL.NTx86]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+[RHEL.NTamd64]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+;
+; General installation section
+;
+
+[viostor_Files_Driver]
+viostor.sys,,,2
+
+[rhelscsi_inst]
+CopyFiles=viostor_Files_Driver
+
+;
+; Service Installation
+;
+
+[rhelscsi_inst.Services]
+AddService = viostor, 0x00000002 , rhelscsi_Service_Inst, rhelscsi_EventLog_Inst
+
+[rhelscsi_Service_Inst]
+ServiceType = %SERVICE_KERNEL_DRIVER%
+StartType = %SERVICE_BOOT_START%
+ErrorControl = %SERVICE_ERROR_NORMAL%
+ServiceBinary = %12%\viostor.sys
+LoadOrderGroup = SCSI miniport
+AddReg = pnpsafe_pci_addreg
+
+[rhelscsi_inst.HW]
+AddReg = pnpsafe_pci_addreg_msix
+
+[rhelscsi_EventLog_Inst]
+AddReg = rhelscsi_EventLog_AddReg
+
+[rhelscsi_EventLog_AddReg]
+HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
+HKR,,TypesSupported,%REG_DWORD%,7
+
+
+[pnpsafe_pci_addreg]
+HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001
+HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000001
+
+[pnpsafe_pci_addreg_msix]
+HKR, "Interrupt Management",, 0x00000010
+HKR, "Interrupt Management\MessageSignaledInterruptProperties",, 0x00000010
+HKR, "Interrupt Management\MessageSignaledInterruptProperties", MSISupported, 0x00010001, 0
+HKR, "Interrupt Management\MessageSignaledInterruptProperties", MessageNumberLimit, 0x00010001, 2
+HKR, "Interrupt Management\Affinity Policy",, 0x00000010
+HKR, "Interrupt Management\Affinity Policy", DevicePolicy, 0x00010001, 5
+
+
+[Strings]
+;
+; Localizable Strings
+;
+diskId1 = "Red Hat VirtIO SCSI controller Installation Disk"
+RHELScsi.DeviceDesc = "Red Hat VirtIO SCSI controller"
+RHEL = "Red Hat, Inc."
+
+;
+; Non-Localizable Strings
+;
+
+REG_EXPAND_SZ = 0x00020000
+REG_DWORD = 0x00010001
+SERVICE_KERNEL_DRIVER = 1
+SERVICE_BOOT_START = 0
+SERVICE_ERROR_NORMAL = 1
+
+
+
diff --git a/viostor/wnet.inf b/viostor/wnet.inf
index aae425a..81d61be 100644
--- a/viostor/wnet.inf
+++ b/viostor/wnet.inf
@@ -1,108 +1,104 @@
-; Copyright (c) 2009, Red Hat Inc.
-[Version]
-Signature="$Windows NT$"
-Provider=%RHEL%
-ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
-Class=SCSIAdapter
-DriverVer = 05/05/2009,4.3.0.17241
-CatalogFile=viostor.cat
-
-;
-; Source file information
-;
-
-[SourceDisksNames]
-1 = %DiskId1%,,,""
-
-[SourceDisksFiles]
-viostor.sys = 1,,
-
-[ControlFlags]
-;ExcludeFromSelect = *
-
-[DestinationDirs]
-DefaultDestDir = 10
-viostor_Files_Driver = 12
-
-;
-; Driver information
-;
-
-[Manufacturer]
-%RHEL% = RHEL,NTx86,NTamd64
-
-[RHEL]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-[RHEL.NTx86]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-[RHEL.NTamd64]
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
-%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
-
-;
-; General installation section
-;
-
-[viostor_Files_Driver]
-viostor.sys,,,2
-
-[rhelscsi_inst]
-CopyFiles=viostor_Files_Driver
-
-
-
-;
-; Service Installation
-;
-
-[rhelscsi_inst.Services]
-AddService = viostor, 0x00000002 , rhelscsi_Service_Inst, rhelscsi_EventLog_Inst
-
-[rhelscsi_Service_Inst]
-ServiceType = %SERVICE_KERNEL_DRIVER%
-StartType = %SERVICE_BOOT_START%
-ErrorControl = %SERVICE_ERROR_NORMAL%
-ServiceBinary = %12%\viostor.sys
-LoadOrderGroup = SCSI miniport
-AddReg = pnpsafe_pci_addreg
-
-
-[rhelscsi_EventLog_Inst]
-AddReg = rhelscsi_EventLog_AddReg
-
-[rhelscsi_EventLog_AddReg]
-HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
-HKR,,TypesSupported,%REG_DWORD%,7
-
-
-[pnpsafe_pci_addreg]
-HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001
-HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000001
-
-[Strings]
-;
-; Localizable Strings
-;
-diskId1 = "Red Hat VirtIO SCSI controller Installation Disk"
-RHELScsi.DeviceDesc = "Red Hat VirtIO SCSI controller"
-RHEL = "Red Hat, Inc."
-
-;
-; Non-Localizable Strings
-;
-
-REG_EXPAND_SZ = 0x00020000
-REG_DWORD = 0x00010001
-SERVICE_KERNEL_DRIVER = 1
-SERVICE_BOOT_START = 0
-SERVICE_ERROR_NORMAL = 1
-
-
-
+; Copyright (c) 2009, Red Hat Inc.
+[Version]
+Signature="$Windows NT$"
+Provider=%RHEL%
+ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
+Class=SCSIAdapter
+DriverVer = 10/10/2009,5.3.0.17241
+CatalogFile=viostor.cat
+
+;
+; Source file information
+;
+
+[SourceDisksNames]
+1 = %DiskId1%,,,""
+
+[SourceDisksFiles]
+viostor.sys = 1,,
+
+[ControlFlags]
+;ExcludeFromSelect = *
+
+[DestinationDirs]
+DefaultDestDir = 10
+viostor_Files_Driver = 12
+
+;
+; Driver information
+;
+
+[Manufacturer]
+%RHEL% = RHEL,NTx86,NTamd64
+
+[RHEL]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+[RHEL.NTx86]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+[RHEL.NTamd64]
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00000000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00020000
+%RHELScsi.DeviceDesc% = rhelscsi_inst, PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4
+
+;
+; General installation section
+;
+
+[viostor_Files_Driver]
+viostor.sys,,,2
+
+[rhelscsi_inst]
+CopyFiles=viostor_Files_Driver
+
+;
+; Service Installation
+;
+
+[rhelscsi_inst.Services]
+AddService = viostor, 0x00000002 , rhelscsi_Service_Inst, rhelscsi_EventLog_Inst
+
+[rhelscsi_Service_Inst]
+ServiceType = %SERVICE_KERNEL_DRIVER%
+StartType = %SERVICE_BOOT_START%
+ErrorControl = %SERVICE_ERROR_NORMAL%
+ServiceBinary = %12%\viostor.sys
+LoadOrderGroup = SCSI miniport
+AddReg = pnpsafe_pci_addreg
+
+[rhelscsi_EventLog_Inst]
+AddReg = rhelscsi_EventLog_AddReg
+
+[rhelscsi_EventLog_AddReg]
+HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll"
+HKR,,TypesSupported,%REG_DWORD%,7
+
+[pnpsafe_pci_addreg]
+HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001
+HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000001
+
+[Strings]
+;
+; Localizable Strings
+;
+diskId1 = "Red Hat VirtIO SCSI controller Installation Disk"
+RHELScsi.DeviceDesc = "Red Hat VirtIO SCSI controller"
+RHEL = "Red Hat, Inc."
+
+;
+; Non-Localizable Strings
+;
+
+REG_EXPAND_SZ = 0x00020000
+REG_DWORD = 0x00010001
+SERVICE_KERNEL_DRIVER = 1
+SERVICE_BOOT_START = 0
+SERVICE_ERROR_NORMAL = 1
+
+
+
reply other threads:[~2009-10-25 11:16 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4AE433A3.6000106@redhat.com \
--to=vrozenfe@redhat.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.