summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/class/cdrom/cdrom.sln18
-rw-r--r--storage/class/cdrom/src/cdrom.infbin10520 -> 8312 bytes
-rw-r--r--storage/class/cdrom/src/cdrom.vcxproj4
-rw-r--r--storage/class/cdrom/src/cdrom.vcxproj.Filters8
-rw-r--r--storage/class/cdrom/src/ioctl.c3
-rw-r--r--storage/class/classpnp/classpnp.sln18
-rw-r--r--storage/class/classpnp/src/autorun.c26
-rw-r--r--storage/class/classpnp/src/class.c55
-rw-r--r--storage/class/classpnp/src/classlog.mof3
-rw-r--r--storage/class/classpnp/src/classp.h89
-rw-r--r--storage/class/classpnp/src/classpnp.vcxproj4
-rw-r--r--storage/class/classpnp/src/classpnp.vcxproj.Filters8
-rw-r--r--storage/class/classpnp/src/classwmi.c20
-rw-r--r--storage/class/classpnp/src/clntirp.c192
-rw-r--r--storage/class/classpnp/src/retry.c26
-rw-r--r--storage/class/classpnp/src/utils.c249
-rw-r--r--storage/class/classpnp/src/xferpkt.c31
-rw-r--r--storage/class/disk/disk.sln18
-rw-r--r--storage/class/disk/src/disk.c21
-rw-r--r--storage/class/disk/src/disk.vcxproj4
-rw-r--r--storage/class/disk/src/disk.vcxproj.Filters8
-rw-r--r--storage/class/disk/src/geometry.c4
-rw-r--r--storage/class/disk/src/pnp.c3
-rw-r--r--storage/filters/addfilter/addfilter.sln18
-rw-r--r--storage/filters/addfilter/src/addfilter.vcxproj4
-rw-r--r--storage/filters/addfilter/src/addfilter.vcxproj.Filters6
-rw-r--r--storage/iscsi/iscsi.sln18
-rw-r--r--storage/iscsi/src/EmptyProject.vcxproj4
-rw-r--r--storage/iscsi/src/EmptyProject.vcxproj.Filters6
-rw-r--r--storage/iscsi/src/client/wmisample.c14
-rw-r--r--storage/iscsi/src/iscsihba.mof30
-rw-r--r--storage/miniports/lsi_u3/lsi_u3.sln18
-rw-r--r--storage/miniports/lsi_u3/src/lsi_u3.vcxproj4
-rw-r--r--storage/miniports/lsi_u3/src/lsi_u3.vcxproj.Filters8
-rw-r--r--storage/miniports/storahci/src/common.c52
-rw-r--r--storage/miniports/storahci/src/common.h2
-rw-r--r--storage/miniports/storahci/src/entrypts.c292
-rw-r--r--storage/miniports/storahci/src/entrypts.h21
-rw-r--r--storage/miniports/storahci/src/hbastat.c92
-rw-r--r--storage/miniports/storahci/src/inbox/storahci.vcxproj4
-rw-r--r--storage/miniports/storahci/src/inbox/storahci.vcxproj.Filters8
-rw-r--r--storage/miniports/storahci/src/io.c163
-rw-r--r--storage/miniports/storahci/src/pnppower.c24
-rw-r--r--storage/miniports/storahci/src/pnppower.h2
-rw-r--r--storage/miniports/storahci/src/util.c29
-rw-r--r--storage/miniports/storahci/src/util.h40
-rw-r--r--storage/miniports/storahci/storahci.sln18
-rw-r--r--storage/msdsm/msdsm.sln18
-rw-r--r--storage/msdsm/src/SampleDSM.vcxproj4
-rw-r--r--storage/msdsm/src/SampleDSM.vcxproj.Filters8
-rw-r--r--storage/msdsm/src/dsmmain.c2
-rw-r--r--storage/msdsm/src/intrface.c24
-rw-r--r--storage/msdsm/src/precomp.h2
-rw-r--r--storage/msdsm/src/utils.c38
-rw-r--r--storage/msdsm/src/wmi.c3
-rw-r--r--storage/ramdisk/ramdisk.sln18
-rw-r--r--storage/ramdisk/src/WdfRamdisk.vcxproj12
-rw-r--r--storage/ramdisk/src/WdfRamdisk.vcxproj.Filters13
-rw-r--r--storage/ramdisk/src/ramdisk.c2
-rw-r--r--storage/ramdisk/src/ramdisk.inxbin2626 -> 5460 bytes
-rw-r--r--storage/sfloppy/sfloppy.sln18
-rw-r--r--storage/sfloppy/src/sfloppy.vcxproj4
-rw-r--r--storage/sfloppy/src/sfloppy.vcxproj.Filters8
-rw-r--r--storage/tools/spti/spti.sln18
-rw-r--r--storage/tools/spti/src/spti.vcxproj4
-rw-r--r--storage/tools/spti/src/spti.vcxproj.Filters6
66 files changed, 1163 insertions, 728 deletions
diff --git a/storage/class/cdrom/cdrom.sln b/storage/class/cdrom/cdrom.sln
index 813369c9..4516f3dc 100644
--- a/storage/class/cdrom/cdrom.sln
+++ b/storage/class/cdrom/cdrom.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdrom", "src\cdrom.vcxproj", "{5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdrom", "src\cdrom.vcxproj", "{9DB6E759-C294-4E18-9013-82FD8F3DD5E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}.Debug|Win32.ActiveCfg = Debug|Win32
- {5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}.Debug|Win32.Build.0 = Debug|Win32
- {5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}.Release|Win32.ActiveCfg = Release|Win32
- {5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}.Release|Win32.Build.0 = Release|Win32
- {5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}.Debug|x64.ActiveCfg = Debug|x64
- {5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}.Debug|x64.Build.0 = Debug|x64
- {5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}.Release|x64.ActiveCfg = Release|x64
- {5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}.Release|x64.Build.0 = Release|x64
+ {9DB6E759-C294-4E18-9013-82FD8F3DD5E6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9DB6E759-C294-4E18-9013-82FD8F3DD5E6}.Debug|Win32.Build.0 = Debug|Win32
+ {9DB6E759-C294-4E18-9013-82FD8F3DD5E6}.Release|Win32.ActiveCfg = Release|Win32
+ {9DB6E759-C294-4E18-9013-82FD8F3DD5E6}.Release|Win32.Build.0 = Release|Win32
+ {9DB6E759-C294-4E18-9013-82FD8F3DD5E6}.Debug|x64.ActiveCfg = Debug|x64
+ {9DB6E759-C294-4E18-9013-82FD8F3DD5E6}.Debug|x64.Build.0 = Debug|x64
+ {9DB6E759-C294-4E18-9013-82FD8F3DD5E6}.Release|x64.ActiveCfg = Release|x64
+ {9DB6E759-C294-4E18-9013-82FD8F3DD5E6}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/class/cdrom/src/cdrom.inf b/storage/class/cdrom/src/cdrom.inf
index a1ba9f7f..d74fe65b 100644
--- a/storage/class/cdrom/src/cdrom.inf
+++ b/storage/class/cdrom/src/cdrom.inf
Binary files differ
diff --git a/storage/class/cdrom/src/cdrom.vcxproj b/storage/class/cdrom/src/cdrom.vcxproj
index 1b8b4bda..689c9716 100644
--- a/storage/class/cdrom/src/cdrom.vcxproj
+++ b/storage/class/cdrom/src/cdrom.vcxproj
@@ -19,13 +19,13 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{5CAAC17A-F6C8-4F60-8599-BF5B710B9E75}</ProjectGuid>
+ <ProjectGuid>{9DB6E759-C294-4E18-9013-82FD8F3DD5E6}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<SupportsPackaging>false</SupportsPackaging>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{1D0354B6-7638-4B49-A326-3F635DF4792D}</SampleGuid>
+ <SampleGuid>{E2CAD978-F695-4642-9CD1-65CB518B0B80}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/class/cdrom/src/cdrom.vcxproj.Filters b/storage/class/cdrom/src/cdrom.vcxproj.Filters
index 984e47ff..57895acd 100644
--- a/storage/class/cdrom/src/cdrom.vcxproj.Filters
+++ b/storage/class/cdrom/src/cdrom.vcxproj.Filters
@@ -3,19 +3,19 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{F4624455-84A0-4D68-9FDA-5A45BDDF16E9}</UniqueIdentifier>
+ <UniqueIdentifier>{1BE21169-AD4D-4A1B-AACD-6310066933B0}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{59782596-7387-4C2F-8B3F-14DD7DBBE39E}</UniqueIdentifier>
+ <UniqueIdentifier>{9B550B9E-2283-4A6B-BAC8-52E0EAB6DD60}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{F55549B9-4C00-441C-8960-79D8E04B2640}</UniqueIdentifier>
+ <UniqueIdentifier>{B3F87DD6-6AE2-4B7C-9C6F-6BC20F347A17}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{BE2B60C1-58DD-4635-A2B4-E75CEC446355}</UniqueIdentifier>
+ <UniqueIdentifier>{4F903A62-C105-4A95-AB1A-2EB0F3AE253F}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
diff --git a/storage/class/cdrom/src/ioctl.c b/storage/class/cdrom/src/ioctl.c
index 49eeba49..590f1419 100644
--- a/storage/class/cdrom/src/ioctl.c
+++ b/storage/class/cdrom/src/ioctl.c
@@ -4150,9 +4150,10 @@ Return Value:
driveLetterName.MaximumLength = sizeof(driveLetterNameBuffer);
driveLetterName.Length = 0;
- queryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = valueName;
queryTable[0].EntryContext = &driveLetterName;
+ queryTable[0].DefaultType = (REG_SZ << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
L"\\Registry\\Machine\\System\\DISK", // why hard coded?
diff --git a/storage/class/classpnp/classpnp.sln b/storage/class/classpnp/classpnp.sln
index b11f5768..8078e6e1 100644
--- a/storage/class/classpnp/classpnp.sln
+++ b/storage/class/classpnp/classpnp.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "classpnp", "src\classpnp.vcxproj", "{427E597B-35E8-4D6C-8AA5-35A4519B33D5}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "classpnp", "src\classpnp.vcxproj", "{CAE2DAC6-A407-41A6-A943-11156A103D14}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {427E597B-35E8-4D6C-8AA5-35A4519B33D5}.Debug|Win32.ActiveCfg = Debug|Win32
- {427E597B-35E8-4D6C-8AA5-35A4519B33D5}.Debug|Win32.Build.0 = Debug|Win32
- {427E597B-35E8-4D6C-8AA5-35A4519B33D5}.Release|Win32.ActiveCfg = Release|Win32
- {427E597B-35E8-4D6C-8AA5-35A4519B33D5}.Release|Win32.Build.0 = Release|Win32
- {427E597B-35E8-4D6C-8AA5-35A4519B33D5}.Debug|x64.ActiveCfg = Debug|x64
- {427E597B-35E8-4D6C-8AA5-35A4519B33D5}.Debug|x64.Build.0 = Debug|x64
- {427E597B-35E8-4D6C-8AA5-35A4519B33D5}.Release|x64.ActiveCfg = Release|x64
- {427E597B-35E8-4D6C-8AA5-35A4519B33D5}.Release|x64.Build.0 = Release|x64
+ {CAE2DAC6-A407-41A6-A943-11156A103D14}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CAE2DAC6-A407-41A6-A943-11156A103D14}.Debug|Win32.Build.0 = Debug|Win32
+ {CAE2DAC6-A407-41A6-A943-11156A103D14}.Release|Win32.ActiveCfg = Release|Win32
+ {CAE2DAC6-A407-41A6-A943-11156A103D14}.Release|Win32.Build.0 = Release|Win32
+ {CAE2DAC6-A407-41A6-A943-11156A103D14}.Debug|x64.ActiveCfg = Debug|x64
+ {CAE2DAC6-A407-41A6-A943-11156A103D14}.Debug|x64.Build.0 = Debug|x64
+ {CAE2DAC6-A407-41A6-A943-11156A103D14}.Release|x64.ActiveCfg = Release|x64
+ {CAE2DAC6-A407-41A6-A943-11156A103D14}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/class/classpnp/src/autorun.c b/storage/class/classpnp/src/autorun.c
index 4dba537b..f0a88414 100644
--- a/storage/class/classpnp/src/autorun.c
+++ b/storage/class/classpnp/src/autorun.c
@@ -804,6 +804,7 @@ ClasspInternalSetMediaChangeState(
MEDIA_CHANGE_DETECTION_STATE oldMediaState;
PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
CLASS_MEDIA_CHANGE_CONTEXT mcnContext;
+ PIO_WORKITEM workItem;
if (!((NewState >= MediaUnknown) && (NewState <= MediaUnavailable))) {
return;
@@ -837,6 +838,25 @@ ClasspInternalSetMediaChangeState(
return;
}
+
+ //
+ // Inform PartMgr that the media changed. It will need to propagate
+ // DO_VERIFY_VOLUME to each partition. Ensure that only one work item
+ // updates the disk's properties at any given time.
+ //
+ if (InterlockedCompareExchange((volatile LONG *)&FdoExtension->PrivateFdoData->UpdateDiskPropertiesWorkItemActive, 1, 0) == 0) {
+
+ workItem = IoAllocateWorkItem(FdoExtension->DeviceObject);
+
+ if (workItem) {
+
+ IoQueueWorkItem(workItem, ClasspUpdateDiskProperties, DelayedWorkQueue, workItem);
+
+ } else {
+
+ InterlockedExchange((volatile LONG *)&FdoExtension->PrivateFdoData->UpdateDiskPropertiesWorkItemActive, 0);
+ }
+ }
if(info->MediaChangeDetectionDisableCount != 0) {
#if DBG
@@ -2595,8 +2615,8 @@ ClasspMediaChangeDeviceInstanceOverride(
RtlZeroMemory(&queryTable[0], sizeof(queryTable));
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
- queryTable[0].DefaultType = REG_DWORD;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
queryTable[0].DefaultLength = 0;
if (i==0) {
@@ -3001,7 +3021,7 @@ ClasspIsMediaChangeDisabledForClass(
parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
parameters[0].Name = L"Autorun";
parameters[0].EntryContext = &mcnRegistryValue;
- parameters[0].DefaultType = REG_DWORD;
+ parameters[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD;
parameters[0].DefaultData = &mcnRegistryValue;
parameters[0].DefaultLength = sizeof(ULONG);
diff --git a/storage/class/classpnp/src/class.c b/storage/class/classpnp/src/class.c
index 6113cd7e..5e7f00f1 100644
--- a/storage/class/classpnp/src/class.c
+++ b/storage/class/classpnp/src/class.c
@@ -1955,13 +1955,6 @@ NTSTATUS ClassPnpStartDevice(IN PDEVICE_OBJECT DeviceObject)
}
- // Initialize performance counter frequency
- KeQueryPerformanceCounter(&(fdoExtension->PrivateFdoData->PerfCounterFrequency));
-
- if (fdoExtension->PrivateFdoData->PerfCounterFrequency.QuadPart == 0) {
- fdoExtension->PrivateFdoData->PerfCounterFrequency.QuadPart = 1;
- }
-
/*
* Anchor the FDO in our static list.
* Pnp is synchronized, so we shouldn't need any synchronization here.
@@ -2244,6 +2237,16 @@ NTSTATUS ClassPnpStartDevice(IN PDEVICE_OBJECT DeviceObject)
UNREFERENCED_PARAMETER(legacyErrorHandling);
#endif
+
+ //
+ // Get the copy offload max target duration value.
+ // This function will set the default value if one hasn't been
+ // specified in the registry.
+ //
+ ClasspGetCopyOffloadMaxDuration(DeviceObject,
+ REG_DISK_CLASS_CONTROL,
+ &(fdoExtension->PrivateFdoData->CopyOffloadMaxTargetDuration));
+
}
}
@@ -2409,6 +2412,7 @@ NTSTATUS ClassReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
isRemoved = ClassAcquireRemoveLock(DeviceObject, Irp);
if (isRemoved) {
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
+ Irp->IoStatus.Information = 0;
ClassReleaseRemoveLock(DeviceObject, Irp);
ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
status = STATUS_DEVICE_DOES_NOT_EXIST;
@@ -2451,6 +2455,7 @@ NTSTATUS ClassReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
_Analysis_assume_(status != STATUS_PENDING);
if (!NT_SUCCESS(status)){
NT_ASSERT(Irp->IoStatus.Status == status);
+ Irp->IoStatus.Information = 0;
ClassReleaseRemoveLock(DeviceObject, Irp);
ClassCompleteRequest (DeviceObject, Irp, IO_NO_INCREMENT);
}
@@ -2575,8 +2580,7 @@ NTSTATUS ClassReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
ClasspMarkIrpAsIdle(Irp, FALSE);
status = ServiceTransferRequest(DeviceObject, Irp, FALSE);
if (fdoData->IdlePrioritySupported == TRUE) {
- fdoData->LastIoTime = ClasspGetCurrentTime(NULL);
- fdoData->IdleTicks = 0;
+ fdoData->LastNonIdleIoTime = ClasspGetCurrentTime();
}
ClassReleaseRemoveLock(DeviceObject, (PVOID)&uniqueAddr);
@@ -7274,6 +7278,7 @@ ClassDeviceControl(
NTSTATUS status;
ULONG modifiedIoControlCode = 0;
+ GUID activityId = {0};
//
@@ -7457,9 +7462,11 @@ ClassDeviceControl(
driveLetterName.Length = 0;
queryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED |
- RTL_QUERY_REGISTRY_DIRECT;
+ RTL_QUERY_REGISTRY_DIRECT |
+ RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = valueName;
queryTable[0].EntryContext = &driveLetterName;
+ queryTable->DefaultType = (REG_SZ << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
L"\\Registry\\Machine\\System\\DISK",
@@ -8550,7 +8557,7 @@ ClassDeviceControl(
// only process Trim action in class layer if possible.
case DeviceDsmAction_Trim: {
- status = ClasspDeviceTrimProcess(DeviceObject, Irp, srb);
+ status = ClasspDeviceTrimProcess(DeviceObject, Irp, &activityId, srb);
break;
}
@@ -9451,10 +9458,10 @@ ClassQueryTimeOutRegistryValue(
RtlZeroMemory(parameters,
(sizeof(RTL_QUERY_REGISTRY_TABLE)*2));
- parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK;
parameters[0].Name = L"TimeOutValue";
parameters[0].EntryContext = &timeOut;
- parameters[0].DefaultType = REG_DWORD;
+ parameters[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD;
parameters[0].DefaultData = &zero;
parameters[0].DefaultLength = sizeof(ULONG);
@@ -12589,10 +12596,10 @@ ClasspScanForSpecialInRegistry(
// Setup the structure to read
//
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = CLASSP_REG_HACK_VALUE_NAME;
queryTable[0].EntryContext = &deviceHacks;
- queryTable[0].DefaultType = REG_DWORD;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD;
queryTable[0].DefaultData = &deviceHacks;
queryTable[0].DefaultLength = 0;
@@ -13369,7 +13376,7 @@ Arguments:
DeviceObject - Supplies the device object associated with this request
Irp - The IRP to be processed
- Srb - An SRB that can be optinally used to process this request
+ Srb - An SRB that can be optimally used to process this request
Return Value:
@@ -15608,12 +15615,18 @@ Return Value:
--*/
{
- NT_ASSERT(
- OffloadWriteContext->TotalSectorsProcessedSuccessfully <=
- OffloadWriteContext->TotalRequestSizeSectors);
+ PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = OffloadWriteContext->Fdo->DeviceExtension;
+ PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
- // Time taken in 100 ns units
+ //
+ // Time taken in 100ns units.
+ //
ULONGLONG durationIn100ns = (KeQueryInterruptTime() - OffloadWriteContext->OperationStartTime);
+ ULONGLONG maxTargetDuration = fdoData->CopyOffloadMaxTargetDuration * 10ULL * 1000 * 1000;
+
+ NT_ASSERT(
+ OffloadWriteContext->TotalSectorsProcessedSuccessfully <=
+ OffloadWriteContext->TotalRequestSizeSectors);
if (OffloadWriteContext->TotalSectorsProcessedSuccessfully == OffloadWriteContext->TotalRequestSizeSectors) {
@@ -15627,7 +15640,7 @@ Return Value:
// Since we don't want a layered timeout mechanism (e.g. guest and parent OS in Hyper-V scenarios)
// to cause a SCSI timeout for the higher layer token operations.
//
- if (MAX_TARGET_DURATION <= durationIn100ns) {
+ if (maxTargetDuration <= durationIn100ns) {
TracePrint((TRACE_LEVEL_WARNING,
TRACE_FLAG_IOCTL,
diff --git a/storage/class/classpnp/src/classlog.mof b/storage/class/classpnp/src/classlog.mof
index b82d2e81..2443193f 100644
--- a/storage/class/classpnp/src/classlog.mof
+++ b/storage/class/classpnp/src/classlog.mof
@@ -1,3 +1,6 @@
+#pragma autorecover
+#pragma namespace("\\\\.\\Root\\WMI")
+
[WMI, guid("F903D6EC-8647-438f-9E42-891F4733EDAF")]
class MSStorageDriver_ScsiRequestBlock {
diff --git a/storage/class/classpnp/src/classp.h b/storage/class/classpnp/src/classp.h
index e0046be8..d7d57e9d 100644
--- a/storage/class/classpnp/src/classp.h
+++ b/storage/class/classpnp/src/classp.h
@@ -74,7 +74,6 @@ Revision History:
#define WPP_CONTROL_GUIDS WPP_CONTROL_GUIDS_NORMAL_FLAGS(WPP_GUID_CLASSPNP)
#endif
-
/*
* IA64 requires 8-byte alignment for pointers, but the IA64 NT kernel expects 16-byte alignment
*/
@@ -113,6 +112,7 @@ extern ULONG ClassMaxInterleavePerCriticalIo;
#define CLASSP_REG_DISABLE_D3COLD (L"DisableD3Cold")
#define CLASSP_REG_QERR_OVERRIDE_MODE (L"QERROverrideMode")
#define CLASSP_REG_LEGACY_ERROR_HANDLING (L"LegacyErrorHandling")
+#define CLASSP_REG_COPY_OFFLOAD_MAX_TARGET_DURATION (L"CopyOffloadMaxTargetDuration")
#define CLASS_PERF_RESTORE_MINIMUM (0x10)
#define CLASS_ERROR_LEVEL_1 (0x4)
@@ -146,6 +146,7 @@ extern ULONG ClassMaxInterleavePerCriticalIo;
#define NUM_MODESENSE_RETRIES 1
#define NUM_MODESELECT_RETRIES 1
#define NUM_DRIVECAPACITY_RETRIES 1
+#define NUM_THIN_PROVISIONING_RETRIES 32
#if (NTDDI_VERSION >= NTDDI_WINBLUE)
@@ -194,7 +195,7 @@ extern ULONG ClassMaxInterleavePerCriticalIo;
#define MAX_RECEIVE_TOKEN_INFORMATION_PARAMETER_DATA_LENGTH MAXULONG
#define MAX_TOKEN_TRANSFER_SIZE MAXULONGLONG
#define MAX_NUMBER_BLOCKS_PER_BLOCK_DEVICE_RANGE_DESCRIPTOR MAXULONG
-#define MAX_TARGET_DURATION (4ULL * 10 * 1000 * 1000) // 4sec in 100ns units
+#define DEFAULT_MAX_TARGET_DURATION 4 // 4sec
#define DEFAULT_MAX_NUMBER_BYTES_PER_SYNC_WRITE_USING_TOKEN (64ULL * 1024 * 1024) // 64MB
#define MAX_NUMBER_BYTES_PER_SYNC_WRITE_USING_TOKEN (256ULL * 1024 * 1024) // 256MB
#define MIN_TOKEN_LIST_IDENTIFIERS 256
@@ -231,6 +232,11 @@ extern ULONG DiskIdleTimeoutInMS;
extern CONST LARGE_INTEGER Magic10000;
#define SHIFT10000 13
+//
+// Constant to help wih various time conversions
+//
+#define CONST_MSECS_PER_SEC 1000
+
#define Convert100nsToMilliseconds(LARGE_INTEGER) \
( \
RtlExtendedMagicDivide((LARGE_INTEGER), Magic10000, SHIFT10000) \
@@ -494,7 +500,8 @@ typedef struct _TRANSFER_PACKET {
* Stuff for retrying the transfer.
*/
#if (NTDDI_VERSION >= NTDDI_WINBLUE)
- USHORT NumRetries; // Total number of retries remaining.
+ UCHAR NumRetries; // Total number of retries remaining.
+ UCHAR NumThinProvisioningRetries; //Number of retries carried out so far for a request failed with THIN_PROVISIONING_SOFT_THRESHOLD_ERROR
UCHAR NumIoTimeoutRetries; // Number of retries remaining for a timed-out request.
UCHAR TimedOut; // Indicates if this packet has timed-out.
#else
@@ -637,6 +644,13 @@ typedef struct _PNL_SLIST_HEADER {
//
struct _CLASS_PRIVATE_FDO_DATA {
+ //
+ // The amount of time allowed for a target to complete a copy offload
+ // operation, in seconds. Default is 4s, but it can be modified via
+ // registry key.
+ //
+ ULONG CopyOffloadMaxTargetDuration;
+
#if (NTDDI_VERSION >= NTDDI_WIN8)
@@ -882,40 +896,35 @@ struct _CLASS_PRIVATE_FDO_DATA {
#endif
//
- // Timer interval for sending low priority I/O
- //
- USHORT IdleTimerInterval;
-
- //
- // Idle counts required to process idle request
+ // Idle duration required to process idle request
// to avoid starvation
//
- USHORT StarvationCount;
+ USHORT StarvationDuration;
//
- // Idle timer tick count
+ // Idle I/O count
//
- ULONG IdleTimerTicks;
+ ULONG IdleIoCount;
//
- // Idle timer tick count
+ // Flag to indicate timer status
//
- ULONG IdleTicks;
+ LONG IdleTimerStarted;
//
- // Idle I/O count
+ // Time when the Idle timer was started
//
- ULONG IdleIoCount;
+ LARGE_INTEGER AntiStarvationStartTime;
//
- // Flag to indicate timer status
+ // Normal priority I/O time
//
- LONG IdleTimerStarted;
+ LARGE_INTEGER LastNonIdleIoTime;
//
- // Normal priority I/O time
+ // Time when the last IO of any priority completed.
//
- LARGE_INTEGER LastIoTime;
+ LARGE_INTEGER LastIoCompletionTime;
//
// Count of active normal priority I/O
@@ -941,9 +950,6 @@ struct _CLASS_PRIVATE_FDO_DATA {
ULONG MaxPowerOperationRetryCount;
PIRP PowerProcessIrp;
- // Counter frequency : Currently used for KeQueryPerferformanceCounter
- LARGE_INTEGER PerfCounterFrequency;
-
//
// Indicates legacy error handling should be used.
// This means:
@@ -1176,15 +1182,16 @@ typedef struct _IO_RETRIED_LOG_MESSAGE_CONTEXT {
#define MINIMUM_RETRY_UNITS ((LONGLONG)32)
#define MODE_PAGE_DATA_SIZE 192
-#define CLASS_IDLE_INTERVAL 50 // 50 milliseconds
+#define CLASS_IDLE_INTERVAL_MIN 12 // 12 milliseconds
+#define CLASS_IDLE_INTERVAL 12 // 12 milliseconds
#define CLASS_STARVATION_INTERVAL 500 // 500 milliseconds
-#define CLASS_IDLE_TIMER_TICKS 4
//
// Value of 50 milliseconds in 100 nanoseconds units
//
#define FIFTY_MS_IN_100NS_UNITS 50 * 100
+
/*
* Simple singly-linked-list queuing macros, with no synchronization.
*/
@@ -1245,21 +1252,15 @@ ClasspIsIdleRequest(
return ((BOOLEAN)Irp->Tail.Overlay.DriverContext[1]);
}
-extern BOOLEAN UseQPCTime;
-
__inline
LARGE_INTEGER
ClasspGetCurrentTime(
- PLARGE_INTEGER Frequency
+ VOID
)
{
LARGE_INTEGER currentTime;
- if (UseQPCTime) {
- currentTime = KeQueryPerformanceCounter(Frequency);
- } else {
- currentTime.QuadPart = (LONGLONG)KeQueryUnbiasedInterruptTime();
- }
+ currentTime.QuadPart = KeQueryUnbiasedInterruptTimePrecise((ULONG64*)&currentTime.QuadPart);
return currentTime;
}
@@ -1267,16 +1268,10 @@ ClasspGetCurrentTime(
__inline
ULONGLONG
ClasspTimeDiffToMs(
- PCLASS_PRIVATE_FDO_DATA FdoData,
ULONGLONG TimeDiff
)
{
- if (UseQPCTime) {
- TimeDiff *= 1000;
- TimeDiff /= FdoData->PerfCounterFrequency.QuadPart;
- } else {
- TimeDiff /= (10 * 1000);
- }
+ TimeDiff /= (10 * 1000);
return TimeDiff;
}
@@ -1839,6 +1834,7 @@ NTSTATUS ClasspDeviceLBProvisioningProperty(
NTSTATUS ClasspDeviceTrimProcess(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp,
+ _In_ PGUID ActivityId,
_Inout_ PSCSI_REQUEST_BLOCK Srb
);
@@ -1906,6 +1902,14 @@ ClasspGetMaximumTokenListIdentifier(
_Out_ PULONG MaximumListIdentifier
);
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS
+ClasspGetCopyOffloadMaxDuration(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_z_ PWSTR RegistryPath,
+ _Out_ PULONG MaxDuration
+ );
+
_IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_min_(PASSIVE_LEVEL)
_IRQL_requires_same_
@@ -2595,6 +2599,11 @@ Return Value:
}
+BOOLEAN
+ClasspIsThinProvisioningError (
+ _In_ PSCSI_REQUEST_BLOCK _Srb
+ );
+
__inline
BOOLEAN
ClasspLowerLayerNotSupport (
diff --git a/storage/class/classpnp/src/classpnp.vcxproj b/storage/class/classpnp/src/classpnp.vcxproj
index 20ea07c2..c2802197 100644
--- a/storage/class/classpnp/src/classpnp.vcxproj
+++ b/storage/class/classpnp/src/classpnp.vcxproj
@@ -19,12 +19,12 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{427E597B-35E8-4D6C-8AA5-35A4519B33D5}</ProjectGuid>
+ <ProjectGuid>{CAE2DAC6-A407-41A6-A943-11156A103D14}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<SupportsPackaging>false</SupportsPackaging>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{F2A79FAF-7AB2-460E-A8F9-E0CB6AE58519}</SampleGuid>
+ <SampleGuid>{58F97C0C-9D73-4882-B4FA-BBEAE3EA4E10}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/class/classpnp/src/classpnp.vcxproj.Filters b/storage/class/classpnp/src/classpnp.vcxproj.Filters
index de33c904..93c2a79b 100644
--- a/storage/class/classpnp/src/classpnp.vcxproj.Filters
+++ b/storage/class/classpnp/src/classpnp.vcxproj.Filters
@@ -3,19 +3,19 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{E57AA4D3-2361-468E-BADF-7E50D1657C78}</UniqueIdentifier>
+ <UniqueIdentifier>{EC5C82CA-040D-44DB-91A3-D25A1FF34443}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{73F07EE3-6460-42CC-9827-F4EB5CBD6FFA}</UniqueIdentifier>
+ <UniqueIdentifier>{88553D70-9C9C-49F9-B2D5-19552AB34B09}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{01AD74A8-90EE-49F4-B392-6C515177B2CB}</UniqueIdentifier>
+ <UniqueIdentifier>{92330849-35A6-4C9A-9499-F2492A79CD86}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{F1A14E0E-14F3-4FBA-B152-C150E51DFCB6}</UniqueIdentifier>
+ <UniqueIdentifier>{128D6F0C-829B-4E8A-A01D-4859DCC86D60}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
diff --git a/storage/class/classpnp/src/classwmi.c b/storage/class/classpnp/src/classwmi.c
index 1df85512..1b1eeeee 100644
--- a/storage/class/classpnp/src/classwmi.c
+++ b/storage/class/classpnp/src/classwmi.c
@@ -40,10 +40,6 @@ Revision History:
#include "classwmi.tmh"
#endif
-const UCHAR wmiInternalMOF[] = {
-#include "classlog.x"
-};
-
#define TIME_STRING_LENGTH 25
BOOLEAN
@@ -95,15 +91,11 @@ ClassFindInternalGuid(
GUIDREGINFO wmiClassGuids[] =
{
{
- MSWmi_MofDataGuid, 1, 0
- },
- {
MSStorageDriver_ClassErrorLogGuid, 1, 0
}
};
-#define MSWmi_MofData_GUID_Index 0
-#define MSStorageDriver_ClassErrorLogGuid_Index 1
+#define MSStorageDriver_ClassErrorLogGuid_Index 0
#define NUM_CLASS_WMI_GUIDS (sizeof(wmiClassGuids) / sizeof(GUIDREGINFO))
@@ -820,15 +812,7 @@ Return Value:
ULONG sizeNeeded = 0, i;
PFUNCTIONAL_DEVICE_EXTENSION fdoExt = DeviceObject->DeviceExtension;
- if (GuidIndex == MSWmi_MofData_GUID_Index) {
- sizeNeeded = sizeof(wmiInternalMOF);
- if (BufferAvail >= sizeNeeded) {
- RtlMoveMemory(Buffer, wmiInternalMOF, sizeof(wmiInternalMOF));
- status = STATUS_SUCCESS;
- } else {
- status = STATUS_BUFFER_TOO_SMALL;
- }
- } else if (GuidIndex == MSStorageDriver_ClassErrorLogGuid_Index) {
+ if (GuidIndex == MSStorageDriver_ClassErrorLogGuid_Index) {
//
// NOTE - ClassErrorLog is still using SCSI_REQUEST_BLOCK and will not be
diff --git a/storage/class/classpnp/src/clntirp.c b/storage/class/classpnp/src/clntirp.c
index d615dce1..c0fbcb1a 100644
--- a/storage/class/classpnp/src/clntirp.c
+++ b/storage/class/classpnp/src/clntirp.c
@@ -31,8 +31,7 @@ Revision History:
VOID
ClasspStartIdleTimer(
- IN PCLASS_PRIVATE_FDO_DATA FdoData,
- IN ULONGLONG IdleInterval
+ IN PCLASS_PRIVATE_FDO_DATA FdoData
);
VOID
@@ -48,6 +47,7 @@ ClasspServiceIdleRequest(
BOOLEAN PostToDpc
);
+
PIRP
ClasspDequeueIdleRequest(
PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
@@ -165,7 +165,6 @@ Routine Description:
Arguments:
FdoExtension - Pointer to the device extension
- IdleInterval - Timer interval
Return Value:
@@ -207,7 +206,7 @@ ClasspInitializeIdleTimer(
CLASSP_REG_IDLE_INTERVAL_NAME,
&idleInterval);
- if ((idleInterval < CLASS_IDLE_TIMER_TICKS) || (idleInterval > USHORT_MAX)) {
+ if ((idleInterval < CLASS_IDLE_INTERVAL_MIN) || (idleInterval > USHORT_MAX)) {
//
// If the interval is too low or too high, reset it to the default value.
//
@@ -220,18 +219,8 @@ ClasspInitializeIdleTimer(
KeInitializeDpc(&fdoData->IdleDpc, ClasspIdleTimerDpc, FdoExtension);
InitializeListHead(&fdoData->IdleIrpList);
fdoData->IdleTimerStarted = FALSE;
- fdoData->IdleTimerInterval = (USHORT) (idleInterval / CLASS_IDLE_TIMER_TICKS);
- fdoData->StarvationCount = CLASS_STARVATION_INTERVAL / fdoData->IdleTimerInterval;
-
- //
- // Due to the coarseness of the idle timer frequency, some variability in
- // the idle interval will be tolerated such that it is the desired idle
- // interval on average.
- fdoData->IdleInterval =
- (USHORT)(idleInterval - (fdoData->IdleTimerInterval / 2));
-
- fdoData->IdleTimerTicks = 0;
- fdoData->IdleTicks = 0;
+ fdoData->StarvationDuration = CLASS_STARVATION_INTERVAL;
+ fdoData->IdleInterval = (USHORT)(idleInterval);
fdoData->IdleIoCount = 0;
fdoData->ActiveIoCount = 0;
fdoData->ActiveIdleIoCount = 0;
@@ -263,8 +252,6 @@ Arguments:
FdoData - Pointer to the private fdo data
- IdleInterval - Amount of time since the completion of the last non-idle request
-
Return Value:
None
@@ -272,8 +259,7 @@ Return Value:
--*/
VOID
ClasspStartIdleTimer(
- IN PCLASS_PRIVATE_FDO_DATA FdoData,
- IN ULONGLONG IdleInterval
+ IN PCLASS_PRIVATE_FDO_DATA FdoData
)
{
LARGE_INTEGER dueTime;
@@ -287,15 +273,9 @@ ClasspStartIdleTimer(
if (!timerStarted) {
//
- // Reset the anti-starvation timer tick counter and set the idle tick
- // counter according to the actual amount of idle time. The latter is
- // important to do to ensure that if the idle queue drains and the timer
- // has to be stopped and started on the arrival of the next idle request,
- // those requests don't get delayed unnecessarily due to IdleTicks not
- // reflecting actual idle time.
+ // Reset the anti-starvation start time.
//
- FdoData->IdleTimerTicks = 0;
- FdoData->IdleTicks = (ULONG)(IdleInterval / FdoData->IdleTimerInterval);
+ FdoData->AntiStarvationStartTime = ClasspGetCurrentTime();
//
// convert milliseconds to a relative 100ns
@@ -305,11 +285,11 @@ ClasspStartIdleTimer(
//
// multiply the period
//
- dueTime.QuadPart = Int32x32To64(FdoData->IdleTimerInterval, mstotimer);
+ dueTime.QuadPart = Int32x32To64(FdoData->IdleInterval, mstotimer);
KeSetTimerEx(&FdoData->IdleTimer,
dueTime,
- FdoData->IdleTimerInterval,
+ FdoData->IdleInterval,
&FdoData->IdleDpc);
}
return;
@@ -369,36 +349,27 @@ Return Value:
--*/
ULONGLONG
ClasspGetIdleTime (
- IN PCLASS_PRIVATE_FDO_DATA FdoData
+ IN PCLASS_PRIVATE_FDO_DATA FdoData,
+ IN LARGE_INTEGER CurrentTime
)
{
ULONGLONG idleTime;
- LARGE_INTEGER currentTime;
NTSTATUS status;
//
- // If there are any outstanding non-idle requests, then there has been no
- // idle time.
- //
- if (FdoData->ActiveIoCount > 0) {
- return 0;
- }
-
- //
// Get the time difference between current time and last I/O
// complete time.
//
- currentTime = ClasspGetCurrentTime(NULL);
- status = RtlULongLongSub((ULONGLONG)currentTime.QuadPart,
- (ULONGLONG)FdoData->LastIoTime.QuadPart,
+ status = RtlULongLongSub((ULONGLONG)CurrentTime.QuadPart,
+ (ULONGLONG)FdoData->LastNonIdleIoTime.QuadPart,
&idleTime);
if (NT_SUCCESS(status)) {
//
// Convert the time to milliseconds.
//
- idleTime = ClasspTimeDiffToMs(FdoData, idleTime);
+ idleTime = ClasspTimeDiffToMs(idleTime);
} else {
//
// Failed to get time difference, assume enough time passed.
@@ -411,58 +382,57 @@ ClasspGetIdleTime (
/*++
-ClasspIdleTicksSufficient
+ClasspIdleDurationSufficient
Routine Description:
- This routine whether enough idle ticks have occurred since the completion of
- the last non-idle request.
+ This routine computes whether enough idle duration has elapsed since the
+ completion of the last non-idle request.
Arguments:
FdoData - Pointer to the private fdo data
+ CurrentTimeIn - If CurrentTimeIn is non-NULL
+ - contents are set to NULL if the time is not updated.
+ - time is updated otherwise
+
Return Value:
- TRUE if sufficient idle ticks have expired to issue the next idle request.
+ TRUE if sufficient idle duration has elapsed to issue the next idle request.
--*/
LOGICAL
-ClasspIdleTicksSufficient (
- IN PCLASS_PRIVATE_FDO_DATA FdoData
+ClasspIdleDurationSufficient (
+ IN PCLASS_PRIVATE_FDO_DATA FdoData,
+ OUT LARGE_INTEGER** CurrentTimeIn
)
{
ULONGLONG idleInterval;
+ LARGE_INTEGER CurrentTime;
//
- // If it has been more than enough idle timer ticks since the completion of
- // the last non-idle request, enough idle time has passed.
- //
-
- if (FdoData->IdleTicks > CLASS_IDLE_TIMER_TICKS) {
- return TRUE;
- }
-
- //
- // If there have not been enough timer ticks, then there has not been
- // enough idle time.
+ // If there are any outstanding non-idle requests, then there has been no
+ // idle time.
//
- if (FdoData->IdleTicks < CLASS_IDLE_TIMER_TICKS) {
+ if (FdoData->ActiveIoCount > 0) {
+ if (CurrentTimeIn != NULL) {
+ *CurrentTimeIn = NULL;
+ }
return FALSE;
}
//
- // IdleTicks can reach CLASS_IDLE_TIMER_TICKS before FdoData->IdleInterval
- // worth of time elapses from the completion of the last non-idle request.
- // This can happen because when the idle timer is running, the last non-idle
- // request can complete at any time in the middle of the timer period (half
- // on average) so on the next timer expiration, IdleTicks will transition
- // 0->1 without its full time having passed since the completion of the last
- // non-idle request. So when IdleTicks is exactly CLASS_IDLE_TIMER_TICKS,
- // explicitly check whether an idle request should be issued now or on the
- // next timer expiration.
+ // Check whether an idle request should be issued now or on the next timer
+ // expiration.
//
- idleInterval = ClasspGetIdleTime(FdoData);
+
+ CurrentTime = ClasspGetCurrentTime();
+ idleInterval = ClasspGetIdleTime(FdoData, CurrentTime);
+
+ if (CurrentTimeIn != NULL) {
+ **CurrentTimeIn = CurrentTime;
+ }
if (idleInterval >= FdoData->IdleInterval) {
return TRUE;
@@ -478,14 +448,8 @@ ClasspIdleTimerDpc
Routine Description:
Timer dpc function. This function will be called once every
- IdleInterval. This will increment the IdleTicks and
- if it goes above 1 (i.e., disk is in idle state) then
- it will service an idle request.
-
- This function will increment IdleTimerTicks if the IdleTicks
- does not go above 1 (i.e., disk is not in idle state). When it
- reaches the starvation idle count (1 second) it will process
- one idle request.
+ IdleInterval. An idle request will be queued if sufficient idle time
+ has elapsed since the last non-idle request.
Arguments:
@@ -509,6 +473,10 @@ ClasspIdleTimerDpc(
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Context;
PCLASS_PRIVATE_FDO_DATA fdoData;
+ ULONGLONG idleTime;
+ NTSTATUS status;
+ LARGE_INTEGER currentTime;
+ LARGE_INTEGER* pCurrentTime;
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(SystemArgument1);
@@ -521,11 +489,10 @@ ClasspIdleTimerDpc(
fdoData = fdoExtension->PrivateFdoData;
- if ((fdoData->ActiveIoCount <= 0) &&
- (++fdoData->IdleTicks >= CLASS_IDLE_TIMER_TICKS)) {
+ if (fdoData->ActiveIoCount <= 0) {
//
- // If there are max active idle request, do not issue another one here.
+ // If there are max active idle requests, do not issue another one here.
//
if (fdoData->ActiveIdleIoCount >= fdoData->IdleActiveIoMax) {
return;
@@ -536,22 +503,48 @@ ClasspIdleTimerDpc(
// request has completed.
//
- if (ClasspIdleTicksSufficient(fdoData)) {
+ pCurrentTime = &currentTime;
+ if (ClasspIdleDurationSufficient(fdoData, &pCurrentTime)) {
//
// We are going to issue an idle request so reset the anti-starvation
// timer counter.
+ // If we are here (Idle duration is sufficient), pCurrentTime is
+ // expected to be set.
//
- fdoData->IdleTimerTicks = 0;
+ NT_ASSERT(pCurrentTime != NULL);
+ fdoData->AntiStarvationStartTime = *pCurrentTime;
ClasspServiceIdleRequest(fdoExtension, FALSE);
}
return;
}
//
+ // Get the time difference between current time and last I/O
+ // complete time.
+ //
+
+ currentTime = ClasspGetCurrentTime();
+ status = RtlULongLongSub((ULONGLONG)currentTime.QuadPart,
+ (ULONGLONG)fdoData->AntiStarvationStartTime.QuadPart,
+ &idleTime);
+
+ if (NT_SUCCESS(status)) {
+ //
+ // Convert the time to milliseconds.
+ //
+ idleTime = ClasspTimeDiffToMs(idleTime);
+ } else {
+ //
+ // Failed to get time difference, assume enough time passed.
+ //
+ idleTime = fdoData->StarvationDuration;
+ }
+
+ //
// If the timer is running then there must be at least one idle priority I/O pending
//
- if (++fdoData->IdleTimerTicks >= fdoData->StarvationCount) {
- fdoData->IdleTimerTicks = 0;
+ if (idleTime >= fdoData->StarvationDuration) {
+ fdoData->AntiStarvationStartTime = currentTime;
TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspIdleTimerDpc: Starvation timer. Send one idle request\n"));
ClasspServiceIdleRequest(fdoExtension, FALSE);
}
@@ -588,24 +581,18 @@ ClasspEnqueueIdleRequest(
PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
KIRQL oldIrql;
BOOLEAN issueRequest = TRUE;
- ULONGLONG idleInterval;
+ LARGE_INTEGER currentTime;
+ LARGE_INTEGER* pCurrentTime;
TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspEnqueueIdleRequest: Queue idle request %p\n", Irp));
IoMarkIrpPending(Irp);
//
- // Get the time difference between current time and last non-idle request
- // complete time. If the there has been enough idle time, then issue the
- // request (unless other factors prevent us from doing so below) and set the
- // idle time such that we starting the timer below, it would start off with
- // enough idle ticks.
+ // Reset issueRequest if the idle duration is not sufficient.
//
- idleInterval = ClasspGetIdleTime(fdoData);
-
- if (idleInterval >= fdoData->IdleInterval) {
- idleInterval = fdoData->IdleTimerInterval * CLASS_IDLE_TIMER_TICKS;
- } else {
+ pCurrentTime = &currentTime;
+ if (ClasspIdleDurationSufficient(fdoData, &pCurrentTime) == FALSE) {
issueRequest = FALSE;
}
@@ -617,7 +604,6 @@ ClasspEnqueueIdleRequest(
issueRequest = FALSE;
}
- TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_TIMER, "ClasspEnqueueIdleRequest: Diff time %I64d\n", idleInterval));
KeAcquireSpinLock(&fdoData->IdleListLock, &oldIrql);
if (IsListEmpty(&fdoData->IdleIrpList)) {
@@ -628,7 +614,7 @@ ClasspEnqueueIdleRequest(
fdoData->IdleIoCount++;
if (!fdoData->IdleTimerStarted) {
- ClasspStartIdleTimer(fdoData, idleInterval);
+ ClasspStartIdleTimer(fdoData);
}
if (fdoData->IdleIoCount != 1) {
@@ -699,6 +685,8 @@ ClasspDequeueIdleRequest(
}
KeReleaseSpinLock(&fdoData->IdleListLock, oldIrql);
+
+
return irp;
}
@@ -736,7 +724,7 @@ ClasspCompleteIdleRequest(
if ((fdoData->IdleIoCount > 0) &&
(fdoData->ActiveIdleIoCount < fdoData->IdleActiveIoMax) &&
(fdoData->ActiveIoCount <= 0) &&
- (ClasspIdleTicksSufficient(fdoData))) {
+ (ClasspIdleDurationSufficient(fdoData, NULL))) {
TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspCompleteIdleRequest: Service next idle reqeusts\n"));
ClasspServiceIdleRequest(FdoExtension, TRUE);
}
@@ -779,5 +767,3 @@ ClasspServiceIdleRequest(
return;
}
-
-
diff --git a/storage/class/classpnp/src/retry.c b/storage/class/classpnp/src/retry.c
index 1a74c0b2..9b732bec 100644
--- a/storage/class/classpnp/src/retry.c
+++ b/storage/class/classpnp/src/retry.c
@@ -458,28 +458,40 @@ BOOLEAN RetryTransferPacket(PTRANSFER_PACKET Pkt)
PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
PCDB pCdb = SrbGetCdb(Pkt->Srb);
- TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "retrying failed transfer (pkt=%ph, op=%s)", Pkt, DBGGETSCSIOPSTR(Pkt->Srb)));
+ if(ClasspIsThinProvisioningError((PSCSI_REQUEST_BLOCK)Pkt->Srb) &&
+ (pCdb != NULL) && IS_SCSIOP_READWRITE(pCdb->CDB10.OperationCode)) {
- NT_ASSERT(Pkt->NumRetries > 0 || Pkt->RetryHistory);
- Pkt->NumRetries--;
+ if(Pkt->NumThinProvisioningRetries >= NUM_THIN_PROVISIONING_RETRIES) {
+ //We've already retried this the maximum times. Bail out.
+ return TRUE;
+ }
+ Pkt->NumThinProvisioningRetries++;
+ }
+ else {
+ NT_ASSERT(Pkt->NumRetries > 0 || Pkt->RetryHistory);
+ Pkt->NumRetries--;
+ }
+
+ TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "retrying failed transfer (pkt=%ph, op=%s)", Pkt, DBGGETSCSIOPSTR(Pkt->Srb)));
if (!fdoData->DisableThrottling) {
//
// If this is the last retry, then turn off disconnect, sync transfer,
// and tagged queuing. On all other retries, leave the original settings.
+ // Do not apply this for thin provisioning soft threshold errors, since
+ // they should succeed as soon as they're retried on the right IT nexus.
//
- if (Pkt->NumRetries == 0) {
+ if ((Pkt->NumRetries == 0) && !ClasspIsThinProvisioningError((PSCSI_REQUEST_BLOCK)Pkt->Srb)) {
scaleDown = TRUE;
}
#if (NTDDI_VERSION >= NTDDI_WINBLUE)
//
// If this request previously timed-out and there are no more retries left
- // for timed-out requests then we should also apply the scale down.
+ // for timed-out requests, then we should also apply the scale down.
//
- if (Pkt->TimedOut &&
- Pkt->NumIoTimeoutRetries == 0) {
+ if (Pkt->TimedOut && Pkt->NumIoTimeoutRetries == 0) {
scaleDown = TRUE;
}
#endif
diff --git a/storage/class/classpnp/src/utils.c b/storage/class/classpnp/src/utils.c
index 20917d83..323d7449 100644
--- a/storage/class/classpnp/src/utils.c
+++ b/storage/class/classpnp/src/utils.c
@@ -118,10 +118,10 @@ VOID ClassGetDeviceParameter(
defaultParameterValue = *ParameterValue;
- queryTable->Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ queryTable->Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable->Name = ParameterName;
queryTable->EntryContext = ParameterValue;
- queryTable->DefaultType = REG_DWORD;
+ queryTable->DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
queryTable->DefaultData = NULL;
queryTable->DefaultLength = 0;
@@ -181,10 +181,10 @@ VOID ClassGetDeviceParameter(
defaultParameterValue = *ParameterValue;
- queryTable->Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ queryTable->Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable->Name = ParameterName;
queryTable->EntryContext = ParameterValue;
- queryTable->DefaultType = REG_DWORD;
+ queryTable->DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
queryTable->DefaultData = NULL;
queryTable->DefaultLength = 0;
@@ -1569,7 +1569,7 @@ ClassReadCapacity16 (
FdoExtension->LowerLayerSupport->AccessAlignment.LowerLayerSupported = Supported;
to indicate that info has been cached.
- NOTE: some future processes may use this funciton to send the command anyway, it will be caller's decision
+ NOTE: some future processes may use this function to send the command anyway, it will be caller's decision
on checking 'AccessAlignment.LowerLayerSupported' in case the cached info is good enough.
*/
{
@@ -1638,7 +1638,7 @@ ClassReadCapacity16 (
//prepare the Srb
if (NT_SUCCESS(status))
{
-
+
SrbSetTimeOutValue(Srb, FdoExtension->TimeOutValue);
SrbSetRequestTag(Srb, SP_UNTAGGED);
SrbSetRequestAttribute(Srb, SRB_SIMPLE_TAG_REQUEST);
@@ -1745,7 +1745,7 @@ NTSTATUS ClasspAccessAlignmentProperty(
//
// Request validation.
- // Note that InputBufferLength and IsFdo have been validated beforing entering this routine.
+ // Note that InputBufferLength and IsFdo have been validated before entering this routine.
//
if (KeGetCurrentIrql() >= DISPATCH_LEVEL) {
@@ -1814,7 +1814,7 @@ NTSTATUS ClasspAccessAlignmentProperty(
} else {
information = 0;
}
- goto Exit;
+
} else {
// case 2: the request is supported and it completes successfully
// case 3: the request is supported by lower stack but other failure status is returned.
@@ -1823,8 +1823,11 @@ NTSTATUS ClasspAccessAlignmentProperty(
information = (ULONG)Irp->IoStatus.Information;
- goto Exit;
}
+
+
+ goto Exit;
+
break;
}
@@ -1851,7 +1854,7 @@ NTSTATUS ClasspAccessAlignmentProperty(
}
case Supported: {
- NT_ASSERT(FALSE); // this case is handled at the begining of the function.
+ NT_ASSERT(FALSE); // this case is handled at the beginning of the function.
status = STATUS_INTERNAL_ERROR;
break;
}
@@ -3154,6 +3157,8 @@ DeviceProcessDsmTrimRequest(
_In_ ULONG DataSetRangesCount,
_In_ ULONG UnmapGranularity,
_In_ ULONG SrbFlags,
+ _In_ PIRP Irp,
+ _In_ PGUID ActivityId,
_Inout_ PSCSI_REQUEST_BLOCK Srb
)
/*++
@@ -3199,8 +3204,11 @@ Return Value:
ULONGLONG maxLbaCount;
ULONGLONG maxParameterListLength;
- UNREFERENCED_PARAMETER(UnmapGranularity);
+ UNREFERENCED_PARAMETER(UnmapGranularity);
+ UNREFERENCED_PARAMETER(ActivityId);
+ UNREFERENCED_PARAMETER(Irp);
+
//
// The given LBA ranges are in DEVICE_DATA_SET_RANGE format and need to be converted into UNMAP Block Descriptors.
// The UNMAP command is able to carry 0xFFFF bytes (0xFFF8 in reality as there are 8 bytes of header plus n*16 bytes of Block Descriptors) of data.
@@ -3320,6 +3328,7 @@ Return Value:
blockDescrIndex = 0;
lbaCount = 0;
+
while (!allDataSetRangeFullyConverted) {
//
@@ -3348,8 +3357,8 @@ Return Value:
//
// Send the UNMAP command when the buffer is full or when all input entries are converted.
//
- if ( (blockDescrIndex == maxBlockDescrCount) || // Buffer full or block descriptor count reached
- (lbaCount == maxLbaCount) || // Block LBA count reached
+ if ((blockDescrIndex == maxBlockDescrCount) || // Buffer full or block descriptor count reached
+ (lbaCount == maxLbaCount) || // Block LBA count reached
allDataSetRangeFullyConverted) { // All DataSetRanges have been converted
USHORT transferSize;
@@ -3457,6 +3466,7 @@ Exit:
NTSTATUS ClasspDeviceTrimProcess(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp,
+ _In_ PGUID ActivityId,
_Inout_ PSCSI_REQUEST_BLOCK Srb
)
/*
@@ -3483,6 +3493,7 @@ NTSTATUS ClasspDeviceTrimProcess(
CLASS_VPD_B0_DATA blockLimitsData;
ULONG generationCount;
+
if ( (DeviceObject->DeviceType != FILE_DEVICE_DISK) ||
(TEST_FLAG(DeviceObject->Characteristics, FILE_FLOPPY_DISKETTE)) ||
(fdoExtension->FunctionSupportInfo->LowerLayerSupport.TrimProcess == Supported) ) {
@@ -3511,6 +3522,7 @@ NTSTATUS ClasspDeviceTrimProcess(
goto Exit;
}
+
//
// If the caller has not set the "entire dataset range" flag then at least
// one dataset range should be specified. However, if the caller *has* set
@@ -3703,6 +3715,8 @@ NTSTATUS ClasspDeviceTrimProcess(
dataSetRangesCount,
granularityInBlocks,
srbFlags,
+ Irp,
+ ActivityId,
Srb);
} else {
// DSM IOCTL should be completed as not supported
@@ -3736,6 +3750,8 @@ Exit:
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
+
+
ClassReleaseRemoveLock(DeviceObject, Irp);
ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
@@ -6725,7 +6741,7 @@ Return Value:
//
// Indicate that there is NO call-back routine.
//
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK;
//
// The value to query.
@@ -6736,7 +6752,7 @@ Return Value:
// Where to put the value, the type of the value, default value and length.
//
queryTable[0].EntryContext = &value;
- queryTable[0].DefaultType = REG_DWORD;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD;
queryTable[0].DefaultData = &value;
queryTable[0].DefaultLength = sizeof(value);
@@ -6765,6 +6781,99 @@ Return Value:
return status;
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS
+ClasspGetCopyOffloadMaxDuration(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_z_ PWSTR RegistryPath,
+ _Out_ PULONG MaxDuration
+ )
+
+ /*++
+
+ Routine Description:
+
+ This routine returns the maximum time (in seconds) that a Copy Offload
+ operation should take to complete by a target.
+
+ Arguments:
+
+ DeviceObject - The device handling the request.
+ RegistryPath - The absolute registry path under which MaxDuration resides.
+ MaxDuration - Returns the value being queried, in seconds.
+
+ Return Value:
+
+ STATUS_SUCCESS or appropriate error status returned by Registry API.
+
+ --*/
+
+{
+ RTL_QUERY_REGISTRY_TABLE queryTable[2];
+ ULONG value = 0;
+ NTSTATUS status;
+
+ TracePrint((TRACE_LEVEL_VERBOSE,
+ TRACE_FLAG_PNP,
+ "ClasspGetCopyOffloadMaxDuration (%p): Entering function.\n",
+ DeviceObject));
+
+ //
+ // Zero the table entries.
+ //
+ RtlZeroMemory(queryTable, sizeof(queryTable));
+
+ //
+ // The query table has two entries. One for CopyOffloadMaxDuration and
+ // the second which is the 'NULL' terminator.
+ //
+ // Indicate that there is NO call-back routine.
+ //
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK;
+
+ //
+ // The value to query.
+ //
+ queryTable[0].Name = CLASSP_REG_COPY_OFFLOAD_MAX_TARGET_DURATION;
+
+ //
+ // Where to put the value, the type of the value, default value and length.
+ //
+ queryTable[0].EntryContext = &value;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
+ queryTable[0].DefaultData = &value;
+ queryTable[0].DefaultLength = sizeof(value);
+
+ //
+ // Try to get the max target duration.
+ //
+ status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ RegistryPath,
+ queryTable,
+ NULL,
+ NULL);
+
+ //
+ // Don't allow the user to set the value to lower than the default (4s) so
+ // they don't break ODX functionality if they accidentally set it too low.
+ //
+ if (NT_SUCCESS(status) &&
+ value > DEFAULT_MAX_TARGET_DURATION) {
+ *MaxDuration = value;
+ } else {
+ *MaxDuration = DEFAULT_MAX_TARGET_DURATION;
+ }
+
+ TracePrint((TRACE_LEVEL_VERBOSE,
+ TRACE_FLAG_PNP,
+ "ClasspGetCopyOffloadMaxDuration (%p): Exiting function with status %x (Max Duration %u seconds).\n",
+ DeviceObject,
+ status,
+ *MaxDuration));
+
+ return status;
+}
+
_IRQL_requires_max_(APC_LEVEL)
_IRQL_requires_min_(PASSIVE_LEVEL)
@@ -8205,7 +8314,7 @@ ClassDeviceHwFirmwareIsPortDriverSupported(
/*
Routine Description:
- This function informs the caller whether the port driver supports hardware firmware requests.
+ This function informs the caller whether the port driver supports hardware firmware requests.
Arguments:
DeviceObject: The target object.
@@ -8343,10 +8452,15 @@ Exit_Firmware_Get_Info:
//
// Firmware information is already cached in classpnp. Return a copy.
//
+ KLOCK_QUEUE_HANDLE lockHandle;
+ KeAcquireInStackQueuedSpinLock(&fdoExtension->FunctionSupportInfo->SyncLock, &lockHandle);
+
ULONG dataLength = min(irpStack->Parameters.DeviceIoControl.OutputBufferLength, fdoExtension->FunctionSupportInfo->HwFirmwareInfo->Size);
memcpy(Irp->AssociatedIrp.SystemBuffer, fdoExtension->FunctionSupportInfo->HwFirmwareInfo, dataLength);
+ KeReleaseInStackQueuedSpinLock(&lockHandle);
+
Irp->IoStatus.Information = dataLength;
}
@@ -8426,6 +8540,8 @@ ClassDeviceHwFirmwareDownloadProcess(
PIRP irp2 = NULL;
PIO_STACK_LOCATION newStack = NULL;
PCDB cdb = NULL;
+ BOOLEAN lockHeld = FALSE;
+ KLOCK_QUEUE_HANDLE lockHandle;
//
@@ -8521,6 +8637,13 @@ ClassDeviceHwFirmwareDownloadProcess(
}
//
+ // Acquire the SyncLock to ensure the HwFirmwareInfo pointer doesn't change
+ // while we're dereferencing it.
+ //
+ lockHeld = TRUE;
+ KeAcquireInStackQueuedSpinLock(&fdoExtension->FunctionSupportInfo->SyncLock, &lockHandle);
+
+ //
// Validate the device support
//
if ((fdoExtension->FunctionSupportInfo->HwFirmwareInfo->SupportUpgrade == FALSE) ||
@@ -8573,6 +8696,14 @@ ClassDeviceHwFirmwareDownloadProcess(
//
bufferSize = ALIGN_UP_BY(firmwareDownload->BufferSize, fdoExtension->FunctionSupportInfo->HwFirmwareInfo->ImagePayloadAlignment);
+ //
+ // We're done accessing HwFirmwareInfo at this point so we can release
+ // the SyncLock.
+ //
+ NT_ASSERT(lockHeld);
+ KeReleaseInStackQueuedSpinLock(&lockHandle);
+ lockHeld = FALSE;
+
#pragma prefast(suppress:6014, "The allocated memory that firmwareImageBuffer points to will be freed in ClassHwFirmwareDownloadComplete().")
firmwareImageBuffer = ExAllocatePoolWithTag(NonPagedPoolNx, bufferSize, CLASSPNP_POOL_TAG_FIRMWARE);
@@ -8586,6 +8717,10 @@ ClassDeviceHwFirmwareDownloadProcess(
RtlCopyMemory(firmwareImageBuffer, firmwareDownload->ImageBuffer, (ULONG)firmwareDownload->BufferSize);
} else {
+ NT_ASSERT(lockHeld);
+ KeReleaseInStackQueuedSpinLock(&lockHandle);
+ lockHeld = FALSE;
+
firmwareImageBuffer = firmwareDownload->ImageBuffer;
bufferSize = (ULONG)firmwareDownload->BufferSize;
}
@@ -8654,7 +8789,7 @@ ClassDeviceHwFirmwareDownloadProcess(
SrbSetCdbLength(Srb, CDB10GENERIC_LENGTH);
cdb = SrbGetCdb(Srb);
cdb->WRITE_BUFFER.OperationCode = SCSIOP_WRITE_DATA_BUFF;
- cdb->WRITE_BUFFER.Mode = 0x0E;
+ cdb->WRITE_BUFFER.Mode = SCSI_WRITE_BUFFER_MODE_DOWNLOAD_MICROCODE_WITH_OFFSETS_SAVE_DEFER_ACTIVATE;
cdb->WRITE_BUFFER.ModeSpecific = 0; //Reserved for Mode 0x0E
cdb->WRITE_BUFFER.BufferID = firmwareDownload->Slot;
@@ -8713,6 +8848,15 @@ ClassDeviceHwFirmwareDownloadProcess(
Exit_Firmware_Download:
//
+ // Release the SyncLock if it's still held.
+ // This should only happen in the failure path.
+ //
+ if (lockHeld) {
+ KeReleaseInStackQueuedSpinLock(&lockHandle);
+ lockHeld = FALSE;
+ }
+
+ //
// Firmware Download request will be failed.
//
NT_ASSERT(!NT_SUCCESS(status));
@@ -8751,6 +8895,8 @@ ClassDeviceHwFirmwareActivateProcess(
BOOLEAN passDown = FALSE;
PCDB cdb = NULL;
ULONG i;
+ BOOLEAN lockHeld = FALSE;
+ KLOCK_QUEUE_HANDLE lockHandle;
//
@@ -8845,6 +8991,13 @@ ClassDeviceHwFirmwareActivateProcess(
}
//
+ // Acquire the SyncLock to ensure the HwFirmwareInfo pointer doesn't change
+ // while we're dereferencing it.
+ //
+ lockHeld = TRUE;
+ KeAcquireInStackQueuedSpinLock(&fdoExtension->FunctionSupportInfo->SyncLock, &lockHandle);
+
+ //
// Validate the device support
//
if (fdoExtension->FunctionSupportInfo->HwFirmwareInfo->SupportUpgrade == FALSE) {
@@ -8870,6 +9023,14 @@ ClassDeviceHwFirmwareActivateProcess(
}
//
+ // We're done accessing HwFirmwareInfo at this point so we can release
+ // the SyncLock.
+ //
+ NT_ASSERT(lockHeld);
+ KeReleaseInStackQueuedSpinLock(&lockHandle);
+ lockHeld = FALSE;
+
+ //
// Process the request by translating it into WRITE BUFFER command.
//
//
@@ -8878,7 +9039,7 @@ ClassDeviceHwFirmwareActivateProcess(
SrbSetCdbLength(Srb, CDB10GENERIC_LENGTH);
cdb = SrbGetCdb(Srb);
cdb->WRITE_BUFFER.OperationCode = SCSIOP_WRITE_DATA_BUFF;
- cdb->WRITE_BUFFER.Mode = 0x0F;
+ cdb->WRITE_BUFFER.Mode = SCSI_WRITE_BUFFER_MODE_ACTIVATE_DEFERRED_MICROCODE;
cdb->WRITE_BUFFER.ModeSpecific = 0; //Reserved for Mode 0x0F
cdb->WRITE_BUFFER.BufferID = firmwareActivate->Slot; //NOTE: this field will be ignored by SCSI device.
@@ -8912,6 +9073,15 @@ ClassDeviceHwFirmwareActivateProcess(
Exit_Firmware_Activate:
//
+ // Release the SyncLock if it's still held.
+ // This should only happen in the failure path.
+ //
+ if (lockHeld) {
+ KeReleaseInStackQueuedSpinLock(&lockHandle);
+ lockHeld = FALSE;
+ }
+
+ //
// Firmware Activate request will be failed.
//
NT_ASSERT(!NT_SUCCESS(status));
@@ -8930,3 +9100,46 @@ Exit_Firmware_Activate:
return status;
}
+
+BOOLEAN
+ClasspIsThinProvisioningError (
+ _In_ PSCSI_REQUEST_BLOCK Srb
+ )
+/*++
+
+Routine Description:
+
+ This routine checks whether the completed SRB Srb was completed with a thin provisioning
+ soft threshold error.
+
+Arguments:
+
+ Srb - the SRB to be checked.
+
+Return Value:
+
+ BOOLEAN
+
+--*/
+{
+ if (TEST_FLAG(Srb->SrbStatus, SRB_STATUS_AUTOSENSE_VALID)) {
+ PVOID senseBuffer = SrbGetSenseInfoBuffer(Srb);
+ if (senseBuffer) {
+ UCHAR senseKey = 0;
+ UCHAR addlSenseCode = 0;
+ UCHAR addlSenseCodeQual = 0;
+ BOOLEAN validSense = ScsiGetSenseKeyAndCodes(senseBuffer,
+ SrbGetSenseInfoBufferLength(Srb),
+ SCSI_SENSE_OPTIONS_NONE,
+ &senseKey,
+ &addlSenseCode,
+ &addlSenseCodeQual);
+
+ return (validSense
+ && (senseKey == SCSI_SENSE_UNIT_ATTENTION)
+ && (addlSenseCode == SCSI_ADSENSE_LB_PROVISIONING)
+ && (addlSenseCodeQual == SCSI_SENSEQ_SOFT_THRESHOLD_REACHED));
+ }
+ }
+ return FALSE;
+}
diff --git a/storage/class/classpnp/src/xferpkt.c b/storage/class/classpnp/src/xferpkt.c
index db728770..e66918b0 100644
--- a/storage/class/classpnp/src/xferpkt.c
+++ b/storage/class/classpnp/src/xferpkt.c
@@ -700,6 +700,7 @@ PTRANSFER_PACKET DequeueFreeTransferPacketEx(
}
+
/*
* SetupReadWriteTransferPacket
*
@@ -824,6 +825,7 @@ VOID SetupReadWriteTransferPacket( PTRANSFER_PACKET Pkt,
Pkt->SyncEventPtr = NULL;
Pkt->CompleteOriginalIrpWhenLastPacketCompletes = TRUE;
Pkt->NumIoTimeoutRetries = fdoData->MaxNumberOfIoRetries;
+ Pkt->NumThinProvisioningRetries = 0;
if (pCdb) {
@@ -927,6 +929,8 @@ NTSTATUS TransferPktComplete(IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Co
BOOLEAN packetDone = FALSE;
BOOLEAN idleRequest = FALSE;
ULONG transferLength;
+ LARGE_INTEGER completionTime;
+ ULONGLONG lastIoCompletionTime;
UNREFERENCED_PARAMETER(NullFdo);
@@ -938,14 +942,31 @@ NTSTATUS TransferPktComplete(IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Co
HISTORYLOGRETURNEDPACKET(pkt);
+ completionTime = ClasspGetCurrentTime();
+
+ //
+ // Record the time at which the last IO completed while snapping the old
+ // value to be used later. This can occur on multiple threads and hence
+ // could be overwritten with an older value. This is OK because this value
+ // is maintained as a heuristic.
+ //
+
+#ifdef _WIN64
+ lastIoCompletionTime = ReadULong64NoFence((volatile ULONG64*)&fdoData->LastIoCompletionTime.QuadPart);
+ WriteULong64NoFence((volatile ULONG64*)&fdoData->LastIoCompletionTime.QuadPart,
+ completionTime.QuadPart);
+#else
+ lastIoCompletionTime = InterlockedExchangeNoFence64((volatile LONG64*)&fdoData->LastIoCompletionTime.QuadPart,
+ completionTime.QuadPart);
+#endif
+
if (fdoData->IdlePrioritySupported == TRUE) {
idleRequest = ClasspIsIdleRequest(pkt->OriginalIrp);
if (idleRequest) {
InterlockedDecrement(&fdoData->ActiveIdleIoCount);
NT_ASSERT(fdoData->ActiveIdleIoCount >= 0);
} else {
- fdoData->LastIoTime = ClasspGetCurrentTime(NULL);
- fdoData->IdleTicks = 0;
+ fdoData->LastNonIdleIoTime = completionTime;
InterlockedDecrement(&fdoData->ActiveIoCount);
NT_ASSERT(fdoData->ActiveIoCount >= 0);
}
@@ -979,6 +1000,7 @@ NTSTATUS TransferPktComplete(IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Co
InterlockedExchangeAdd((PLONG)&pkt->OriginalIrp->IoStatus.Information,
(LONG)transferLength);
+
if ((pkt->InLowMemRetry) ||
(pkt->DriverUsesStartIO && pkt->LowMemRetry_remainingBufLen > 0)) {
packetDone = StepLowMemRetry(pkt);
@@ -1028,6 +1050,7 @@ NTSTATUS TransferPktComplete(IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Co
ClassReleaseQueue(pkt->Fdo);
}
+
if (NT_SUCCESS(Irp->IoStatus.Status)){
/*
* The error was recovered above in the InterpretTransferPacketError() call.
@@ -1741,7 +1764,6 @@ Return Value:
Pkt->ContinuationRoutine = ClasspPopulateTokenTransferPacketDone;
Pkt->ContinuationContext = OffloadReadContext;
-
TracePrint((TRACE_LEVEL_VERBOSE,
TRACE_FLAG_IOCTL,
"ClasspSetupPopulateTokenTransferPacket (%p): Exiting function with Irp %p\n",
@@ -1839,7 +1861,6 @@ Return Value:
Pkt->ContinuationRoutine = ClasspReceivePopulateTokenInformationTransferPacketDone;
Pkt->ContinuationContext = OffloadReadContext;
-
TracePrint((TRACE_LEVEL_VERBOSE,
TRACE_FLAG_IOCTL,
"ClasspSetupReceivePopulateTokenInformationTransferPacket (%p): Exiting function with Irp %p\n",
@@ -1941,7 +1962,6 @@ Return Value:
Pkt->ContinuationRoutine = ClasspWriteUsingTokenTransferPacketDone;
Pkt->ContinuationContext = OffloadWriteContext;
-
TracePrint((TRACE_LEVEL_VERBOSE,
TRACE_FLAG_IOCTL,
"ClasspSetupWriteUsingTokenTransferPacket (%p): Exiting function with Irp %p\n",
@@ -2040,7 +2060,6 @@ Return Value:
Pkt->ContinuationRoutine = ClasspReceiveWriteUsingTokenInformationTransferPacketDone;
Pkt->ContinuationContext = OffloadWriteContext;
-
TracePrint((TRACE_LEVEL_VERBOSE,
TRACE_FLAG_IOCTL,
"ClasspSetupReceiveWriteUsingTokenInformationTransferPacket (%p): Exiting function with Irp %p\n",
diff --git a/storage/class/disk/disk.sln b/storage/class/disk/disk.sln
index 3632e931..26ff24dd 100644
--- a/storage/class/disk/disk.sln
+++ b/storage/class/disk/disk.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "disk", "src\disk.vcxproj", "{0900F953-9DAF-4C58-9137-45A2DEC9C62C}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "disk", "src\disk.vcxproj", "{C4E8B1CC-0131-442C-8EB8-8E84F938878A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {0900F953-9DAF-4C58-9137-45A2DEC9C62C}.Debug|Win32.ActiveCfg = Debug|Win32
- {0900F953-9DAF-4C58-9137-45A2DEC9C62C}.Debug|Win32.Build.0 = Debug|Win32
- {0900F953-9DAF-4C58-9137-45A2DEC9C62C}.Release|Win32.ActiveCfg = Release|Win32
- {0900F953-9DAF-4C58-9137-45A2DEC9C62C}.Release|Win32.Build.0 = Release|Win32
- {0900F953-9DAF-4C58-9137-45A2DEC9C62C}.Debug|x64.ActiveCfg = Debug|x64
- {0900F953-9DAF-4C58-9137-45A2DEC9C62C}.Debug|x64.Build.0 = Debug|x64
- {0900F953-9DAF-4C58-9137-45A2DEC9C62C}.Release|x64.ActiveCfg = Release|x64
- {0900F953-9DAF-4C58-9137-45A2DEC9C62C}.Release|x64.Build.0 = Release|x64
+ {C4E8B1CC-0131-442C-8EB8-8E84F938878A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C4E8B1CC-0131-442C-8EB8-8E84F938878A}.Debug|Win32.Build.0 = Debug|Win32
+ {C4E8B1CC-0131-442C-8EB8-8E84F938878A}.Release|Win32.ActiveCfg = Release|Win32
+ {C4E8B1CC-0131-442C-8EB8-8E84F938878A}.Release|Win32.Build.0 = Release|Win32
+ {C4E8B1CC-0131-442C-8EB8-8E84F938878A}.Debug|x64.ActiveCfg = Debug|x64
+ {C4E8B1CC-0131-442C-8EB8-8E84F938878A}.Debug|x64.Build.0 = Debug|x64
+ {C4E8B1CC-0131-442C-8EB8-8E84F938878A}.Release|x64.ActiveCfg = Release|x64
+ {C4E8B1CC-0131-442C-8EB8-8E84F938878A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/class/disk/src/disk.c b/storage/class/disk/src/disk.c
index 3d4d19b4..05f0d6d3 100644
--- a/storage/class/disk/src/disk.c
+++ b/storage/class/disk/src/disk.c
@@ -1550,6 +1550,7 @@ Return Value:
PIO_STACK_LOCATION irpSp = NULL;
PSTOR_ADDR_BTL8 storAddrBtl8;
PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16;
+ NTSTATUS SyncCacheStatus = STATUS_SUCCESS;
//
// Fill in the srb fields appropriately
@@ -1623,7 +1624,7 @@ Return Value:
TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushDispatch: sending sync cache\n"));
- ClassSendSrbSynchronous(Fdo, srb, NULL, 0, TRUE);
+ SyncCacheStatus = ClassSendSrbSynchronous(Fdo, srb, NULL, 0, TRUE);
}
//
@@ -1669,7 +1670,7 @@ Return Value:
irpSp->MajorFunction = IRP_MJ_SCSI;
irpSp->Parameters.Scsi.Srb = srb;
- IoSetCompletionRoutine(FlushContext->CurrIrp, DiskFlushComplete, NULL, TRUE, TRUE, TRUE);
+ IoSetCompletionRoutine(FlushContext->CurrIrp, DiskFlushComplete, (PVOID)SyncCacheStatus, TRUE, TRUE, TRUE);
TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_SCSI, "DiskFlushDispatch: sending srb flush on irp %p\n", FlushContext->CurrIrp));
@@ -1700,7 +1701,9 @@ Arguments:
Fdo - The device object which requested the completion routine
Irp - The irp that is being completed
- Context - The flush group context
+ Context - If disk had write cache enabled and SYNC CACHE command was sent as 1st part of FLUSH processing
+ then context must carry the completion status of SYNC CACHE request,
+ else context must be set to STATUS_SUCCESS.
Return Value:
@@ -1713,8 +1716,7 @@ Return Value:
NTSTATUS status;
PFUNCTIONAL_DEVICE_EXTENSION fdoExt;
PDISK_DATA diskData;
-
- UNREFERENCED_PARAMETER(Context);
+ NTSTATUS SyncCacheStatus = (NTSTATUS) Context;
TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL, "DiskFlushComplete: %p %p\n", Fdo, Irp));
@@ -1742,6 +1744,15 @@ Return Value:
NT_ASSERT(status != STATUS_MORE_PROCESSING_REQUIRED);
//
+ // If sync cache failed earlier, final status of the flush request needs to be failure
+ // even if SRB_FUNCTION_FLUSH srb request succeeded
+ //
+ if (NT_SUCCESS(status) &&
+ (!NT_SUCCESS(SyncCacheStatus))) {
+ Irp->IoStatus.Status = status = SyncCacheStatus;
+ }
+
+ //
// Complete the flush requests tagged to this one
//
diff --git a/storage/class/disk/src/disk.vcxproj b/storage/class/disk/src/disk.vcxproj
index 1f52e370..bc5efddb 100644
--- a/storage/class/disk/src/disk.vcxproj
+++ b/storage/class/disk/src/disk.vcxproj
@@ -19,12 +19,12 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{0900F953-9DAF-4C58-9137-45A2DEC9C62C}</ProjectGuid>
+ <ProjectGuid>{C4E8B1CC-0131-442C-8EB8-8E84F938878A}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<SupportsPackaging>false</SupportsPackaging>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{6222553B-2B65-4267-9522-973010FB316D}</SampleGuid>
+ <SampleGuid>{1257A10C-96B8-46FB-9FFD-6726981343C7}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/class/disk/src/disk.vcxproj.Filters b/storage/class/disk/src/disk.vcxproj.Filters
index 1a2af052..5c982e78 100644
--- a/storage/class/disk/src/disk.vcxproj.Filters
+++ b/storage/class/disk/src/disk.vcxproj.Filters
@@ -3,19 +3,19 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{9D58AF57-E3D3-492B-A93C-CD4BD860C101}</UniqueIdentifier>
+ <UniqueIdentifier>{5312DB94-F2AD-4908-9DC6-C3525D0469E6}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{5021C225-A54E-4A00-A24F-A0AEC3B6B92A}</UniqueIdentifier>
+ <UniqueIdentifier>{1EA3AD8C-6E4B-4964-A3D1-62178CDEC868}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{2092A6B9-C332-464C-B263-00060DE1B3E0}</UniqueIdentifier>
+ <UniqueIdentifier>{2A5B4A49-7B7B-4C84-9F4D-4B3B50FFA526}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{2F3C9ECA-BD6F-472C-915B-51096E28B70C}</UniqueIdentifier>
+ <UniqueIdentifier>{48E85F2C-8024-453C-8D4D-AFA7E6BB0AB7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
diff --git a/storage/class/disk/src/geometry.c b/storage/class/disk/src/geometry.c
index 911a33a4..a852c092 100644
--- a/storage/class/disk/src/geometry.c
+++ b/storage/class/disk/src/geometry.c
@@ -1358,8 +1358,8 @@ Return Value:
// ISSUE-2000/5/24-henrygab - figure out if there's a way to keep
// removals from happening while doing this.
//
-
- for(deviceObject = DriverObject->DeviceObject, unmatchedDiskCount = 0;
+ unmatchedDiskCount = 0;
+ for(deviceObject = DriverObject->DeviceObject;
deviceObject != NULL;
#pragma prefast(suppress:28175, "Need to access the opaque field to scan through the list of disks")
deviceObject = deviceObject->NextDevice) {
diff --git a/storage/class/disk/src/pnp.c b/storage/class/disk/src/pnp.c
index bb3a33c5..5eb333e7 100644
--- a/storage/class/disk/src/pnp.c
+++ b/storage/class/disk/src/pnp.c
@@ -122,9 +122,10 @@ Return Value:
LEAVE;
}
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = L"RootPartitionMountable";
queryTable[0].EntryContext = &(rootPartitionMountable);
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
#pragma prefast(suppress:6309, "We don't have QueryRoutine so Context doesn't make any sense")
status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
diff --git a/storage/filters/addfilter/addfilter.sln b/storage/filters/addfilter/addfilter.sln
index d0a0bda9..f2c404f5 100644
--- a/storage/filters/addfilter/addfilter.sln
+++ b/storage/filters/addfilter/addfilter.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "addfilter", "src\addfilter.vcxproj", "{333BB1A9-B991-4148-8E4A-717743859C27}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "addfilter", "src\addfilter.vcxproj", "{95C071C0-CBCC-4943-BB7D-90E2EDD17043}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {333BB1A9-B991-4148-8E4A-717743859C27}.Debug|Win32.ActiveCfg = Debug|Win32
- {333BB1A9-B991-4148-8E4A-717743859C27}.Debug|Win32.Build.0 = Debug|Win32
- {333BB1A9-B991-4148-8E4A-717743859C27}.Release|Win32.ActiveCfg = Release|Win32
- {333BB1A9-B991-4148-8E4A-717743859C27}.Release|Win32.Build.0 = Release|Win32
- {333BB1A9-B991-4148-8E4A-717743859C27}.Debug|x64.ActiveCfg = Debug|x64
- {333BB1A9-B991-4148-8E4A-717743859C27}.Debug|x64.Build.0 = Debug|x64
- {333BB1A9-B991-4148-8E4A-717743859C27}.Release|x64.ActiveCfg = Release|x64
- {333BB1A9-B991-4148-8E4A-717743859C27}.Release|x64.Build.0 = Release|x64
+ {95C071C0-CBCC-4943-BB7D-90E2EDD17043}.Debug|Win32.ActiveCfg = Debug|Win32
+ {95C071C0-CBCC-4943-BB7D-90E2EDD17043}.Debug|Win32.Build.0 = Debug|Win32
+ {95C071C0-CBCC-4943-BB7D-90E2EDD17043}.Release|Win32.ActiveCfg = Release|Win32
+ {95C071C0-CBCC-4943-BB7D-90E2EDD17043}.Release|Win32.Build.0 = Release|Win32
+ {95C071C0-CBCC-4943-BB7D-90E2EDD17043}.Debug|x64.ActiveCfg = Debug|x64
+ {95C071C0-CBCC-4943-BB7D-90E2EDD17043}.Debug|x64.Build.0 = Debug|x64
+ {95C071C0-CBCC-4943-BB7D-90E2EDD17043}.Release|x64.ActiveCfg = Release|x64
+ {95C071C0-CBCC-4943-BB7D-90E2EDD17043}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/filters/addfilter/src/addfilter.vcxproj b/storage/filters/addfilter/src/addfilter.vcxproj
index 5ed66238..1cb9300f 100644
--- a/storage/filters/addfilter/src/addfilter.vcxproj
+++ b/storage/filters/addfilter/src/addfilter.vcxproj
@@ -19,11 +19,11 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{333BB1A9-B991-4148-8E4A-717743859C27}</ProjectGuid>
+ <ProjectGuid>{95C071C0-CBCC-4943-BB7D-90E2EDD17043}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{4D1BE240-118A-47DA-A950-1599577B4F12}</SampleGuid>
+ <SampleGuid>{E441786B-1740-49DB-ACB6-E800A4DB2D15}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/filters/addfilter/src/addfilter.vcxproj.Filters b/storage/filters/addfilter/src/addfilter.vcxproj.Filters
index b8180f80..9b5df5cf 100644
--- a/storage/filters/addfilter/src/addfilter.vcxproj.Filters
+++ b/storage/filters/addfilter/src/addfilter.vcxproj.Filters
@@ -3,15 +3,15 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{2EA932C6-BBAE-4F02-8679-F051D9F4FC59}</UniqueIdentifier>
+ <UniqueIdentifier>{BFD7B380-2B08-4124-81F2-BD9E9E1E59BB}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{AB31727D-D0C9-437A-9354-C58898448CE9}</UniqueIdentifier>
+ <UniqueIdentifier>{84770C65-A89D-40AC-BFB6-2D42A6ECD7C4}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{A9B9B1E8-BC9B-4D25-BD02-7849CB9CBFA2}</UniqueIdentifier>
+ <UniqueIdentifier>{E60018BB-F626-48CB-90FA-2817FC2C2C06}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
diff --git a/storage/iscsi/iscsi.sln b/storage/iscsi/iscsi.sln
index 1af68126..819e26da 100644
--- a/storage/iscsi/iscsi.sln
+++ b/storage/iscsi/iscsi.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EmptyProject", "src\EmptyProject.vcxproj", "{455C49DA-CEA2-4534-BD01-3580A803AE6F}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EmptyProject", "src\EmptyProject.vcxproj", "{D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {455C49DA-CEA2-4534-BD01-3580A803AE6F}.Debug|Win32.ActiveCfg = Debug|Win32
- {455C49DA-CEA2-4534-BD01-3580A803AE6F}.Debug|Win32.Build.0 = Debug|Win32
- {455C49DA-CEA2-4534-BD01-3580A803AE6F}.Release|Win32.ActiveCfg = Release|Win32
- {455C49DA-CEA2-4534-BD01-3580A803AE6F}.Release|Win32.Build.0 = Release|Win32
- {455C49DA-CEA2-4534-BD01-3580A803AE6F}.Debug|x64.ActiveCfg = Debug|x64
- {455C49DA-CEA2-4534-BD01-3580A803AE6F}.Debug|x64.Build.0 = Debug|x64
- {455C49DA-CEA2-4534-BD01-3580A803AE6F}.Release|x64.ActiveCfg = Release|x64
- {455C49DA-CEA2-4534-BD01-3580A803AE6F}.Release|x64.Build.0 = Release|x64
+ {D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}.Debug|Win32.Build.0 = Debug|Win32
+ {D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}.Release|Win32.ActiveCfg = Release|Win32
+ {D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}.Release|Win32.Build.0 = Release|Win32
+ {D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}.Debug|x64.ActiveCfg = Debug|x64
+ {D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}.Debug|x64.Build.0 = Debug|x64
+ {D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}.Release|x64.ActiveCfg = Release|x64
+ {D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/iscsi/src/EmptyProject.vcxproj b/storage/iscsi/src/EmptyProject.vcxproj
index 9623b594..21c5ce69 100644
--- a/storage/iscsi/src/EmptyProject.vcxproj
+++ b/storage/iscsi/src/EmptyProject.vcxproj
@@ -19,12 +19,12 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{455C49DA-CEA2-4534-BD01-3580A803AE6F}</ProjectGuid>
+ <ProjectGuid>{D522AB21-5E8C-4E3F-9934-AE9C8C23C7E6}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<SupportsPackaging>false</SupportsPackaging>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{DBC645C7-90F6-4E12-9D2A-F5B9CF347789}</SampleGuid>
+ <SampleGuid>{DDD40F41-C9A9-428F-8C00-862850DDBB19}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/iscsi/src/EmptyProject.vcxproj.Filters b/storage/iscsi/src/EmptyProject.vcxproj.Filters
index e26968ac..7d076428 100644
--- a/storage/iscsi/src/EmptyProject.vcxproj.Filters
+++ b/storage/iscsi/src/EmptyProject.vcxproj.Filters
@@ -3,15 +3,15 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{924AB849-60C2-446A-918F-F4F4F8DECE00}</UniqueIdentifier>
+ <UniqueIdentifier>{BE829036-D337-411D-A34F-863A98618FCC}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{67F9C43E-310B-4E5D-9F7E-42661F07ABD0}</UniqueIdentifier>
+ <UniqueIdentifier>{1552D96B-99E9-4C33-AFDC-C6EC4B876958}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{D255EEDA-7C9B-4D68-8180-B81EE573C108}</UniqueIdentifier>
+ <UniqueIdentifier>{D1E77C47-3EE0-4A0C-BCD1-2834CCFEF43C}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/storage/iscsi/src/client/wmisample.c b/storage/iscsi/src/client/wmisample.c
index aff10be5..7ead7fec 100644
--- a/storage/iscsi/src/client/wmisample.c
+++ b/storage/iscsi/src/client/wmisample.c
@@ -4117,8 +4117,8 @@ Routine Description:
adapterExtension->InitiatorSecretLen = 0;
- if (InBufferSize >= FIELD_OFFSET(SetCHAPSharedSecret_IN,
- SharedSecret)) {
+ if (InBufferSize >= (ULONG)FIELD_OFFSET(SetCHAPSharedSecret_IN,
+ SharedSecret)) {
setCHAPSecretIn = (PSetCHAPSharedSecret_IN) Buffer;
@@ -4187,8 +4187,8 @@ Routine Description:
adapterExtension->RadiusSecretLen = 0;
- if (InBufferSize >= FIELD_OFFSET(SetRADIUSSharedSecret_IN,
- SharedSecret)) {
+ if (InBufferSize >= (ULONG)FIELD_OFFSET(SetRADIUSSharedSecret_IN,
+ SharedSecret)) {
setRADIUSSecretIn = (PSetRADIUSSharedSecret_IN) Buffer;
@@ -4321,7 +4321,7 @@ Routine Description:
updatedCount = count + 1;
size = updatedCount * sizeof(ISCSI_IP_Address);
- adapterExtension->RadiusServerList = ExAllocatePoolWithTag(NonPagedPool,
+ adapterExtension->RadiusServerList = ExAllocatePoolWithTag(NonPagedPoolNx,
size,
'vrSR');
@@ -4446,7 +4446,7 @@ Routine Description:
if (updatedCount > 0) {
- adapterExtension->RadiusServerList = ExAllocatePoolWithTag(NonPagedPool,
+ adapterExtension->RadiusServerList = ExAllocatePoolWithTag(NonPagedPoolNx,
size,
'vrSR');
@@ -6300,7 +6300,7 @@ iSpSetLoadBalancePolicy(
//
if (!overFlow) {
- LBPolicy = iSpAllocatePool(NonPagedPool,
+ LBPolicy = iSpAllocatePool(NonPagedPoolNx,
sizeNeeded,
ISCSI_TAG_LB_POLICY);
if (LBPolicy != NULL) {
diff --git a/storage/iscsi/src/iscsihba.mof b/storage/iscsi/src/iscsihba.mof
index 35307c75..d0b57d70 100644
--- a/storage/iscsi/src/iscsihba.mof
+++ b/storage/iscsi/src/iscsihba.mof
@@ -377,6 +377,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -4173,6 +4183,16 @@ class ISCSI_TargetMapping
+
+
+
+
+
+
+
+
+
+
@@ -8419,6 +8439,16 @@ class MSiSCSI_RADIUSConfig
+
+
+
+
+
+
+
+
+
+
diff --git a/storage/miniports/lsi_u3/lsi_u3.sln b/storage/miniports/lsi_u3/lsi_u3.sln
index 4a7f30f9..94476382 100644
--- a/storage/miniports/lsi_u3/lsi_u3.sln
+++ b/storage/miniports/lsi_u3/lsi_u3.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lsi_u3", "src\lsi_u3.vcxproj", "{87B36607-F24D-435F-9BFB-7A6A34281099}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lsi_u3", "src\lsi_u3.vcxproj", "{75BE5762-0334-4CA9-9018-831B9DFFCB0A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {87B36607-F24D-435F-9BFB-7A6A34281099}.Debug|Win32.ActiveCfg = Debug|Win32
- {87B36607-F24D-435F-9BFB-7A6A34281099}.Debug|Win32.Build.0 = Debug|Win32
- {87B36607-F24D-435F-9BFB-7A6A34281099}.Release|Win32.ActiveCfg = Release|Win32
- {87B36607-F24D-435F-9BFB-7A6A34281099}.Release|Win32.Build.0 = Release|Win32
- {87B36607-F24D-435F-9BFB-7A6A34281099}.Debug|x64.ActiveCfg = Debug|x64
- {87B36607-F24D-435F-9BFB-7A6A34281099}.Debug|x64.Build.0 = Debug|x64
- {87B36607-F24D-435F-9BFB-7A6A34281099}.Release|x64.ActiveCfg = Release|x64
- {87B36607-F24D-435F-9BFB-7A6A34281099}.Release|x64.Build.0 = Release|x64
+ {75BE5762-0334-4CA9-9018-831B9DFFCB0A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {75BE5762-0334-4CA9-9018-831B9DFFCB0A}.Debug|Win32.Build.0 = Debug|Win32
+ {75BE5762-0334-4CA9-9018-831B9DFFCB0A}.Release|Win32.ActiveCfg = Release|Win32
+ {75BE5762-0334-4CA9-9018-831B9DFFCB0A}.Release|Win32.Build.0 = Release|Win32
+ {75BE5762-0334-4CA9-9018-831B9DFFCB0A}.Debug|x64.ActiveCfg = Debug|x64
+ {75BE5762-0334-4CA9-9018-831B9DFFCB0A}.Debug|x64.Build.0 = Debug|x64
+ {75BE5762-0334-4CA9-9018-831B9DFFCB0A}.Release|x64.ActiveCfg = Release|x64
+ {75BE5762-0334-4CA9-9018-831B9DFFCB0A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/miniports/lsi_u3/src/lsi_u3.vcxproj b/storage/miniports/lsi_u3/src/lsi_u3.vcxproj
index 60efb225..f9a2aff6 100644
--- a/storage/miniports/lsi_u3/src/lsi_u3.vcxproj
+++ b/storage/miniports/lsi_u3/src/lsi_u3.vcxproj
@@ -19,11 +19,11 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{87B36607-F24D-435F-9BFB-7A6A34281099}</ProjectGuid>
+ <ProjectGuid>{75BE5762-0334-4CA9-9018-831B9DFFCB0A}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{CC0A1E13-737D-44AB-AEA7-090A615626CD}</SampleGuid>
+ <SampleGuid>{A109C08F-5073-4F9A-9971-1DE62D52E8C7}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/miniports/lsi_u3/src/lsi_u3.vcxproj.Filters b/storage/miniports/lsi_u3/src/lsi_u3.vcxproj.Filters
index caefea6e..066d765f 100644
--- a/storage/miniports/lsi_u3/src/lsi_u3.vcxproj.Filters
+++ b/storage/miniports/lsi_u3/src/lsi_u3.vcxproj.Filters
@@ -3,19 +3,19 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{09EE6680-A14D-44ED-821E-84C9D83F8B90}</UniqueIdentifier>
+ <UniqueIdentifier>{8FC57EF8-4B37-4FFB-BB81-DEC7E9EA83A7}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{D43CC645-EED6-45A1-A624-6B263A67507F}</UniqueIdentifier>
+ <UniqueIdentifier>{019C8D2C-9EC3-4F20-994E-CBC0421B6BC2}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{63C10C98-8018-475C-9CA4-ABE5369AAECC}</UniqueIdentifier>
+ <UniqueIdentifier>{07BCA435-374B-4D03-8777-720EDC43FC4D}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{8C8BEEAF-38C4-4D3F-AC07-C116824B0A79}</UniqueIdentifier>
+ <UniqueIdentifier>{7C96440B-3FD6-4AEE-A117-AEF668C021FF}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
diff --git a/storage/miniports/storahci/src/common.c b/storage/miniports/storahci/src/common.c
index c37803bd..2c1dd991 100644
--- a/storage/miniports/storahci/src/common.c
+++ b/storage/miniports/storahci/src/common.c
@@ -85,6 +85,12 @@ QueryPhysicalTopologyIoctlProcess(
_In_ PSTORAGE_REQUEST_BLOCK Srb
);
+VOID
+AtaAlwaysSuccessRequestCompletion (
+ _In_ PAHCI_CHANNEL_EXTENSION ChannelExtension,
+ _In_ PSTORAGE_REQUEST_BLOCK Srb
+ );
+
ULONG
SCSItoATA(
_In_ PAHCI_CHANNEL_EXTENSION ChannelExtension,
@@ -740,6 +746,7 @@ SrbConvertToATACommand(
status = AtaWriteBufferRequest(ChannelExtension, Srb, Cdb);
break;
+
default:
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
@@ -1503,9 +1510,6 @@ AtaModeSenseRequest (
return STOR_STATUS_INSUFFICIENT_RESOURCES;
}
- // initialize to success
- Srb->SrbStatus = SRB_STATUS_SUCCESS;
-
// this initializes the wrapper structure and sets the ModeDataLength
// field
status = AtaInitModePageHeaderWrapper(Cdb, modePageHeader, srbDataBufferLength, &modePageHeaderWrapper);
@@ -1552,7 +1556,7 @@ AtaModeSenseRequest (
SetCommandReg((&srbExtension->TaskFile.Current), IDE_COMMAND_IDENTIFY);
return STOR_STATUS_SUCCESS; //Get Media Protect Status will be preformed in AtaModeSenseRequestCompletionWriteCache.
- }
+ }
} else {
Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
}
@@ -1568,6 +1572,9 @@ AtaModeSenseRequest (
srbExtension->CompletionRoutine = AtaModeSenseRequestCompletionMediaStatus;
SetCommandReg((&srbExtension->TaskFile.Current), IDE_COMMAND_GET_MEDIA_STATUS);
+ } else {
+ // Return header information if there is no other information to retrieve.
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
}
return STOR_STATUS_SUCCESS;
@@ -2454,8 +2461,25 @@ AtaStartStopUnitRequest (
SetCommandReg((&srbExtension->TaskFile.Current), IDE_COMMAND_STANDBY_IMMEDIATE);
}
} else {
- //no action required for AHCI
- Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ //
+ // If 48Bit LBA supported and its not SSD, spin up the device right away using
+ // mechanism suggested by SCSI to ATA translation specification (SAT-4 Rev 2 Table 73)
+ // Ignore if this is an eHDD (1667 supported) as immediate spin up may not be needed
+ //
+ if (Support48Bit(&ChannelExtension->DeviceExtension->DeviceParameters) &&
+ (!DeviceIncursNoSeekPenalty(ChannelExtension)) &&
+ (ChannelExtension->DeviceExtension->IdentifyDeviceData->AdditionalSupported.IEEE1667 == 0)) {
+ srbExtension->AtaFunction = ATA_FUNCTION_ATA_COMMAND;
+ srbExtension->CompletionRoutine = AtaAlwaysSuccessRequestCompletion;
+
+ SetSectorCount((&srbExtension->TaskFile.Current), 1);
+ SetDeviceReg((&srbExtension->TaskFile.Current), IDE_LBA_MODE);
+ SetCommandReg((&srbExtension->TaskFile.Current), IDE_COMMAND_VERIFY_EXT);
+ } else {
+ //no action needed
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ }
+
}
return STOR_STATUS_SUCCESS;
@@ -3268,6 +3292,7 @@ AtaWriteBufferRequest (
return STOR_STATUS_SUCCESS;
}
+
UCHAR
AtaMapError(
_In_ PAHCI_CHANNEL_EXTENSION ChannelExtension,
@@ -4258,6 +4283,7 @@ SmartIdentifyData(
if ( srbDataBufferLength >= sizeof(SRB_IO_CONTROL) + RTL_SIZEOF_THROUGH_FIELD(SENDCMDOUTPARAMS, DriverStatus) ) {
outParams->DriverStatus.bDriverError = SMART_INVALID_BUFFER;
outParams->DriverStatus.bIDEError = 0;
+ outParams->cBufferSize = 0;
}
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
return STOR_STATUS_BUFFER_TOO_SMALL;
@@ -4268,6 +4294,7 @@ SmartIdentifyData(
NT_ASSERT(FALSE);
outParams->DriverStatus.bDriverError = SMART_INVALID_DRIVE;
outParams->DriverStatus.bIDEError = 0;
+ outParams->cBufferSize = 0;
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
return STOR_STATUS_INVALID_DEVICE_REQUEST;
}
@@ -4329,6 +4356,7 @@ SmartGeneric(
if (srbDataBufferLength >= (sizeof(SRB_IO_CONTROL) + RTL_SIZEOF_THROUGH_FIELD(SENDCMDOUTPARAMS, DriverStatus))) {
outParams->DriverStatus.bDriverError = SMART_INVALID_BUFFER;
outParams->DriverStatus.bIDEError = 0;
+ outParams->cBufferSize = 0;
}
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
@@ -4383,6 +4411,7 @@ SmartGeneric(
if (srbDataBufferLength >= (sizeof(SRB_IO_CONTROL) + RTL_SIZEOF_THROUGH_FIELD(SENDCMDOUTPARAMS, DriverStatus))) {
outParams->DriverStatus.bDriverError = SMART_INVALID_BUFFER;
outParams->DriverStatus.bIDEError = 0;
+ outParams->cBufferSize = 0;
}
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
return STOR_STATUS_BUFFER_TOO_SMALL;
@@ -4442,7 +4471,7 @@ SmartGeneric(
srbExtension->TaskFile.Current.bDriveHeadReg = 0xA0 | (inParams->irDriveRegs.bDriveHeadReg & 0x0F);
srbExtension->TaskFile.Current.bCommandReg = inParams->irDriveRegs.bCommandReg;
- Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ Srb->SrbStatus = SRB_STATUS_PENDING;
return STOR_STATUS_SUCCESS;
}
@@ -4604,7 +4633,7 @@ NVCacheGeneric(
srbExtension->TaskFile.Current.bDriveHeadReg = 0xA0;
srbExtension->TaskFile.Current.bCommandReg = NVC_ATA_NV_CACHE_COMMAND;
- Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ Srb->SrbStatus = SRB_STATUS_PENDING;
return STOR_STATUS_SUCCESS;
}
@@ -6942,7 +6971,7 @@ IssueSmartReadLogCommand(
_In_ UCHAR LogAddress,
_In_ USHORT PageNumber,
_In_ USHORT BlockCount,
- _In_ PSTOR_PHYSICAL_ADDRESS PhysicalAddress,
+ _In_opt_ PSTOR_PHYSICAL_ADDRESS PhysicalAddress,
_In_ PVOID DataBuffer,
_In_opt_ PSRB_COMPLETION_ROUTINE CompletionRoutine
)
@@ -7852,10 +7881,9 @@ Return Value:
deviceData = (PSTORAGE_PHYSICAL_DEVICE_DATA)(adapterData + 1);
if (!queryAdapterTopology) {
- UCHAR lun = 0;
- SrbGetPathTargetLun(Srb, NULL, NULL, &lun);
+ UCHAR pathId = SrbGetPathId(Srb);
- GetDevicePhysicalTopologyData(AdapterExtension->PortExtension[lun], deviceData);
+ GetDevicePhysicalTopologyData(AdapterExtension->PortExtension[pathId], deviceData);
} else {
ULONG availableBufferLength = topologyBufferLength - FIELD_OFFSET(STORAGE_PHYSICAL_TOPOLOGY_DESCRIPTOR, Node) -
sizeof(STORAGE_PHYSICAL_NODE_DATA) - sizeof(STORAGE_PHYSICAL_ADAPTER_DATA);
diff --git a/storage/miniports/storahci/src/common.h b/storage/miniports/storahci/src/common.h
index ef57a240..3b066131 100644
--- a/storage/miniports/storahci/src/common.h
+++ b/storage/miniports/storahci/src/common.h
@@ -84,6 +84,7 @@ Revision History:
#define ATA_FLAGS_ACTIVE_REFERENCE (1 << 10) // indicates Active Reference needs to be acquired before processing the Srb and released after processing the Srb
#define ATA_FLAGS_SENSEDATA_SET (1 << 11) // indicates sense data has been set to the Srb
+
//
// helper macros
//
@@ -861,6 +862,7 @@ AtaReportLunsCommand(
_In_ PVOID Context
);
+
UCHAR
AtaMapError(
_In_ PAHCI_CHANNEL_EXTENSION ChannelExtension,
diff --git a/storage/miniports/storahci/src/entrypts.c b/storage/miniports/storahci/src/entrypts.c
index 4a950473..e9c070c8 100644
--- a/storage/miniports/storahci/src/entrypts.c
+++ b/storage/miniports/storahci/src/entrypts.c
@@ -791,7 +791,7 @@ AhciHwInitialize (
//
perfConfigData.Version = STOR_PERF_VERSION;
perfConfigData.Size = sizeof(PERF_CONFIGURATION_DATA);
-
+
status = StorPortInitializePerfOpts(AdapterExtension, TRUE, &perfConfigData);
//
@@ -829,19 +829,20 @@ AhciHwInitialize (
perfConfigData.MessageTargets = adapterExtension->MessageGroupAffinity;
}
- //
- // Support concurrent channel so that ports can have StartIo routine running concurrently.
- //
- perfConfigData.Flags |= STOR_PERF_CONCURRENT_CHANNELS;
- perfConfigData.ConcurrentChannels = (adapterExtension->PortImplemented + 1);
-
}
+ //
+ // Support concurrent channel so that ports can have StartIo routine running concurrently.
+ //
+ perfConfigData.Flags |= STOR_PERF_CONCURRENT_CHANNELS;
+ perfConfigData.ConcurrentChannels = NumberOfSetBits(adapterExtension->PortImplemented);
+
status = StorPortInitializePerfOpts(AdapterExtension, FALSE, &perfConfigData);
NT_ASSERT(status == STOR_STATUS_SUCCESS);
}
#endif
+
//
// async process to get all ports into running state
//
@@ -1352,7 +1353,7 @@ AhciHwResetBus (
*/
{
BOOLEAN status = FALSE;
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
PAHCI_ADAPTER_EXTENSION adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
if ( IsPortValid(adapterExtension, PathId) ) {
@@ -1374,32 +1375,97 @@ AhciHwBuildIo (
PAHCI_ADAPTER_EXTENSION adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
PAHCI_CHANNEL_EXTENSION channelExtension = NULL;
UCHAR pathId = SrbGetPathId(Srb);
- PVOID srbSenseBuffer = NULL;
- UCHAR srbSenseBufferLength = 0;
+ ULONG function = SrbGetSrbFunction(Srb);
+ ULONG srbFlags = SrbGetSrbFlags(Srb);
+ PAHCI_SRB_EXTENSION srbExtension = GetSrbExtension((PSTORAGE_REQUEST_BLOCK)Srb);
//
// Make sure the incoming Srb with the expected type
//
NT_ASSERT(Srb->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK);
- // SrbExtension is not Null-ed by Storport, so do it here.
- AhciZeroMemory((PCHAR)GetSrbExtension((PSTORAGE_REQUEST_BLOCK)Srb), sizeof(AHCI_SRB_EXTENSION));
-
- RequestGetSrbScsiData((PSTORAGE_REQUEST_BLOCK)Srb, NULL, NULL, &srbSenseBuffer, &srbSenseBufferLength);
+ //
+ // SrbStatus value should have been set to pending.
+ //
+ NT_ASSERT(Srb->SrbStatus == SRB_STATUS_PENDING);
- if ((srbSenseBuffer != NULL) && (srbSenseBufferLength > 0)) {
- AhciZeroMemory((PCHAR)srbSenseBuffer, srbSenseBufferLength);
- }
+ // SrbExtension is not Null-ed by Storport, so do it here.
+ AhciZeroMemory((PCHAR)srbExtension, sizeof(AHCI_SRB_EXTENSION));
channelExtension = adapterExtension->PortExtension[pathId];
if ( IsPortValid(adapterExtension, pathId) &&
- (SrbGetSrbFunction(Srb) == SRB_FUNCTION_EXECUTE_SCSI) &&
+ (function == SRB_FUNCTION_EXECUTE_SCSI) &&
(channelExtension->StateFlags.PowerDown == TRUE)) {
AhciPortPowerUp(channelExtension);
}
- return TRUE;
+ //
+ // Prepare the Device Command before StartIo routine for SRB_FUNCTION_IO_CONTROL and SRB_FUNCTION_EXECUTE_SCSI requests.
+ // This can reduce the lock contention between StartIo and Interrupt locks.
+ //
+ if ((function == SRB_FUNCTION_EXECUTE_SCSI) ||
+ ((function == SRB_FUNCTION_IO_CONTROL) && ((srbFlags & SRB_IOCTL_FLAGS_ADAPTER_REQUEST) == 0))) {
+
+ if ( !IsPortValid(adapterExtension, pathId) ) {
+ Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
+ goto exit;
+ }
+ }
+
+ switch (function) {
+ case SRB_FUNCTION_IO_CONTROL: {
+
+ if ((srbFlags & SRB_IOCTL_FLAGS_ADAPTER_REQUEST) == 0) {
+
+ IOCTLtoATA(adapterExtension->PortExtension[pathId], (PSTORAGE_REQUEST_BLOCK)Srb);
+
+ if (srbExtension->AtaFunction != 0) {
+ if ( ( srbExtension->Sgl == NULL ) && ( IsDataTransferNeeded((PSTORAGE_REQUEST_BLOCK)Srb) ) ) {
+ srbExtension->Sgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(adapterExtension, Srb);
+ }
+ }
+ }
+
+ break;
+ }
+
+ case SRB_FUNCTION_EXECUTE_SCSI: {
+
+ SCSItoATA(adapterExtension->PortExtension[pathId], (PSTORAGE_REQUEST_BLOCK)Srb);
+
+ if (srbExtension->AtaFunction != 0) {
+ if ( ( srbExtension->Sgl == NULL ) && ( IsDataTransferNeeded((PSTORAGE_REQUEST_BLOCK)Srb) ) ) {
+ srbExtension->Sgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(adapterExtension, Srb);
+ }
+ }
+
+ break;
+ }
+
+ default: {
+ //
+ // All other requests will be processed in StartIo routine.
+ //
+ break;
+ }
+ }
+
+exit:
+
+ if (Srb->SrbStatus != SRB_STATUS_PENDING) {
+ //
+ // This routine should return FALSE when SRB is completed.
+ //
+ StorPortNotification(RequestComplete, AdapterExtension, Srb);
+
+ return FALSE;
+ } else {
+ //
+ // This routine should return TRUE when SRB is not completed.
+ //
+ return TRUE;
+ }
}
BOOLEAN
@@ -1415,7 +1481,7 @@ AhciHwStartIo (
*/
{
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
PAHCI_ADAPTER_EXTENSION adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
ULONG function = SrbGetSrbFunction(Srb);
UCHAR pathId = SrbGetPathId(Srb);
@@ -1574,37 +1640,9 @@ AhciHwStartIo (
break;
}
- case SRB_FUNCTION_IO_CONTROL: {
- PAHCI_SRB_EXTENSION srbExtension = GetSrbExtension((PSTORAGE_REQUEST_BLOCK)Srb);
-
- IOCTLtoATA(adapterExtension->PortExtension[pathId], (PSTORAGE_REQUEST_BLOCK)Srb);
- if (srbExtension->AtaFunction != 0) {
- if ( ( srbExtension->Sgl == NULL ) && ( IsDataTransferNeeded((PSTORAGE_REQUEST_BLOCK)Srb) ) ) {
- srbExtension->Sgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(adapterExtension, Srb);
- }
- processIO = TRUE;
- } else {
- // complete Srb if no command should be sent to device.
- NT_ASSERT(Srb->SrbStatus != SRB_STATUS_PENDING);
- StorPortNotification(RequestComplete, AdapterExtension, Srb);
- }
- break;
- }
-
+ case SRB_FUNCTION_IO_CONTROL:
case SRB_FUNCTION_EXECUTE_SCSI: {
- PAHCI_SRB_EXTENSION srbExtension = GetSrbExtension((PSTORAGE_REQUEST_BLOCK)Srb);
-
- SCSItoATA(adapterExtension->PortExtension[pathId], (PSTORAGE_REQUEST_BLOCK)Srb);
- if (srbExtension->AtaFunction != 0) {
- if ( ( srbExtension->Sgl == NULL ) && ( IsDataTransferNeeded((PSTORAGE_REQUEST_BLOCK)Srb) ) ) {
- srbExtension->Sgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(adapterExtension, Srb);
- }
- processIO = TRUE;
- } else {
- // complete Srb if no command should be sent to device.
- NT_ASSERT(Srb->SrbStatus != SRB_STATUS_PENDING);
- StorPortNotification(RequestComplete, AdapterExtension, Srb);
- }
+ processIO = TRUE;
break;
}
@@ -1709,82 +1747,12 @@ AhciHwStartIo (
PortAcquireActiveReference(adapterExtension->PortExtension[pathId], (PSTORAGE_REQUEST_BLOCK)Srb, NULL);
}
- AhciInterruptSpinlockAcquire(adapterExtension, pathId, &lockhandle);
- AddQueue(adapterExtension->PortExtension[pathId], &adapterExtension->PortExtension[pathId]->SrbQueue, (PSTORAGE_REQUEST_BLOCK)Srb, 0xDEADBEEF, 0x11);
- AhciGetNextIos(adapterExtension->PortExtension[pathId], TRUE);
- AhciInterruptSpinlockRelease(adapterExtension, pathId, &lockhandle);
- }
-
- return TRUE;
-}
-
-VOID
-AhciGetNextIos (
- _In_ PAHCI_CHANNEL_EXTENSION ChannelExtension,
- _In_ BOOLEAN AtDIRQL
- )
-/*
- get Srb from queue and program it to adapter.
+ AhciProcessIo(adapterExtension->PortExtension[pathId], (PSTORAGE_REQUEST_BLOCK)Srb, FALSE);
+ ActivateQueue(adapterExtension->PortExtension[pathId], FALSE);
- assumption: internal request doesn't call this routine. Otherwise, the check of available slot should be changed.
-*/
-{
- PSTORAGE_REQUEST_BLOCK Srb;
- BOOLEAN keepFilling;
- ULONG i, commandSlotMask, allocated;
-
- //1.0 Check if command processing should happen. If not, this function will be called again when it is ready.
- if (ChannelExtension->StartState.ChannelNextStartState != StartComplete) {
- //We could be waiting ... but it is possible there is no device. If we know there is no device, then fail all commands.
- if (ChannelExtension->StartState.ChannelNextStartState == StartFailed) {
- // complete all requests still in queue
- AhciPortFailAllIos(ChannelExtension, SRB_STATUS_NO_DEVICE, AtDIRQL);
- }
- return;
- }
-
- if (ChannelExtension->StateFlags.PowerDown == TRUE) {
- //We should wait for device to power up.
- return;
}
- //1.1 Initialize Variables
- commandSlotMask = 0;
-
- //If there is a command in the Srb Queue ...
- if (ChannelExtension->SrbQueue.Head != NULL) {
- keepFilling = TRUE;
- //get a mask of all slots expect slot 0, which is reserved for internal use
- for (i = 1; i <= ChannelExtension->AdapterExtension->CAP.NCS; i++) {
- commandSlotMask |= ( 1 << i );
- }
- } else {
- keepFilling = FALSE;
- }
-
- while (keepFilling) {
- keepFilling = FALSE;
- allocated = GetOccupiedSlots(ChannelExtension);
-
- if ((~allocated & commandSlotMask) != 0) {
- //there is empty slot. get the next IO
- Srb = RemoveQueue(ChannelExtension, &ChannelExtension->SrbQueue, 0xDEADC0DE, 0x1F);
- if (Srb != NULL) {
- NT_ASSERT(SrbGetPathId(Srb) == ChannelExtension->PortNumber);
- keepFilling = TRUE;
-
- // get a Srb, try to find an empty slot, fill command table and command header, put Srb into IO slices.
- AhciProcessIo(ChannelExtension, Srb, AtDIRQL);
-
- } else { //No more SRBs. Finish.
- keepFilling = FALSE;
- }
- }
- }
-
- //Check to see if IO is ready to be programmed to adapter
- ActivateQueue(ChannelExtension, AtDIRQL);
- return;
+ return TRUE;
}
VOID
@@ -1886,9 +1854,13 @@ Return Values:
cmd.AsUlong = 0;
ssts.AsUlong = 0;
pxisMask.AsUlong = serrMask.AsUlong = 0;
+ serr.AsUlong = 0;
pxis.AsUlong = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->IS.AsUlong);
- serr.AsUlong = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SERR.AsUlong);
+
+ if (pxis.IFS || pxis.HBDS || pxis.HBFS || pxis.TFES || pxis.PCS || pxis.PRCS) {
+ serr.AsUlong = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SERR.AsUlong);
+ }
//2.1 Understand interrupts on this channel
//2.1.1 Handle Fatal Errors: Interface Fatal Error Status || Host Bus Data Error Status || Host Bus Fatal Error Status || Task File Error Status
@@ -1924,7 +1896,7 @@ Return Values:
pxisMask.AsUlong = 0;
pxisMask.CPDS = 1;
StorPortWriteRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->IS.AsUlong, pxisMask.AsUlong);
- // Handle bus rescan processing processing
+ // Handle bus rescan processing
ChannelExtension->StateFlags.CallAhciReportBusChange = 1;
}
@@ -1942,7 +1914,7 @@ Return Values:
StorPortWriteRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->IS.AsUlong, pxisMask.AsUlong);
// Mechanical Presence Switch Attached to Port
if (cmd.MPSP) {
- // Handle bus rescan processing processing
+ // Handle bus rescan processing
ChannelExtension->StateFlags.CallAhciReportBusChange = 1;
}
}
@@ -1955,7 +1927,7 @@ Return Values:
StorPortWriteRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SERR.AsUlong, serrMask.AsUlong);
// PCS = 1 could be an unsolicited COMINIT on an already detected drive. See AHCI 6.2.2.3 Recovery of Unsolicited COMINIT
if (!IgnoreHotPlug(ChannelExtension) && (cmd.ST == 0)) {
- // Handle bus rescan processing processing
+ // Handle bus rescan processing
ChannelExtension->StateFlags.CallAhciReportBusChange = 1;
}
}
@@ -1990,6 +1962,9 @@ Return Values:
// This is precautionary as there shall be no IO when D3 occurred, but the miniport may always create its own commands.
ChannelExtension->SlotManager.CommandsToComplete = GetOccupiedSlots(ChannelExtension);
ChannelExtension->SlotManager.CommandsIssued = 0;
+ ChannelExtension->SlotManager.NCQueueSliceIssued = 0;
+ ChannelExtension->SlotManager.NormalQueueSliceIssued = 0;
+ ChannelExtension->SlotManager.SingleIoSliceIssued = 0;
ChannelExtension->SlotManager.NCQueueSlice = 0;
ChannelExtension->SlotManager.NormalQueueSlice = 0;
ChannelExtension->SlotManager.SingleIoSlice = 0;
@@ -2003,7 +1978,7 @@ Return Values:
P_Running_StartAttempt(ChannelExtension, TRUE);
}
} else if ((ssts.DET == 0) && (ssts.IPM == 0)) {
- // Handle bus rescan processing processing
+ // Handle bus rescan processing
ChannelExtension->StateFlags.CallAhciReportBusChange = 1;
}
}
@@ -2044,16 +2019,17 @@ Return Values:
// and this is the only async notification.
// Notification failure of STOR_STATUS_INVALID_DEVICE_REQUEST is ok as Storport may no longer find
// the unit as it may have been surprise removed.
- asyncNotifyFlags = (RAID_ASYNC_NOTIFY_FLAG_MEDIA_STATUS | RAID_ASYNC_NOTIFY_FLAG_DEVICE_STATUS |
- RAID_ASYNC_NOTIFY_FLAG_DEVICE_OPERATION);
+ asyncNotifyFlags = (RAID_ASYNC_NOTIFY_FLAG_MEDIA_STATUS |
+ RAID_ASYNC_NOTIFY_FLAG_DEVICE_STATUS |
+ RAID_ASYNC_NOTIFY_FLAG_DEVICE_OPERATION);
storStatus = StorPortAsyncNotificationDetected(ChannelExtension->AdapterExtension,
(PSTOR_ADDRESS)&ChannelExtension->DeviceExtension[0].DeviceAddress,
asyncNotifyFlags);
NT_ASSERT((storStatus == STOR_STATUS_SUCCESS) ||
- (storStatus == STOR_STATUS_BUSY) ||
- (storStatus == STOR_STATUS_INVALID_DEVICE_REQUEST));
+ (storStatus == STOR_STATUS_BUSY) ||
+ (storStatus == STOR_STATUS_INVALID_DEVICE_REQUEST));
// not actually use this variable.
UNREFERENCED_PARAMETER(storStatus);
@@ -2085,25 +2061,28 @@ Return Values:
StorPortWriteRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->IS.AsUlong, pxisMask.AsUlong);
}
- // preserve taskfile for using in command completion process
- ChannelExtension->TaskFileData.AsUlong = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->TFD.AsUlong);
+ //3. error process
+ if (ErrorRecoveryIsPending(ChannelExtension)) {
+ // preserve taskfile for using in command completion process
+ ChannelExtension->TaskFileData.AsUlong = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->TFD.AsUlong);
- if ((ChannelExtension->TaskFileData.AsUlong == MAXULONG) && IsAdapterRemoved(ChannelExtension)) {
- // controller has been surprise removed
- return;
- }
+ if ((ChannelExtension->TaskFileData.AsUlong == MAXULONG) && IsAdapterRemoved(ChannelExtension)) {
+ // controller has been surprise removed
+ return;
+ }
- //2.4 error process
- if (ErrorRecoveryIsPending(ChannelExtension)) {
AhciPortErrorRecovery(ChannelExtension);
}
+ else {
+ ChannelExtension->TaskFileData.AsUlong = 0x40;
+ }
- //3. Clear channel interrupt
+ //4. Clear channel interrupt
is = 0;
is |= (1 << ChannelExtension->PortNumber);
StorPortWriteRegisterUlong(ChannelExtension->AdapterExtension, ChannelExtension->AdapterExtension->IS, is);
- //4. Complete outstanding commands
+ //5. Complete outstanding commands
ci = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->CI);
sact = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->SACT);
@@ -2119,6 +2098,10 @@ Return Values:
ChannelExtension->SlotManager.CommandsToComplete |= (ChannelExtension->SlotManager.CommandsIssued & ~outstanding);
ChannelExtension->SlotManager.CommandsIssued &= outstanding;
+ ChannelExtension->SlotManager.NCQueueSliceIssued &= outstanding;
+ ChannelExtension->SlotManager.NormalQueueSliceIssued &= outstanding;
+ ChannelExtension->SlotManager.SingleIoSliceIssued &= outstanding;
+
// recording execution history for completing SRB
RecordInterruptHistory(ChannelExtension, pxis.AsUlong, ssts.AsUlong, serr.AsUlong, ci, sact, 0x20000005); //AhciHwInterrupt complete IO
@@ -2129,17 +2112,14 @@ Return Values:
}
//6.1 Partial to Slumber auto transit
- cmd.AsUlong = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->CMD.AsUlong);
+ if ((outstanding == 0) &&
+ PartialToSlumberTransitionIsAllowed(ChannelExtension, &cmd)) {
- if ((cmd.AsUlong == MAXULONG) && IsAdapterRemoved(ChannelExtension)) {
- // controller has been surprise removed
- return;
- }
-
- if (PartialToSlumberTransitionIsAllowed(ChannelExtension, cmd, ci, sact)) {
ULONG status;
+
// convert interval value from ms to us. allow 20ms of coalescing with other timers
status = StorPortRequestTimer(ChannelExtension->AdapterExtension, ChannelExtension->WorkerTimer, AhciAutoPartialToSlumber, ChannelExtension, ChannelExtension->AutoPartialToSlumberInterval * 1000, 20000);
+
if (status == STOR_STATUS_SUCCESS) {
StorPortDebugPrint(3, "StorAHCI - LPM: Port %02d - Transit into Slumber from Partial - Scheduled \n", ChannelExtension->PortNumber);
}
@@ -2182,6 +2162,7 @@ Return Values:
ULONG is;
ULONG interruptPorts;
ULONG i;
+ UCHAR interruptPortCount;
PAHCI_ADAPTER_EXTENSION adapterExtension = (PAHCI_ADAPTER_EXTENSION)AdapterExtension;
@@ -2200,11 +2181,17 @@ Return Values:
return FALSE;
}
+ interruptPortCount = NumberOfSetBits(interruptPorts);
+
//
// In case of multi-ports have interrupt pending, using round robin to choose a port handle its interrupt.
// After this routine exits, other pending interrupts will trigger interrupt again.
//
- i = (adapterExtension->LastInterruptedPort + 1) % (adapterExtension->HighestPort + 1);
+ if (interruptPortCount > 1) {
+ i = (adapterExtension->LastInterruptedPort + 1) % (adapterExtension->HighestPort + 1);
+ } else {
+ i = adapterExtension->LastInterruptedPort;
+ }
do {
if ( ((interruptPorts & (1 << i)) != 0) && IsPortStartCapable(adapterExtension->PortExtension[i]) ) {
@@ -2595,7 +2582,7 @@ Return Value:
//
case ScsiUnitSurpriseRemoval: {
PSTOR_ADDR_BTL8 storAddrBtl8 = (PSTOR_ADDR_BTL8)Parameters;
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
if (IsPortValid(adapterExtension, storAddrBtl8->Path)) {
@@ -2607,6 +2594,9 @@ Return Value:
//
channelExtension->SlotManager.CommandsToComplete = channelExtension->SlotManager.CommandsIssued;
channelExtension->SlotManager.CommandsIssued = 0;
+ channelExtension->SlotManager.NCQueueSliceIssued = 0;
+ channelExtension->SlotManager.NormalQueueSliceIssued = 0;
+ channelExtension->SlotManager.SingleIoSliceIssued = 0;
channelExtension->SlotManager.HighPriorityAttribute &= ~channelExtension->SlotManager.CommandsToComplete;
AhciCompleteIssuedSRBs(channelExtension, SRB_STATUS_NO_DEVICE, TRUE);
diff --git a/storage/miniports/storahci/src/entrypts.h b/storage/miniports/storahci/src/entrypts.h
index fbf2cb5b..56adcb0e 100644
--- a/storage/miniports/storahci/src/entrypts.h
+++ b/storage/miniports/storahci/src/entrypts.h
@@ -267,6 +267,18 @@ typedef struct _SLOT_MANAGER {
ULONG CommandsIssued;
ULONG CommandsToComplete;
+
+ //
+ // These issued slices are used to determine the type of command
+ // being programmed to adapter.
+ // They are used instead of reading PxCI and PxSACT.
+ //
+ ULONG NCQueueSliceIssued;
+ ULONG NormalQueueSliceIssued;
+ ULONG SingleIoSliceIssued;
+
+ ULONG Reserved;
+
} SLOT_MANAGER, *PSLOT_MANAGER;
typedef struct _EXECUTION_HISTORY {
@@ -457,9 +469,6 @@ typedef struct _AHCI_CHANNEL_EXTENSION {
SLOT_MANAGER SlotManager;
SLOT_CONTENT Slot[AHCI_MAX_NCQ_REQUEST_COUNT];
-//Port IO Queue
- STORAHCI_QUEUE SrbQueue;
-
//IO Completion Queue and DPC
STORAHCI_QUEUE CompletionQueue;
STOR_DPC CompletionDpc;
@@ -647,12 +656,6 @@ AhciHwMSIInterrupt (
);
VOID
-AhciGetNextIos (
- _In_ PAHCI_CHANNEL_EXTENSION ChannelExtension,
- _In_ BOOLEAN AtDIRQL
- );
-
-VOID
AhciDeviceStart (
_In_ PAHCI_CHANNEL_EXTENSION ChannelExtension
);
diff --git a/storage/miniports/storahci/src/hbastat.c b/storage/miniports/storahci/src/hbastat.c
index b7c205bd..fc518675 100644
--- a/storage/miniports/storahci/src/hbastat.c
+++ b/storage/miniports/storahci/src/hbastat.c
@@ -452,11 +452,12 @@ RunNextPort(
// run next port or declare the ports running process completed.
if (nextPortExtension != NULL) {
- if (nextPortExtension->StartState.ChannelNextStartState == 0) {
+ if ((nextPortExtension->StartState.ChannelNextStartState == 0) ||
+ (nextPortExtension->StartState.ChannelNextStartState == Stopped)) {
P_Running_StartAttempt(nextPortExtension, AtDIRQL);
} else {
// return, do nothing here as the Port Start effort has been made.
- // RunNextPort() is only used in AhciAdapterRunAllPorts() which is one time operation from AhciHwFindAdapter.
+ // RunNextPort() is only used in AhciAdapterRunAllPorts() which is called by AhciHwFindAdapter.
// In other cases, P_Running_StartAttempt() will be called directly for each port.
return;
}
@@ -486,7 +487,7 @@ Affected Variables/Registers:
none
*/
{
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
if (!AtDIRQL) {
AhciInterruptSpinlockAcquire(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
@@ -537,7 +538,7 @@ P_Running_Callback(
// only clear the bit if this is the first timer callback in Port Start process
if (callbackIndex == 1) {
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
AhciInterruptSpinlockAcquire(AdapterExtension, channelExtension->PortNumber, &lockhandle);
@@ -1108,7 +1109,7 @@ WaitOnBSYDRQ_Start:
}
//3.1 Set ST to 1
if ( ( tfd.STS.BSY == 0) && ( tfd.STS.DRQ == 0) ) {
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
BOOLEAN needSpinLock;
if ( TimerCallbackProcess && (ChannelExtension->StartState.DirectStartInProcess == 1) ) {
@@ -1138,7 +1139,7 @@ WaitOnBSYDRQ_Start:
StorPortDebugPrint(3, "StorAHCI - LPM: Port %02d - Port Started\n", ChannelExtension->PortNumber);
//Start requests on this Port
- AhciGetNextIos(ChannelExtension, TRUE);
+ ActivateQueue(ChannelExtension, TRUE);
ChannelExtension->StartState.DirectStartInProcess = 0;
@@ -1243,7 +1244,7 @@ Affected Variables/Registers:
none
*/
{
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
BOOLEAN needSpinLock;
if ( TimerCallbackProcess && (ChannelExtension->StartState.DirectStartInProcess == 1) ) {
@@ -1283,6 +1284,9 @@ Affected Variables/Registers:
//1.2 clear out the programmed slots
ChannelExtension->SlotManager.CommandsToComplete = GetOccupiedSlots(ChannelExtension);
ChannelExtension->SlotManager.CommandsIssued = 0;
+ ChannelExtension->SlotManager.NCQueueSliceIssued = 0;
+ ChannelExtension->SlotManager.NormalQueueSliceIssued = 0;
+ ChannelExtension->SlotManager.SingleIoSliceIssued = 0;
ChannelExtension->SlotManager.NCQueueSlice = 0;
ChannelExtension->SlotManager.NormalQueueSlice = 0;
ChannelExtension->SlotManager.SingleIoSlice = 0;
@@ -1292,7 +1296,7 @@ Affected Variables/Registers:
PortClearPendingInterrupt(ChannelExtension);
Set_PxIE(ChannelExtension, &ChannelExtension->Px->IE);
- //2.1 Call AhciGetNextIos to complete all outstanding commands now that ChannelNextStartState is StartFailed
+ //2.1 Call AhciPortFailAllIos to complete all outstanding commands now that ChannelNextStartState is StartFailed
AhciPortFailAllIos(ChannelExtension, SRB_STATUS_NO_DEVICE, TRUE);
ChannelExtension->StartState.DirectStartInProcess = 0;
@@ -1435,6 +1439,9 @@ Affected Variables/Registers:
ci &= ~(1 << failingCommand);
// Move the errant command from Issued list to the 'to complete' list
ChannelExtension->SlotManager.CommandsIssued &= ~(1 << failingCommand);
+ ChannelExtension->SlotManager.NCQueueSliceIssued &= ~(1 << failingCommand);
+ ChannelExtension->SlotManager.NormalQueueSliceIssued &= ~(1 << failingCommand);
+ ChannelExtension->SlotManager.SingleIoSliceIssued &= ~(1 << failingCommand);
ChannelExtension->SlotManager.HighPriorityAttribute &= ~(1 << failingCommand);
ChannelExtension->SlotManager.CommandsToComplete |= (1 << failingCommand);
@@ -1480,6 +1487,9 @@ Affected Variables/Registers:
//2.2 Restore the unsent programmed commands for careful reprocessing
ChannelExtension->SlotManager.NormalQueueSlice |= ci; //put the commands that didn't get a chance to finish back into the normal queue
ChannelExtension->SlotManager.CommandsIssued &= ~ci; //Remove the unfinished commands from the 'issued' list
+ ChannelExtension->SlotManager.NCQueueSliceIssued &= ~ci;
+ ChannelExtension->SlotManager.NormalQueueSliceIssued &= ~ci;
+ ChannelExtension->SlotManager.SingleIoSliceIssued &= ~ci;
//2.3 If there were commands that are ready to complete, complete them
if (ChannelExtension->SlotManager.CommandsToComplete) {
@@ -1517,8 +1527,8 @@ NcqErrorRecoveryCompletion (
*/
{
PAHCI_SRB_EXTENSION srbExtension = GetSrbExtension(Srb);
- ULONG issuedCommands = (ULONG)srbExtension->CompletionContext;
- STOR_LOCK_HANDLE lockhandle = { 0 };
+ ULONG issuedCommands = (ULONG)(ULONG_PTR)srbExtension->CompletionContext;
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
BOOLEAN fallBacktoReset = FALSE;
RecordExecutionHistory(ChannelExtension, 0x0000001b); //Enter NcqErrorRecoveryCompletion
@@ -1633,6 +1643,15 @@ NcqErrorRecoveryCompletion (
RecordExecutionHistory(ChannelExtension, 0x1002001b); //NcqErrorRecoveryCompletion, NCQ Tag doesn't belong to issued commands.
}
+ } else if ((Srb->SrbStatus == SRB_STATUS_BUSY) &&
+ (srbExtension->QueueTag == 0xFF)) {
+ //
+ // Read NCQ Error Log cannot be issued, as all slots are occupied.
+ //
+ fallBacktoReset = TRUE;
+
+ RecordExecutionHistory(ChannelExtension, 0x1004001b); //NcqErrorRecoveryCompletion, Read NCQ Error Log cannot be issued, as all slots are occupied..
+
} else {
//
// Read NCQ Error Log failed. Completes all NCQ commands back to upper layer.
@@ -1654,6 +1673,7 @@ NcqErrorRecoveryCompletion (
//
ChannelExtension->SlotManager.NCQueueSlice &= ~issuedCommands;
ChannelExtension->SlotManager.CommandsIssued |= issuedCommands;
+ ChannelExtension->SlotManager.NCQueueSliceIssued |= issuedCommands;
AhciPortReset(ChannelExtension, FALSE);
AhciInterruptSpinlockRelease(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
@@ -1753,7 +1773,7 @@ Called by:
//
// COMRESET is issued, bail out the function.
//
- RecordExecutionHistory(ChannelExtension, 0x10160014); //AhciNcqErrorRecovery, RESET is bing issued.
+ RecordExecutionHistory(ChannelExtension, 0x10160014); //AhciNcqErrorRecovery, RESET is being issued.
AhciPortReset(ChannelExtension, FALSE);
return;
}
@@ -1766,7 +1786,7 @@ Called by:
//
// COMRESET is issued, bail out the function.
//
- RecordExecutionHistory(ChannelExtension, 0x10170014); //AhciNcqErrorRecovery, RESET is bing issued because Local Srb is in use.
+ RecordExecutionHistory(ChannelExtension, 0x10170014); //AhciNcqErrorRecovery, RESET is being issued because slot 0 is in use.
AhciPortReset(ChannelExtension, FALSE);
return;
}
@@ -1775,7 +1795,22 @@ Called by:
ChannelExtension->PortNumber, ChannelExtension->SlotManager.CommandsIssued);
//
+ // Only one NCQ Error Recovery should be happening at a time.
+ // If we get another error before we finished processing the previous one
+ // then this is likely a device issue so do reset.
+ //
+ NT_ASSERT(ChannelExtension->StateFlags.NcqErrorRecoveryInProcess == 0);
+ if (ChannelExtension->StateFlags.NcqErrorRecoveryInProcess) {
+ RecordExecutionHistory(ChannelExtension, 0x10170015); //AhciNcqErrorRecovery, RESET is being issued because NCQ error recovery is already in progress.
+ AhciPortReset(ChannelExtension, FALSE);
+ return;
+ }
+
+ //
// Set the state flag indicating it's in NCQ Error Recovery process.
+ // This doesn't get cleared until NcqErrorRecoverCompletion is called,
+ // which happens after the local Sense.Srb is removed from the completion
+ // queue. (It also gets cleared on a port reset.)
//
ChannelExtension->StateFlags.NcqErrorRecoveryInProcess = 1;
@@ -1805,6 +1840,7 @@ Called by:
//
ChannelExtension->SlotManager.NCQueueSlice |= ChannelExtension->SlotManager.CommandsIssued;
ChannelExtension->SlotManager.CommandsIssued = 0;
+ ChannelExtension->SlotManager.NCQueueSliceIssued = 0;
IssueReadLogExtCommand( ChannelExtension,
(PSTORAGE_REQUEST_BLOCK)&ChannelExtension->Sense.Srb,
@@ -1964,25 +2000,31 @@ Return Values:
//3.1 Complete all issued commands
ChannelExtension->SlotManager.CommandsToComplete = ChannelExtension->SlotManager.CommandsIssued;
ChannelExtension->SlotManager.CommandsIssued = 0;
+ ChannelExtension->SlotManager.NCQueueSliceIssued = 0;
+ ChannelExtension->SlotManager.NormalQueueSliceIssued = 0;
+ ChannelExtension->SlotManager.SingleIoSliceIssued = 0;
ChannelExtension->SlotManager.HighPriorityAttribute &= ~ChannelExtension->SlotManager.CommandsToComplete;
commandsToCompleteCount = NumberOfSetBits(ChannelExtension->SlotManager.CommandsToComplete);
if (commandsToCompleteCount > 0) {
- UCHAR completeStatus;
+ UCHAR completeStatus = SRB_STATUS_BUS_RESET;
- //
- // Slot 0 is reserved for miniport internal request.
- // It's preferred to return SRB_STATUS_BUS_RESET to internal request to make it aware of reset happened.
- //
- if ((commandsToCompleteCount == 1) && ((ChannelExtension->SlotManager.CommandsToComplete & 0x00000001) == 0)) {
- // we know the error is for this command as it's the only one programmed to adapter,
- // set status to be SRB_STATUS_ERROR to make sure the function - AtaMapError() assigns the real error to Srb
- completeStatus = SRB_STATUS_ERROR;
- } else {
- // more than one command were programmed, we don't know which one triggered the error.
- // set status to be SRB_STATUS_BUS_RESET to reflect the action StorAHCI is doing.
- completeStatus = SRB_STATUS_BUS_RESET;
+ if (commandsToCompleteCount == 1) {
+ ULONG i;
+
+ for (i = 0; i <= ChannelExtension->AdapterExtension->CAP.NCS; i++) {
+ if (((ChannelExtension->SlotManager.CommandsToComplete & (1 << i)) != 0) &&
+ (ChannelExtension->Slot[i].Srb != NULL) &&
+ (!IsMiniportInternalSrb(ChannelExtension, ChannelExtension->Slot[i].Srb))) {
+ //
+ // we know the error is for this command as it's the only one programmed to adapter,
+ // set status to be SRB_STATUS_ERROR for external Srb to make sure the function - AtaMapError() assigns the real error to Srb
+ // It's preferred to return SRB_STATUS_BUS_RESET to internal request to make it aware of reset happened.
+ //
+ completeStatus = SRB_STATUS_ERROR;
+ }
+ }
}
AhciCompleteIssuedSRBs(ChannelExtension, completeStatus, TRUE); //AhciPortReset is under Interrupt spinlock
diff --git a/storage/miniports/storahci/src/inbox/storahci.vcxproj b/storage/miniports/storahci/src/inbox/storahci.vcxproj
index 814b30bb..7e694879 100644
--- a/storage/miniports/storahci/src/inbox/storahci.vcxproj
+++ b/storage/miniports/storahci/src/inbox/storahci.vcxproj
@@ -19,12 +19,12 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}</ProjectGuid>
+ <ProjectGuid>{1452B3C2-50A6-4F07-BF00-413B7A51E3A4}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<SupportsPackaging>false</SupportsPackaging>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{B2834C28-91D9-4DD3-834C-5B0E01FE209E}</SampleGuid>
+ <SampleGuid>{4DCDD06A-EB9F-4DF7-B94F-404879FE230C}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/miniports/storahci/src/inbox/storahci.vcxproj.Filters b/storage/miniports/storahci/src/inbox/storahci.vcxproj.Filters
index 28955cf7..fae19bee 100644
--- a/storage/miniports/storahci/src/inbox/storahci.vcxproj.Filters
+++ b/storage/miniports/storahci/src/inbox/storahci.vcxproj.Filters
@@ -3,19 +3,19 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{34CAC986-8E31-4820-81B7-24D604716F2F}</UniqueIdentifier>
+ <UniqueIdentifier>{387A6887-A65F-4D9D-80DC-9996A3D3A11D}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{731AD279-B426-4E8B-92A3-B85F17830429}</UniqueIdentifier>
+ <UniqueIdentifier>{9F0A2448-A7B5-4E1F-B667-36C52DE052BE}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{F7069D72-4B89-4988-B16F-C3B43A6CD3AF}</UniqueIdentifier>
+ <UniqueIdentifier>{6585B2E9-A69A-4E00-89EA-5AE31ECF93B3}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{1390D1D1-490F-4A63-903E-AADFFF96098E}</UniqueIdentifier>
+ <UniqueIdentifier>{1A5345B0-8D71-4A9B-8B1D-4CF5AA1168E4}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
diff --git a/storage/miniports/storahci/src/io.c b/storage/miniports/storahci/src/io.c
index 722ca7b6..3a517854 100644
--- a/storage/miniports/storahci/src/io.c
+++ b/storage/miniports/storahci/src/io.c
@@ -179,9 +179,8 @@ Input Parameters:
Tag: bit 31 ~ 24, Queue->CurrentDepth: bit 23 ~ 0
*/
{
- PVOID tempTail, foundSrb;
- ULONG srbsFound;
-
+ PVOID tempTail, foundSrb;
+ ULONG srbsFound;
UNREFERENCED_PARAMETER(ChannelExtension);
if (Queue->Tail == NULL) {
@@ -213,6 +212,8 @@ Input Parameters:
if (Queue->CurrentDepth > Queue->DeepestDepth) {
Queue->DeepestDepth = Queue->CurrentDepth;
}
+
+ return;
}
PSTORAGE_REQUEST_BLOCK
@@ -223,8 +224,8 @@ RemoveQueue (
_In_ UCHAR Tag
)
{
- PVOID nextSrb, foundSrb;
- ULONG srbsFound;
+ PVOID nextSrb, foundSrb;
+ ULONG srbsFound;
UNREFERENCED_PARAMETER(ChannelExtension);
@@ -260,6 +261,7 @@ RemoveQueue (
if (Queue->CurrentDepth > Queue->DeepestDepth) {
Queue->DeepestDepth = Queue->CurrentDepth;
}
+
return (PSTORAGE_REQUEST_BLOCK)nextSrb;
}
@@ -297,56 +299,56 @@ Affected Variables/Registers:
Return Values:
--*/
{
- BOOLEAN status;
- AHCI_COMMAND cmd;
- ULONG sact;
- ULONG ci;
- ULONG slotsToActivate;
- BOOLEAN activateNcq;
+ BOOLEAN status = TRUE;
+ ULONG slotsToActivate = 0;
+ BOOLEAN activateNcq = FALSE;
int i;
PAHCI_ADAPTER_EXTENSION adapterExtension = ChannelExtension->AdapterExtension;
- STOR_LOCK_HANDLE lockhandle = { 0 };
-
- if (!AtDIRQL) {
- AhciInterruptSpinlockAcquire(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
- }
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
//1.1 Initialize variables
if (LogExecuteFullDetail(adapterExtension->LogFlags)) {
RecordExecutionHistory(ChannelExtension, 0x00000022);//ActivateQueue
}
- slotsToActivate = 0;
- activateNcq = FALSE;
+ // If the programming should not happen now, leave
+ if (ChannelExtension->StartState.ChannelNextStartState != StartComplete) {
+ RecordExecutionHistory(ChannelExtension, 0x10010022);//ActivateQueue, Channel Not Yet Started
+ status = FALSE;
+ return status;
+ }
- //1.1.1 If there is no command to program, leave
- if ( (ChannelExtension->SlotManager.SingleIoSlice == 0) &&
- (ChannelExtension->SlotManager.NormalQueueSlice == 0) &&
- (ChannelExtension->SlotManager.NCQueueSlice == 0) ) {
- //
- if (LogExecuteFullDetail(adapterExtension->LogFlags)) {
- RecordExecutionHistory(ChannelExtension, 0x10040022);//ActivateQueue, No Commands to program
- }
+ if (ChannelExtension->StateFlags.QueuePaused == TRUE) {
+ RecordExecutionHistory(ChannelExtension, 0x10020022);//ActivateQueue, Channel Queue Paused
status = FALSE;
- goto Exit;
+ return status;
}
- //1.2 If the programming should not happen now, leave
if ( !IsPortStartCapable(ChannelExtension) ) {
RecordExecutionHistory(ChannelExtension, 0x10030022);//ActivateQueue, Channel Not Start Capable
status = FALSE;
- goto Exit;
+ return status;
}
if ( ErrorRecoveryIsPending(ChannelExtension) ) {
RecordExecutionHistory(ChannelExtension, 0x10070022);//ActivateQueue, Error Recovery is pending.
status = FALSE;
- goto Exit;
+ return status;
}
- if (ChannelExtension->StateFlags.QueuePaused == TRUE) {
- RecordExecutionHistory(ChannelExtension, 0x10020022);//ActivateQueue, Channel Queue Paused
+ if (!AtDIRQL) {
+ AhciInterruptSpinlockAcquire(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
+ }
+
+ //1.1.1 If there is no command to program, leave
+ if ( (ChannelExtension->SlotManager.SingleIoSlice == 0) &&
+ (ChannelExtension->SlotManager.NormalQueueSlice == 0) &&
+ (ChannelExtension->SlotManager.NCQueueSlice == 0) ) {
+
+ if (LogExecuteFullDetail(adapterExtension->LogFlags)) {
+ RecordExecutionHistory(ChannelExtension, 0x10040022);//ActivateQueue, No Commands to program
+ }
status = FALSE;
goto Exit;
}
@@ -361,31 +363,23 @@ Return Values:
goto Exit;
}
- cmd.AsUlong = StorPortReadRegisterUlong(adapterExtension, &ChannelExtension->Px->CMD.AsUlong);
- if (cmd.ST == 0) {
- RecordExecutionHistory(ChannelExtension, 0x10010022);//ActivateQueue, Channel Not Yet Started
- status = FALSE;
- goto Exit;
- }
-
//2.1 Choose the Queue with which to program the controller
- sact = StorPortReadRegisterUlong(adapterExtension, &ChannelExtension->Px->SACT);
- ci = StorPortReadRegisterUlong(adapterExtension, &ChannelExtension->Px->CI);
//2.1.2 Single IO SRBs have highest priority.
if(ChannelExtension->SlotManager.SingleIoSlice != 0) {
- if ( ( sact == 0 ) && ( ci == 0 ) ) {
+ if ( (ChannelExtension->SlotManager.NCQueueSliceIssued | ChannelExtension->SlotManager.NormalQueueSliceIssued | ChannelExtension->SlotManager.SingleIoSliceIssued) == 0 ) {
//Safely get Single IO in round robin fashion
i = GetSingleIo(ChannelExtension);
if (i != 0xff) {
slotsToActivate = (1 << i);
ChannelExtension->SlotManager.SingleIoSlice &= ~slotsToActivate;
+ ChannelExtension->SlotManager.SingleIoSliceIssued |= slotsToActivate;
ChannelExtension->StateFlags.QueuePaused = TRUE; //and pause the queue so no other IO get programmed
}
}
//2.1.2 When there are no Single IO commands, Normal IO get the next highest priority
} else if (ChannelExtension->SlotManager.NormalQueueSlice != 0) {
// Normal commands can not be sent when NCQ commands are outstanding. When the NCQ commands complete ActivateQueue will get called again.
- if (sact == 0) {
+ if (ChannelExtension->SlotManager.NCQueueSliceIssued == 0) {
//Grab the High Priority Normal IO before the Low Priority Normal IO
slotsToActivate = ChannelExtension->SlotManager.HighPriorityAttribute & ChannelExtension->SlotManager.NormalQueueSlice;
//If there aren't any High Priority, grab everything else
@@ -395,11 +389,13 @@ Return Values:
slotsToActivate = ChannelExtension->SlotManager.NormalQueueSlice;
ChannelExtension->SlotManager.NormalQueueSlice = 0;
}
+ ChannelExtension->SlotManager.NormalQueueSliceIssued |= slotsToActivate;
}
//2.1.3 When there are no Single or Normal commands, NCQ commands get the next highest priority
- } else if (ChannelExtension->SlotManager.NCQueueSlice != 0) {
+ } else if ((ChannelExtension->SlotManager.NCQueueSlice != 0) &&
+ (ChannelExtension->StateFlags.NcqErrorRecoveryInProcess == 0)) {
// NCQ commands can not be sent when Normal commands are outstanding. When the Normal commands complete, Activate Queue will get called again.
- if ( ( ci != 0 ) && (sact == 0) ) {
+ if ( ( ChannelExtension->SlotManager.SingleIoSliceIssued | ChannelExtension->SlotManager.NormalQueueSliceIssued ) != 0 ) {
slotsToActivate = 0;
} else {
//Grab the High Priority NCQ IO before the Low Priority NCQ IO
@@ -418,6 +414,7 @@ Return Values:
//and if there are any IO still selected, clear them from the NCQueue
activateNcq = TRUE; //Remember to program SACT for these commands
ChannelExtension->SlotManager.NCQueueSlice &= ~slotsToActivate;
+ ChannelExtension->SlotManager.NCQueueSliceIssued |= slotsToActivate;
//the selected IO will be activated at the end of this function
}
}
@@ -458,13 +455,21 @@ Return Values:
}
if (LogExecuteFullDetail(adapterExtension->LogFlags)) {
- RecordInterruptHistory(ChannelExtension, slotsToActivate, 0, 0, ci, sact, 0x10060022); //ActivateQueue, after getting IO slices,
+ RecordInterruptHistory(ChannelExtension,
+ slotsToActivate,
+ 0,
+ 0,
+ (ChannelExtension->SlotManager.SingleIoSliceIssued | ChannelExtension->SlotManager.NormalQueueSliceIssued),
+ ChannelExtension->SlotManager.NCQueueSliceIssued,
+ 0x10060022); //ActivateQueue, after getting IO slices,
+
RecordExecutionHistory(ChannelExtension, 0x10050022);//Exit ActivateQueue
}
status = TRUE;
Exit:
+
if (!AtDIRQL) {
AhciInterruptSpinlockRelease(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
}
@@ -570,7 +575,7 @@ Affected Variables/Registers:
//This shall never happen.
//The completed slot has no SRB so it can not be completed back to Storport.
//Give back the empty slot
- //NT_ASSERT(FALSE);
+ NT_ASSERT(FALSE);
ChannelExtension->SlotManager.CommandsToComplete &= ~(1 << i);
ChannelExtension->SlotManager.HighPriorityAttribute &= ~(1 << i);
continue;
@@ -639,7 +644,7 @@ Affected Variables/Registers:
}
//3.1 Start the next IO(s) if any
- AhciGetNextIos(ChannelExtension, AtDIRQL);
+ ActivateQueue(ChannelExtension, AtDIRQL);
return;
}
@@ -1034,16 +1039,17 @@ This routine does following:
1. Check if no device command associated with Srb, or the port failed to start. Bail out in these cases.
2. Central place for special command handling.
3. Get available slot
- 4. Call AhciFormIo() to Fill the slot; Program command Table & Header; Put IO in Slice
+ 4. Fill the slot; Program command Table & Header; Put IO in Slice
Note: This routine can be called even the Port is stopped.
- This routine and the calling routine AhciFormIo() does NOT program IO to adapter.
+ This routine does NOT program IO to adapter.
*/
{
PAHCI_SRB_EXTENSION srbExtension = GetSrbExtension(Srb);
- UCHAR pathId = 0;
- UCHAR targetId = 0;
- UCHAR lun = 0;
+ UCHAR pathId = 0;
+ UCHAR targetId = 0;
+ UCHAR lun = 0;
+ STOR_LOCK_HANDLE lockHandle = {InterruptLock, 0};
SrbGetPathTargetLun(Srb, &pathId, &targetId, &lun);
@@ -1100,6 +1106,10 @@ Note: This routine can be called even the Port is stopped.
}
//3 Find an available slot/tag (AHCI 1.1 Section 5.5.1)
+ if (!AtDIRQL) {
+ AhciInterruptSpinlockAcquire(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockHandle);
+ }
+
GetAvailableSlot(ChannelExtension, Srb); //srbExtension->QueueTag will be set
// 3.1 If no tag is available, reject the command to be retried later
@@ -1112,9 +1122,9 @@ Note: This routine can be called even the Port is stopped.
}
Srb->SrbStatus = SRB_STATUS_BUSY;
MarkSrbToBeCompleted(Srb);
- AhciCompleteRequest(ChannelExtension, Srb, AtDIRQL);
+ AhciCompleteRequest(ChannelExtension, Srb, TRUE);
RecordExecutionHistory(ChannelExtension, 0x10030020); //AllocateQueueTagFailed
- return TRUE;
+ goto exit;
}
#ifdef DBG
@@ -1139,15 +1149,24 @@ Note: This routine can be called even the Port is stopped.
}
MarkSrbToBeCompleted(Srb);
- AhciCompleteRequest(ChannelExtension, Srb, AtDIRQL);
+ AhciCompleteRequest(ChannelExtension, Srb, TRUE);
RecordExecutionHistory(ChannelExtension, 0x10040020);//Tag given for slot in use
- return TRUE;
+ goto exit;
}
}
#endif
+
//srbExtension->QueueTag and Slot[srbExtension->QueueTag] are now guaranteed ready.
+
+ AhciFormIo (ChannelExtension, Srb, TRUE);
- return AhciFormIo (ChannelExtension, Srb, AtDIRQL);
+exit:
+
+ if (!AtDIRQL) {
+ AhciInterruptSpinlockRelease(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockHandle);
+ }
+
+ return TRUE;
}
BOOLEAN
@@ -1248,6 +1267,7 @@ AhciFormIo(
}
+
//3. Build the PRD Table in CommandTable.
if( IsDataTransferNeeded(slotContent->Srb) ) {
prdtLength = SRBtoPRDT(ChannelExtension, slotContent);
@@ -1312,6 +1332,8 @@ AhciFormIo(
return TRUE;
}
+
+
PSCSI_REQUEST_BLOCK
BuildRequestSenseSrb(
_In_ PAHCI_CHANNEL_EXTENSION ChannelExtension,
@@ -1336,6 +1358,10 @@ BuildRequestSenseSrb(
return NULL;
}
+ if ((srbSenseBuffer != NULL) && (srbSenseBufferLength > 0)) {
+ AhciZeroMemory((PCHAR)srbSenseBuffer, srbSenseBufferLength);
+ }
+
//2. initialize Srb and SrbExtension structures.
AhciZeroMemory((PCHAR)senseSrb, sizeof(SCSI_REQUEST_BLOCK));
AhciZeroMemory((PCHAR)srbExtension, sizeof(AHCI_SRB_EXTENSION));
@@ -1383,18 +1409,8 @@ AhciPortFailAllIos(
_In_ BOOLEAN AtDIRQL
)
{
- PSTORAGE_REQUEST_BLOCK srb;
UCHAR i;
- // complete all requests still in queue
- srb = RemoveQueue(ChannelExtension, &ChannelExtension->SrbQueue, 0xDEADC0DE, 0x1F);
- while (srb != NULL) {
- srb->SrbStatus = SrbStatus;
- MarkSrbToBeCompleted(srb);
- AhciCompleteRequest(ChannelExtension, srb, AtDIRQL);
- srb = RemoveQueue(ChannelExtension, &ChannelExtension->SrbQueue, 0xDEADC0DE, 0x1F);
- }
-
// complete all requests in slots
for (i = 0; i <= ChannelExtension->AdapterExtension->CAP.NCS; i++) {
if (ChannelExtension->Slot[i].Srb != NULL) {
@@ -1417,7 +1433,7 @@ AhciPortSrbCompletionDpcRoutine(
)
{
PAHCI_CHANNEL_EXTENSION channelExtension = (PAHCI_CHANNEL_EXTENSION)SystemArgument1;
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
PSTORAGE_REQUEST_BLOCK srb = NULL;
PSRB_COMPLETION_ROUTINE completionRoutine = NULL;
BOOLEAN reservedSlotInUse = FALSE;
@@ -1464,17 +1480,20 @@ AhciPortSrbCompletionDpcRoutine(
if ( (srbExtension->AtaFunction != 0) &&
(!SrbShouldBeCompleted(srbExtension->Flags)) &&
(srb->SrbStatus != SRB_STATUS_BUS_RESET) ) {
+
// new command associated needs to be processed, do not complete the request.
- AhciInterruptSpinlockAcquire(channelExtension->AdapterExtension, channelExtension->PortNumber, &lockhandle);
- AhciProcessIo(channelExtension, srb, TRUE);
- AhciInterruptSpinlockRelease(channelExtension->AdapterExtension, channelExtension->PortNumber, &lockhandle);
+ AhciProcessIo(channelExtension, srb, FALSE);
+
// this Srb should not be completed yet
completeSrb = FALSE;
sendCommand = TRUE;
+
} else if (SrbShouldBeCompleted(srbExtension->Flags)) {
// clear the flag
CLRMASK(srbExtension->Flags, ATA_FLAGS_COMPLETE_SRB);
}
+
+
} else {
// a Srb without completion routine should be completed.
}
diff --git a/storage/miniports/storahci/src/pnppower.c b/storage/miniports/storahci/src/pnppower.c
index dec0fde7..ca9b6ff6 100644
--- a/storage/miniports/storahci/src/pnppower.c
+++ b/storage/miniports/storahci/src/pnppower.c
@@ -732,7 +732,7 @@ IssueReadLogExtCommand(
_In_ USHORT PageNumber,
_In_ USHORT BlockCount,
_In_ USHORT FeatureField,
- _In_ PSTOR_PHYSICAL_ADDRESS PhysicalAddress,
+ _In_opt_ PSTOR_PHYSICAL_ADDRESS PhysicalAddress,
_In_ PVOID DataBuffer,
_In_opt_ PSRB_COMPLETION_ROUTINE CompletionRoutine
)
@@ -1357,10 +1357,18 @@ AhciPortSmartCompletion(
outParams->DriverStatus.bDriverError = 0;
outParams->DriverStatus.bIDEError = 0;
+ // RETURN_SMART_STATUS does not perform data transfer but copies the registers.
+ if (srbExtension->TaskFile.Current.bFeaturesReg == RETURN_SMART_STATUS) {
+ outParams->cBufferSize = sizeof(ATAREGISTERS);
+ } else {
+ outParams->cBufferSize = srbExtension->DataTransferLength;
+ }
+
} else {
// command failed
outParams->DriverStatus.bDriverError = SMART_IDE_ERROR;
outParams->DriverStatus.bIDEError = srbExtension->AtaStatus;
+ outParams->cBufferSize = 0;
}
return;
@@ -1656,8 +1664,6 @@ AhciDeviceInitialize (
_In_ PAHCI_CHANNEL_EXTENSION ChannelExtension
)
{
- STOR_LOCK_HANDLE lockhandle = {0};
-
RecordExecutionHistory(ChannelExtension, 0x00000007); //AhciDeviceInitialize
//1 update preserved commands per device needs.
@@ -1702,9 +1708,7 @@ AhciDeviceInitialize (
//5.1 Configure device with init commands and persistent configuration commands
AhciPortIssueInitCommands(ChannelExtension);
- AhciInterruptSpinlockAcquire(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
- ActivateQueue(ChannelExtension, TRUE);
- AhciInterruptSpinlockRelease(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
+ ActivateQueue(ChannelExtension, FALSE);
RecordExecutionHistory(ChannelExtension, 0x10000007);//Exit AhciDeviceInitialize
return TRUE;
@@ -2002,10 +2006,7 @@ AhciPortPowerSettingNotification(
needRestartIo = AhciLpmSettingsModes(ChannelExtension, userLpmPowerSettings);
if (needRestartIo) {
- STOR_LOCK_HANDLE lockhandle = {0};
- AhciInterruptSpinlockAcquire(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
- ActivateQueue(ChannelExtension, TRUE);
- AhciInterruptSpinlockRelease(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
+ ActivateQueue(ChannelExtension, FALSE);
}
}
@@ -2059,7 +2060,8 @@ AhciAutoPartialToSlumber(
ci = StorPortReadRegisterUlong(AdapterExtension, &channelExtension->Px->CI);
sact = StorPortReadRegisterUlong(AdapterExtension, &channelExtension->Px->SACT);
- if (!PartialToSlumberTransitionIsAllowed(channelExtension, cmd, ci, sact)) {
+ if (((ci | sact) != 0) ||
+ !PartialToSlumberTransitionIsAllowed(channelExtension, &cmd)) {
// validate again in case any condition changed that not allowing StorAHCI to perform Partial to Slumber transition.
StorPortDebugPrint(3, "StorAHCI - LPM: Port %02d - Transit into Slumber from Partial - bailed out, request outstanding: CI: 0x%08X, SACT: 0x%08X \n", channelExtension->PortNumber, ci, sact);
diff --git a/storage/miniports/storahci/src/pnppower.h b/storage/miniports/storahci/src/pnppower.h
index 9ee482f1..366c6bb5 100644
--- a/storage/miniports/storahci/src/pnppower.h
+++ b/storage/miniports/storahci/src/pnppower.h
@@ -158,7 +158,7 @@ IssueReadLogExtCommand(
_In_ USHORT PageNumber,
_In_ USHORT BlockCount,
_In_ USHORT FeatureField,
- _In_ PSTOR_PHYSICAL_ADDRESS PhysicalAddress,
+ _In_opt_ PSTOR_PHYSICAL_ADDRESS PhysicalAddress,
_In_ PVOID DataBuffer,
_In_opt_ PSRB_COMPLETION_ROUTINE CompletionRoutine
);
diff --git a/storage/miniports/storahci/src/util.c b/storage/miniports/storahci/src/util.c
index 992ff2c7..e7ed0cba 100644
--- a/storage/miniports/storahci/src/util.c
+++ b/storage/miniports/storahci/src/util.c
@@ -189,7 +189,7 @@ Return Value:
//2. Copy data
ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].Function = Function;
- if(ChannelExtension->AdapterExtension->IS) {
+ if (ChannelExtension->AdapterExtension->IS) {
// Keep using the old field "IS" to save StateFlags information.
StorPortCopyMemory(&ChannelExtension->ExecutionHistory[ChannelExtension->ExecutionHistoryNextAvailableIndex].IS, &ChannelExtension->StateFlags, sizeof(ULONG));
} else {
@@ -494,7 +494,7 @@ PortBusChangeProcess (
)
{
AHCI_SERIAL_ATA_CONTROL sctl;
- STOR_LOCK_HANDLE lockhandle = {0};
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
ULONG status = STOR_STATUS_UNSUCCESSFUL;
//1 if link speed was limited, restore the supported value.
@@ -821,6 +821,7 @@ AhciCompleteJustSlottedRequest(
PAHCI_SRB_EXTENSION srbExtension;
BOOLEAN isSenseSrb;
PSTORAGE_REQUEST_BLOCK srbToComplete;
+ STOR_LOCK_HANDLE lockHandle = {InterruptLock, 0};
srbExtension = GetSrbExtension(Srb);
slotContent = &ChannelExtension->Slot[srbExtension->QueueTag];
@@ -842,6 +843,10 @@ AhciCompleteJustSlottedRequest(
srbToComplete = Srb;
}
+ if (!AtDIRQL) {
+ AhciInterruptSpinlockAcquire(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockHandle);
+ }
+
//1. Make the slot available again
slotContent->CmdHeader = NULL;
slotContent->CommandHistoryIndex = 0;
@@ -865,6 +870,10 @@ AhciCompleteJustSlottedRequest(
ChannelExtension->SlotManager.CommandsToComplete &= ~(1 << srbExtension->QueueTag);
}
+ if (!AtDIRQL) {
+ AhciInterruptSpinlockRelease(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockHandle);
+ }
+
//3. Complete the command
AhciCompleteRequest(ChannelExtension, srbToComplete, AtDIRQL);
@@ -890,7 +899,7 @@ Called by:
ReleaseSlottedCommand
NOTE:
- The caller of this routine should call AhciGetNextIos or ActiveQueue to program the command (from Srb completion routine) to adapter
+ The caller of this routine should call ActiveQueue to program the command (from Srb completion routine) to adapter
--*/
{
@@ -900,9 +909,9 @@ NOTE:
if ( ((srbExtension->Flags & ATA_FLAGS_ACTIVE_REFERENCE) != 0) ||
(srbExtension->CompletionRoutine != NULL) ) {
- STOR_LOCK_HANDLE lockhandle = {0};
-
if (AtDIRQL == FALSE) {
+ STOR_LOCK_HANDLE lockhandle = {InterruptLock, 0};
+
AhciInterruptSpinlockAcquire(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
AddQueue(ChannelExtension, &ChannelExtension->CompletionQueue, Srb, 0xDEADBEEF, 0x90);
AhciInterruptSpinlockRelease(ChannelExtension->AdapterExtension, ChannelExtension->PortNumber, &lockhandle);
@@ -986,6 +995,16 @@ Return Value:
return;
}
+ // case of Sense.Srb used for NCQ error recovery.
+ if ((Srb == (PSTORAGE_REQUEST_BLOCK)&ChannelExtension->Sense.Srb) &&
+ IsAtaCommand(srbExtension->AtaFunction)) {
+
+ if ((allocated & (1 << 0)) == 0) {
+ srbExtension->QueueTag = 0;
+ return;
+ }
+ }
+
//2.2 Chose the slot circularly starting with CCS
for (i = limit; i <= ChannelExtension->AdapterExtension->CAP.NCS; i++) {
if ( (allocated & (1 << i)) == 0 ) {
diff --git a/storage/miniports/storahci/src/util.h b/storage/miniports/storahci/src/util.h
index b07b465a..c05339b1 100644
--- a/storage/miniports/storahci/src/util.h
+++ b/storage/miniports/storahci/src/util.h
@@ -1221,16 +1221,12 @@ __inline
BOOLEAN
PartialToSlumberTransitionIsAllowed (
_In_ PAHCI_CHANNEL_EXTENSION ChannelExtension,
- _In_ AHCI_COMMAND CMD,
- _In_ ULONG CI,
- _In_ ULONG SACT
+ _In_opt_ PAHCI_COMMAND CMD
)
{
- if ( (CI != 0) || (SACT != 0) ) {
- //device still has request pending
- return FALSE;
- }
-
+ PAHCI_COMMAND cmdRegister = NULL;
+ AHCI_COMMAND cmd = {0};
+
if ((ChannelExtension->LastUserLpmPowerSetting & 0x3) == 0) {
//Neither HIPM nor DIPM is allowed. e.g. LastUserLpmPowerSetting --- bit 0: HIPM; bit 1: DIPM
return FALSE;
@@ -1257,12 +1253,6 @@ PartialToSlumberTransitionIsAllowed (
}
- if ( ( (ChannelExtension->AdapterExtension->CAP.SALP == 0) || (CMD.ALPE == 0) ) &&
- (!IsDeviceSupportsDIPM(ChannelExtension->DeviceExtension[0].IdentifyDeviceData)) ) {
- //Neither HIPM nor DIPM is enabled.
- return FALSE;
- }
-
if ( ((ChannelExtension->LastUserLpmPowerSetting & 0x2) != 0) &&
(ChannelExtension->DeviceExtension->IdentifyDeviceData->SerialAtaCapabilities.DeviceAutoPS == 1) &&
(ChannelExtension->DeviceExtension->IdentifyDeviceData->SerialAtaFeaturesEnabled.DeviceAutoPS == 1) ) {
@@ -1271,10 +1261,26 @@ PartialToSlumberTransitionIsAllowed (
return FALSE;
}
+ //
+ // Only access PxCMD register when it's needed.
+ //
+ if ((CMD != NULL) && (CMD->AsUlong != 0)) {
+ cmdRegister = CMD;
+ } else {
+ cmd.AsUlong = StorPortReadRegisterUlong(ChannelExtension->AdapterExtension, &ChannelExtension->Px->CMD.AsUlong);
+ cmdRegister = &cmd;
+ }
+
+ if ( ( (ChannelExtension->AdapterExtension->CAP.SALP == 0) || (cmdRegister->ALPE == 0) ) &&
+ (!IsDeviceSupportsDIPM(ChannelExtension->DeviceExtension[0].IdentifyDeviceData)) ) {
+ //Neither HIPM nor DIPM is enabled.
+ return FALSE;
+ }
+
if ( (ChannelExtension->AdapterExtension->CAP.SALP == 1) &&
- (CMD.ALPE != 0) &&
- ( (CMD.ASP == 1) ||
- ( (ChannelExtension->AdapterExtension->CAP2.APST != 0) && (CMD.APSTE != 0) ) ) ) {
+ (cmdRegister->ALPE != 0) &&
+ ( (cmdRegister->ASP == 1) ||
+ ( (ChannelExtension->AdapterExtension->CAP2.APST != 0) && (cmdRegister->APSTE != 0) ) ) ) {
// HIPM is enabled. AND
// either Host initiates Slumber automatically, OR
// Host supports and enabled auto Partial to Slumber.
diff --git a/storage/miniports/storahci/storahci.sln b/storage/miniports/storahci/storahci.sln
index bc97b455..fd7aaea4 100644
--- a/storage/miniports/storahci/storahci.sln
+++ b/storage/miniports/storahci/storahci.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "storahci", "src\inbox\storahci.vcxproj", "{A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "storahci", "src\inbox\storahci.vcxproj", "{1452B3C2-50A6-4F07-BF00-413B7A51E3A4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}.Debug|Win32.ActiveCfg = Debug|Win32
- {A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}.Debug|Win32.Build.0 = Debug|Win32
- {A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}.Release|Win32.ActiveCfg = Release|Win32
- {A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}.Release|Win32.Build.0 = Release|Win32
- {A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}.Debug|x64.ActiveCfg = Debug|x64
- {A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}.Debug|x64.Build.0 = Debug|x64
- {A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}.Release|x64.ActiveCfg = Release|x64
- {A0F8FE2B-5512-436E-A77F-4A24EAAACA7C}.Release|x64.Build.0 = Release|x64
+ {1452B3C2-50A6-4F07-BF00-413B7A51E3A4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1452B3C2-50A6-4F07-BF00-413B7A51E3A4}.Debug|Win32.Build.0 = Debug|Win32
+ {1452B3C2-50A6-4F07-BF00-413B7A51E3A4}.Release|Win32.ActiveCfg = Release|Win32
+ {1452B3C2-50A6-4F07-BF00-413B7A51E3A4}.Release|Win32.Build.0 = Release|Win32
+ {1452B3C2-50A6-4F07-BF00-413B7A51E3A4}.Debug|x64.ActiveCfg = Debug|x64
+ {1452B3C2-50A6-4F07-BF00-413B7A51E3A4}.Debug|x64.Build.0 = Debug|x64
+ {1452B3C2-50A6-4F07-BF00-413B7A51E3A4}.Release|x64.ActiveCfg = Release|x64
+ {1452B3C2-50A6-4F07-BF00-413B7A51E3A4}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/msdsm/msdsm.sln b/storage/msdsm/msdsm.sln
index c70a97ea..26e0a90d 100644
--- a/storage/msdsm/msdsm.sln
+++ b/storage/msdsm/msdsm.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleDSM", "src\SampleDSM.vcxproj", "{D093D3C3-53D2-4E2A-A634-CFBE482CC29D}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleDSM", "src\SampleDSM.vcxproj", "{65A3C0DB-248E-4365-83D2-E4DE6E764C6C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {D093D3C3-53D2-4E2A-A634-CFBE482CC29D}.Debug|Win32.ActiveCfg = Debug|Win32
- {D093D3C3-53D2-4E2A-A634-CFBE482CC29D}.Debug|Win32.Build.0 = Debug|Win32
- {D093D3C3-53D2-4E2A-A634-CFBE482CC29D}.Release|Win32.ActiveCfg = Release|Win32
- {D093D3C3-53D2-4E2A-A634-CFBE482CC29D}.Release|Win32.Build.0 = Release|Win32
- {D093D3C3-53D2-4E2A-A634-CFBE482CC29D}.Debug|x64.ActiveCfg = Debug|x64
- {D093D3C3-53D2-4E2A-A634-CFBE482CC29D}.Debug|x64.Build.0 = Debug|x64
- {D093D3C3-53D2-4E2A-A634-CFBE482CC29D}.Release|x64.ActiveCfg = Release|x64
- {D093D3C3-53D2-4E2A-A634-CFBE482CC29D}.Release|x64.Build.0 = Release|x64
+ {65A3C0DB-248E-4365-83D2-E4DE6E764C6C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {65A3C0DB-248E-4365-83D2-E4DE6E764C6C}.Debug|Win32.Build.0 = Debug|Win32
+ {65A3C0DB-248E-4365-83D2-E4DE6E764C6C}.Release|Win32.ActiveCfg = Release|Win32
+ {65A3C0DB-248E-4365-83D2-E4DE6E764C6C}.Release|Win32.Build.0 = Release|Win32
+ {65A3C0DB-248E-4365-83D2-E4DE6E764C6C}.Debug|x64.ActiveCfg = Debug|x64
+ {65A3C0DB-248E-4365-83D2-E4DE6E764C6C}.Debug|x64.Build.0 = Debug|x64
+ {65A3C0DB-248E-4365-83D2-E4DE6E764C6C}.Release|x64.ActiveCfg = Release|x64
+ {65A3C0DB-248E-4365-83D2-E4DE6E764C6C}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/msdsm/src/SampleDSM.vcxproj b/storage/msdsm/src/SampleDSM.vcxproj
index c4870a68..9b5563f5 100644
--- a/storage/msdsm/src/SampleDSM.vcxproj
+++ b/storage/msdsm/src/SampleDSM.vcxproj
@@ -19,12 +19,12 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{D093D3C3-53D2-4E2A-A634-CFBE482CC29D}</ProjectGuid>
+ <ProjectGuid>{65A3C0DB-248E-4365-83D2-E4DE6E764C6C}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<SupportsPackaging>false</SupportsPackaging>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{0B2AAAFE-CC5D-4581-92BE-2CFF7879B4E8}</SampleGuid>
+ <SampleGuid>{C7903CA3-734F-46C5-AECC-1824E8E189EE}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/msdsm/src/SampleDSM.vcxproj.Filters b/storage/msdsm/src/SampleDSM.vcxproj.Filters
index ab3c118a..5d097976 100644
--- a/storage/msdsm/src/SampleDSM.vcxproj.Filters
+++ b/storage/msdsm/src/SampleDSM.vcxproj.Filters
@@ -3,19 +3,19 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{5467502E-BE53-48E3-9B4D-2727B895913F}</UniqueIdentifier>
+ <UniqueIdentifier>{DF2838D8-1C88-49F8-9A61-165CDBE203E4}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{E67880DC-0E2B-4629-9BC4-6DE655C52134}</UniqueIdentifier>
+ <UniqueIdentifier>{53AF5736-142C-496F-93D0-CA43CC76BF9C}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{77134D09-E871-4C7B-8EBB-BC35E319ABF8}</UniqueIdentifier>
+ <UniqueIdentifier>{DDA0526B-40A0-4BB7-AAAC-EF10718F6C00}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{029DDD29-646E-4A6D-AF49-A8F30315A59D}</UniqueIdentifier>
+ <UniqueIdentifier>{35E21F2D-00EC-4D8E-A5FC-B6B1E43B41E7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
diff --git a/storage/msdsm/src/dsmmain.c b/storage/msdsm/src/dsmmain.c
index 1b414081..bad147d7 100644
--- a/storage/msdsm/src/dsmmain.c
+++ b/storage/msdsm/src/dsmmain.c
@@ -2409,7 +2409,7 @@ Return Value:
// Create a new entry if the group does not exist in the zombie group list.
//
if (groupInZombieList == FALSE) {
- newZombieGroup = (PDSM_ZOMBIEGROUP_ENTRY)DsmpAllocatePool(NonPagedPool,
+ newZombieGroup = (PDSM_ZOMBIEGROUP_ENTRY)DsmpAllocatePool(NonPagedPoolNx,
sizeof(DSM_ZOMBIEGROUP_ENTRY),
DSM_TAG_ZOMBIEGROUP_ENTRY);
if (newZombieGroup != NULL) {
diff --git a/storage/msdsm/src/intrface.c b/storage/msdsm/src/intrface.c
index ab05199a..e7c1eb29 100644
--- a/storage/msdsm/src/intrface.c
+++ b/storage/msdsm/src/intrface.c
@@ -24,8 +24,6 @@ Environment:
--*/
-#define DEBUG_MAIN_SOURCE 1
-
#include "precomp.h"
#ifdef DEBUG_USE_WPP
@@ -36,7 +34,7 @@ Environment:
//
-// Flag to indicate whether to NT_ASSERT or ignore a paritcular condition.
+// Flag to indicate whether to NT_ASSERT or ignore a particular condition.
//
BOOLEAN DoAssert = TRUE;
@@ -452,6 +450,8 @@ Return Value:
NT_ASSERT(NT_SUCCESS(ioStatus.Status));
+
+
return;
}
@@ -2722,6 +2722,22 @@ Return Value:
if (DsmpIsDeviceInitialized(deviceInfo)) {
+ if (deviceInfo->Unresponsive) {
+ //
+ // Since the device is marked unresponsive, there
+ // is no point in sending RTPG or TUR down
+ // as that will fail by port driver.
+ // but that doesn't necessarily mean that the path doesn't exist.
+ // Return SUCCESS here so that MPIO doesn't remove
+ // disk in case of failover etc.
+ // If really this path is gone, this should get deleted
+ // as part of pnp removal and then if no other paths are left
+ // disk will be removed
+ //
+ status = STATUS_SUCCESS;
+ return status;
+ }
+
irql = ExAcquireSpinLockExclusive(&(dsmCtxt->DsmContextLock));
//
@@ -3844,7 +3860,7 @@ Return Value:
DsmIds));
//
- // Determine whether this is a special-case request - PR or QOS.
+ // Determine whether this is a special-case request.
//
if (DsmpReservationCommand(Irp, Srb)) {
diff --git a/storage/msdsm/src/precomp.h b/storage/msdsm/src/precomp.h
index de4f4e1f..c199724e 100644
--- a/storage/msdsm/src/precomp.h
+++ b/storage/msdsm/src/precomp.h
@@ -17,6 +17,8 @@ Revision History:
#pragma once
+#define DEBUG_MAIN_SOURCE 1
+
#include <stdio.h>
#include <stdarg.h>
diff --git a/storage/msdsm/src/utils.c b/storage/msdsm/src/utils.c
index 529e7536..2f1bcbe1 100644
--- a/storage/msdsm/src/utils.c
+++ b/storage/msdsm/src/utils.c
@@ -307,9 +307,10 @@ Return Value:
// The query table has two entries. One for the supporteddeviceList and
// the second which is the 'NULL' terminator.
//
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_DISABLE_STATISTICS;
queryTable[0].EntryContext = StatsGatherChoice;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
registryKeyName,
@@ -437,7 +438,7 @@ Return Value:
// Indicate that there is NO call-back routine, and to give back the MULTI_SZ as
// one blob, as opposed to individual unicode strings.
//
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND | RTL_QUERY_REGISTRY_TYPECHECK;
//
// The value to query.
@@ -451,7 +452,7 @@ Return Value:
// is why we can't use Context->SupportedDevices directly in the call.
//
queryTable[0].EntryContext = &inquiryStrings;
- queryTable[0].DefaultType = REG_MULTI_SZ;
+ queryTable[0].DefaultType = (REG_MULTI_SZ << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_MULTI_SZ;
queryTable[0].DefaultData = defaultIDs;
queryTable[0].DefaultLength = sizeof(defaultIDs);
@@ -2921,9 +2922,11 @@ Return Value :
RtlZeroMemory(queryTable, sizeof(queryTable));
queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT |
- RTL_QUERY_REGISTRY_REQUIRED;
+ RTL_QUERY_REGISTRY_REQUIRED |
+ RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_LOAD_BALANCE_POLICY;
queryTable[0].EntryContext = LoadBalanceType;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
deviceKey,
@@ -3191,9 +3194,11 @@ Return Value :
RtlZeroMemory(queryTable, sizeof(queryTable));
queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT |
- RTL_QUERY_REGISTRY_REQUIRED;
+ RTL_QUERY_REGISTRY_REQUIRED |
+ RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_LOAD_BALANCE_POLICY;
queryTable[0].EntryContext = LoadBalanceType;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
targetKey,
@@ -3346,9 +3351,11 @@ Return Value :
RtlZeroMemory(queryTable, sizeof(queryTable));
queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT |
- RTL_QUERY_REGISTRY_REQUIRED;
+ RTL_QUERY_REGISTRY_REQUIRED |
+ RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_LOAD_BALANCE_POLICY;
queryTable[0].EntryContext = LoadBalanceType;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
parametersKey,
@@ -4835,9 +4842,11 @@ Return Value:
RtlZeroMemory(queryTable, sizeof(queryTable));
queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT |
- RTL_QUERY_REGISTRY_REQUIRED;
+ RTL_QUERY_REGISTRY_REQUIRED |
+ RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_PATH_WEIGHT;
queryTable[0].EntryContext = PathWeight;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
pathWeightQueryStatus = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
dsmPathKey,
@@ -4860,9 +4869,11 @@ Return Value:
RtlZeroMemory(queryTable, sizeof(queryTable));
queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT |
- RTL_QUERY_REGISTRY_REQUIRED;
+ RTL_QUERY_REGISTRY_REQUIRED |
+ RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_PRIMARY_PATH;
queryTable[0].EntryContext = PrimaryPath;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
dsmPathKey,
@@ -4878,9 +4889,11 @@ Return Value:
RtlZeroMemory(queryTable, sizeof(queryTable));
queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT |
- RTL_QUERY_REGISTRY_REQUIRED;
+ RTL_QUERY_REGISTRY_REQUIRED |
+ RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_OPTIMIZED_PATH;
queryTable[0].EntryContext = OptimizedPath;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
dsmPathKey,
@@ -7746,9 +7759,10 @@ Return Value:
// The query table has two entries. One for the state transition time and
// the second which is the 'NULL' terminator.
//
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_MAX_STATE_TRANSITION_TIME_VALUE_NAME;
queryTable[0].EntryContext = RetryTime;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
registryKeyName,
@@ -7833,10 +7847,10 @@ Return Value:
// The query table has two entries. One for whether to use cache, and
// and the second which is the 'NULL' terminator.
//
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_USE_CACHE_FOR_LEAST_BLOCKS;
queryTable[0].EntryContext = UseCacheForLeastBlocks;
- queryTable[0].DefaultType = REG_BINARY;
+ queryTable[0].DefaultType = (REG_BINARY << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_BINARY;
queryTable[0].DefaultLength = sizeof(BOOLEAN);
queryTable[0].DefaultData = &useCacheForLeastBlocksDefault;
diff --git a/storage/msdsm/src/wmi.c b/storage/msdsm/src/wmi.c
index 8dcf309a..090ce8b8 100644
--- a/storage/msdsm/src/wmi.c
+++ b/storage/msdsm/src/wmi.c
@@ -3603,9 +3603,10 @@ Return Value:
RtlZeroMemory(queryTable, sizeof(queryTable));
- queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_TYPECHECK;
queryTable[0].Name = DSM_LOAD_BALANCE_POLICY;
queryTable[0].EntryContext = &loadBalanceType;
+ queryTable[0].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
targetKey,
diff --git a/storage/ramdisk/ramdisk.sln b/storage/ramdisk/ramdisk.sln
index a94adfd1..ca8409b5 100644
--- a/storage/ramdisk/ramdisk.sln
+++ b/storage/ramdisk/ramdisk.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WdfRamdisk", "src\WdfRamdisk.vcxproj", "{8BD18F95-E980-494A-9058-F0DA28C0ECB9}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WdfRamdisk", "src\WdfRamdisk.vcxproj", "{68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {8BD18F95-E980-494A-9058-F0DA28C0ECB9}.Debug|Win32.ActiveCfg = Debug|Win32
- {8BD18F95-E980-494A-9058-F0DA28C0ECB9}.Debug|Win32.Build.0 = Debug|Win32
- {8BD18F95-E980-494A-9058-F0DA28C0ECB9}.Release|Win32.ActiveCfg = Release|Win32
- {8BD18F95-E980-494A-9058-F0DA28C0ECB9}.Release|Win32.Build.0 = Release|Win32
- {8BD18F95-E980-494A-9058-F0DA28C0ECB9}.Debug|x64.ActiveCfg = Debug|x64
- {8BD18F95-E980-494A-9058-F0DA28C0ECB9}.Debug|x64.Build.0 = Debug|x64
- {8BD18F95-E980-494A-9058-F0DA28C0ECB9}.Release|x64.ActiveCfg = Release|x64
- {8BD18F95-E980-494A-9058-F0DA28C0ECB9}.Release|x64.Build.0 = Release|x64
+ {68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}.Debug|Win32.ActiveCfg = Debug|Win32
+ {68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}.Debug|Win32.Build.0 = Debug|Win32
+ {68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}.Release|Win32.ActiveCfg = Release|Win32
+ {68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}.Release|Win32.Build.0 = Release|Win32
+ {68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}.Debug|x64.ActiveCfg = Debug|x64
+ {68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}.Debug|x64.Build.0 = Debug|x64
+ {68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}.Release|x64.ActiveCfg = Release|x64
+ {68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/ramdisk/src/WdfRamdisk.vcxproj b/storage/ramdisk/src/WdfRamdisk.vcxproj
index 655faf0f..10e35ae1 100644
--- a/storage/ramdisk/src/WdfRamdisk.vcxproj
+++ b/storage/ramdisk/src/WdfRamdisk.vcxproj
@@ -19,12 +19,12 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{8BD18F95-E980-494A-9058-F0DA28C0ECB9}</ProjectGuid>
+ <ProjectGuid>{68CDA2C2-2417-4963-9AEF-CB1B9FEF6069}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{E179004E-17AB-4904-B671-B3D996E2E00C}</SampleGuid>
+ <SampleGuid>{D76D15E5-06FE-43C8-A0E5-988E71FD53AB}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -75,13 +75,7 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ItemGroup Label="WrappedTaskItems">
- <Inf Include=".\ramdisk.inx">
- <Architecture>$(InfArch)</Architecture>
- <SpecifyArchitecture>true</SpecifyArchitecture>
- <CopyOutput>.\$(IntDir)\ramdisk.inf</CopyOutput>
- </Inf>
- </ItemGroup>
+ <ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>WdfRamdisk</TargetName>
</PropertyGroup>
diff --git a/storage/ramdisk/src/WdfRamdisk.vcxproj.Filters b/storage/ramdisk/src/WdfRamdisk.vcxproj.Filters
index d4dc5230..b5fde5b1 100644
--- a/storage/ramdisk/src/WdfRamdisk.vcxproj.Filters
+++ b/storage/ramdisk/src/WdfRamdisk.vcxproj.Filters
@@ -3,27 +3,22 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{B4C67F3E-3D06-47B0-A09C-4E0740919AF8}</UniqueIdentifier>
+ <UniqueIdentifier>{961D42E9-6D94-4E93-8D32-CF1C674B07B6}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{74F7327B-A6C4-481F-998B-5D49FAC38D3D}</UniqueIdentifier>
+ <UniqueIdentifier>{D22FB3CB-1355-4386-84BE-230FFB99DCFE}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{1E530CA0-70B5-4B7F-A753-F3CDA9804897}</UniqueIdentifier>
+ <UniqueIdentifier>{28C48AF7-BB6E-4F6A-922D-9BF76BC2AC8A}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{7B63C0F9-A06F-453D-8701-3EA7C844F62D}</UniqueIdentifier>
+ <UniqueIdentifier>{576E635F-EBBD-4ECA-8F75-D27C53603644}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
- <Inf Include=".\ramdisk.inx">
- <Filter>Driver Files</Filter>
- </Inf>
- </ItemGroup>
- <ItemGroup>
<ClCompile Include="forward_progress.c">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/storage/ramdisk/src/ramdisk.c b/storage/ramdisk/src/ramdisk.c
index ce571706..5411f3a9 100644
--- a/storage/ramdisk/src/ramdisk.c
+++ b/storage/ramdisk/src/ramdisk.c
@@ -484,7 +484,7 @@ Return Value:
// Allocate memory for the disk image.
//
pDeviceExtension->DiskImage = ExAllocatePoolWithTag(
- NonPagedPool,
+ NonPagedPoolNx,
pDeviceExtension->DiskRegInfo.DiskSize,
RAMDISK_TAG
);
diff --git a/storage/ramdisk/src/ramdisk.inx b/storage/ramdisk/src/ramdisk.inx
index 85210823..cf48a217 100644
--- a/storage/ramdisk/src/ramdisk.inx
+++ b/storage/ramdisk/src/ramdisk.inx
Binary files differ
diff --git a/storage/sfloppy/sfloppy.sln b/storage/sfloppy/sfloppy.sln
index 08aacade..ad9d60c3 100644
--- a/storage/sfloppy/sfloppy.sln
+++ b/storage/sfloppy/sfloppy.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sfloppy", "src\sfloppy.vcxproj", "{A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sfloppy", "src\sfloppy.vcxproj", "{97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}.Debug|Win32.ActiveCfg = Debug|Win32
- {A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}.Debug|Win32.Build.0 = Debug|Win32
- {A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}.Release|Win32.ActiveCfg = Release|Win32
- {A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}.Release|Win32.Build.0 = Release|Win32
- {A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}.Debug|x64.ActiveCfg = Debug|x64
- {A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}.Debug|x64.Build.0 = Debug|x64
- {A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}.Release|x64.ActiveCfg = Release|x64
- {A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}.Release|x64.Build.0 = Release|x64
+ {97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}.Debug|Win32.Build.0 = Debug|Win32
+ {97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}.Release|Win32.ActiveCfg = Release|Win32
+ {97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}.Release|Win32.Build.0 = Release|Win32
+ {97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}.Debug|x64.ActiveCfg = Debug|x64
+ {97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}.Debug|x64.Build.0 = Debug|x64
+ {97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}.Release|x64.ActiveCfg = Release|x64
+ {97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/sfloppy/src/sfloppy.vcxproj b/storage/sfloppy/src/sfloppy.vcxproj
index 2a76c175..ee6e08f9 100644
--- a/storage/sfloppy/src/sfloppy.vcxproj
+++ b/storage/sfloppy/src/sfloppy.vcxproj
@@ -19,12 +19,12 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{A18D5221-BD8F-40B5-BF73-8BCBECCCEFC7}</ProjectGuid>
+ <ProjectGuid>{97D2E67D-8E5F-43CD-B8EB-C5DBB43C7EB7}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<SupportsPackaging>false</SupportsPackaging>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{C458139C-2A5A-4D66-A35E-B77FBAF95078}</SampleGuid>
+ <SampleGuid>{6B097D1A-972A-41E8-A5C4-3691455FBB8B}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/sfloppy/src/sfloppy.vcxproj.Filters b/storage/sfloppy/src/sfloppy.vcxproj.Filters
index be90688a..3c28ea16 100644
--- a/storage/sfloppy/src/sfloppy.vcxproj.Filters
+++ b/storage/sfloppy/src/sfloppy.vcxproj.Filters
@@ -3,19 +3,19 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{25A4709A-0B52-42AD-8DE1-F6C233C9EF20}</UniqueIdentifier>
+ <UniqueIdentifier>{4BC320E9-22F6-4E58-8E7B-B87F90A2226B}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{D3F642A9-4C3E-4E09-AB52-7C7C45748D34}</UniqueIdentifier>
+ <UniqueIdentifier>{1B1144FD-B9FD-45E0-846D-0C0A89430459}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{65EE5CDD-5FEB-4C5B-9ABE-2E0354873707}</UniqueIdentifier>
+ <UniqueIdentifier>{BC1B1BDB-FAE7-4C16-A4B2-EBDC273AB7BC}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{37C9762C-6FA5-486F-87D6-E2B8083013F8}</UniqueIdentifier>
+ <UniqueIdentifier>{3AF8BBF9-34B1-4CEA-8BC6-305FB857F626}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
diff --git a/storage/tools/spti/spti.sln b/storage/tools/spti/spti.sln
index 38b869ff..3075d257 100644
--- a/storage/tools/spti/spti.sln
+++ b/storage/tools/spti/spti.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0
MinimumVisualStudioVersion = 12.0
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spti", "src\spti.vcxproj", "{D4F0486B-D89B-4BD7-9050-D75E28882A57}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spti", "src\spti.vcxproj", "{DBA7C5E3-522A-4974-B0C3-543BBC1665FF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +13,14 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {D4F0486B-D89B-4BD7-9050-D75E28882A57}.Debug|Win32.ActiveCfg = Debug|Win32
- {D4F0486B-D89B-4BD7-9050-D75E28882A57}.Debug|Win32.Build.0 = Debug|Win32
- {D4F0486B-D89B-4BD7-9050-D75E28882A57}.Release|Win32.ActiveCfg = Release|Win32
- {D4F0486B-D89B-4BD7-9050-D75E28882A57}.Release|Win32.Build.0 = Release|Win32
- {D4F0486B-D89B-4BD7-9050-D75E28882A57}.Debug|x64.ActiveCfg = Debug|x64
- {D4F0486B-D89B-4BD7-9050-D75E28882A57}.Debug|x64.Build.0 = Debug|x64
- {D4F0486B-D89B-4BD7-9050-D75E28882A57}.Release|x64.ActiveCfg = Release|x64
- {D4F0486B-D89B-4BD7-9050-D75E28882A57}.Release|x64.Build.0 = Release|x64
+ {DBA7C5E3-522A-4974-B0C3-543BBC1665FF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DBA7C5E3-522A-4974-B0C3-543BBC1665FF}.Debug|Win32.Build.0 = Debug|Win32
+ {DBA7C5E3-522A-4974-B0C3-543BBC1665FF}.Release|Win32.ActiveCfg = Release|Win32
+ {DBA7C5E3-522A-4974-B0C3-543BBC1665FF}.Release|Win32.Build.0 = Release|Win32
+ {DBA7C5E3-522A-4974-B0C3-543BBC1665FF}.Debug|x64.ActiveCfg = Debug|x64
+ {DBA7C5E3-522A-4974-B0C3-543BBC1665FF}.Debug|x64.Build.0 = Debug|x64
+ {DBA7C5E3-522A-4974-B0C3-543BBC1665FF}.Release|x64.ActiveCfg = Release|x64
+ {DBA7C5E3-522A-4974-B0C3-543BBC1665FF}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/storage/tools/spti/src/spti.vcxproj b/storage/tools/spti/src/spti.vcxproj
index 01ae43d8..25cb31d5 100644
--- a/storage/tools/spti/src/spti.vcxproj
+++ b/storage/tools/spti/src/spti.vcxproj
@@ -19,11 +19,11 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{40B0D7DE-6A79-41C5-A355-A999BB42A951}</ProjectGuid>
+ <ProjectGuid>{DBA7C5E3-522A-4974-B0C3-543BBC1665FF}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{7002EA4E-B7BB-4431-A747-8D770F3AD59B}</SampleGuid>
+ <SampleGuid>{2A05EF6E-AE10-41D1-B69C-7F7FA900C3AF}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
diff --git a/storage/tools/spti/src/spti.vcxproj.Filters b/storage/tools/spti/src/spti.vcxproj.Filters
index 43ad3833..3e529631 100644
--- a/storage/tools/spti/src/spti.vcxproj.Filters
+++ b/storage/tools/spti/src/spti.vcxproj.Filters
@@ -3,15 +3,15 @@
<ItemGroup>
<Filter Include="Source Files">
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{BB423131-A93F-46FB-BA43-CF499EC9CC89}</UniqueIdentifier>
+ <UniqueIdentifier>{375FCCC2-18CE-4664-831F-EA5D78430D2A}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{C6BB7E16-A4A0-4C56-ACCF-284379723BB1}</UniqueIdentifier>
+ <UniqueIdentifier>{54174E24-721E-4847-9A4B-E6920C428B4F}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{65D2BE7B-77DA-4A13-9FF9-664CD8AAF907}</UniqueIdentifier>
+ <UniqueIdentifier>{E9DF5BAA-ADC0-4E88-A522-113000A45C10}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>