/*++ BUILD Version: 0001 // Increment this if a change has global effects Copyright (c) Microsoft Corporation. All rights reserved. Module Name: ntddscsi.h Abstract: This is the include file that defines all constants and types for accessing the SCSI port adapters. --*/ // // Interface GUIDs // // need these GUIDs outside conditional includes so that user can // #include in precompiled header // #include in a single source file // #include in that source file a second time to instantiate the GUIDs // #ifdef DEFINE_GUID // // Make sure FAR is defined... // #ifndef FAR #ifdef _WIN32 #define FAR #else #define FAR _far #endif #endif DEFINE_GUID(ScsiRawInterfaceGuid, 0x53f56309L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); DEFINE_GUID(WmiScsiAddressGuid, 0x53f5630fL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); #endif #ifndef _NTDDSCSIH_ #define _NTDDSCSIH_ #include #pragma region Desktop Family or OneCore Family #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) #ifdef __cplusplus extern "C" { #endif #if _MSC_VER >= 1200 #pragma warning(push) #pragma warning(disable:4820) /* padding added after data member */ #endif // // Device Name - this string is the name of the device. It is the name // that should be passed to NtOpenFile when accessing the device. // // Note: For devices that support multiple units, it should be suffixed // with the Ascii representation of the unit number. // #define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER #define FILE_DEVICE_SCSI 0x0000001b #define DD_SCSI_DEVICE_NAME "\\Device\\ScsiPort" // // NtDeviceIoControlFile IoControlCode values for this device. // // Warning: Remember that the low two bits of the code specify how the // buffers are passed to the driver! // #define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_FREE_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0409, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_IDE_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_ATA_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_ATA_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x040c, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_ATA_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x040d, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MINIPORT_PROCESS_SERVICE_IRP CTL_CODE(IOCTL_SCSI_BASE, 0x040e, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MPIO_PASS_THROUGH_PATH CTL_CODE(IOCTL_SCSI_BASE, 0x040f, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MPIO_PASS_THROUGH_PATH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0410, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_PASS_THROUGH_EX CTL_CODE(IOCTL_SCSI_BASE, 0x0411, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_PASS_THROUGH_DIRECT_EX CTL_CODE(IOCTL_SCSI_BASE, 0x0412, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MPIO_PASS_THROUGH_PATH_EX CTL_CODE(IOCTL_SCSI_BASE, 0x0413, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MPIO_PASS_THROUGH_PATH_DIRECT_EX CTL_CODE(IOCTL_SCSI_BASE, 0x0414, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // // Note: Function code values of less than 0x800 are reserved for Microsoft. Values of 0x800 and higher can be used by vendors. // So do not use function code of 0x800 and higher to define new IOCTLs in this file. // // // Non Volatile Cache support // #define IOCTL_SCSI_MINIPORT_NVCACHE ((FILE_DEVICE_SCSI << 16) + 0x0600) // // Hybrid Device support // #define IOCTL_SCSI_MINIPORT_HYBRID ((FILE_DEVICE_SCSI << 16) + 0x0620) // // Firmware upgrade support // #define IOCTL_SCSI_MINIPORT_FIRMWARE ((FILE_DEVICE_SCSI << 16) + 0x0780) // // Diagnostic support // #define IOCTL_SCSI_MINIPORT_DIAGNOSTIC ((FILE_DEVICE_SCSI << 16) + 0x0900) // // Define the SCSI pass through structure. // typedef struct _SCSI_PASS_THROUGH { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; ULONG_PTR DataBufferOffset; ULONG SenseInfoOffset; UCHAR Cdb[16]; }SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; // // Define the SCSI pass through direct structure. // typedef struct _SCSI_PASS_THROUGH_DIRECT { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; PVOID DataBuffer; ULONG SenseInfoOffset; UCHAR Cdb[16]; }SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; // // Define the SCSI pass through direct structure for Win64 (thunking). // #if defined(_WIN64) typedef struct _SCSI_PASS_THROUGH32 { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; ULONG32 DataBufferOffset; ULONG SenseInfoOffset; UCHAR Cdb[16]; }SCSI_PASS_THROUGH32, *PSCSI_PASS_THROUGH32; // // Define the SCSI pass through direct structure. // typedef struct _SCSI_PASS_THROUGH_DIRECT32 { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; VOID * POINTER_32 DataBuffer; ULONG SenseInfoOffset; UCHAR Cdb[16]; }SCSI_PASS_THROUGH_DIRECT32, *PSCSI_PASS_THROUGH_DIRECT32; #endif // // Data structure for IOCTL_SCSI_PASS_THROUGH_EX // typedef struct _SCSI_PASS_THROUGH_EX { ULONG Version; ULONG Length; // size of the structure ULONG CdbLength; // non-zero value should be set by caller ULONG StorAddressLength; // non-zero value should be set by caller UCHAR ScsiStatus; UCHAR SenseInfoLength; // optional, can be zero UCHAR DataDirection; // data transfer direction UCHAR Reserved; // padding ULONG TimeOutValue; ULONG StorAddressOffset; // a value bigger than (structure size + CdbLength) should be set by caller ULONG SenseInfoOffset; ULONG DataOutTransferLength; // optional, can be zero ULONG DataInTransferLength; // optional, can be zero ULONG_PTR DataOutBufferOffset; ULONG_PTR DataInBufferOffset; _Field_size_bytes_full_(CdbLength) UCHAR Cdb[ANYSIZE_ARRAY]; } SCSI_PASS_THROUGH_EX, *PSCSI_PASS_THROUGH_EX; // // Data structure for IOCTL_SCSI_PASS_THROUGH_DIRECT_EX // typedef struct _SCSI_PASS_THROUGH_DIRECT_EX { ULONG Version; ULONG Length; // size of the structure ULONG CdbLength; // non-zero value should be set by caller ULONG StorAddressLength; // non-zero value should be set by caller UCHAR ScsiStatus; UCHAR SenseInfoLength; // optional, can be zero UCHAR DataDirection; // data transfer direction UCHAR Reserved; // padding ULONG TimeOutValue; ULONG StorAddressOffset; // a value bigger than (structure size + CdbLength) should be set by caller ULONG SenseInfoOffset; ULONG DataOutTransferLength; // optional, can be zero ULONG DataInTransferLength; // optional, can be zero _Field_size_bytes_full_(DataOutTransferLength) VOID * DataOutBuffer; _Field_size_bytes_full_opt_(DataInTransferLength) VOID * DataInBuffer; _Field_size_bytes_full_(CdbLength) UCHAR Cdb[ANYSIZE_ARRAY]; } SCSI_PASS_THROUGH_DIRECT_EX, *PSCSI_PASS_THROUGH_DIRECT_EX; // // Structure needed for WOW64 support // #if defined(_WIN64) // // Data structure for IOCTL_SCSI_PASS_THROUGH_EX // typedef struct _SCSI_PASS_THROUGH32_EX { ULONG Version; ULONG Length; // size of the structure ULONG CdbLength; // non-zero value should be set by caller ULONG StorAddressLength; // non-zero value should be set by caller UCHAR ScsiStatus; UCHAR SenseInfoLength; // optional, can be zero UCHAR DataDirection; // data transfer direction UCHAR Reserved; // padding ULONG TimeOutValue; ULONG StorAddressOffset; // a value bigger than (structure size + CdbLength) should be set by caller ULONG SenseInfoOffset; ULONG DataOutTransferLength; // optional, can be zero ULONG DataInTransferLength; // optional, can be zero ULONG32 DataOutBufferOffset; ULONG32 DataInBufferOffset; _Field_size_bytes_full_(CdbLength) UCHAR Cdb[ANYSIZE_ARRAY]; } SCSI_PASS_THROUGH32_EX, *PSCSI_PASS_THROUGH32_EX; // // Data structure for IOCTL_SCSI_PASS_THROUGH_DIRECT_EX // typedef struct _SCSI_PASS_THROUGH_DIRECT32_EX { ULONG Version; ULONG Length; // size of the structure ULONG CdbLength; // non-zero value should be set by caller ULONG StorAddressLength; // non-zero value should be set by caller UCHAR ScsiStatus; UCHAR SenseInfoLength; // optional, can be zero UCHAR DataDirection; // data transfer direction UCHAR Reserved; // padding ULONG TimeOutValue; ULONG StorAddressOffset; // a value bigger than (structure size + CdbLength) should be set by caller ULONG SenseInfoOffset; ULONG DataOutTransferLength; // optional, can be zero ULONG DataInTransferLength; // optional, can be zero _Field_size_bytes_full_(DataOutTransferLength) VOID * POINTER_32 DataOutBuffer; _Field_size_bytes_full_opt_(DataInTransferLength) VOID * POINTER_32 DataInBuffer; _Field_size_bytes_full_(CdbLength) UCHAR Cdb[ANYSIZE_ARRAY]; } SCSI_PASS_THROUGH_DIRECT32_EX, *PSCSI_PASS_THROUGH_DIRECT32_EX; #endif // // ATA pass through structure // typedef struct _ATA_PASS_THROUGH_EX { USHORT Length; USHORT AtaFlags; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR ReservedAsUchar; ULONG DataTransferLength; ULONG TimeOutValue; ULONG ReservedAsUlong; ULONG_PTR DataBufferOffset; UCHAR PreviousTaskFile[8]; UCHAR CurrentTaskFile[8]; } ATA_PASS_THROUGH_EX, *PATA_PASS_THROUGH_EX; // // ATA pass through direct structure. // typedef struct _ATA_PASS_THROUGH_DIRECT { USHORT Length; USHORT AtaFlags; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR ReservedAsUchar; ULONG DataTransferLength; ULONG TimeOutValue; ULONG ReservedAsUlong; PVOID DataBuffer; UCHAR PreviousTaskFile[8]; UCHAR CurrentTaskFile[8]; } ATA_PASS_THROUGH_DIRECT, *PATA_PASS_THROUGH_DIRECT; // // Define the ATA pass through direct structure for Win64 (thunking). // #if defined(_WIN64) typedef struct _ATA_PASS_THROUGH_EX32 { USHORT Length; USHORT AtaFlags; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR ReservedAsUchar; ULONG DataTransferLength; ULONG TimeOutValue; ULONG ReservedAsUlong; ULONG32 DataBufferOffset; UCHAR PreviousTaskFile[8]; UCHAR CurrentTaskFile[8]; } ATA_PASS_THROUGH_EX32, *PATA_PASS_THROUGH_EX32; // // ATA pass through direct structure. // typedef struct _ATA_PASS_THROUGH_DIRECT32 { USHORT Length; USHORT AtaFlags; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR ReservedAsUchar; ULONG DataTransferLength; ULONG TimeOutValue; ULONG ReservedAsUlong; VOID * POINTER_32 DataBuffer; UCHAR PreviousTaskFile[8]; UCHAR CurrentTaskFile[8]; } ATA_PASS_THROUGH_DIRECT32, *PATA_PASS_THROUGH_DIRECT32; #endif // // ATA Pass Through Flags // #define ATA_FLAGS_DRDY_REQUIRED (1 << 0) #define ATA_FLAGS_DATA_IN (1 << 1) #define ATA_FLAGS_DATA_OUT (1 << 2) #define ATA_FLAGS_48BIT_COMMAND (1 << 3) #define ATA_FLAGS_USE_DMA (1 << 4) #define ATA_FLAGS_NO_MULTIPLE (1 << 5) // // Define header for IOCTL_ATA_MINIPORT // typedef struct _IDE_IO_CONTROL { ULONG HeaderLength; UCHAR Signature[8]; ULONG Timeout; ULONG ControlCode; ULONG ReturnStatus; ULONG DataLength; } IDE_IO_CONTROL, *PIDE_IO_CONTROL; // // Define the structure for IOCTL_MPIO_PASS_THROUGH_PATH. // typedef struct _MPIO_PASS_THROUGH_PATH { SCSI_PASS_THROUGH PassThrough; ULONG Version; USHORT Length; UCHAR Flags; UCHAR PortNumber; ULONGLONG MpioPathId; } MPIO_PASS_THROUGH_PATH, *PMPIO_PASS_THROUGH_PATH; // // Define the structure for IOCTL_MPIO_PASS_THROUGH_PATH_DIRECT. // typedef struct _MPIO_PASS_THROUGH_PATH_DIRECT { SCSI_PASS_THROUGH_DIRECT PassThrough; ULONG Version; USHORT Length; UCHAR Flags; UCHAR PortNumber; ULONGLONG MpioPathId; } MPIO_PASS_THROUGH_PATH_DIRECT, *PMPIO_PASS_THROUGH_PATH_DIRECT; // // Define the structure for IOCTL_MPIO_PASS_THROUGH_PATH_EX. // typedef struct _MPIO_PASS_THROUGH_PATH_EX { ULONG PassThroughOffset; // Offset to a SCSI_PASS_THROUGH_EX structure. ULONG Version; USHORT Length; UCHAR Flags; UCHAR PortNumber; ULONGLONG MpioPathId; } MPIO_PASS_THROUGH_PATH_EX, *PMPIO_PASS_THROUGH_PATH_EX; // // Define the structure for IOCTL_MPIO_PASS_THROUGH_PATH_DIRECT_EX. // typedef struct _MPIO_PASS_THROUGH_PATH_DIRECT_EX { ULONG PassThroughOffset; // Offset to a PSCSI_PASS_THROUGH_DIRECT_EX structure. ULONG Version; USHORT Length; UCHAR Flags; UCHAR PortNumber; ULONGLONG MpioPathId; } MPIO_PASS_THROUGH_PATH_DIRECT_EX, *PMPIO_PASS_THROUGH_PATH_DIRECT_EX; // // Define the IOCTL_MPIO_PASS_THROUGH_PATH structure for Win64 (thunking). // #if defined(_WIN64) typedef struct _MPIO_PASS_THROUGH_PATH32 { SCSI_PASS_THROUGH32 PassThrough; ULONG Version; USHORT Length; UCHAR Flags; UCHAR PortNumber; ULONGLONG MpioPathId; } MPIO_PASS_THROUGH_PATH32, *PMPIO_PASS_THROUGH_PATH32; // // Define the IOCTL_MPIO_PASS_THROUGH_PATH_DIRECT structure for Win64 (thunking). // typedef struct _MPIO_PASS_THROUGH_PATH_DIRECT32 { SCSI_PASS_THROUGH_DIRECT32 PassThrough; ULONG Version; USHORT Length; UCHAR Flags; UCHAR PortNumber; ULONGLONG MpioPathId; } MPIO_PASS_THROUGH_PATH_DIRECT32, *PMPIO_PASS_THROUGH_PATH_DIRECT32; // // Define the IOCTL_MPIO_PASS_THROUGH_PATH_EX structure for Win64 (thunking). // typedef struct _MPIO_PASS_THROUGH_PATH32_EX { ULONG PassThroughOffset; // Offset to a PSCSI_PASS_THROUGH32_EX structure. ULONG Version; USHORT Length; UCHAR Flags; UCHAR PortNumber; ULONGLONG MpioPathId; } MPIO_PASS_THROUGH_PATH32_EX, *PMPIO_PASS_THROUGH_PATH32_EX; // // Define the IOCTL_MPIO_PASS_THROUGH_PATH_DIRECT_EX structure for Win64 (thunking). // typedef struct _MPIO_PASS_THROUGH_PATH_DIRECT32_EX { ULONG PassThroughOffset; // Offset to a PSCSI_PASS_THROUGH_DIRECT32_EX structure. ULONG Version; USHORT Length; UCHAR Flags; UCHAR PortNumber; ULONGLONG MpioPathId; } MPIO_PASS_THROUGH_PATH_DIRECT32_EX, *PMPIO_PASS_THROUGH_PATH_DIRECT32_EX; #endif // // Define SCSI information. // Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. // typedef struct _SCSI_BUS_DATA { UCHAR NumberOfLogicalUnits; UCHAR InitiatorBusId; ULONG InquiryDataOffset; }SCSI_BUS_DATA, *PSCSI_BUS_DATA; // // Define SCSI adapter bus information structure.. // Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. // typedef struct _SCSI_ADAPTER_BUS_INFO { UCHAR NumberOfBuses; SCSI_BUS_DATA BusData[1]; } SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; // // Define SCSI adapter bus information. // Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL. // typedef struct _SCSI_INQUIRY_DATA { UCHAR PathId; UCHAR TargetId; UCHAR Lun; BOOLEAN DeviceClaimed; ULONG InquiryDataLength; ULONG NextInquiryDataOffset; UCHAR InquiryData[1]; }SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; // // Define header for I/O control SRB. // // // Acceptable signatures for SCSI IOCTL MINIPORT calls. Must be equal in byte size to sizeof(SrbIoctl->Signature) // #define IOCTL_MINIPORT_SIGNATURE_SCSIDISK "SCSIDISK" #define IOCTL_MINIPORT_SIGNATURE_HYBRDISK "HYBRDISK" #define IOCTL_MINIPORT_SIGNATURE_DSM_NOTIFICATION "MPDSM " #define IOCTL_MINIPORT_SIGNATURE_DSM_GENERAL "MPDSMGEN" #define IOCTL_MINIPORT_SIGNATURE_FIRMWARE "FIRMWARE" #define IOCTL_MINIPORT_SIGNATURE_QUERY_PROTOCOL "PROTOCOL" #define IOCTL_MINIPORT_SIGNATURE_SET_PROTOCOL "SETPROTO" #define IOCTL_MINIPORT_SIGNATURE_QUERY_TEMPERATURE "TEMPERAT" #define IOCTL_MINIPORT_SIGNATURE_SET_TEMPERATURE_THRESHOLD "SETTEMPT" #define IOCTL_MINIPORT_SIGNATURE_QUERY_PHYSICAL_TOPOLOGY "TOPOLOGY" #define IOCTL_MINIPORT_SIGNATURE_ENDURANCE_INFO "ENDURINF" typedef struct _SRB_IO_CONTROL { ULONG HeaderLength; UCHAR Signature[8]; ULONG Timeout; ULONG ControlCode; ULONG ReturnCode; ULONG Length; } SRB_IO_CONTROL, *PSRB_IO_CONTROL; typedef struct _NVCACHE_REQUEST_BLOCK { ULONG NRBSize; USHORT Function; ULONG NRBFlags; ULONG NRBStatus; ULONG Count; ULONGLONG LBA; ULONG DataBufSize; ULONG NVCacheStatus; ULONG NVCacheSubStatus; } NVCACHE_REQUEST_BLOCK, *PNVCACHE_REQUEST_BLOCK; #define NRB_FUNCTION_NVCACHE_INFO 0xEC #define NRB_FUNCTION_SPINDLE_STATUS 0xE5 #define NRB_FUNCTION_NVCACHE_POWER_MODE_SET 0x00 #define NRB_FUNCTION_NVCACHE_POWER_MODE_RETURN 0x01 #define NRB_FUNCTION_FLUSH_NVCACHE 0x14 #define NRB_FUNCTION_QUERY_PINNED_SET 0x12 #define NRB_FUNCTION_QUERY_CACHE_MISS 0x13 #define NRB_FUNCTION_ADD_LBAS_PINNED_SET 0x10 #define NRB_FUNCTION_REMOVE_LBAS_PINNED_SET 0x11 #define NRB_FUNCTION_QUERY_ASCENDER_STATUS 0xD0 #define NRB_FUNCTION_QUERY_HYBRID_DISK_STATUS 0xD1 // // The NRB function - NRB_FUNCTION_PASS_HINT_PAYLOAD is deprecated. // #define NRB_FUNCTION_PASS_HINT_PAYLOAD 0xE0 // // Function set to control write back caching policy separated non volatile cache in the miniport // #define NRB_FUNCTION_NVSEPARATED_INFO 0xc0 #define NRB_FUNCTION_NVSEPARATED_FLUSH 0xc1 #define NRB_FUNCTION_NVSEPARATED_WB_DISABLE 0xc2 #define NRB_FUNCTION_NVSEPARATED_WB_REVERT_DEFAULT 0xc3 #define NRB_SUCCESS 0 #define NRB_ILLEGAL_REQUEST 1 #define NRB_INVALID_PARAMETER 2 #define NRB_INPUT_DATA_OVERRUN 3 #define NRB_INPUT_DATA_UNDERRUN 4 #define NRB_OUTPUT_DATA_OVERRUN 5 #define NRB_OUTPUT_DATA_UNDERRUN 6 typedef struct _NV_FEATURE_PARAMETER{ USHORT NVPowerModeEnabled; USHORT NVParameterReserv1; USHORT NVCmdEnabled; USHORT NVParameterReserv2; USHORT NVPowerModeVer; USHORT NVCmdVer; ULONG NVSize; // in number of LBA USHORT NVReadSpeed; // in MB/s USHORT NVWrtSpeed; ULONG DeviceSpinUpTime; // in second } NV_FEATURE_PARAMETER, *PNV_FEATURE_PARAMETER; #pragma warning(push) #pragma warning(disable:4214) // bit fields other than int #pragma warning(disable:4201) // nameless struct/unions // // NOTE that data structure NVCACHE_HINT_PAYLOAD is deprecated along with NRB function - NRB_FUNCTION_PASS_HINT_PAYLOAD. // // Parameter structure for NRB_FUNCTION_PASS_HINT_PAYLOAD request // This is the corresponding data structure for FIS 0x27 defined in SATA-IO spec. // Caller that prepares this data structure shall set '0' to any non-used data field. // #pragma pack(push, nvcachehintpayload, 1) typedef struct _NVCACHE_HINT_PAYLOAD { UCHAR Command; // 0x63 or 0x64 UCHAR Feature7_0; // when Commmand is 0x63, bit 0 - 3 reflects SubCommand UCHAR Feature15_8; UCHAR Count15_8; // when Commmand is 0x64, bit 0 - 4 reflects SubCommand UCHAR LBA7_0; UCHAR LBA15_8; UCHAR LBA23_16; UCHAR LBA31_24; UCHAR LBA39_32; UCHAR LBA47_40; UCHAR Auxiliary7_0; UCHAR Auxiliary23_16; UCHAR Reserved[4]; } NVCACHE_HINT_PAYLOAD, *PNVCACHE_HINT_PAYLOAD; #pragma pack(pop, nvcachehintpayload) // // Parameter structure for NRB_FUNCTION_NVSEPARATED_INFO request // // Describes parameters of non volatile cache, supported by the miniport (aka separated nv cache). // // Caching is associated with the logical unit, it is up to the miniport to implement the exact scope (adapter or unit). MP caching is relative // to what miniport considers as primary non volatile media for the unit. Miniport caching layer is separate from the caching layer integrated // on the device and managed by the specific NRB functions. Miniport may have to support both separated cache and on device cache as well // as volatile caches. Volatile cache policy is queried through the StorageProperty interface. // // Note that owner of the caching policy may be miniport or the HBA firmware, in either case miniport is the handler of the policy setting. // typedef struct _NV_SEP_CACHE_PARAMETER{ ULONG Version; // Version of the request structure ULONG Size; // Size of this structure in bytes union { struct { // // Capability flags, describing separated non volatile cache // UCHAR WriteCacheEnabled : 1; // Is write caching enabled by the miniport as a persistent policy UCHAR WriteCacheChangeable: 1; // Does the miniport respect change in write caching policy UCHAR WriteThroughIOSupported :1;// Does the miniport support WriteThrough semantics for the NV cache on individual Writes . UCHAR FlushCacheSupported :1; // Does the miniport support flushing of the NV cache UCHAR ReservedBits: 4; } CacheFlags; UCHAR CacheFlagsSet; } Flags; // // Persistent (cross boot) and effective caching types // UCHAR WriteCacheType; // Type of the NV cache (policy) supported by the miniport - persistent setting. UCHAR WriteCacheTypeEffective;// Effective type of the NV cache (policy) used by the miniport at the time of query. UCHAR ParameterReserve1[3]; } NV_SEP_CACHE_PARAMETER, *PNV_SEP_CACHE_PARAMETER; // // Define version value for the structure // #define NV_SEP_CACHE_PARAMETER_VERSION_1 1 #define NV_SEP_CACHE_PARAMETER_VERSION NV_SEP_CACHE_PARAMETER_VERSION_1 // // Caching policy for separated NV cache. // // There are 2 distinct settings fields, one describing policy as used by the miniport // after boot. The other field describes current effective policy setting, which may be impacted by NRB_FUNCTION_NVSEPARATED_WB_DISABLE // // Caller of NRB_FUNCTION_NVSEPARATED_INFO should expect only the effective policy setting to be modified if the query is made after // call to NRB_FUNCTION_NVSEPARATED_WB_DISABLE (or other control codes in the future). // // Control of the persistent policy setting (WriteCacheType) is performed only through miniport proprietary interfaces // typedef enum _NV_SEP_WRITE_CACHE_TYPE { NVSEPWriteCacheTypeUnknown = 0, // Miniport can't report the type of the write cache NVSEPWriteCacheTypeNone = 1, // Miniport doesn't support non volatile write cache NVSEPWriteCacheTypeWriteBack = 2, // Miniport supports write back caching NVSEPWriteCacheTypeWriteThrough = 3 // Miniport supports write through caching } NV_SEP_WRITE_CACHE_TYPE, *PNV_SEP_WRITE_CACHE_TYPE; #pragma warning(pop) // // STORAGE_DIAGNOSTIC_STATUS definitions // #define STORAGE_DIAGNOSTIC_STATUS_SUCCESS 0 #define STORAGE_DIAGNOSTIC_STATUS_BUFFER_TOO_SMALL 0x1 #define STORAGE_DIAGNOSTIC_STATUS_UNSUPPORTED_VERSION 0x2 #define STORAGE_DIAGNOSTIC_STATUS_INVALID_PARAMETER 0x3 #define STORAGE_DIAGNOSTIC_STATUS_INVALID_SIGNATURE 0x4 #define STORAGE_DIAGNOSTIC_STATUS_INVALID_TARGET_TYPE 0x5 #define STORAGE_DIAGNOSTIC_STATUS_MORE_DATA 0x6 // // Diagnostic level allow caller to control what kinds of data the provider should return. // // Currently there is only default level defined, provider makes the call to return // anything it assumes helpful for diagnostic purpose. // typedef enum _MP_STORAGE_DIAGNOSTIC_LEVEL { MpStorageDiagnosticLevelDefault = 0, MpStorageDiagnosticLevelMax } MP_STORAGE_DIAGNOSTIC_LEVEL, *PMP_STORAGE_DIAGNOSTIC_LEVEL; typedef enum _MP_STORAGE_DIAGNOSTIC_TARGET_TYPE { MpStorageDiagnosticTargetTypeUndefined = 0, MpStorageDiagnosticTargetTypeMiniport = 2, MpStorageDiagnosticTargetTypeHbaFirmware, MpStorageDiagnosticTargetTypeMax } MP_STORAGE_DIAGNOSTIC_TARGET_TYPE, *PMP_STORAGE_DIAGNOSTIC_TARGET_TYPE; // // IOCTL_SCSI_MINIPORT_DIAGNOSTIC // // Diagnostic request to Miniport // // // Parameter for STORAGE_DIAGNOSTIC_MP_REQUEST // Input buffer should contain SRB_IO_CONTROL, STORAGE_DIAGNOSTIC_MP_REQUEST structures. // // Fields in STORAGE_DIAGNOSTIC_MP_REQUEST // - Input: Version // - Input: TargetType // - Input: Level // - Output: ProviderId // - Input/Output: BufferSize // As input: // "BufferSize" should be set to number of bytes allocated for the DataBuffer. // As output: // If the request is failed because of buffer too short, "BufferSize" should be set to the // length required for DataBuffer by the diagnostic data provider; // If the request is successful, it should be filled with returned data size of DataBuffer; // For other cases, it should be cleared to 0. // - Output: DataBuffer // typedef struct _STORAGE_DIAGNOSTIC_MP_REQUEST { // Size of this structure. ULONG Version; // Whole size of the structure and the associated data buffer. ULONG Size; // Request target type. MP_STORAGE_DIAGNOSTIC_TARGET_TYPE TargetType; // Diagnostic level. MP_STORAGE_DIAGNOSTIC_LEVEL Level; // GUID of diagnostic data provider. GUID ProviderId; // Data buffer size. ULONG BufferSize; // Reserved for future use. ULONG Reserved; // Diagnostic data buffer. _Field_size_(BufferSize) UCHAR DataBuffer[ANYSIZE_ARRAY]; } STORAGE_DIAGNOSTIC_MP_REQUEST, *PSTORAGE_DIAGNOSTIC_MP_REQUEST; // // MINIPORT_IOCTL block for data set management notifications // // Structure used to describe the list of ranges to process, should match the one in ntddstor.h // typedef struct _MP_DEVICE_DATA_SET_RANGE { LONGLONG StartingOffset; // Measured in bytes, must align to a sector boundary ULONGLONG LengthInBytes; // Multiple of sector size. } MP_DEVICE_DATA_SET_RANGE, *PMP_DEVICE_DATA_SET_RANGE; typedef struct _DSM_NOTIFICATION_REQUEST_BLOCK { ULONG Size; // Length of this structure ULONG Version; // Version of the template ULONG NotifyFlags; // Same as in DSM definitions (eg Begin, End) ULONG DataSetProfile; // Expected profile of IO access (based on OS file type : eg, hibernation, crashdump) ULONG Reserved[3]; // Reserved for future use ULONG DataSetRangesCount; MP_DEVICE_DATA_SET_RANGE DataSetRanges[ANYSIZE_ARRAY]; } DSM_NOTIFICATION_REQUEST_BLOCK,*PDSM_NOTIFICATION_REQUEST_BLOCK; // // Define version value for the structure // #define MINIPORT_DSM_NOTIFICATION_VERSION_1 1 #define MINIPORT_DSM_NOTIFICATION_VERSION MINIPORT_DSM_NOTIFICATION_VERSION_1 // // Define access profiles, which are passed to the miniport, as describing expected access pattern to the dataset // #define MINIPORT_DSM_PROFILE_UNKNOWN 0 #define MINIPORT_DSM_PROFILE_PAGE_FILE 1 #define MINIPORT_DSM_PROFILE_HIBERNATION_FILE 2 #define MINIPORT_DSM_PROFILE_CRASHDUMP_FILE 3 // // Notification flag values - consistent with DSM flags, defined in ntddstor.h // #define MINIPORT_DSM_NOTIFY_FLAG_BEGIN 0x00000001 // The given LBA range is being used as defined by the profileID #define MINIPORT_DSM_NOTIFY_FLAG_END 0x00000002 // The given LBA range is no longer being used as defined by the proileID // // Data structure and definitions related to IOCTL_SCSI_MINIPORT_HYBRID // #define HYBRID_FUNCTION_GET_INFO 0x01 #define HYBRID_FUNCTION_DISABLE_CACHING_MEDIUM 0x10 #define HYBRID_FUNCTION_ENABLE_CACHING_MEDIUM 0x11 #define HYBRID_FUNCTION_SET_DIRTY_THRESHOLD 0x12 #define HYBRID_FUNCTION_DEMOTE_BY_SIZE 0x13 // // HYBRID IOCTL status // #define HYBRID_STATUS_SUCCESS 0x0 #define HYBRID_STATUS_ILLEGAL_REQUEST 0x1 #define HYBRID_STATUS_INVALID_PARAMETER 0x2 #define HYBRID_STATUS_OUTPUT_BUFFER_TOO_SMALL 0x3 // // A driver should keep a "RefCount" for HYBRID_FUNCTION_ENABLE_CACHING_MEDIUM. // e.g. it increases this value every time when it receives a HYBRID_FUNCTION_ENABLE_CACHING_MEDIUM call. // // When driver receives HYBRID_FUNCTION_DISABLE_CACHING_MEDIUM call, it decreases "RefCount" when it's bigger than 0, // and then only send command to disable caching medium when the new "RefCount" value is 0. // // In case of HYBRID_FUNCTION_DISABLE_CACHING_MEDIUM is received but no command is sent to device because of decreased "RefCount" is not 0, // the driver returns following status to inform caller. // #define HYBRID_STATUS_ENABLE_REFCOUNT_HOLD 0x10 // // General input data structure. // Any data structures in input buffer after SRB_IO_CONTROL should contain HYBRID_REQUEST_BLOCK. // #define HYBRID_REQUEST_BLOCK_STRUCTURE_VERSION 0x1 typedef struct _HYBRID_REQUEST_BLOCK { ULONG Version; // HYBRID_REQUEST_BLOCK_STRUCTURE_VERSION ULONG Size; // Size of the data structure. ULONG Function; // Function code ULONG Flags; ULONG DataBufferOffset; // the offset is from the beginning of buffer. e.g. from beginning of SRB_IO_CONTROL. The value should be multiple of sizeof(PVOID); Value 0 means that there is no data buffer. ULONG DataBufferLength; // length of the buffer } HYBRID_REQUEST_BLOCK, *PHYBRID_REQUEST_BLOCK; // // Parameter for HYBRID_FUNCTION_GET_INFO // Input buffer should contain SRB_IO_CONTROL and HYBRID_REQUEST_BLOCK data structures. // Field "DataBufferOffset" of HYBRID_REQUEST_BLOCK points to output data buffer and HYBRID_INFORMATION should be returned. // // // Output parameter for HYBRID_FUNCTION_GET_INFO // typedef enum _NVCACHE_TYPE { NvCacheTypeUnknown = 0, // Driver can't report the type of the nvcache NvCacheTypeNone = 1, // Device doesn't support non-volatile cache NvCacheTypeWriteBack = 2, // Device supports write back caching NvCacheTypeWriteThrough = 3 // Device supports write through caching } NVCACHE_TYPE; typedef enum _NVCACHE_STATUS { NvCacheStatusUnknown = 0, // Driver can't report non-volatile cache status NvCacheStatusDisabling = 1, // non-volatile cache is in process of being disabled. NvCacheStatusDisabled = 2, // non-volatile cache has been disabled. NvCacheStatusEnabled = 3 // non-volatile cache has been enabled. } NVCACHE_STATUS; typedef struct _NVCACHE_PRIORITY_LEVEL_DESCRIPTOR { UCHAR PriorityLevel; UCHAR Reserved0[3]; ULONG ConsumedNVMSizeFraction; ULONG ConsumedMappingResourcesFraction; ULONG ConsumedNVMSizeForDirtyDataFraction; ULONG ConsumedMappingResourcesForDirtyDataFraction; ULONG Reserved1; } NVCACHE_PRIORITY_LEVEL_DESCRIPTOR, *PNVCACHE_PRIORITY_LEVEL_DESCRIPTOR; #define HYBRID_REQUEST_INFO_STRUCTURE_VERSION 0x1 #pragma warning(push) #pragma warning(disable:4214) // bit fields other than int #pragma warning(disable:4200) // nonstandard extension used : zero-sized array in struct/union typedef struct _HYBRID_INFORMATION { ULONG Version; // HYBRID_REQUEST_INFO_STRUCTURE_VERSION ULONG Size; // sizeof(HYBRID_INFORMATION) BOOLEAN HybridSupported; NVCACHE_STATUS Status; // for hybrid disk, expect values can be: NvCacheStatusDisabling, NvCacheStatusDisabled or NvCacheStatusEnabled NVCACHE_TYPE CacheTypeEffective; // for hybrid disk, expect value will be: NvCacheTypeWriteBack NVCACHE_TYPE CacheTypeDefault; // for hybrid disk, expect values can be: NvCacheTypeWriteBack ULONG FractionBase; // Base value of all fraction type of fields in the data structure. For hybrid disk, value of this field will be 255. ULONGLONG CacheSize; // total size of NVCache. unit: LBA count struct { ULONG WriteCacheChangeable : 1; // Does the device respect change in write caching policy ULONG WriteThroughIoSupported : 1; // Does the device support WriteThrough semantics for the NVCache on individual Writes. ULONG FlushCacheSupported : 1; // Does the device support flushing of the NVCache ULONG Removable : 1; // Does the nvcache can be removed. ULONG ReservedBits : 28; } Attributes; struct { UCHAR PriorityLevelCount; // A non-zero value indicates the non-volatile cache supports priority levels. BOOLEAN MaxPriorityBehavior; // If set to TRUE, the disk may fail IO sent with max priority level when it cannot find space for the IO in caching medium. UCHAR OptimalWriteGranularity; // In LBAs. Value is the power value (of 2). Value 0xFF means that Optimal Write Granularity is not indicated. // For example: value 0 indicates 2^0 = 1 logical sector, 1 indicates 2^1 = 2 logical sectors UCHAR Reserved; ULONG DirtyThresholdLow; // fraction type of value, with base "FractionBase". ULONG DirtyThresholdHigh; // fraction type of value, with base "FractionBase". struct { ULONG CacheDisable : 1; // support of disabling the caching medium ULONG SetDirtyThreshold : 1; // support of Setting dirty threshold for the entire caching medium ULONG PriorityDemoteBySize : 1; // support of demote by size command ULONG PriorityChangeByLbaRange : 1; // support of change by lba command ULONG Evict : 1; // support of evict command ULONG ReservedBits : 27; ULONG MaxEvictCommands; // Max outstanding Evict commands concurrently. Only value when "Evict" value is 1. ULONG MaxLbaRangeCountForEvict; // Count of LBA ranges can be associated with evict command. Only value when "Evict" value is 1. ULONG MaxLbaRangeCountForChangeLba; // Count of LBA ranges associated with PriorityChangeByLbaRange command. Only value when "PriorityChangeByLbaRange" value is 1. } SupportedCommands; NVCACHE_PRIORITY_LEVEL_DESCRIPTOR Priority[0]; } Priorities; } HYBRID_INFORMATION, *PHYBRID_INFORMATION; #pragma warning(pop) // // Parameter for HYBRID_FUNCTION_DISABLE_CACHING_MEDIUM and HYBRID_FUNCTION_ENABLE_CACHING_MEDIUM // Input buffer should contain SRB_IO_CONTROL and HYBRID_REQUEST_BLOCK data structures. // Field "DataBufferOffset" of HYBRID_REQUEST_BLOCK should be set to "0" indicating there is no other parameter associated. // NOTE that these functions don't have output parameter. // // // Parameter for HYBRID_FUNCTION_SET_DIRTY_THRESHOLD // Input buffer should contain SRB_IO_CONTROL, HYBRID_REQUEST_BLOCK and HYBRID_DIRTY_THRESHOLDS data structures. // Field "DataBufferOffset" of HYBRID_REQUEST_BLOCK should be set to the starting offset of HYBRID_DIRTY_THRESHOLDS from beginning of buffer. // NOTE that these functions don't have output parameter. // typedef struct _HYBRID_DIRTY_THRESHOLDS { ULONG Version; ULONG Size; // sizeof(HYBRID_DIRTY_THRESHOLDS) ULONG DirtyLowThreshold; // ULONG DirtyHighThreshold; // >= DirtyLowThreshold } HYBRID_DIRTY_THRESHOLDS, *PHYBRID_DIRTY_THRESHOLDS; // // Parameter for HYBRID_FUNCTION_DEMOTE_BY_SIZE // Input buffer should contain SRB_IO_CONTROL, HYBRID_REQUEST_BLOCK and HYBRID_DEMOTE_BY_SIZE data structures. // Field "DataBufferOffset" of HYBRID_REQUEST_BLOCK should be set to the starting offset of HYBRID_DEMOTE_BY_SIZE from beginning of buffer. // NOTE that these functions don't have output parameter. // typedef struct _HYBRID_DEMOTE_BY_SIZE { ULONG Version; ULONG Size; // sizeof(HYBRID_DEMOTE_BY_SIZE) UCHAR SourcePriority; // 1 ~ max priority UCHAR TargetPriority; // < SourcePriority USHORT Reserved0; ULONG Reserved1; ULONGLONG LbaCount; // How many LBAs should be demoted } HYBRID_DEMOTE_BY_SIZE, *PHYBRID_DEMOTE_BY_SIZE; // // Data structure and definitions related to IOCTL_SCSI_MINIPORT_FIRMWARE // #define FIRMWARE_FUNCTION_GET_INFO 0x01 #define FIRMWARE_FUNCTION_DOWNLOAD 0x02 #define FIRMWARE_FUNCTION_ACTIVATE 0x03 // // FIRMWARE IOCTL status // #define FIRMWARE_STATUS_SUCCESS 0x0 #define FIRMWARE_STATUS_ERROR 0x1 #define FIRMWARE_STATUS_ILLEGAL_REQUEST 0x2 #define FIRMWARE_STATUS_INVALID_PARAMETER 0x3 #define FIRMWARE_STATUS_INPUT_BUFFER_TOO_BIG 0x4 #define FIRMWARE_STATUS_OUTPUT_BUFFER_TOO_SMALL 0x5 #define FIRMWARE_STATUS_INVALID_SLOT 0x6 #define FIRMWARE_STATUS_INVALID_IMAGE 0x7 #define FIRMWARE_STATUS_CONTROLLER_ERROR 0x10 #define FIRMWARE_STATUS_POWER_CYCLE_REQUIRED 0x20 #define FIRMWARE_STATUS_DEVICE_ERROR 0x40 #define FIRMWARE_STATUS_INTERFACE_CRC_ERROR 0x80 #define FIRMWARE_STATUS_UNCORRECTABLE_DATA_ERROR 0x81 #define FIRMWARE_STATUS_MEDIA_CHANGE 0x82 #define FIRMWARE_STATUS_ID_NOT_FOUND 0x83 #define FIRMWARE_STATUS_MEDIA_CHANGE_REQUEST 0x84 #define FIRMWARE_STATUS_COMMAND_ABORT 0x85 #define FIRMWARE_STATUS_END_OF_MEDIA 0x86 #define FIRMWARE_STATUS_ILLEGAL_LENGTH 0x87 // // For IOCTL_SCSI_MINIPORT_FIRMWARE, the data buffer should contain following structures/fields: // 1. SRB_IO_CONTROL // This is the header data structure indicating which IOCTL is sent. In this case, it's IOCTL_SCSI_MINIPORT_FIRMWARE. // 2. FIRMWARE_REQUEST_BLOCK // This data structure shall be right after SRB_IO_CONTROL. It indicates: // a: the function code of firmware request. // b: the data buffer location (in field - DataBufferOffset) and length (in field - DataBufferLength) for the firmware function. // DataBufferOffset: should have value: ALIGN_UP(sizeof(SRB_IO_CONTROL) + sizeof(FIRMWARE_REQUEST_BLOCK), PVOID). This is to make sure the buffer is pointer aligned. // 3. Padding. In case of (sizeof(SRB_IO_CONTROL) + sizeof(FIRMWARE_REQUEST_BLOCK)) is not multiple of pointer size, there will be padding space. // 4. STORAGE_FIRMWARE_INFO or STORAGE_FIRMWARE_DOWNLOAD or STORAGE_FIRMWARE_ACTIVATE depending on the function code of firmware request. // #define FIRMWARE_REQUEST_BLOCK_STRUCTURE_VERSION 0x1 typedef struct _FIRMWARE_REQUEST_BLOCK { ULONG Version; // FIRMWARE_REQUEST_BLOCK_STRUCTURE_VERSION ULONG Size; // Size of the data structure. ULONG Function; // Function code ULONG Flags; ULONG DataBufferOffset; // the offset is from the beginning of buffer. e.g. from beginning of SRB_IO_CONTROL. The value should be multiple of sizeof(PVOID); Value 0 means that there is no data buffer. ULONG DataBufferLength; // length of the buffer } FIRMWARE_REQUEST_BLOCK, *PFIRMWARE_REQUEST_BLOCK; // // The request is for Controller if this flag is set. Otherwise, it's for Device/Unit. // #define FIRMWARE_REQUEST_FLAG_CONTROLLER 0x00000001 // // Indicate that current FW image segment is the last one. // #define FIRMWARE_REQUEST_FLAG_LAST_SEGMENT 0x00000002 // // Indicate that current FW image segment is the first one. // #define FIRMWARE_REQUEST_FLAG_FIRST_SEGMENT 0x00000004 // // Indicate that the existing firmware in slot should be activated immediately without // controller reset. // #define FIRMWARE_REQUEST_FLAG_SWITCH_TO_FIRMWARE_WITHOUT_RESET 0x10000000 // // Indicate that any existing firmware in slot should be replaced with the downloaded image, // and activated with controller reset. // #define FIRMWARE_REQUEST_FLAG_REPLACE_AND_SWITCH_UPON_RESET 0x20000000 // // Indicate that any existing firmware in slot should be replaced with the downloaded image. // #define FIRMWARE_REQUEST_FLAG_REPLACE_EXISTING_IMAGE 0x40000000 // // Indicate that the existing firmware in slot should be activated. // This flag is only valid for fimrware_activate request. It's ignored for other requests. // #define FIRMWARE_REQUEST_FLAG_SWITCH_TO_EXISTING_FIRMWARE 0x80000000 // // Parameter for FIRMWARE_FUNCTION_GET_INFO // Input buffer should contain SRB_IO_CONTROL and FIRMWARE_REQUEST_BLOCK data structures. // Field "DataBufferOffset" of FIRMWARE_REQUEST_BLOCK points to output data buffer and STORAGE_FIRMWARE_INFO should be returned. // // // NOTE: In case of (NTDDI_VERSION >= NTDDI_WINTHRESHOLD), applications should use // IOCTL_STORAGE_FIRMWARE_GET_INFO // IOCTL_STORAGE_FIRMWARE_DOWNLOAD // IOCTL_STORAGE_FIRMWARE_ACTIVATE // to work on storage firmware query and update. // // Storage port driver uses FIRMWARE_FUNCTION_GET_INFO as corresponding interface to communicate to miniport. // Version 1 data structures below are kept for backwards compatibility only. It's recommended that miniport drivers support Version 2 data structures. // // // Output parameter for FIRMWARE_FUNCTION_GET_INFO // The total size of returned data is for Firmware Info is: // sizeof(STORAGE_FIRMWARE_INFO) + sizeof(STORAGE_FIRMWARE_SLOT_INFO) * SlotCount. // If the buffer is not big enough, callee should set "FIRMWARE_STATUS_OUTPUT_BUFFER_TOO_SMALL" into "ReturnCode" field of SRB_IO_CONTROL, // and the required size in "DataBufferLength" field of FIRMWARE_REQUEST_BLOCK. // #define STORAGE_FIRMWARE_INFO_STRUCTURE_VERSION 0x1 #define STORAGE_FIRMWARE_INFO_STRUCTURE_VERSION_V2 0x2 #define STORAGE_FIRMWARE_INFO_INVALID_SLOT 0xFF typedef struct _STORAGE_FIRMWARE_SLOT_INFO { UCHAR SlotNumber; BOOLEAN ReadOnly; UCHAR Reserved[6]; union { UCHAR Info[8]; ULONGLONG AsUlonglong; } Revision; } STORAGE_FIRMWARE_SLOT_INFO, *PSTORAGE_FIRMWARE_SLOT_INFO; #define STORAGE_FIRMWARE_SLOT_INFO_V2_REVISION_LENGTH 16 typedef struct _STORAGE_FIRMWARE_SLOT_INFO_V2 { UCHAR SlotNumber; BOOLEAN ReadOnly; UCHAR Reserved[6]; UCHAR Revision[STORAGE_FIRMWARE_SLOT_INFO_V2_REVISION_LENGTH]; } STORAGE_FIRMWARE_SLOT_INFO_V2, *PSTORAGE_FIRMWARE_SLOT_INFO_V2; #pragma warning(push) #pragma warning(disable:4200) // nonstandard extension used : zero-sized array in struct/union typedef struct _STORAGE_FIRMWARE_INFO { ULONG Version; // STORAGE_FIRMWARE_INFO_STRUCTURE_VERSION ULONG Size; // sizeof(STORAGE_FIRMWARE_INFO) BOOLEAN UpgradeSupport; UCHAR SlotCount; UCHAR ActiveSlot; UCHAR PendingActivateSlot; ULONG Reserved; STORAGE_FIRMWARE_SLOT_INFO Slot[0]; } STORAGE_FIRMWARE_INFO, *PSTORAGE_FIRMWARE_INFO; typedef struct _STORAGE_FIRMWARE_INFO_V2 { ULONG Version; // STORAGE_FIRMWARE_INFO_STRUCTURE_VERSION_V2 ULONG Size; // sizeof(STORAGE_FIRMWARE_INFO_V2) BOOLEAN UpgradeSupport; UCHAR SlotCount; UCHAR ActiveSlot; UCHAR PendingActivateSlot; BOOLEAN FirmwareShared; // The firmware applies to both device and adapter. For example: PCIe SSD. UCHAR Reserved[3]; ULONG ImagePayloadAlignment; // Number of bytes. Max: PAGE_SIZE. The transfer size should be multiple of this unit size. Some protocol requires at least sector size. 0 means the value is not valid. ULONG ImagePayloadMaxSize; // for a single command. STORAGE_FIRMWARE_SLOT_INFO_V2 Slot[0]; } STORAGE_FIRMWARE_INFO_V2, *PSTORAGE_FIRMWARE_INFO_V2; // // Parameter for FIRMWARE_FUNCTION_DOWNLOAD // Input buffer should contain SRB_IO_CONTROL and FIRMWARE_REQUEST_BLOCK data structures. // Field "DataBufferOffset" of FIRMWARE_REQUEST_BLOCK points to input data buffer that contains STORAGE_FIRMWARE_DOWNLOAD. // #define STORAGE_FIRMWARE_DOWNLOAD_STRUCTURE_VERSION 0x1 #define STORAGE_FIRMWARE_DOWNLOAD_STRUCTURE_VERSION_V2 0x2 typedef struct _STORAGE_FIRMWARE_DOWNLOAD { ULONG Version; // STORAGE_FIRMWARE_DOWNLOAD_STRUCTURE_VERSION ULONG Size; // sizeof(STORAGE_FIRMWARE_DOWNLOAD) ULONGLONG Offset; // image file offset, should be aligned to value of "ImagePayloadAlignment" from STORAGE_FIRMWARE_INFO. ULONGLONG BufferSize; // should be multiple of value of "ImagePayloadAlignment" from STORAGE_FIRMWARE_INFO UCHAR ImageBuffer[0]; // firmware image file. } STORAGE_FIRMWARE_DOWNLOAD, *PSTORAGE_FIRMWARE_DOWNLOAD; typedef struct _STORAGE_FIRMWARE_DOWNLOAD_V2 { ULONG Version; // STORAGE_FIRMWARE_DOWNLOAD_STRUCTURE_VERSION_V2 ULONG Size; // sizeof(STORAGE_FIRMWARE_DOWNLOAD_V2) ULONGLONG Offset; // image file offset, should be aligned to value of "ImagePayloadAlignment" from STORAGE_FIRMWARE_INFO. ULONGLONG BufferSize; // should be multiple of value of "ImagePayloadAlignment" from STORAGE_FIRMWARE_INFO UCHAR Slot; UCHAR Reserved[3]; ULONG ImageSize; UCHAR ImageBuffer[0]; // firmware image file. } STORAGE_FIRMWARE_DOWNLOAD_V2, *PSTORAGE_FIRMWARE_DOWNLOAD_V2; #pragma warning(pop) // // Parameter for FIRMWARE_FUNCTION_ACTIVATE // Input buffer should contain SRB_IO_CONTROL and FIRMWARE_REQUEST_BLOCK data structures. // Field "DataBufferOffset" of FIRMWARE_REQUEST_BLOCK points to input data buffer that contains STORAGE_FIRMWARE_ACTIVATE. // #define STORAGE_FIRMWARE_ACTIVATE_STRUCTURE_VERSION 0x1 typedef struct _STORAGE_FIRMWARE_ACTIVATE { ULONG Version; ULONG Size; UCHAR SlotToActivate; UCHAR Reserved0[3]; } STORAGE_FIRMWARE_ACTIVATE, *PSTORAGE_FIRMWARE_ACTIVATE; // // SCSI port driver capabilities structure. // typedef struct _IO_SCSI_CAPABILITIES { // // Length of this structure // ULONG Length; // // Maximum transfer size in single SRB // ULONG MaximumTransferLength; // // Maximum number of physical pages per data buffer // ULONG MaximumPhysicalPages; // // Async calls from port to class // ULONG SupportedAsynchronousEvents; // // Alignment mask for data transfers. // ULONG AlignmentMask; // // Supports tagged queuing // BOOLEAN TaggedQueuing; // // Host adapter scans down for bios devices. // BOOLEAN AdapterScansDown; // // The host adapter uses programmed I/O. // BOOLEAN AdapterUsesPio; } IO_SCSI_CAPABILITIES, *PIO_SCSI_CAPABILITIES; typedef struct _SCSI_ADDRESS { ULONG Length; UCHAR PortNumber; UCHAR PathId; UCHAR TargetId; UCHAR Lun; } SCSI_ADDRESS, *PSCSI_ADDRESS; // // Define structure for returning crash dump pointers. // struct _ADAPTER_OBJECT; #define DUMP_POINTERS_VERSION_1 1 #define DUMP_POINTERS_VERSION_2 2 #define DUMP_POINTERS_VERSION_3 3 #define DUMP_POINTERS_VERSION_4 4 #define DUMP_DRIVER_NAME_LENGTH 15 typedef LONG DUMP_DEVICE_POWERON_ROUTINE( _In_ PVOID Context ); typedef DUMP_DEVICE_POWERON_ROUTINE *PDUMP_DEVICE_POWERON_ROUTINE; typedef struct _DUMP_POINTERS_VERSION { // // Dump pointers structure version // ULONG Version; // // Dump pointers structure size // ULONG Size; } DUMP_POINTERS_VERSION, *PDUMP_POINTERS_VERSION; typedef struct _DUMP_POINTERS { struct _ADAPTER_OBJECT *AdapterObject; PVOID MappedRegisterBase; PVOID DumpData; PVOID CommonBufferVa; LARGE_INTEGER CommonBufferPa; ULONG CommonBufferSize; BOOLEAN AllocateCommonBuffers; #if (NTDDI_VERSION < NTDDI_WINXP) UCHAR Spare1[3]; #else BOOLEAN UseDiskDump; UCHAR Spare1[2]; #endif PVOID DeviceObject; } DUMP_POINTERS, *PDUMP_POINTERS; typedef struct _DUMP_POINTERS_EX { DUMP_POINTERS_VERSION Header; PVOID DumpData; PVOID CommonBufferVa; ULONG CommonBufferSize; BOOLEAN AllocateCommonBuffers; PVOID DeviceObject; PVOID DriverList; #if (NTDDI_VERSION >= NTDDI_WIN8) // // Start of DUMP_POINTERS_EX_V3 specific fields // ULONG dwPortFlags; // Bit mask of various flags, returned by the port driver to crashdump driver // // Configuration values for device telemetry collection - obtained from either live device or from the registry. // ULONG MaxDeviceDumpSectionSize;// Size of the buffer to hold complete telemetry section from the storage stack (header, public and private subsections) ULONG MaxDeviceDumpLevel; // Max level of device dump to request from the device at the crash time // // Maximum transfer size supported in dump stack // ULONG MaxTransferSize; // // Field needed to support DMA operations in diskdump for storport miniports. // PVOID AdapterObject; PVOID MappedRegisterBase; // // Pointer to stack managed 'device ready for dump'. // PBOOLEAN DeviceReady; #endif #if (NTDDI_VERSION >= NTDDI_WINBLUE) // // Start of DUMP_POINTERS_EX_V4 specific fields // // // Dump device power up callback // PDUMP_DEVICE_POWERON_ROUTINE DumpDevicePowerOn; PVOID DumpDevicePowerOnContext; #endif } DUMP_POINTERS_EX, *PDUMP_POINTERS_EX; #if (NTDDI_VERSION == NTDDI_WIN8) // // Size of the different DUMP_POINTERS_EX structures // #define DUMP_POINTERS_EX_V2_SIZE ((ULONG)FIELD_OFFSET(DUMP_POINTERS_EX, dwPortFlags)) #define DUMP_POINTERS_EX_V3_SIZE sizeof(DUMP_POINTERS_EX) #elif (NTDDI_VERSION >= NTDDI_WINBLUE) #define DUMP_POINTERS_EX_V2_SIZE ((ULONG)FIELD_OFFSET(DUMP_POINTERS_EX, dwPortFlags)) #define DUMP_POINTERS_EX_V3_SIZE ((ULONG)FIELD_OFFSET(DUMP_POINTERS_EX, DumpDevicePowerOn)) #define DUMP_POINTERS_EX_V4_SIZE sizeof(DUMP_POINTERS_EX) #endif // // Bit flag values, returned by the port driver in DUMP_POINTERS_EX structure // // // Driver stack & controller support 64-bit physical memory // #define DUMP_EX_FLAG_SUPPORT_64BITMEMORY 0x00000001 // // Driver stack is capable of producing device and driver telemetry data (individual device may not be able to return data) // #define DUMP_EX_FLAG_SUPPORT_DD_TELEMETRY 0x00000002 // // Driver stack is capable of working after a system resume // #define DUMP_EX_FLAG_RESUME_SUPPORT 0x00000004 // // Driver stack is capable to provide driver full path(DUMP_DRIVER_EX is allocated/used by lower stack) // #define DUMP_EX_FLAG_DRIVER_FULL_PATH_SUPPORT 0x00000008 typedef struct _DUMP_DRIVER { // // Dump driver list from port driver // PVOID DumpDriverList; // // Name of the driver to be loaded // WCHAR DriverName[DUMP_DRIVER_NAME_LENGTH]; // // Driver base name // WCHAR BaseName[DUMP_DRIVER_NAME_LENGTH]; } DUMP_DRIVER, *PDUMP_DRIVER; // // Duplicate UNICODE_STRING definition here to eliminate dependancy // with other header file. // // Unicode strings are counted 16-bit character strings. If they are // NULL terminated, Length does not include trailing NULL. // typedef struct _NTSCSI_UNICODE_STRING { USHORT Length; USHORT MaximumLength; #ifdef MIDL_PASS [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer; #else // MIDL_PASS _Field_size_bytes_part_opt_(MaximumLength, Length) PWCH Buffer; #endif // MIDL_PASS } NTSCSI_UNICODE_STRING; typedef NTSCSI_UNICODE_STRING *PNTSCSI_UNICODE_STRING; typedef struct _DUMP_DRIVER_EX { // // Dump driver list from port driver // PVOID DumpDriverList; // // Name of the driver to be loaded // WCHAR DriverName[DUMP_DRIVER_NAME_LENGTH]; // // Driver base name // WCHAR BaseName[DUMP_DRIVER_NAME_LENGTH]; // // Driver full path string // NTSCSI_UNICODE_STRING DriverFullPath; } DUMP_DRIVER_EX, *PDUMP_DRIVER_EX; // // Define values for pass-through DataIn field. // #define SCSI_IOCTL_DATA_OUT 0 #define SCSI_IOCTL_DATA_IN 1 #define SCSI_IOCTL_DATA_UNSPECIFIED 2 // // This value specifies that there is both a data-in and data-out buffer. // This value is only relevant when used for the DataDirection field of // SCSI_PASS_THROUGH_EX and SCSI_PASS_THROUGH_DIRECT_EX. // #define SCSI_IOCTL_DATA_BIDIRECTIONAL 3 // // Define values for MPIO-pass-through-path Flags field. // #define MPIO_IOCTL_FLAG_USE_PATHID 1 #define MPIO_IOCTL_FLAG_USE_SCSIADDRESS 2 #define MPIO_IOCTL_FLAG_INVOLVE_DSM 4 #pragma warning(push) #pragma warning(disable:4214) // bit fields other than int to disable this around the struct #pragma warning(disable:4201) // nameless struct/union // // Parameters for IOCTL_SCSI_MINIPORT/IOCTL_MINIPORT_SIGNATURE_ENDURANCE_INFO // The storage port driver uses these structures when communicating with the miniport. // typedef struct _STORAGE_ENDURANCE_INFO { ULONG ValidFields; // ValidFields represents bit mapping of valid fields of any type // Eg: Bit 0 stands for GroupId, Bit 1 stands for Flags, Bit 3 for BytesReadCount ULONG GroupId; // Set Id Eg: Set Id for NVMe sets struct { ULONG Shared:1; // TRUE if information is shared with multiple units/groups ULONG Reserved:31; } Flags; ULONG LifePercentage; // Used life percentage UCHAR BytesReadCount[16]; // Total bytes read from device (Billion Unit) UCHAR ByteWriteCount[16]; // Total bytes written to device (Billion Unit) } STORAGE_ENDURANCE_INFO, *PSTORAGE_ENDURANCE_INFO; typedef struct _STORAGE_ENDURANCE_DATA_DESCRIPTOR { ULONG Version; // Version of the endurance information structure ULONG Size; // Size of the endurance information STORAGE_ENDURANCE_INFO EnduranceInfo; // Endurance Information of the device } STORAGE_ENDURANCE_DATA_DESCRIPTOR, *PSTORAGE_ENDURANCE_DATA_DESCRIPTOR; #pragma warning(pop) #if _MSC_VER >= 1200 #pragma warning(pop) #endif #ifdef __cplusplus } #endif #endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) */ #pragma endregion #endif