Skip to contentSkip to conversation

viostor driver. Add MSI-X support

PATCH New Vadim Rozenfeld 1 participant 1 message Oct 25, 2009 KVM

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 viostor driver. Add MSI-X support

repository: /home/vadimr/shares/kvm-guest-drivers-windows
branch: master
commit 8d7431f1080345c06abdb2ec334fb654da2a59fa

Author: Vadim Rozenfeld<[email protected]>
Date:   Sun Oct 25 13:04:09 2009 +0200

[PATCH] Add MSI-X support

viostor/SOURCES +1 -0
index 561cfc0..1352710 100644
@@ -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
viostor/virtio_pci.c +28 -5
index 6bf26cc..9d47763 100644
@@ -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;
 }
 
viostor/virtio_pci.h +11 -2
index fc31163..8f99e18 100644
@@ -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(
viostor/virtio_stor.c +124 -28

235 lines not on this page · raw message

viostor/virtio_stor.h +1 -0
index dd4728e..221c653 100644
@@ -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 {
viostor/virtio_stor_hw_helper.c +1 -1
index 3c09259..893b40f 100644
@@ -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
viostor/wlh.inf +117 -108

225 lines not on this page · raw message

viostor/wnet.inf +104 -108

212 lines not on this page · raw message

--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

viostor/SOURCES +1 -0
index 561cfc0..1352710 100644
@@ -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
viostor/virtio_pci.c +28 -5
index 6bf26cc..9d47763 100644
@@ -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;
 }
 
viostor/virtio_pci.h +11 -2
index fc31163..8f99e18 100644
@@ -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(
viostor/virtio_stor.c +124 -28

235 lines not on this page · raw message

viostor/virtio_stor.h +1 -0
index dd4728e..221c653 100644
@@ -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 {
viostor/virtio_stor_hw_helper.c +1 -1
index 3c09259..893b40f 100644
@@ -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 
viostor/wlh.inf +117 -108

225 lines not on this page · raw message

viostor/wnet.inf +104 -108

212 lines not on this page · raw message