diff options
Diffstat (limited to 'storage')
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 Binary files differindex a1ba9f7f..d74fe65b 100644 --- a/storage/class/cdrom/src/cdrom.inf +++ b/storage/class/cdrom/src/cdrom.inf 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*)¤tTime.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 = ¤tTime; + 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 = ¤tTime; + 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 Binary files differindex 85210823..cf48a217 100644 --- a/storage/ramdisk/src/ramdisk.inx +++ b/storage/ramdisk/src/ramdisk.inx 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> |
