[prev in list] [next in list] [prev in thread] [next in thread]
List: kvm-commits
Subject: [COMMIT] [WIN-GUEST_DRIVERS] Update viostor drivers (WinXP support, MSI support, new build scripts)
From: Yan Vugenfirer <yvugenfi () redhat ! com>
Date: 2010-03-31 14:43:26
Message-ID: 201003311443.o2VEhQDU012092 () int-mx02 ! intmail ! prod ! int ! phx2 ! redhat ! com
[Download RAW message or body]
repository: C:/dev/kvm-guest-drivers-windows
branch: master
commit 70fff68250b1a33e8576c41eaf6e79c13b72730f
Author: Yan Vugenfirer <yvugenfi@redhat.com>
Date: Wed Mar 31 17:42:35 2010 +0300
[WIN-GUEST_DRIVERS] Update viostor drivers (WinXP support, MSI support, new build \
scripts)
Signed-off-by: Vadim Rozenfeld <vrozenfe@redhat.com>
diff --git a/viostor/SOURCES b/viostor/SOURCES
index edc46ef..5701b78 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
!elseif "$(DDK_TARGET_OS)" == "WinXP"
TARGETLIBS=$(SDK_LIB_PATH)\scsiport.lib
diff --git a/viostor/buildAll.bat b/viostor/buildAll.bat
index 668efe7..526c368 100644
--- a/viostor/buildAll.bat
+++ b/viostor/buildAll.bat
@@ -1,90 +1,74 @@
-:
-: Set global parameters:
-:
+@echo off
-: Use Windows 7 DDK
-if "%DDKVER%"=="" set DDKVER=7600.16385.0
+set SYS_FILE_NAME=viostor
-: By default DDK is installed under C:\WINDDK, but it can be installed in different \
location
-if "%DDKISNTALLROOT%"=="" set DDKISNTALLROOT=C:\WINDDK\
-set BUILDROOT=%DDKISNTALLROOT%%DDKVER%
-set X64ENV=x64
-if "%DDKVER%"=="6000" set X64ENV=amd64
+for %%A in (Win7 Wnet Wlh WXp) do for %%B in (32 64) do call :%%A_%%B
+goto :eof
-if not "%1"=="" goto parameters_here
-echo no parameters specified, rebuild all
-call clean.bat
-call "%0" WIN7 WIN7_64 Vista Vista64 Win2003 Win200364 XP
+:buildsys
+call buildOne.bat %1 %2
goto :eof
-:parameters_here
-:nextparam
-if "%1"=="" goto :eof
-goto %1
-:continue
-shift
-goto nextparam
-
-:Win7
-set DDKBUILDENV=
-pushd %BUILDROOT%
-call %BUILDROOT%\bin\setenv.bat %BUILDROOT% fre WIN7
-popd
-build -cZg
-
-goto continue
-
-:Win7_64
-set DDKBUILDENV=
-pushd %BUILDROOT%
-call %BUILDROOT%\bin\setenv.bat %BUILDROOT% %X64ENV% fre WIN7
-popd
-build -cZg
-
-goto continue
-
-
-:Vista
-set DDKBUILDENV=
-pushd %BUILDROOT%
-call %BUILDROOT%\bin\setenv.bat %BUILDROOT% fre Wlh
-popd
-build -cZg
+:packsys
+call packOne.bat %1 %2 %SYS_FILE_NAME% %3
+goto :eof
-goto continue
+:buildpack
+call :buildsys %1 %2
+call :packsys %1 %2 %3
+set BUILD_OS=
+set BUILD_ARC=
+set INF_FILE_NAME=
+goto :eof
-:Vista64
-set DDKBUILDENV=
-pushd %BUILDROOT%
-call %BUILDROOT%\bin\setenv.bat %BUILDROOT% %X64ENV% fre Wlh
-popd
-build -cZg
+:WIN7_32
+set BUILD_OS=Win7
+set BUILD_ARC=x86
+set INF_FILE_NAME=Wlh
+call :buildpack %BUILD_OS% %BUILD_ARC% %INF_FILE_NAME%
+goto :eof
-goto continue
+:WIN7_64
+set BUILD_OS=Win7
+set BUILD_ARC=x64
+set INF_FILE_NAME=Wlh
+call :buildpack %BUILD_OS% %BUILD_ARC% %INF_FILE_NAME%
+goto :eof
-:Win2003
-set DDKBUILDENV=
-pushd %BUILDROOT%
-call %BUILDROOT%\bin\setenv.bat %BUILDROOT% fre WNET
-popd
-build -cZg
+:WLH_32
+set BUILD_OS=Wlh
+set BUILD_ARC=x86
+set INF_FILE_NAME=Wlh
+call :buildpack %BUILD_OS% %BUILD_ARC% %INF_FILE_NAME%
+goto :eof
-goto continue
+:WLH_64
+set BUILD_OS=Wlh
+set BUILD_ARC=x64
+set INF_FILE_NAME=Wlh
+call :buildpack %BUILD_OS% %BUILD_ARC% %INF_FILE_NAME%
+goto :eof
-:Win200364
-set DDKBUILDENV=
-pushd %BUILDROOT%
-call %BUILDROOT%\bin\setenv.bat %BUILDROOT% %X64ENV% fre WNET
-popd
-build -cZg
+:WNET_32
+set BUILD_OS=Wnet
+set BUILD_ARC=x86
+set INF_FILE_NAME=Wnet
+call :buildpack %BUILD_OS% %BUILD_ARC% %INF_FILE_NAME%
+goto :eof
-goto continue
+:WNET_64
+set BUILD_OS=Wnet
+set BUILD_ARC=x64
+set INF_FILE_NAME=Wnet
+call :buildpack %BUILD_OS% %BUILD_ARC% %INF_FILE_NAME%
+goto :eof
-:XP
-set DDKBUILDENV=
-pushd %BUILDROOT%
-call %BUILDROOT%\bin\setenv.bat %BUILDROOT% fre WXP
-popd
-build -cZg
+:WXP_32
+set BUILD_OS=WXp
+set BUILD_ARC=x86
+set INF_FILE_NAME=Wxp
+call :buildpack %BUILD_OS% %BUILD_ARC% %INF_FILE_NAME%
+goto :eof
+:WXP_64
goto :eof
diff --git a/viostor/buildDDK.bat b/viostor/buildDDK.bat
deleted file mode 100644
index 8c39eee..0000000
--- a/viostor/buildDDK.bat
+++ /dev/null
@@ -1,7 +0,0 @@
-set DDKVER=6001.18001
-set BUILDROOT=C:\WINDDK\%DDKVER%
-pushd %BUILDROOT%
-set X64ENV=x64
-call %BUILDROOT%\bin\setenv.bat %BUILDROOT% fre %1 %2
-popd
-build -cZg
diff --git a/viostor/buildOne.bat b/viostor/buildOne.bat
new file mode 100644
index 0000000..8ecc35d
--- /dev/null
+++ b/viostor/buildOne.bat
@@ -0,0 +1,13 @@
+@echo off
+
+if "%DDKVER%"=="" set DDKVER=7600.16385.0
+set BUILDROOT=C:\WINDDK\%DDKVER%
+
+set DDKBUILDENV=
+pushd %BUILDROOT%
+call %BUILDROOT%\bin\setenv.bat %BUILDROOT% %2 fre %1 no_oacr
+popd
+build -cZg
+
+set DDKVER=
+set BUILDROOT=
\ No newline at end of file
diff --git a/viostor/buildOne_bat b/viostor/buildOne_bat
new file mode 100644
index 0000000..8ecc35d
--- /dev/null
+++ b/viostor/buildOne_bat
@@ -0,0 +1,13 @@
+@echo off
+
+if "%DDKVER%"=="" set DDKVER=7600.16385.0
+set BUILDROOT=C:\WINDDK\%DDKVER%
+
+set DDKBUILDENV=
+pushd %BUILDROOT%
+call %BUILDROOT%\bin\setenv.bat %BUILDROOT% %2 fre %1 no_oacr
+popd
+build -cZg
+
+set DDKVER=
+set BUILDROOT=
\ No newline at end of file
diff --git a/viostor/clean.bat b/viostor/clean.bat
index e47a389..a66b789 100644
--- a/viostor/clean.bat
+++ b/viostor/clean.bat
@@ -1,16 +1,15 @@
-rmdir /S /Q Debug
-rmdir /S /Q Release
+@echo on
+
+rmdir /S /Q .\Install
+
rmdir /S /Q objfre_wxp_x86
rmdir /S /Q objfre_wnet_x86
rmdir /S /Q objfre_wnet_amd64
-rmdir /S /Q objfre_w2k_x86
rmdir /S /Q objfre_wlh_x86
rmdir /S /Q objfre_wlh_amd64
rmdir /S /Q objfre_win7_x86
rmdir /S /Q objfre_win7_amd64
-
-
del /F *.log *.wrn *.err
diff --git a/viostor/packOne.bat b/viostor/packOne.bat
new file mode 100644
index 0000000..8afd09a
--- /dev/null
+++ b/viostor/packOne.bat
@@ -0,0 +1,61 @@
+@echo off
+: Param1 - Win7 | Wlh | Wnet | XP
+: Param2 - x86|x64
+: Param3 - sys name
+: Param3 - inf name
+
+if "%2"=="x64" set %%2=amd64
+
+if /i "%1"=="Win7" goto :checkarch
+if /i "%1"=="Wlh" goto :checkarch
+if /i "%1"=="Wnet" goto :checkarch
+if /i "%1"=="WXp" goto :checkarch
+goto :printerr
+:checkarch
+if /i "%2"=="x86" goto :makeinstall
+if /i "%2"=="x64" goto :makeinstall
+:printerr
+echo wrong parameters (1)%1 (2)%2 (3)%3
+pause
+goto :eof
+
+:makeinstall
+if "%DDKVER%"=="" set DDKVER=7600.16385.0
+set BUILDROOT=C:\WINDDK\%DDKVER%
+
+set INST_OS=%1
+set INST_ARC=%2
+set SYS_NAME=%3
+set INF_NAME=%4
+rem set INST_EXT=INST_ARC
+
+if /i "%INST_ARC%"=="x64" goto :set_x64
+
+set INST_EXT=i386
+goto :startcopy
+
+:set_x64
+set INST_ARC=amd64
+set INST_EXT=amd64
+
+:startcopy
+set SYS_PATH_AND_NAME=objfre_%INST_OS%_%INST_ARC%\%INST_EXT%\%SYS_NAME%.sys
+set PDB_PATH_AND_NAME=objfre_%INST_OS%_%INST_ARC%\%INST_EXT%\%SYS_NAME%.pdb
+set INF_PATH_AND_NAME=%INF_NAME%.inf
+
+rem echo makeinstall %1 %2 %3 %4
+mkdir .\Install\%INST_OS%\%INST_ARC%
+del /Q .\Install\%INST_OS%\%INST_ARC%\%FILE_NAME%.*
+copy /Y %SYS_PATH_AND_NAME% .\Install\%INST_OS%\%INST_ARC%
+copy /Y %PDB_PATH_AND_NAME% .\Install\%INST_OS%\%INST_ARC%
+copy /Y %INF_PATH_AND_NAME% .\Install\%INST_OS%\%INST_ARC%\%SYS_NAME%.inf
+
+set INST_OS=
+set INST_ARC=
+set SYS_NAME=
+set INF_NAME=
+set SYS_PATH_AND_NAME=
+set PDB_PATH_AND_NAME=
+set INF_PATH_AND_NAME=
+set DDKVER=
+set BUILDROOT=
\ No newline at end of file
diff --git a/viostor/virtio_pci.c b/viostor/virtio_pci.c
index a72b019..ffa2ed0 100644
--- a/viostor/virtio_pci.c
+++ b/viostor/virtio_pci.c
@@ -30,25 +30,6 @@
#include "virtio_stor.h"
-VOID
-VirtIODeviceDumpRegisters(
- IN PVOID DeviceExtension)
-{
- PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
-
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s\n", __FUNCTION__));
-
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("[VIRTIO_PCI_HOST_FEATURES] = %x\n", \
ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_HOST_FEATURES))));
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("[VIRTIO_PCI_GUEST_FEATURES] = %x\n", \
ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_GUEST_FEATURES))));
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("[VIRTIO_PCI_QUEUE_PFN] = %x\n", \
ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_QUEUE_PFN))));
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("[VIRTIO_PCI_QUEUE_NUM] = %x\n", \
ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_QUEUE_NUM))));
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("[VIRTIO_PCI_QUEUE_SEL] = %x\n", \
ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_QUEUE_SEL))));
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("[VIRTIO_PCI_QUEUE_NOTIFY] = %x\n", \
ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_QUEUE_NOTIFY))));
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("[VIRTIO_PCI_STATUS] = %x\n", \
ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_STATUS))));
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("[VIRTIO_PCI_ISR] = %x\n", \
ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_ISR))));
-}
-
-
bool
VirtIODeviceGetHostFeature(
IN PVOID DeviceExtension,
diff --git a/viostor/virtio_pci.h b/viostor/virtio_pci.h
index 3e143d4..9916759 100644
--- a/viostor/virtio_pci.h
+++ b/viostor/virtio_pci.h
@@ -82,10 +82,6 @@ VOID
VirtIODeviceReset(
IN PVOID DeviceExtension);
-VOID
-VirtIODeviceDumpRegisters(
- IN PVOID DeviceExtension);
-
bool
VirtIODeviceGetHostFeature(
IN PVOID DeviceExtension,
diff --git a/viostor/virtio_ring.c b/viostor/virtio_ring.c
index 2911cef..cedb4f5 100644
--- a/viostor/virtio_ring.c
+++ b/viostor/virtio_ring.c
@@ -42,6 +42,63 @@ initialize_virtqueue(
//#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
#define to_vvq(_vq) (struct vring_virtqueue *)_vq
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+/* Set up an indirect table of descriptors and add it to the queue. */
+static
+int
+vring_add_indirect(
+ IN struct vring_virtqueue *vq,
+ IN struct VirtIOBufferDescriptor sg[],
+ IN unsigned int out,
+ IN unsigned int in,
+ IN PVOID va)
+{
+ struct vring_desc *desc = (struct vring_desc *)va;
+ unsigned head;
+ unsigned int i;
+ STOR_PHYSICAL_ADDRESS addr;
+ ULONG len;
+
+ addr = StorPortGetPhysicalAddress(vq->vq.DeviceExtension, NULL, desc, &len);
+ if (!addr.QuadPart) {
+ return vq->vring.num;
+ }
+ /* Transfer entries from the sg list into the indirect page */
+ for (i = 0; i < out; i++) {
+ desc[i].flags = VRING_DESC_F_NEXT;
+ desc[i].addr = sg->physAddr.QuadPart;
+ desc[i].len = sg->ulSize;
+ desc[i].next = i+1;
+ sg++;
+ }
+ for (; i < (out + in); i++) {
+ desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
+ desc[i].addr = sg->physAddr.QuadPart;
+ desc[i].len = sg->ulSize;
+ desc[i].next = i+1;
+ sg++;
+ }
+
+ /* Last one doesn't continue. */
+ desc[i-1].flags &= ~VRING_DESC_F_NEXT;
+ desc[i-1].next = 0;
+
+ /* We're about to use a buffer */
+ vq->num_free--;
+
+ /* Use a single buffer which doesn't continue */
+ head = vq->free_head;
+ vq->vring.desc[head].flags = VRING_DESC_F_INDIRECT;
+ vq->vring.desc[head].addr = addr.QuadPart;
+ vq->vring.desc[head].len = i * sizeof(struct vring_desc);
+
+ /* Update free pointer */
+ vq->free_head = vq->vring.desc[head].next;
+
+ return head;
+}
+#endif
+
static
int
vring_add_buf(
@@ -53,12 +110,28 @@ vring_add_buf(
{
struct vring_virtqueue *vq = to_vvq(_vq);
unsigned int i, avail, head, prev;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ PSCSI_REQUEST_BLOCK Srb;
+ PRHEL_SRB_EXTENSION srbExt;
+ PADAPTER_EXTENSION adaptExt;
+ pblk_req vbr;
+#endif
if(data == NULL) {
RhelDbgPrint(TRACE_LEVEL_ERROR, ("%s: data is NULL!\n", __FUNCTION__) );
return -1;
}
-
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ adaptExt = (PADAPTER_EXTENSION)vq->vq.DeviceExtension;
+ vbr = (pblk_req) data;
+ Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
+ srbExt = (PRHEL_SRB_EXTENSION)Srb->SrbExtension;
+ if (srbExt->addr && (out + in) > 1 && vq->num_free) {
+ head = vring_add_indirect(vq, sg, out, in, srbExt->addr);
+ if (head != vq->vring.num)
+ goto add_head;
+ }
+#endif
if(out + in > vq->vring.num) {
RhelDbgPrint(TRACE_LEVEL_ERROR, ("%s: out + in > vq->vring.num!\n", \
__FUNCTION__) ); return -1;
@@ -104,7 +177,9 @@ vring_add_buf(
/* Update free pointer */
vq->free_head = i;
-
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+add_head:
+#endif
/* Set token. */
vq->data[head] = data;
@@ -118,12 +193,15 @@ vring_add_buf(
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s: Added buffer head %i to %p\n",
__FUNCTION__, head, vq) );
-
- return 0;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ if (adaptExt->indirect)
+ return vq->num_free ? vq->vring.num : 0;
+#endif
+ return vq->num_free;
}
-static
-VOID
+static
+VOID
vring_kick_always(
struct virtqueue *_vq)
{
@@ -174,12 +252,23 @@ detach_buf(
unsigned int head)
{
unsigned int i;
+ PVOID addr;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ STOR_PHYSICAL_ADDRESS pa;
+#endif
/* Clear data ptr. */
vq->data[head] = NULL;
/* Put back on free list: find end */
i = head;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ if (vq->vring.desc[i].flags & VRING_DESC_F_INDIRECT) {
+ pa.QuadPart = vq->vring.desc[i].addr;
+ addr = StorPortGetVirtualAddress(vq->vq.DeviceExtension, pa);
+ StorPortFreePool(vq->vq.DeviceExtension, addr);
+ }
+#endif
while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
i = vq->vring.desc[i].next;
vq->num_free++;
@@ -233,7 +322,7 @@ vring_get_buf(
unsigned int i;
if (!more_used(vq)) {
- RhelDbgPrint(TRACE_LEVEL_ERROR, ("No more buffers in queue: last_used_idx %d \
vring.used->idx %d\n", vq->last_used_idx, vq->vring.used->idx)); + \
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("No more buffers in queue: last_used_idx %d \
vring.used->idx %d\n", vq->last_used_idx, vq->vring.used->idx)); return NULL;
}
@@ -242,14 +331,14 @@ vring_get_buf(
i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id;
*len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len;
- RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s>>> id %d, len %d\n", __FUNCTION__, i, \
*len) ); + RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("%s>>> id %d, len %d\n", \
__FUNCTION__, i, *len) );
if (i >= vq->vring.num) {
- RhelDbgPrint(TRACE_LEVEL_ERROR, ("id %u out of range\n", i) );
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("id %u out of range\n", i) );
return NULL;
}
if (!vq->data[i]) {
- RhelDbgPrint(TRACE_LEVEL_ERROR, ("id %u is not a head!\n", i) );
+ RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("id %u is not a head!\n", i) );
return NULL;
}
@@ -314,11 +403,11 @@ initialize_virtqueue(
vq->num_free = num;
vq->free_head = 0;
for (i = 0; i < num-1; i++)
- vq->vring.desc[i].next = i+1;
+ vq->vring.desc[i].next = (u16)(i+1);
}
-struct
+struct
virtqueue*
vring_new_virtqueue(
unsigned int num,
@@ -327,7 +416,6 @@ vring_new_virtqueue(
IN VOID (*notify)(struct virtqueue *))
{
struct vring_virtqueue *vq;
- unsigned int i;
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s: Creating new virtqueue>>> size %d, pages \
%p\n", __FUNCTION__, num, pages) );
diff --git a/viostor/virtio_ring.h b/viostor/virtio_ring.h
index c43f954..6992000 100644
--- a/viostor/virtio_ring.h
+++ b/viostor/virtio_ring.h
@@ -19,15 +19,19 @@
#include "VirtIO.h"
/* This marks a buffer as continuing via the next field. */
-#define VRING_DESC_F_NEXT 1
+#define VRING_DESC_F_NEXT 1
/* This marks a buffer as write-only (otherwise read-only). */
-#define VRING_DESC_F_WRITE 2
+#define VRING_DESC_F_WRITE 2
+#define VRING_DESC_F_INDIRECT 4
/* This means don't notify other side when buffer added. */
-#define VRING_USED_F_NO_NOTIFY 1
+#define VRING_USED_F_NO_NOTIFY 1
/* This means don't interrupt guest when buffer consumed. */
-#define VRING_AVAIL_F_NO_INTERRUPT 1
+#define VRING_AVAIL_F_NO_INTERRUPT 1
+#define VIRTIO_RING_F_INDIRECT_DESC 28
+
+#pragma warning(disable:4200)
#pragma pack (push)
#pragma pack (1)
diff --git a/viostor/virtio_stor.c b/viostor/virtio_stor.c
index d363909..7f9e9f1 100644
--- a/viostor/virtio_stor.c
+++ b/viostor/virtio_stor.c
@@ -16,7 +16,7 @@
#include "virtio_stor_utils.h"
#include "virtio_stor_hw_helper.h"
-ULONG RhelDbgLevel = TRACE_LEVEL_NONE;
+ULONG RhelDbgLevel = TRACE_LEVEL_ERROR;
BOOLEAN IsCrashDumpMode;
BOOLEAN
@@ -202,6 +202,11 @@ VirtIoFindAdapter(
ULONG vq_sz;
USHORT pageNum;
+ UNREFERENCED_PARAMETER( HwContext );
+ UNREFERENCED_PARAMETER( BusInformation );
+ UNREFERENCED_PARAMETER( ArgumentString );
+ UNREFERENCED_PARAMETER( Again );
+
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s (%d)\n", __FUNCTION__, \
KeGetCurrentIrql()));
adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
@@ -210,7 +215,6 @@ VirtIoFindAdapter(
ConfigInfo->Master = TRUE;
ConfigInfo->ScatterGather = TRUE;
- ConfigInfo->CachesData = TRUE;
ConfigInfo->DmaWidth = Width32Bits;
ConfigInfo->Dma32BitAddresses = TRUE;
ConfigInfo->Dma64BitAddresses = TRUE;
@@ -220,7 +224,7 @@ VirtIoFindAdapter(
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
#ifdef MSI_SUPPORTED
ConfigInfo->HwMSInterruptRoutine = VirtIoMSInterruptRoutine;
- ConfigInfo->InterruptSynchronizationMode=InterruptSynchronizePerMessage;//InterruptSynchronizeAll;//
+ ConfigInfo->InterruptSynchronizationMode=InterruptSynchronizePerMessage;
#endif
#else
ConfigInfo->MapBuffers = TRUE;
@@ -296,11 +300,14 @@ VirtIoFindAdapter(
return SP_RETURN_ERROR;
}
+ VirtIODeviceReset(DeviceExtension);
ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + VIRTIO_PCI_QUEUE_SEL), \
(USHORT)0); if (adaptExt->dump_mode) {
ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + \
VIRTIO_PCI_QUEUE_PFN),(USHORT)0); }
+ adaptExt->features = ScsiPortReadPortUlong((PULONG)(adaptExt->device_base + \
VIRTIO_PCI_HOST_FEATURES)); + ConfigInfo->CachesData = \
CHECKBIT(adaptExt->features, VIRTIO_BLK_F_WCACHE) ? TRUE : FALSE;
pageNum = ScsiPortReadPortUshort((PUSHORT)(adaptExt->device_base + \
VIRTIO_PCI_QUEUE_NUM)); vr_sz = vring_size(pageNum,PAGE_SIZE);
@@ -309,12 +316,20 @@ VirtIoFindAdapter(
if(adaptExt->dump_mode) {
ConfigInfo->NumberOfPhysicalBreaks = 8;
} else {
- ConfigInfo->NumberOfPhysicalBreaks = 16;
+ ConfigInfo->NumberOfPhysicalBreaks = MAX_PHYS_SEGMENTS + 1;
}
- ConfigInfo->MaximumTransferLength = ConfigInfo->NumberOfPhysicalBreaks * \
PAGE_SIZE; + ConfigInfo->MaximumTransferLength = 0x00FFFFFF;
adaptExt->queue_depth = pageNum / ConfigInfo->NumberOfPhysicalBreaks - 1;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ if(!adaptExt->dump_mode) {
+ adaptExt->indirect = CHECKBIT(adaptExt->features, \
VIRTIO_RING_F_INDIRECT_DESC); + }
+ if(adaptExt->indirect) {
+ adaptExt->queue_depth <<= 1;
+ }
+#endif
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("breaks_number = %x queue_depth = %x\n",
ConfigInfo->NumberOfPhysicalBreaks,
adaptExt->queue_depth));
@@ -338,8 +353,9 @@ VirtIoFindAdapter(
adaptExt->virtqueue = \
(vring_virtqueue*)((ULONG_PTR)(adaptExt->pci_vq_info.queue) + vr_sz);
InitializeListHead(&adaptExt->list_head);
+#ifdef USE_STORPORT
InitializeListHead(&adaptExt->complete_list);
-
+#endif
return SP_RETURN_FOUND;
}
@@ -369,11 +385,12 @@ VirtIoHwInitialize(
PADAPTER_EXTENSION adaptExt;
u64 cap;
u32 v;
- struct virtio_blk_geometry vgeo;
#ifdef MSI_SUPPORTED
MESSAGE_INTERRUPT_INFORMATION msi_info;
#endif
+ struct virtio_blk_geometry vgeo;
+
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s (%d)\n", __FUNCTION__, \
KeGetCurrentIrql()));
adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
@@ -411,15 +428,15 @@ VirtIoHwInitialize(
return FALSE;
}
- if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_BARRIER)) {
+ if (CHECKBIT(adaptExt->features, VIRTIO_BLK_F_BARRIER)) {
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_BARRIER\n"));
}
- if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_RO)) {
+ if (CHECKBIT(adaptExt->features, VIRTIO_BLK_F_RO)) {
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_RO\n"));
}
- if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_SIZE_MAX)) {
+ if (CHECKBIT(adaptExt->features, VIRTIO_BLK_F_SIZE_MAX)) {
VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, size_max),
&v, sizeof(v));
adaptExt->info.size_max = v;
@@ -427,21 +444,21 @@ VirtIoHwInitialize(
adaptExt->info.size_max = SECTOR_SIZE;
}
- if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_SEG_MAX)) {
+ if (CHECKBIT(adaptExt->features, VIRTIO_BLK_F_SEG_MAX)) {
VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, seg_max),
&v, sizeof(v));
adaptExt->info.seg_max = v;
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_SEG_MAX = %d\n", \
adaptExt->info.seg_max)); }
- if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_BLK_SIZE)) {
+ if (CHECKBIT(adaptExt->features, VIRTIO_BLK_F_BLK_SIZE)) {
VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, blk_size),
&v, sizeof(v));
adaptExt->info.blk_size = v;
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_BLK_SIZE = %d\n", \
adaptExt->info.blk_size)); }
- if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_GEOMETRY)) {
+ if (CHECKBIT(adaptExt->features, VIRTIO_BLK_F_GEOMETRY)) {
VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, geometry),
&vgeo, sizeof(vgeo));
adaptExt->info.geometry.cylinders= vgeo.cylinders;
@@ -450,19 +467,32 @@ VirtIoHwInitialize(
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_GEOMETRY. cylinders = \
%d heads = %d sectors = %d\n", adaptExt->info.geometry.cylinders, \
adaptExt->info.geometry.heads, adaptExt->info.geometry.sectors)); }
- if (VirtIODeviceGetHostFeature(DeviceExtension, VIRTIO_BLK_F_IDENTIFY)) {
- VirtIODeviceGet(DeviceExtension, FIELD_OFFSET(blk_config, identify),
- &adaptExt->info.identify, VIRTIO_BLK_ID_LEN);
- adaptExt->has_sn = TRUE;
- RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("VIRTIO_BLK_F_IDENTIFY. \n"));
- }
-
-
VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, capacity),
&cap, sizeof(cap));
adaptExt->info.capacity = cap;
RhelDbgPrint(TRACE_LEVEL_INFORMATION, ("capacity = %08I64X\n", \
adaptExt->info.capacity));
+
+ if(CHECKBIT(adaptExt->features, VIRTIO_BLK_F_TOPOLOGY)) {
+ VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, \
physical_block_exp), + &adaptExt->info.physical_block_exp, \
sizeof(adaptExt->info.physical_block_exp)); + RhelDbgPrint(TRACE_LEVEL_ERROR, \
("physical_block_exp = %d\n", adaptExt->info.physical_block_exp)); +
+ VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, \
alignment_offset), + &adaptExt->info.alignment_offset, \
sizeof(adaptExt->info.alignment_offset)); + RhelDbgPrint(TRACE_LEVEL_ERROR, \
("alignment_offset = %d\n", adaptExt->info.alignment_offset)); +
+ VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, min_io_size),
+ &adaptExt->info.min_io_size, \
sizeof(adaptExt->info.min_io_size)); + RhelDbgPrint(TRACE_LEVEL_ERROR, \
("min_io_size = %d\n", adaptExt->info.min_io_size)); +
+ VirtIODeviceGet( DeviceExtension, FIELD_OFFSET(blk_config, opt_io_size),
+ &adaptExt->info.opt_io_size, \
sizeof(adaptExt->info.opt_io_size)); + RhelDbgPrint(TRACE_LEVEL_ERROR, \
("opt_io_size = %d\n", adaptExt->info.opt_io_size)); +
+ }
+
+
memset(&adaptExt->inquiry_data, 0, sizeof(INQUIRYDATA));
adaptExt->inquiry_data.ANSIVersion = 4;
@@ -481,7 +511,6 @@ VirtIoHwInitialize(
return StorPortEnablePassiveInitialization(DeviceExtension, \
VirtIoPassiveInitializeRoutine); }
#endif
-
return TRUE;
}
@@ -504,14 +533,27 @@ VirtIoStartIo(
}
case SRB_FUNCTION_PNP:
case SRB_FUNCTION_POWER:
- case SRB_FUNCTION_SHUTDOWN:
- case SRB_FUNCTION_FLUSH:
case SRB_FUNCTION_RESET_DEVICE:
case SRB_FUNCTION_RESET_LOGICAL_UNIT: {
Srb->SrbStatus = SRB_STATUS_SUCCESS;
CompleteSRB(DeviceExtension, Srb);
return TRUE;
}
+ case SRB_FUNCTION_SHUTDOWN:
+ case SRB_FUNCTION_FLUSH: {
+ if(CHECKBIT(adaptExt->features, VIRTIO_BLK_F_WCACHE)) {
+ Srb->SrbStatus = SRB_STATUS_PENDING;
+ if(!RhelDoFlush(DeviceExtension, Srb)) {
+ Srb->SrbStatus = SRB_STATUS_BUSY;
+ CompleteSRB(DeviceExtension, Srb);
+ }
+ } else {
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ CompleteSRB(DeviceExtension, Srb);
+ }
+ return TRUE;
+ }
+
default: {
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
CompleteSRB(DeviceExtension, Srb);
@@ -530,10 +572,13 @@ VirtIoStartIo(
CompleteSRB(DeviceExtension, Srb);
return TRUE;
}
+
+ case SCSIOP_READ_CAPACITY16:
case SCSIOP_READ_CAPACITY: {
PREAD_CAPACITY_DATA readCap;
PREAD_CAPACITY_DATA_EX readCapEx;
u64 lastLBA;
+ u64 blocksize;
#ifdef USE_STORPORT
BOOLEAN depthSet;
depthSet = StorPortSetDeviceQueueDepth(DeviceExtension,
@@ -546,7 +591,8 @@ VirtIoStartIo(
readCap = (PREAD_CAPACITY_DATA)Srb->DataBuffer;
readCapEx = (PREAD_CAPACITY_DATA_EX)Srb->DataBuffer;
- lastLBA = adaptExt->info.capacity - 1;
+ lastLBA = (adaptExt->info.capacity >> adaptExt->info.physical_block_exp) \
- 1; + blocksize = adaptExt->info.size_max * (1 << \
adaptExt->info.physical_block_exp); if (Srb->DataTransferLength == \
sizeof(READ_CAPACITY_DATA)) { if (lastLBA > 0xFFFFFFFF) {
readCap->LogicalBlockAddress = (ULONG)-1;
@@ -555,14 +601,14 @@ VirtIoStartIo(
&lastLBA);
}
REVERSE_BYTES(&readCap->BytesPerBlock,
- &adaptExt->info.size_max);
+ &blocksize);
} else {
ASSERT(Srb->DataTransferLength ==
sizeof(READ_CAPACITY_DATA_EX));
REVERSE_BYTES_QUAD(&readCapEx->LogicalBlockAddress.QuadPart,
&lastLBA);
- REVERSE_BYTES(&readCap->BytesPerBlock,
- &adaptExt->info.size_max);
+ REVERSE_BYTES(&readCapEx->BytesPerBlock,
+ &blocksize);
}
Srb->SrbStatus = SRB_STATUS_SUCCESS;
@@ -570,7 +616,9 @@ VirtIoStartIo(
return TRUE;
}
case SCSIOP_READ:
- case SCSIOP_WRITE: {
+ case SCSIOP_WRITE:
+ case SCSIOP_READ16:
+ case SCSIOP_WRITE16: {
Srb->SrbStatus = SRB_STATUS_PENDING;
if(!RhelDoReadWrite(DeviceExtension, Srb)) {
Srb->SrbStatus = SRB_STATUS_BUSY;
@@ -590,6 +638,7 @@ VirtIoStartIo(
case SCSIOP_RELEASE_UNIT:
case SCSIOP_RELEASE_UNIT10:
case SCSIOP_VERIFY:
+ case SCSIOP_VERIFY16:
case SCSIOP_SYNCHRONIZE_CACHE:
case SCSIOP_MEDIUM_REMOVAL: {
Srb->SrbStatus = SRB_STATUS_SUCCESS;
@@ -622,7 +671,6 @@ VirtIoInterrupt(
{
pblk_req vbr;
unsigned int len;
- unsigned long flags;
PADAPTER_EXTENSION adaptExt;
BOOLEAN isInterruptServiced = FALSE;
PSCSI_REQUEST_BLOCK Srb;
@@ -659,6 +707,9 @@ VirtIoResetBus(
IN ULONG PathId
)
{
+ UNREFERENCED_PARAMETER( DeviceExtension );
+ UNREFERENCED_PARAMETER( PathId );
+
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("<--->%s\n", __FUNCTION__));
return TRUE;
}
@@ -707,7 +758,7 @@ VirtIoAdapterControl(
RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("ScsiRestartAdapter\n"));
adaptExt->pci_vq_info.vq = NULL;
#ifdef MSI_SUPPORTED
- if(!adaptExt->dump_mode & adaptExt->msix_vectors) {
+ if(!adaptExt->dump_mode && adaptExt->msix_vectors) {
adaptExt->pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, \
0, adaptExt->msix_vectors); }
#endif
@@ -784,7 +835,7 @@ VirtIoBuildIo(
srbExt->vbr.sg[sgElement].ulSize = sgList->List[i].Length;
}
- srbExt->vbr.out_hdr.sector = RhelGetLba(cdb);
+ srbExt->vbr.out_hdr.sector = RhelGetLba(DeviceExtension, cdb);
srbExt->vbr.out_hdr.ioprio = 0;
srbExt->vbr.req = (struct request *)Srb;
@@ -816,7 +867,6 @@ VirtIoMSInterruptRoutine (
{
pblk_req vbr;
unsigned int len;
- unsigned long flags;
PADAPTER_EXTENSION adaptExt;
PSCSI_REQUEST_BLOCK Srb;
@@ -889,13 +939,8 @@ RhelScsiGetInquiryData(
PVPD_SERIAL_NUMBER_PAGE SerialPage;
SerialPage = (PVPD_SERIAL_NUMBER_PAGE)Srb->DataBuffer;
SerialPage->PageCode = VPD_SERIAL_NUMBER;
- if(adaptExt->has_sn) {
- SerialPage->PageLength = VIRTIO_BLK_ID_SN_BYTES;
- ScsiPortMoveMemory(&SerialPage->SerialNumber[0], \
&adaptExt->info.identify[VIRTIO_BLK_ID_SN], VIRTIO_BLK_ID_SN_BYTES);
- } else {
- SerialPage->PageLength = 1;
- SerialPage->SerialNumber[0] = '0';
- }
+ SerialPage->PageLength = 1;
+ SerialPage->SerialNumber[0] = '0';
Srb->DataTransferLength = sizeof(VPD_SERIAL_NUMBER_PAGE) + \
SerialPage->PageLength; }
else if ((cdb->CDB6INQUIRY3.PageCode == VPD_DEVICE_IDENTIFIERS) &&
@@ -943,7 +988,10 @@ RhelScsiReportLuns(
)
{
UCHAR SrbStatus = SRB_STATUS_SUCCESS;
- PUCHAR data = Srb->DataBuffer;
+ PUCHAR data = (PUCHAR)Srb->DataBuffer;
+
+ UNREFERENCED_PARAMETER( DeviceExtension );
+
data[3]=8;
Srb->ScsiStatus = SCSISTAT_GOOD;
Srb->SrbStatus = SrbStatus;
@@ -963,6 +1011,9 @@ RhelScsiGetModeSense(
PMODE_PARAMETER_HEADER header;
PMODE_CACHING_PAGE cachePage;
PMODE_PARAMETER_BLOCK blockDescriptor;
+ PADAPTER_EXTENSION adaptExt;
+
+ adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
ModeSenseDataLen = Srb->DataTransferLength;
@@ -987,11 +1038,11 @@ RhelScsiGetModeSense(
header->ModeDataLength = sizeof(MODE_CACHING_PAGE) + 3;
cachePage = (PMODE_CACHING_PAGE)header;
- (ULONG_PTR)cachePage += sizeof(MODE_PARAMETER_HEADER);
+ cachePage = (PMODE_CACHING_PAGE)((unsigned char *)(cachePage) + \
(ULONG)sizeof(MODE_PARAMETER_HEADER)); memset(cachePage, 0, \
sizeof(MODE_CACHING_PAGE)); cachePage->PageCode = MODE_PAGE_CACHING;
cachePage->PageLength = 10;
- cachePage->WriteCacheEnable = 1;
+ cachePage->WriteCacheEnable = CHECKBIT(adaptExt->features, \
VIRTIO_BLK_F_WCACHE) ? 1 : 0;
Srb->DataTransferLength = sizeof(MODE_PARAMETER_HEADER) +
sizeof(MODE_CACHING_PAGE);
@@ -1019,7 +1070,7 @@ RhelScsiGetModeSense(
header->BlockDescriptorLength = sizeof(MODE_PARAMETER_BLOCK);
blockDescriptor = (PMODE_PARAMETER_BLOCK)header;
- (ULONG_PTR)blockDescriptor += sizeof(MODE_PARAMETER_HEADER);
+ blockDescriptor = (PMODE_PARAMETER_BLOCK)((unsigned char \
*)(blockDescriptor) + (ULONG)sizeof(MODE_PARAMETER_HEADER));
memset(blockDescriptor, 0, sizeof(MODE_PARAMETER_HEADER));
@@ -1037,58 +1088,6 @@ RhelScsiGetModeSense(
return SrbStatus;
}
-ULONGLONG
-RhelGetLba(
- PCDB Cdb
- )
-{
-
- EIGHT_BYTE lba;
-
- switch (Cdb->CDB6GENERIC.OperationCode) {
-
- case SCSIOP_READ:
- case SCSIOP_WRITE:
- case SCSIOP_WRITE_VERIFY: {
- lba.AsULongLong = 0;
- lba.Byte0 = Cdb->CDB10.LogicalBlockByte3;
- lba.Byte1 = Cdb->CDB10.LogicalBlockByte2;
- lba.Byte2 = Cdb->CDB10.LogicalBlockByte1;
- lba.Byte3 = Cdb->CDB10.LogicalBlockByte0;
- return lba.AsULongLong;
- }
- case SCSIOP_READ6:
- case SCSIOP_WRITE6: {
- lba.AsULongLong = 0;
- lba.Byte0 = Cdb->CDB6READWRITE.LogicalBlockMsb1;
- lba.Byte1 = Cdb->CDB6READWRITE.LogicalBlockMsb0;
- lba.Byte2 = Cdb->CDB6READWRITE.LogicalBlockLsb;
- return lba.AsULongLong;
- }
- case SCSIOP_READ12:
- case SCSIOP_WRITE12:
- case SCSIOP_WRITE_VERIFY12: {
- lba.AsULongLong = 0;
- REVERSE_BYTES(&lba, &Cdb->CDB12.LogicalBlock[0]);
- return lba.AsULongLong;
- }
- case SCSIOP_READ16:
- case SCSIOP_WRITE16:
- case SCSIOP_WRITE_VERIFY16: {
- lba.AsULongLong = 0;
- REVERSE_BYTES_QUAD(&lba, &Cdb->CDB16.LogicalBlock[0]);
- return lba.AsULongLong;
- }
- default: {
- break;
- }
- }
-
- ASSERT(FALSE);
- return (ULONGLONG)-1;
-
-}
-
VOID
CompleteSRB(
IN PVOID DeviceExtension,
@@ -1115,9 +1114,13 @@ CompleteDPC(
IN ULONG MessageID
)
{
- PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
- PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
-
+ PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
+#ifdef USE_STORPORT
+ PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+#else
+ PRHEL_SRB_EXTENSION srbExt = (PRHEL_SRB_EXTENSION)Srb->SrbExtension;
+ UNREFERENCED_PARAMETER( MessageID );
+#endif
RemoveEntryList(&vbr->list_entry);
#ifdef USE_STORPORT
@@ -1125,15 +1128,26 @@ CompleteDPC(
InsertTailList(&adaptExt->complete_list, &vbr->list_entry);
StorPortIssueDpc(DeviceExtension,
&adaptExt->completion_dpc,
- (PVOID)MessageID,
+ ULongToPtr(MessageID),
NULL);
return;
}
-#endif
CompleteSRB(DeviceExtension, Srb);
+#else
+ ScsiPortNotification(RequestComplete,
+ DeviceExtension,
+ Srb);
+ if(srbExt->call_next) {
+ ScsiPortNotification(NextLuRequest,
+ DeviceExtension,
+ Srb->PathId,
+ Srb->TargetId,
+ Srb->Lun);
+ }
+#endif
}
-
#ifdef USE_STORPORT
+#pragma warning(disable: 4100 4701)
VOID
CompleteDpcRoutine(
IN PSTOR_DPC Dpc,
@@ -1144,42 +1158,62 @@ CompleteDpcRoutine(
{
STOR_LOCK_HANDLE LockHandle;
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)Context;
- ULONG MessageID = (ULONG)SystemArgument1;
+
+#ifdef MSI_SUPPORTED
+ ULONG MessageID = PtrToUlong(SystemArgument1);
ULONG OldIrql;
+#endif
+#ifdef MSI_SUPPORTED
if(adaptExt->msix_vectors) {
StorPortAcquireMSISpinLock (Context, MessageID, &OldIrql);
} else {
+#endif
StorPortAcquireSpinLock ( Context, InterruptLock , NULL, &LockHandle);
+#ifdef MSI_SUPPORTED
}
+#endif
+
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;
+#ifdef MSI_SUPPORTED
if(adaptExt->msix_vectors) {
StorPortReleaseMSISpinLock (Context, MessageID, OldIrql);
} else {
+#endif
StorPortReleaseSpinLock (Context, &LockHandle);
+#ifdef MSI_SUPPORTED
}
+#endif
ScsiPortNotification(RequestComplete,
Context,
Srb);
+#ifdef MSI_SUPPORTED
if(adaptExt->msix_vectors) {
StorPortAcquireMSISpinLock (Context, MessageID, &OldIrql);
} else {
+#endif
StorPortAcquireSpinLock ( Context, InterruptLock , NULL, &LockHandle);
+#ifdef MSI_SUPPORTED
}
+#endif
}
+#ifdef MSI_SUPPORTED
if(adaptExt->msix_vectors) {
StorPortReleaseMSISpinLock (Context, MessageID, OldIrql);
} else {
+#endif
StorPortReleaseSpinLock (Context, &LockHandle);
+#ifdef MSI_SUPPORTED
}
+#endif
return;
}
#endif
diff --git a/viostor/virtio_stor.h b/viostor/virtio_stor.h
index 456fa0e..9c99b75 100644
--- a/viostor/virtio_stor.h
+++ b/viostor/virtio_stor.h
@@ -30,29 +30,29 @@ typedef struct VirtIOBufferDescriptor VIO_SG, *PVIO_SG;
/* Feature bits */
-#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
-#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
-#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
-#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */
-#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
-#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/
+#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
+#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
+#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
+#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */
+#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
+#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
-#define VIRTIO_BLK_F_IDENTIFY 8 /* ATA IDENTIFY supported */
-
-#define VIRTIO_BLK_ID_LEN 256 /* length of identify u16 array */
-#define VIRTIO_BLK_ID_SN 10 /* start of char * serial# */
-#define VIRTIO_BLK_ID_SN_BYTES 20 /* length in bytes of serial# */
+#define VIRTIO_BLK_F_WCACHE 9 /* write cache enabled */
+#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */
/* These two define direction. */
-#define VIRTIO_BLK_T_IN 0
-#define VIRTIO_BLK_T_OUT 1
+#define VIRTIO_BLK_T_IN 0
+#define VIRTIO_BLK_T_OUT 1
+
+#define VIRTIO_BLK_T_SCSI_CMD 2
+#define VIRTIO_BLK_T_FLUSH 4
-#define VIRTIO_BLK_S_OK 0
-#define VIRTIO_BLK_S_IOERR 1
-#define VIRTIO_BLK_S_UNSUPP 2
+#define VIRTIO_BLK_S_OK 0
+#define VIRTIO_BLK_S_IOERR 1
+#define VIRTIO_BLK_S_UNSUPP 2
#define SECTOR_SIZE 512
-#define MAX_PHYS_SEGMENTS 128
+#define MAX_PHYS_SEGMENTS 16
#define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS)
#define IO_PORT_LENGTH 0x40
@@ -72,7 +72,10 @@ typedef struct virtio_blk_config {
} geometry;
/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
u32 blk_size;
- u16 identify[VIRTIO_BLK_ID_LEN];
+ u8 physical_block_exp;
+ u8 alignment_offset;
+ u16 min_io_size;
+ u16 opt_io_size;
}blk_config, *pblk_config;
#pragma pack()
@@ -99,26 +102,32 @@ typedef struct _ADAPTER_EXTENSION {
vring_virtqueue* virtqueue;
INQUIRYDATA inquiry_data;
blk_config info;
+ ULONG breaks_number;
+ ULONG transfer_size;
ULONG queue_depth;
BOOLEAN dump_mode;
LIST_ENTRY list_head;
- LIST_ENTRY complete_list;
+ ULONG msix_vectors;
+ ULONG features;
#ifdef USE_STORPORT
+ LIST_ENTRY complete_list;
STOR_DPC completion_dpc;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ BOOLEAN indirect;
+#endif
#endif
- BOOLEAN has_sn;
- ULONG msix_vectors;
}ADAPTER_EXTENSION, *PADAPTER_EXTENSION;
typedef struct _RHEL_SRB_EXTENSION {
blk_req vbr;
ULONG out;
ULONG in;
+#ifndef USE_STORPORT
+ BOOLEAN call_next;
+#endif
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ PVOID addr;
+#endif
}RHEL_SRB_EXTENSION, *PRHEL_SRB_EXTENSION;
-ULONGLONG
-RhelGetLba(
- PCDB Cdb
- );
-
#endif ___VIOSTOR__H__
diff --git a/viostor/virtio_stor_hw_helper.c b/viostor/virtio_stor_hw_helper.c
index ed6abf7..ed2e5d2 100644
--- a/viostor/virtio_stor_hw_helper.c
+++ b/viostor/virtio_stor_hw_helper.c
@@ -13,10 +13,82 @@
*
**********************************************************************/
#include "virtio_stor_hw_helper.h"
+#include"virtio_stor_utils.h"
#ifdef USE_STORPORT
BOOLEAN
-SynchronizedAccessRoutine(
+SynchronizedFlushRoutine(
+ IN PVOID DeviceExtension,
+ IN PVOID Context
+ )
+{
+ PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+ PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK) Context;
+ PRHEL_SRB_EXTENSION srbExt = (PRHEL_SRB_EXTENSION)Srb->SrbExtension;
+
+ srbExt->vbr.out_hdr.ioprio = 0;
+ srbExt->vbr.req = (struct request *)Srb;
+ srbExt->vbr.out_hdr.type = VIRTIO_BLK_T_FLUSH;
+ srbExt->out = 1;
+ srbExt->in = 1;
+
+ if (adaptExt->pci_vq_info.vq->vq_ops->add_buf(adaptExt->pci_vq_info.vq,
+ &srbExt->vbr.sg[0],
+ srbExt->out, srbExt->in,
+ &srbExt->vbr) >= 0){
+ InsertTailList(&adaptExt->list_head, &srbExt->vbr.list_entry);
+ adaptExt->pci_vq_info.vq->vq_ops->kick(adaptExt->pci_vq_info.vq);
+ return TRUE;
+ }
+
+ RhelDbgPrint(TRACE_LEVEL_ERROR, ("%s StorPortBusy\n", __FUNCTION__));
+ StorPortBusy(DeviceExtension, 2);
+ return FALSE;
+}
+
+BOOLEAN
+RhelDoFlush(PVOID DeviceExtension,
+ PSCSI_REQUEST_BLOCK Srb)
+{
+ return StorPortSynchronizeAccess(DeviceExtension, SynchronizedFlushRoutine, \
(PVOID)Srb); +}
+#else
+BOOLEAN
+RhelDoFlush(PVOID DeviceExtension,
+ PSCSI_REQUEST_BLOCK Srb)
+{
+ PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+ PRHEL_SRB_EXTENSION srbExt = (PRHEL_SRB_EXTENSION)Srb->SrbExtension;
+ int num_free;
+
+ srbExt->vbr.out_hdr.ioprio = 0;
+ srbExt->vbr.req = (struct request *)Srb;
+ srbExt->vbr.out_hdr.type = VIRTIO_BLK_T_FLUSH;
+ srbExt->out = 1;
+ srbExt->in = 1;
+
+ num_free = adaptExt->pci_vq_info.vq->vq_ops->add_buf(adaptExt->pci_vq_info.vq,
+ &srbExt->vbr.sg[0],
+ srbExt->out, srbExt->in,
+ &srbExt->vbr);
+
+ if ( num_free >= 0) {
+ InsertTailList(&adaptExt->list_head, &srbExt->vbr.list_entry);
+ adaptExt->pci_vq_info.vq->vq_ops->kick(adaptExt->pci_vq_info.vq);
+ srbExt->call_next = FALSE;
+ if(num_free < VIRTIO_MAX_SG) {
+ srbExt->call_next = TRUE;
+ } else {
+ ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, \
Srb->TargetId, Srb->Lun); + }
+ }
+ return TRUE;
+}
+#endif
+
+#ifdef USE_STORPORT
+BOOLEAN
+SynchronizedReadWriteRoutine(
IN PVOID DeviceExtension,
IN PVOID Context
)
@@ -27,12 +99,14 @@ SynchronizedAccessRoutine(
if (adaptExt->pci_vq_info.vq->vq_ops->add_buf(adaptExt->pci_vq_info.vq,
&srbExt->vbr.sg[0],
srbExt->out, srbExt->in,
- &srbExt->vbr) == 0){
+ &srbExt->vbr) >= 0){
InsertTailList(&adaptExt->list_head, &srbExt->vbr.list_entry);
adaptExt->pci_vq_info.vq->vq_ops->kick(adaptExt->pci_vq_info.vq);
return TRUE;
}
- StorPortBusy(DeviceExtension, 10);
+
+ RhelDbgPrint(TRACE_LEVEL_ERROR, ("%s StorPortBusy\n", __FUNCTION__));
+ StorPortBusy(DeviceExtension, 5);
return FALSE;
}
@@ -40,7 +114,29 @@ BOOLEAN
RhelDoReadWrite(PVOID DeviceExtension,
PSCSI_REQUEST_BLOCK Srb)
{
- return StorPortSynchronizeAccess(DeviceExtension, SynchronizedAccessRoutine, \
(PVOID)Srb); + BOOLEAN res = FALSE;
+ PRHEL_SRB_EXTENSION srbExt = (PRHEL_SRB_EXTENSION)Srb->SrbExtension;
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+ NTSTATUS status = STATUS_SUCCESS;
+ struct vring_desc *desc = NULL;
+ srbExt->addr = NULL;
+#endif
+ res = StorPortSynchronizeAccess(DeviceExtension, SynchronizedReadWriteRoutine, \
(PVOID)Srb); +#if (NTDDI_VERSION >= NTDDI_VISTA)
+
+ if (!res) {
+ status = StorPortAllocatePool(DeviceExtension,
+ (srbExt->out + srbExt->in) * sizeof(struct \
vring_desc), + 'rdnI', (PVOID)&desc);
+ if (!NT_SUCCESS(status)) {
+ RhelDbgPrint(TRACE_LEVEL_ERROR, ("%s StorPortAllocatePool failed \
0x%x\n", __FUNCTION__, status) ); + return FALSE;
+ }
+ srbExt->addr = desc;
+ res = StorPortSynchronizeAccess(DeviceExtension, \
SynchronizedReadWriteRoutine, (PVOID)Srb); + }
+#endif
+ return res;
}
#else
BOOLEAN
@@ -54,6 +150,8 @@ RhelDoReadWrite(PVOID DeviceExtension,
PVOID DataBuffer;
PADAPTER_EXTENSION adaptExt;
PRHEL_SRB_EXTENSION srbExt;
+ int num_free;
+
cdb = (PCDB)&Srb->Cdb[0];
srbExt = (PRHEL_SRB_EXTENSION)Srb->SrbExtension;
adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
@@ -69,7 +167,7 @@ RhelDoReadWrite(PVOID DeviceExtension,
sgElement++;
}
- srbExt->vbr.out_hdr.sector = RhelGetLba(cdb);
+ srbExt->vbr.out_hdr.sector = RhelGetLba(DeviceExtension, cdb);
srbExt->vbr.out_hdr.ioprio = 0;
srbExt->vbr.req = (struct request *)Srb;
@@ -88,18 +186,22 @@ RhelDoReadWrite(PVOID DeviceExtension,
srbExt->vbr.sg[sgElement].physAddr = ScsiPortGetPhysicalAddress(DeviceExtension, \
NULL, &srbExt->vbr.status, &fragLen); srbExt->vbr.sg[sgElement].ulSize = \
sizeof(srbExt->vbr.status);
-
-
- if (adaptExt->pci_vq_info.vq->vq_ops->add_buf(adaptExt->pci_vq_info.vq,
+ num_free = adaptExt->pci_vq_info.vq->vq_ops->add_buf(adaptExt->pci_vq_info.vq,
&srbExt->vbr.sg[0],
srbExt->out, srbExt->in,
- &srbExt->vbr) == 0) {
-//FIXME
+ &srbExt->vbr);
+
+ if ( num_free >= 0) {
InsertTailList(&adaptExt->list_head, &srbExt->vbr.list_entry);
adaptExt->pci_vq_info.vq->vq_ops->kick(adaptExt->pci_vq_info.vq);
- return TRUE;
+ srbExt->call_next = FALSE;
+ if(num_free < VIRTIO_MAX_SG) {
+ srbExt->call_next = TRUE;
+ } else {
+ ScsiPortNotification(NextLuRequest, DeviceExtension, Srb->PathId, \
Srb->TargetId, Srb->Lun); + }
}
- return FALSE;
+ return TRUE;
}
#endif
@@ -110,10 +212,62 @@ RhelShutDown(
{
PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+ VirtIODeviceReset(DeviceExtension);
+ ScsiPortWritePortUshort((PUSHORT)(adaptExt->device_base + \
VIRTIO_PCI_GUEST_FEATURES), 0); if (adaptExt->pci_vq_info.vq) {
adaptExt->pci_vq_info.vq->vq_ops->shutdown(adaptExt->pci_vq_info.vq);
VirtIODeviceDeleteVirtualQueue(adaptExt->pci_vq_info.vq);
adaptExt->pci_vq_info.vq = NULL;
}
- VirtIODeviceReset(DeviceExtension);
+}
+
+ULONGLONG
+RhelGetLba(
+ IN PVOID DeviceExtension,
+ IN PCDB Cdb
+ )
+{
+
+ EIGHT_BYTE lba;
+ PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
+
+ lba.AsULongLong = 0;
+
+ switch (Cdb->CDB6GENERIC.OperationCode) {
+
+ case SCSIOP_READ:
+ case SCSIOP_WRITE:
+ case SCSIOP_WRITE_VERIFY: {
+ lba.Byte0 = Cdb->CDB10.LogicalBlockByte3;
+ lba.Byte1 = Cdb->CDB10.LogicalBlockByte2;
+ lba.Byte2 = Cdb->CDB10.LogicalBlockByte1;
+ lba.Byte3 = Cdb->CDB10.LogicalBlockByte0;
+ }
+ break;
+ case SCSIOP_READ6:
+ case SCSIOP_WRITE6: {
+ lba.Byte0 = Cdb->CDB6READWRITE.LogicalBlockMsb1;
+ lba.Byte1 = Cdb->CDB6READWRITE.LogicalBlockMsb0;
+ lba.Byte2 = Cdb->CDB6READWRITE.LogicalBlockLsb;
+ }
+ break;
+ case SCSIOP_READ12:
+ case SCSIOP_WRITE12:
+ case SCSIOP_WRITE_VERIFY12: {
+ REVERSE_BYTES(&lba, &Cdb->CDB12.LogicalBlock[0]);
+ }
+ break;
+ case SCSIOP_READ16:
+ case SCSIOP_WRITE16:
+ case SCSIOP_WRITE_VERIFY16: {
+ REVERSE_BYTES_QUAD(&lba, &Cdb->CDB16.LogicalBlock[0]);
+ }
+ break;
+ default: {
+ ASSERT(FALSE);
+ return (ULONGLONG)-1;
+ }
+ }
+
+ return (lba.AsULongLong << adaptExt->info.physical_block_exp);
}
diff --git a/viostor/virtio_stor_hw_helper.h b/viostor/virtio_stor_hw_helper.h
index c1fcafa..13c1938 100644
--- a/viostor/virtio_stor_hw_helper.h
+++ b/viostor/virtio_stor_hw_helper.h
@@ -35,9 +35,22 @@ RhelDoReadWrite(
PSCSI_REQUEST_BLOCK Srb
);
+BOOLEAN
+RhelDoFlush(
+ IN PVOID DeviceExtension,
+ PSCSI_REQUEST_BLOCK Srb
+ );
+
VOID
RhelShutDown(
IN PVOID DeviceExtension
);
+ULONGLONG
+RhelGetLba(
+ IN PVOID DeviceExtension,
+ IN PCDB Cdb
+ );
+
+
#endif ___VIOSTOR_HW_HELPER_H___
diff --git a/viostor/virtio_stor_utils.h b/viostor/virtio_stor_utils.h
index 43e904c..c490341 100644
--- a/viostor/virtio_stor_utils.h
+++ b/viostor/virtio_stor_utils.h
@@ -23,6 +23,8 @@
#endif
#include <stdarg.h>
+#define CHECKBIT(value, nbit) (((value) & (1 << (nbit))) != 0)
+
int
_cdecl
_vsnprintf(
diff --git a/viostor/wxp.inf b/viostor/wxp.inf
new file mode 100644
index 0000000..6665149
--- /dev/null
+++ b/viostor/wxp.inf
@@ -0,0 +1,101 @@
+; 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
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic