├── VS2013_sln_proj ├── nvme Package │ └── nvme Package.vcxproj ├── nvme.sln └── nvme │ └── nvme.vcxproj ├── docs ├── Comm_Driver_features_1.docx ├── PT_IOCTL.doc ├── WindowsTraceCollection.pdf └── WindowsWmiDesc.pdf └── source ├── MAKEFILE ├── nvme.h ├── nvme.inf ├── nvme.rc ├── nvmeInit.c ├── nvmeInit.h ├── nvmeIo.c ├── nvmeIo.h ├── nvmeIoctl.h ├── nvmeMofData.mof ├── nvmePwrMgmt.c ├── nvmePwrMgmt.h ├── nvmeReg.h ├── nvmeSnti.c ├── nvmeSnti.h ├── nvmeSntiTypes.h ├── nvmeSntiUtils.h ├── nvmeStat.c ├── nvmeStd.c ├── nvmeStd.h ├── nvmeWmi.c ├── nvmeWmi.h ├── nvme_tracing.h ├── precomp.h └── sources /VS2013_sln_proj/nvme Package/nvme Package.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Win8.1 Debug 6 | Win32 7 | 8 | 9 | Win8 Debug 10 | Win32 11 | 12 | 13 | Win8.1 Release 14 | Win32 15 | 16 | 17 | Win8 Release 18 | Win32 19 | 20 | 21 | Win7 Debug 22 | Win32 23 | 24 | 25 | Win7 Release 26 | Win32 27 | 28 | 29 | Win8.1 Debug 30 | x64 31 | 32 | 33 | Win8 Debug 34 | x64 35 | 36 | 37 | Win8.1 Release 38 | x64 39 | 40 | 41 | Win8 Release 42 | x64 43 | 44 | 45 | Win7 Debug 46 | x64 47 | 48 | 49 | Win7 Release 50 | x64 51 | 52 | 53 | 54 | {E67E2C23-BDBE-47A1-8302-170EED4516F9} 55 | {4605da2c-74a5-4865-98e1-152ef136825f} 56 | v4.5 57 | 11.0 58 | Win8 Debug 59 | Win32 60 | 61 | 62 | nvme_Package 63 | $(VCTargetsPath11) 64 | 65 | 66 | Utility 67 | Package 68 | true 69 | 70 | 71 | 72 | WindowsV6.3 73 | true 74 | WindowsKernelModeDriver8.1 75 | 76 | 77 | Windows8 78 | true 79 | WindowsKernelModeDriver8.1 80 | 81 | 82 | WindowsV6.3 83 | false 84 | WindowsKernelModeDriver8.1 85 | 86 | 87 | Windows8 88 | false 89 | WindowsKernelModeDriver8.1 90 | 91 | 92 | Windows7 93 | true 94 | WindowsKernelModeDriver8.1 95 | 96 | 97 | Windows7 98 | false 99 | WindowsKernelModeDriver8.1 100 | 101 | 102 | WindowsV6.3 103 | true 104 | WindowsKernelModeDriver8.1 105 | 106 | 107 | Windows8 108 | true 109 | WindowsKernelModeDriver8.1 110 | 111 | 112 | WindowsV6.3 113 | false 114 | WindowsKernelModeDriver8.1 115 | 116 | 117 | Windows8 118 | false 119 | WindowsKernelModeDriver8.1 120 | 121 | 122 | Windows7 123 | true 124 | WindowsKernelModeDriver8.1 125 | 126 | 127 | Windows7 128 | false 129 | WindowsKernelModeDriver8.1 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | sys 140 | 141 | 142 | DbgengKernelDebugger 143 | False 144 | True 145 | 146 | 147 | 148 | False 149 | False 150 | True 151 | 152 | 133563 153 | 154 | 155 | sys 156 | 157 | 158 | sys 159 | 160 | 161 | sys 162 | 163 | 164 | sys 165 | 166 | 167 | sys 168 | 169 | 170 | sys 171 | 172 | 173 | sys 174 | 175 | 176 | sys 177 | 178 | 179 | 180 | 1.4.0.0 181 | 182 | 183 | 184 | 185 | nvme64.cat 186 | 187 | 188 | 189 | 190 | 1.4.0.0 191 | 192 | 193 | 194 | 195 | 1.4.0.0 196 | 197 | 198 | 199 | 200 | nvme64.cat 201 | 202 | 203 | 204 | 205 | nvme64.cat 206 | 207 | 208 | 209 | 210 | 1.4.0.0 211 | 212 | 213 | 214 | 215 | 1.4.0.0 216 | 217 | 218 | 219 | 220 | nvme86.cat 221 | 222 | 223 | 224 | 225 | nvme86.cat 226 | 227 | 228 | 229 | 230 | 1.4.0.0 231 | 232 | 233 | 234 | 235 | nvme86.cat 236 | 237 | 238 | 239 | 240 | 1.4.0.0 241 | 242 | 243 | 244 | 245 | nvme64.cat 246 | 247 | 248 | 249 | 250 | 1.4.0.0 251 | 252 | 253 | 254 | 255 | 1.4.0.0 256 | 257 | 258 | 259 | 260 | nvme64.cat 261 | 262 | 263 | 264 | 265 | nvme64.cat 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | {4228e762-9381-4da4-9dda-04a47fa2dac4} 274 | 275 | 276 | 277 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /VS2013_sln_proj/nvme.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 2013 3 | VisualStudioVersion = 12.0.30723.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nvme", "nvme\nvme.vcxproj", "{4228E762-9381-4DA4-9DDA-04A47FA2DAC4}" 6 | EndProject 7 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nvme Package", "nvme Package\nvme Package.vcxproj", "{E67E2C23-BDBE-47A1-8302-170EED4516F9}" 8 | ProjectSection(ProjectDependencies) = postProject 9 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4} = {4228E762-9381-4DA4-9DDA-04A47FA2DAC4} 10 | EndProjectSection 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Win7 Debug|Win32 = Win7 Debug|Win32 15 | Win7 Debug|x64 = Win7 Debug|x64 16 | Win7 Release|Win32 = Win7 Release|Win32 17 | Win7 Release|x64 = Win7 Release|x64 18 | Win8 Debug|Win32 = Win8 Debug|Win32 19 | Win8 Debug|x64 = Win8 Debug|x64 20 | Win8 Release|Win32 = Win8 Release|Win32 21 | Win8 Release|x64 = Win8 Release|x64 22 | Win8.1 Debug|Win32 = Win8.1 Debug|Win32 23 | Win8.1 Debug|x64 = Win8.1 Debug|x64 24 | Win8.1 Release|Win32 = Win8.1 Release|Win32 25 | Win8.1 Release|x64 = Win8.1 Release|x64 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 29 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 30 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 31 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 32 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 33 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 34 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 35 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 36 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 37 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 38 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Release|x64.Build.0 = Win7 Release|x64 39 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 40 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 41 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 42 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 43 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 44 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 45 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 46 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 47 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 48 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 49 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 50 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Release|x64.Build.0 = Win8 Release|x64 51 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 52 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32 53 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32 54 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32 55 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 56 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 57 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 58 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32 59 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32 60 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32 61 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 62 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 63 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 64 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 65 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 66 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 67 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 68 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 69 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 70 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 71 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 72 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 73 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 74 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Release|x64.Build.0 = Win7 Release|x64 75 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 76 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 77 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 78 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 79 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 80 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 81 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 82 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 83 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 84 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 85 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 86 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Release|x64.Build.0 = Win8 Release|x64 87 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 88 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32 89 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32 90 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32 91 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 92 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 93 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 94 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32 95 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32 96 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32 97 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 98 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 99 | {E67E2C23-BDBE-47A1-8302-170EED4516F9}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 100 | EndGlobalSection 101 | GlobalSection(SolutionProperties) = preSolution 102 | HideSolutionNode = FALSE 103 | EndGlobalSection 104 | EndGlobal 105 | -------------------------------------------------------------------------------- /VS2013_sln_proj/nvme/nvme.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Win8.1 Debug 6 | Win32 7 | 8 | 9 | Win8 Debug 10 | Win32 11 | 12 | 13 | Win8.1 Release 14 | Win32 15 | 16 | 17 | Win8 Release 18 | Win32 19 | 20 | 21 | Win7 Debug 22 | Win32 23 | 24 | 25 | Win7 Release 26 | Win32 27 | 28 | 29 | Win8.1 Debug 30 | x64 31 | 32 | 33 | Win8 Debug 34 | x64 35 | 36 | 37 | Win8.1 Release 38 | x64 39 | 40 | 41 | Win8 Release 42 | x64 43 | 44 | 45 | Win7 Debug 46 | x64 47 | 48 | 49 | Win7 Release 50 | x64 51 | 52 | 53 | 54 | {4228E762-9381-4DA4-9DDA-04A47FA2DAC4} 55 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 56 | v4.5 57 | 11.0 58 | Win8 Debug 59 | Win32 60 | 61 | 62 | nvme 63 | $(VCTargetsPath11) 64 | 65 | 66 | Driver 67 | WDM 68 | 69 | 70 | 71 | WindowsV6.3 72 | true 73 | WindowsKernelModeDriver8.1 74 | 75 | 76 | Windows8 77 | true 78 | WindowsKernelModeDriver8.1 79 | 80 | 81 | WindowsV6.3 82 | false 83 | WindowsKernelModeDriver8.1 84 | 85 | 86 | Windows8 87 | false 88 | WindowsKernelModeDriver8.1 89 | 90 | 91 | Windows7 92 | true 93 | WindowsKernelModeDriver8.1 94 | 95 | 96 | Windows7 97 | false 98 | WindowsKernelModeDriver8.1 99 | 100 | 101 | WindowsV6.3 102 | true 103 | WindowsKernelModeDriver8.1 104 | 105 | 106 | Windows8 107 | true 108 | WindowsKernelModeDriver8.1 109 | 110 | 111 | WindowsV6.3 112 | false 113 | WindowsKernelModeDriver8.1 114 | 115 | 116 | Windows8 117 | false 118 | WindowsKernelModeDriver8.1 119 | 120 | 121 | Windows7 122 | true 123 | WindowsKernelModeDriver8.1 124 | 125 | 126 | Windows7 127 | false 128 | WindowsKernelModeDriver8.1 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | DbgengKernelDebugger 140 | 141 | 142 | 143 | true 144 | __KERNEL_;__MSWINDOWS__;%(PreprocessorDefinitions) 145 | Level3 146 | true 147 | true 148 | StorPortDebugPrint(LEVEL,MSG,...) 149 | {km-StorDefault.tpl}*.tmh 150 | ..\..\source\nvme_tracing.h 151 | 152 | 153 | $(DDK_LIB_PATH)\wdm.lib;$(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\scsiwmi.lib;%(AdditionalDependencies) 154 | 155 | 156 | 1.4.0.0 157 | nvme64.cat 158 | 159 | 160 | true 161 | 162 | 163 | "../../source/%(FileName).bmf" 164 | 165 | 166 | 167 | 168 | true 169 | __KERNEL_;__MSWINDOWS__;%(PreprocessorDefinitions) 170 | true 171 | true 172 | StorPortDebugPrint(LEVEL,MSG,...) 173 | ..\..\source\nvme_tracing.h 174 | 175 | 176 | {km-StorDefault.tpl}*.tmh 177 | Level3 178 | 179 | 180 | $(DDK_LIB_PATH)\wdm.lib;$(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\scsiwmi.lib;%(AdditionalDependencies) 181 | 182 | 183 | 1.4.0.0 184 | nvme64.cat 185 | 186 | 187 | true 188 | 189 | 190 | "../../source/%(FileName).bmf" 191 | 192 | 193 | 194 | 195 | true 196 | __KERNEL_;__MSWINDOWS__;%(PreprocessorDefinitions) 197 | Level3 198 | true 199 | StorPortDebugPrint(LEVEL,MSG,...) 200 | true 201 | {km-StorDefault.tpl}*.tmh 202 | ..\..\source\nvme_tracing.h 203 | 204 | 205 | $(DDK_LIB_PATH)\wdm.lib;$(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\scsiwmi.lib;%(AdditionalDependencies) 206 | 207 | 208 | 1.4.0.0 209 | nvme64.cat 210 | 211 | 212 | true 213 | 214 | 215 | "../../source/%(FileName).bmf" 216 | 217 | 218 | 219 | 220 | true 221 | __KERNEL_;MSWINDOWS__;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) 222 | Level3 223 | true 224 | true 225 | StorPortDebugPrint(LEVEL,MSG,...) 226 | {km-StorDefault.tpl}*.tmh 227 | ..\..\source\nvme_tracing.h 228 | 229 | 230 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 231 | 232 | 233 | 1.4.0.0 234 | 235 | 236 | nvme64.cat 237 | 238 | 239 | true 240 | 241 | 242 | "../../source/%(FileName).bmf" 243 | 244 | 245 | 246 | 247 | true 248 | __KERNEL_;__MSWINDOWS;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) 249 | true 250 | true 251 | StorPortDebugPrint(LEVEL,MSG,...) 252 | {km-StorDefault.tpl}*.tmh 253 | ..\..\source\nvme_tracing.h 254 | Level3 255 | 256 | 257 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 258 | 259 | 260 | 1.4.0.0 261 | 262 | 263 | nvme64.cat 264 | 265 | 266 | true 267 | 268 | 269 | "../../source/%(FileName).bmf" 270 | 271 | 272 | 273 | 274 | "$(IntDir)nvmeMofData.h" 275 | -u -h"$(IntDir)nvmeMofData.h" 276 | 277 | 278 | 279 | 280 | true 281 | __KERNEL_;__MSWINDOWS;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) 282 | Level3 283 | true 284 | true 285 | StorPortDebugPrint(LEVEL,MSG,...) 286 | {km-StorDefault.tpl}*.tmh 287 | ..\..\source\nvme_tracing.h 288 | 289 | 290 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 291 | 292 | 293 | 1.4.0.0 294 | 295 | 296 | nvme64.cat 297 | 298 | 299 | true 300 | 301 | 302 | "../../source/%(FileName).bmf" 303 | 304 | 305 | 306 | 307 | true 308 | __KERNEL_;__MSWINDOWS__;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) 309 | Level3 310 | true 311 | true 312 | StorPortDebugPrint(LEVEL,MSG,...) 313 | {km-StorDefault.tpl}*.tmh 314 | ..\..\source\nvme_tracing.h 315 | 316 | 317 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 318 | 319 | 320 | 1.4.0.0 321 | 322 | 323 | nvme86.cat 324 | 325 | 326 | true 327 | 328 | 329 | "../../source/%(FileName).bmf" 330 | 331 | 332 | 333 | 334 | true 335 | __KERNEL_;__MSWINDOWS__;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) 336 | Level3 337 | true 338 | true 339 | StorPortDebugPrint(LEVEL,MSG,...) 340 | {km-StorDefault.tpl}*.tmh 341 | ..\..\source\nvme_tracing.h 342 | 343 | 344 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 345 | 346 | 347 | 1.4.0.0 348 | 349 | 350 | nvme86.cat 351 | 352 | 353 | true 354 | 355 | 356 | "../../source/%(FileName).bmf" 357 | 358 | 359 | 360 | 361 | true 362 | __KERNEL_;__MSWINDOWS__;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) 363 | Level3 364 | true 365 | true 366 | StorPortDebugPrint(LEVEL,MSG,...) 367 | {km-StorDefault.tpl}*.tmh 368 | ..\..\source\nvme_tracing.h 369 | 370 | 371 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 372 | 373 | 374 | nvme86.cat 375 | 376 | 377 | true 378 | 379 | 380 | "../../source/%(FileName).bmf" 381 | 382 | 383 | 384 | 385 | true 386 | __KERNEL_;__MSWINDOWS__;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) 387 | Level3 388 | true 389 | true 390 | StorPortDebugPrint(LEVEL,MSG,...) 391 | {km-StorDefault.tpl}*.tmh 392 | ..\..\source\nvme_tracing.h 393 | 394 | 395 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 396 | 397 | 398 | nvme86.cat 399 | 400 | 401 | true 402 | 403 | 404 | "../../source/%(FileName).bmf" 405 | 406 | 407 | 408 | 409 | true 410 | __KERNEL_;__MSWINDOWS__;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) 411 | Level3 412 | true 413 | true 414 | StorPortDebugPrint(LEVEL,MSG,...) 415 | {km-StorDefault.tpl}*.tmh 416 | ..\..\source\nvme_tracing.h 417 | 418 | 419 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 420 | 421 | 422 | 1.4.0.0 423 | 424 | 425 | nvme86.cat 426 | 427 | 428 | true 429 | 430 | 431 | "../../source/%(FileName).bmf" 432 | 433 | 434 | 435 | 436 | true 437 | __KERNEL_;__MSWINDOWS__;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions) 438 | Level3 439 | true 440 | true 441 | StorPortDebugPrint(LEVEL,MSG,...) 442 | {km-StorDefault.tpl}*.tmh 443 | ..\..\source\nvme_tracing.h 444 | 445 | 446 | $(DDK_LIB_PATH)\storport.lib;$(DDK_LIB_PATH)\wdm.lib;%(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\wmilib.lib;$(DDK_LIB_PATH)\scsiwmi.lib 447 | 448 | 449 | nvme86.cat 450 | 451 | 452 | true 453 | 454 | 455 | "../../source/%(FileName).bmf" 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | -------------------------------------------------------------------------------- /docs/Comm_Driver_features_1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/docs/Comm_Driver_features_1.docx -------------------------------------------------------------------------------- /docs/PT_IOCTL.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/docs/PT_IOCTL.doc -------------------------------------------------------------------------------- /docs/WindowsTraceCollection.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/docs/WindowsTraceCollection.pdf -------------------------------------------------------------------------------- /docs/WindowsWmiDesc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/docs/WindowsWmiDesc.pdf -------------------------------------------------------------------------------- /source/MAKEFILE: -------------------------------------------------------------------------------- 1 | # 2 | # DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source 3 | # file to this component. This file merely indirects to the real make file 4 | # that is shared by all the components of NT OS/2 5 | # 6 | MINIMUM_NT_TARGET_VERSION=0x502 7 | !INCLUDE $(NTMAKEENV)\makefile.def 8 | 9 | -------------------------------------------------------------------------------- /source/nvme.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/source/nvme.h -------------------------------------------------------------------------------- /source/nvme.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Installation inf for the NVME Miniport 3 | ; 4 | 5 | [Version] 6 | Signature="$Windows NT$" 7 | Provider=%COMM% 8 | ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318} 9 | Class=SCSIAdapter 10 | DriverVer=12/08/2016, 1.5.1200.00 11 | ;CatalogFile.NTAMD64 = nvme64.cat 12 | ;CatalogFile.NTx86 = nvme86.cat 13 | 14 | [PackageInfo] 15 | Name=NVMe 16 | 17 | [Manufacturer] 18 | %COMM% = COMM, NTamd64, NTx86 19 | 20 | [SourceDisksNames] 21 | 1 = %DiskId1%,,,"" 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | [nvme_Service_Inst] 27 | ServiceType = %SERVICE_KERNEL_DRIVER% 28 | StartType = %SERVICE_BOOT_START% 29 | ErrorControl = %SERVICE_ERROR_NORMAL% 30 | ServiceBinary = %12%\nvme.sys 31 | LoadOrderGroup = SCSI miniport 32 | AddReg = pnpsafe_pci_addreg 33 | AddReg = Parameters 34 | 35 | [nvme_EventLog_Inst] 36 | AddReg = nvme_EventLog_AddReg 37 | 38 | [nvme_EventLog_AddReg] 39 | HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\IoLogMsg.dll" 40 | HKR,,TypesSupported,%REG_DWORD%,7 41 | 42 | [pnpsafe_pci_addreg] 43 | HKR, "Parameters\PnpInterface", "5", %REG_DWORD%, 0x00000001 44 | HKR, "Parameters", "BusType", %REG_DWORD%, 0x00000011 45 | 46 | [msi_addreg] 47 | HKR, Interrupt Management, 0x00000010 48 | HKR, Interrupt Management\MessageSignaledInterruptProperties, 0x00000010 49 | HKR, Interrupt Management\MessageSignaledInterruptProperties, MSISupported, %REG_DWORD%, 1 50 | HKR, Interrupt Management\MessageSignaledInterruptProperties, MessageNumberLimit, %REG_DWORD%, 120 51 | HKR, Interrupt Management\Affinity Policy, 0x00000010 52 | HKR, Interrupt Management\Affinity Policy, DevicePolicy, %REG_DWORD%, 5 ;IrqPolicySpreadMessagesAcrossAllProcessors 53 | HKR, Interrupt Management\Affinity Policy, DevicePriority, %REG_DWORD%, 3 54 | HKR, Interrupt Management\Affinity Policy, GroupPolicy, %REG_DWORD%, 1 55 | 56 | [Parameters] 57 | HKR, Parameters\Device, Namespaces, %REG_DWORD%, 0x00000010 ; max number of namespaces supported 58 | HKR, Parameters\Device, MaxTXSize, %REG_DWORD%, 0x00020000 ; max trasnfer size 59 | HKR, Parameters\Device, AdQEntries, %REG_DWORD%, 0x00000080 ; admin queue size (num of entries) 60 | HKR, Parameters\Device, IoQEntries, %REG_DWORD%, 0x00000400 ; IO queue size (num of entries) 61 | HKR, Parameters\Device, IntCoalescingTime, %REG_DWORD%, 0x00000000 ; time threshold for INT coalescing 62 | HKR, Parameters\Device, IntCoalescingEntries, %REG_DWORD%, 0x00000000 ; # of entries threadhold for INT coalescing 63 | 64 | ;****************************************************************************** 65 | ;* 66 | ;* 32-BIT X86 ARCHITECTURE 67 | ;* 68 | ;* This section specifies the 32-bit architecture specific INF file entries 69 | ;* required to install a driver as a 32-bit compatible driver. 70 | ;* 71 | ;****************************************************************************** 72 | [SourceDisksFiles.x86] 73 | nvme.sys = 1,,, 74 | 75 | [COMM.NTx86] 76 | %COMMNvme.DeviceDesc% = nvme_inst, PCI\CC_010802 77 | ;%COMMNvmeChat.DeviceDesc% = nvme_inst, PCI\CC_010802 78 | 79 | [nvme_inst.ntx86] 80 | CopyFiles=@nvme.sys 81 | 82 | [nvme_inst.ntx86.HW] 83 | AddReg = msi_addreg 84 | 85 | [nvme_inst.ntx86.Services] 86 | AddService = nvme, 0x00000002 , nvme_Service_Inst, nvme_EventLog_Inst 87 | 88 | 89 | ;****************************************************************************** 90 | ;* 91 | ;* 64-BIT X86 ARCHITECTURE 92 | ;* 93 | ;* This section specifies the 64-bit architecture specific INF file entries 94 | ;* required to install a driver as a 64-bit compatible driver. 95 | ;* 96 | ;****************************************************************************** 97 | 98 | [SourceDisksFiles.amd64] 99 | nvme.sys = 1,,, 100 | 101 | [COMM.NTamd64] 102 | %COMMNvme.DeviceDesc% = nvme_inst, PCI\CC_010802 103 | ;%COMMNvmeChat.DeviceDesc% = nvme_inst, PCI\CC_010802 104 | 105 | [nvme_inst.NTamd64] 106 | CopyFiles=@nvme.sys 107 | 108 | [nvme_inst.NTamd64.HW] 109 | AddReg = msi_addreg 110 | 111 | [nvme_inst.NTamd64.Services] 112 | AddService = nvme, 0x00000002 , nvme_Service_Inst, nvme_EventLog_Inst 113 | 114 | 115 | [Strings] 116 | ; 117 | ; Localizable Strings 118 | ; 119 | diskId1 = "NVMe Installation Disk" 120 | CommNvme.DeviceDesc = "Community OFA NVMe 1.2 Storport Miniport" 121 | COMM = "Community" 122 | 123 | ; 124 | ; Non-Localizable Strings 125 | ; 126 | 127 | REG_EXPAND_SZ = 0x00020000 128 | REG_DWORD = 0x00010001 129 | SERVICE_KERNEL_DRIVER = 1 130 | SERVICE_BOOT_START = 0 131 | SERVICE_ERROR_NORMAL = 1 132 | -------------------------------------------------------------------------------- /source/nvme.rc: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | #include 45 | 46 | #include 47 | 48 | #define VER_FILETYPE VFT_DRV 49 | #define VER_FILESUBTYPE VFT2_DRV_SYSTEM 50 | #define VER_FILEDESCRIPTION_STR "Standard NVMe Storport Miniport Driver" 51 | #define VER_INTERNALNAME_STR "nvme.sys" 52 | #define VER_ORIGINALFILENAME_STR "nvme.sys" 53 | 54 | #include "common.ver" 55 | 56 | 57 | MofResource MOFDATA nvmeMofData.bmf 58 | -------------------------------------------------------------------------------- /source/nvmeInit.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/source/nvmeInit.h -------------------------------------------------------------------------------- /source/nvmeIo.c: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: nvmeIo.c 46 | */ 47 | 48 | #include "precomp.h" 49 | #ifndef DBG 50 | #include "nvmeIo.tmh" 51 | #endif 52 | 53 | #if DBG 54 | BOOLEAN gResetTest = FALSE; 55 | ULONG gResetCounter = 0; 56 | ULONG gResetCount = 20000; 57 | #endif 58 | /******************************************************************************* 59 | * NVMeIssueCmd 60 | * 61 | * @brief NVMeIssueCmd can be called to issue one command at a time by ringing 62 | * the specific doorbell register with the updated Submission Queue Tail 63 | * Pointer. This routine copies the caller prepared submission entry data 64 | * pointed by pTempSubEntry to next available submission entry of the 65 | * specific queue before issuing the command. 66 | * 67 | * @param pAE - Pointer to hardware device extension. 68 | * @param QueueID - Which submission queue to issue the command 69 | * @param pTempSubEntry - The caller prepared Submission entry data 70 | * 71 | * @return ULONG 72 | * STOR_STATUS_SUCCESS - If the command is issued successfully 73 | * Otherwise - If anything goes wrong 74 | ******************************************************************************/ 75 | ULONG NVMeIssueCmd( 76 | PNVME_DEVICE_EXTENSION pAE, 77 | USHORT QueueID, 78 | PVOID pTempSubEntry 79 | ) 80 | { 81 | PQUEUE_INFO pQI = &pAE->QueueInfo; 82 | PSUB_QUEUE_INFO pSQI = NULL; 83 | PNVMe_COMMAND pNVMeCmd = NULL; 84 | USHORT tempSqTail = 0; 85 | 86 | /* Make sure the parameters are valid */ 87 | if (QueueID > pQI->NumSubIoQCreated || pTempSubEntry == NULL) 88 | return (STOR_STATUS_INVALID_PARAMETER); 89 | 90 | /* 91 | * Locate the current submission entry and 92 | * copy the fields from the temp buffer 93 | */ 94 | pSQI = pQI->pSubQueueInfo + QueueID; 95 | 96 | /* First make sure FW is draining this SQ */ 97 | tempSqTail = ((pSQI->SubQTailPtr + 1) == pSQI->SubQEntries) 98 | ? 0 : pSQI->SubQTailPtr + 1; 99 | 100 | if (tempSqTail == pSQI->SubQHeadPtr) { 101 | #ifdef HISTORY 102 | TracePathSubmit(ISSUE_RETURN_BUSY, QueueID, ((PNVMe_COMMAND)pTempSubEntry)->NSID, 103 | ((PNVMe_COMMAND)pTempSubEntry)->CDW0, 0, 0, 0); 104 | #endif 105 | return (STOR_STATUS_INSUFFICIENT_RESOURCES); 106 | } 107 | 108 | pNVMeCmd = (PNVMe_COMMAND)pSQI->pSubQStart; 109 | pNVMeCmd += pSQI->SubQTailPtr; 110 | 111 | StorPortCopyMemory((PVOID)pNVMeCmd, pTempSubEntry, sizeof(NVMe_COMMAND)); 112 | 113 | /* Increase the tail pointer by 1 and reset it if needed */ 114 | pSQI->SubQTailPtr = tempSqTail; 115 | 116 | /* 117 | * Track # of outstanding requests for this SQ 118 | */ 119 | pSQI->Requests++; 120 | 121 | #ifdef HISTORY 122 | TracePathSubmit(ISSUE, QueueID, ((PNVMe_COMMAND)pTempSubEntry)->NSID, 123 | ((PNVMe_COMMAND)pTempSubEntry)->CDW0, pSQI->SubQTailPtr, 0, 0); 124 | #endif 125 | /* Now issue the command via Doorbell register */ 126 | StorPortWriteRegisterUlong(pAE, pSQI->pSubTDBL, (ULONG)pSQI->SubQTailPtr); 127 | 128 | #if DBG 129 | if (gResetTest && (gResetCounter++ > gResetCount)) { 130 | gResetCounter = 0; 131 | 132 | /* quick hack for testing internally driven resets */ 133 | NVMeResetController(pAE, NULL); 134 | return STOR_STATUS_SUCCESS; 135 | } 136 | #endif /* DBG */ 137 | 138 | /* 139 | * This is for polling mode. This code can 140 | * potentially be updated to implement polling for other situations 141 | * as well keeping in mind that it was originally implmented to account 142 | * for prototype Chatham device that didn't have line INTs 143 | */ 144 | #if defined(ALL_POLLING) 145 | if (pAE->ResMapTbl.NumMsiMsgGranted == 0) { 146 | ULONG entryStatus = STOR_STATUS_UNSUCCESSFUL; 147 | PNVMe_COMPLETION_QUEUE_ENTRY pCplEntry = NULL; 148 | PNVME_SRB_EXTENSION pSrbExtension = NULL; 149 | PCPL_QUEUE_INFO pCQI = pQI->pCplQueueInfo + QueueID; 150 | PRES_MAPPING_TBL pRMT = &pAE->ResMapTbl; 151 | BOOLEAN learning; 152 | 153 | while (entryStatus != STOR_STATUS_SUCCESS) { 154 | entryStatus = NVMeGetCplEntry(pAE, pCQI, &pCplEntry); 155 | if (entryStatus == STOR_STATUS_SUCCESS) { 156 | 157 | NVMeCompleteCmd(pAE, 158 | pCplEntry->DW2.SQID, 159 | pCplEntry->DW2.SQHD, 160 | pCplEntry->DW3.CID, 161 | (PVOID)&pSrbExtension); 162 | 163 | if (pSrbExtension != NULL) { 164 | 165 | pSrbExtension->pCplEntry = pCplEntry; 166 | learning = ((pAE->LearningCores < pRMT->NumActiveCores) && 167 | (QueueID > 0)) ? TRUE : FALSE; 168 | if (learning) { 169 | pAE->LearningCores++; 170 | } 171 | } 172 | 173 | if ((pSrbExtension->pNvmeCompletionRoutine == NULL) && 174 | (SntiMapCompletionStatus(pSrbExtension) == TRUE)) { 175 | IO_StorPortNotification(RequestComplete, 176 | pAE, 177 | pSrbExtension->pSrb); 178 | 179 | } else if ((pSrbExtension->pNvmeCompletionRoutine(pAE, 180 | (PVOID)pSrbExtension) == TRUE) && 181 | (pSrbExtension->pSrb != NULL)) { 182 | IO_StorPortNotification(RequestComplete, 183 | pAE, 184 | pSrbExtension->pSrb); 185 | } 186 | StorPortWriteRegisterUlong(pAE, 187 | pCQI->pCplHDBL, 188 | (ULONG)pCQI->CplQHeadPtr); 189 | } 190 | } 191 | } 192 | #endif /* POLLING */ 193 | 194 | return STOR_STATUS_SUCCESS; 195 | } /* NVMeIssueCmd */ 196 | 197 | /******************************************************************************* 198 | * ProcessIo 199 | * 200 | * @brief Routine for processing an I/O request (both internal and externa) 201 | * and setting up all the necessary info. Then, calls NVMeIssueCmd to 202 | * issue the command to the controller. 203 | * 204 | * @param AdapterExtension - pointer to device extension 205 | * @param SrbExtension - SRB extension for this command 206 | * @param QueueType - type of queue (admin or I/O) 207 | * @param AcquireLock - if the caller needs the StartIO lock acquired or not 208 | * 209 | * @return BOOLEAN 210 | * TRUE - command was processed successfully 211 | * FALSE - If anything goes wrong 212 | ******************************************************************************/ 213 | BOOLEAN 214 | ProcessIo( 215 | __in PNVME_DEVICE_EXTENSION pAdapterExtension, 216 | __in PNVME_SRB_EXTENSION pSrbExtension, 217 | __in NVME_QUEUE_TYPE QueueType, 218 | __in BOOLEAN AcquireLock 219 | ) 220 | { 221 | PNVMe_COMMAND pNvmeCmd; 222 | ULONG StorStatus; 223 | IO_SUBMIT_STATUS IoStatus = SUBMITTED; 224 | PCMD_INFO pCmdInfo = NULL; 225 | PROCESSOR_NUMBER ProcNumber; 226 | USHORT SubQueue = 0; 227 | USHORT CplQueue = 0; 228 | STOR_LOCK_HANDLE hStartIoLock = {0}; 229 | BOOLEAN completeStatus = FALSE; 230 | #ifdef PRP_DBG 231 | PVOID pVa = NULL; 232 | #endif 233 | 234 | __try { 235 | 236 | if (AcquireLock == TRUE) { 237 | StorPortAcquireSpinLock(pAdapterExtension, 238 | StartIoLock, 239 | NULL, 240 | &hStartIoLock); 241 | } 242 | 243 | if (pAdapterExtension->ntldrDump == FALSE) { 244 | StorStatus = StorPortGetCurrentProcessorNumber((PVOID)pAdapterExtension, 245 | &ProcNumber); 246 | if (StorStatus != STOR_STATUS_SUCCESS) { 247 | IoStatus = NOT_SUBMITTED; 248 | __leave; 249 | } 250 | } else { 251 | memset(&ProcNumber, 0, sizeof(PROCESSOR_NUMBER)); 252 | } 253 | 254 | #if DBG 255 | /* save off the submitting core info for debug CT learning purposes */ 256 | pSrbExtension->procNum = ProcNumber; 257 | #endif 258 | 259 | /* 1 - Select Queue based on CPU */ 260 | if (QueueType == NVME_QUEUE_TYPE_IO) { 261 | 262 | StorStatus = NVMeMapCore2Queue(pAdapterExtension, 263 | &ProcNumber, 264 | &SubQueue, 265 | &CplQueue); 266 | 267 | if (StorStatus != STOR_STATUS_SUCCESS) { 268 | IoStatus = NOT_SUBMITTED; 269 | __leave; 270 | } 271 | } else { 272 | /* It's an admin queue */ 273 | SubQueue = CplQueue = 0; 274 | } 275 | 276 | /* 2 - Choose CID for the CMD_ENTRY */ 277 | StorStatus = NVMeGetCmdEntry(pAdapterExtension, 278 | SubQueue, 279 | (PVOID)pSrbExtension, 280 | &pCmdInfo); 281 | 282 | if (StorStatus != STOR_STATUS_SUCCESS) { 283 | IoStatus = BUSY; 284 | __leave; 285 | } 286 | 287 | pNvmeCmd = &pSrbExtension->nvmeSqeUnit; 288 | #pragma prefast(suppress:6011,"This pointer is not NULL") 289 | pNvmeCmd->CDW0.CID = (USHORT)pCmdInfo->CmdID; 290 | 291 | #ifdef DUMB_DRIVER 292 | /* 293 | * For reads/writes, create PRP list in pre-allocated 294 | * space describing the dbl buff location... make sure that 295 | * we do not double buffer NVMe Flush commands. 296 | */ 297 | if ((QueueType == NVME_QUEUE_TYPE_IO) && 298 | (pNvmeCmd->CDW0.OPC != NVM_FLUSH)) { 299 | ULONG len = GET_DATA_LENGTH(pSrbExtension->pSrb); 300 | ULONG i = 1; 301 | PUINT64 pPrpList = (PUINT64)pCmdInfo->pDblPrpListVir; 302 | 303 | ASSERT(len <= DUMB_DRIVER_SZ); 304 | 305 | if (len <= (PAGE_SIZE * 2)) { 306 | pNvmeCmd->PRP1 = pCmdInfo->dblPhy.QuadPart; 307 | if (len > PAGE_SIZE) { 308 | pNvmeCmd->PRP2 = pCmdInfo->dblPhy.QuadPart + PAGE_SIZE; 309 | } else { 310 | pNvmeCmd->PRP2 = 0; 311 | } 312 | } else { 313 | pNvmeCmd->PRP1 = pCmdInfo->dblPhy.QuadPart; 314 | len -= PAGE_SIZE; 315 | pNvmeCmd->PRP2 = pCmdInfo->dblPrpListPhy.QuadPart; 316 | 317 | while (len > 0) { 318 | *pPrpList = pCmdInfo->dblPhy.QuadPart + (PAGE_SIZE * i); 319 | len -= PAGE_SIZE; 320 | pPrpList++; 321 | i++; 322 | } 323 | } 324 | /* Pre-allacted so this had better be true! */ 325 | ASSERT(IS_SYS_PAGE_ALIGNED(pNvmeCmd->PRP1)); 326 | ASSERT(IS_SYS_PAGE_ALIGNED(pNvmeCmd->PRP2)); 327 | 328 | // Get Virtual address, only for read or write 329 | if (IS_CMD_DATA_IN(pNvmeCmd->CDW0.OPC) || 330 | IS_CMD_DATA_OUT(pNvmeCmd->CDW0.OPC)) { 331 | /* 332 | * Save the dblBuff location, Srb databuff location and len 333 | * all in one handy location in the srb ext 334 | */ 335 | StorStatus = StorPortGetSystemAddress(pAdapterExtension, 336 | pSrbExtension->pSrb, 337 | &pSrbExtension->pSrbDataVir); 338 | 339 | ASSERT(StorStatus == STOR_STATUS_SUCCESS); 340 | 341 | pSrbExtension->dataLen = GET_DATA_LENGTH(pSrbExtension->pSrb); 342 | pSrbExtension->pDblVir = pCmdInfo->pDblVir; 343 | 344 | /* 345 | * For a write, copy data to the dbl buff, read data will 346 | * be copied out in the ISR 347 | */ 348 | if (IS_CMD_DATA_OUT(pNvmeCmd->CDW0.OPC)) { 349 | StorPortCopyMemory(pSrbExtension->pDblVir, 350 | pSrbExtension->pSrbDataVir, 351 | pSrbExtension->dataLen); 352 | } 353 | } 354 | } 355 | #else /* DUMB_DRIVER */ 356 | /* 357 | * 3 - If a PRP list is used, copy the buildIO prepared list to the 358 | * preallocated memory location and update the entry not the pCmdInfo is a 359 | * stack var but contains a to the pre allocated mem which is what we're 360 | * updating. 361 | */ 362 | #ifndef PRP_DBG 363 | if (pSrbExtension->numberOfPrpEntries > 2) { 364 | pNvmeCmd->PRP2 = pCmdInfo->prpListPhyAddr.QuadPart; 365 | 366 | /* 367 | * Copy the PRP list pointed to by PRP2. Size of the copy is total num 368 | * of PRPs -1 because PRP1 is not in the PRP list pointed to by PRP2. 369 | */ 370 | StorPortCopyMemory( 371 | (PVOID)pCmdInfo->pPRPList, 372 | (PVOID)&pSrbExtension->prpList[0], 373 | ((pSrbExtension->numberOfPrpEntries - 1) * sizeof(UINT64))); 374 | } 375 | #else 376 | if (pSrbExtension->pSrb) { 377 | StorPortGetSystemAddress(pSrbExtension->pNvmeDevExt, 378 | pSrbExtension->pSrb, 379 | &pVa); 380 | StorPortDebugPrint(INFO, 381 | "NVME: Process Cmd 0x%x VA 0x%x 0x%x SLBA 0x%x 0x%x for LEN 0x%x\n", 382 | pNvmeCmd->CDW0.OPC, 383 | (ULONGLONG)pVa >> 32, (ULONG)pVa, 384 | pNvmeCmd->CDW11, 385 | pNvmeCmd->CDW10, 386 | GET_DATA_LENGTH(pSrbExtension->pSrb)); 387 | } 388 | 389 | if (pSrbExtension->numberOfPrpEntries > 2) { 390 | ULONG i; 391 | pNvmeCmd->PRP2 = pCmdInfo->prpListPhyAddr.QuadPart; 392 | 393 | StorPortCopyMemory( 394 | (PVOID)pCmdInfo->pPRPList, 395 | (PVOID)&pSrbExtension->prpList[0], 396 | ((pSrbExtension->numberOfPrpEntries - 1) * sizeof(UINT64))); 397 | 398 | StorPortDebugPrint(INFO, 399 | "NVME: Process prp1 0x%x 0x%x prp2 0x%x 0x%x (list for 0x%x entries)\n", 400 | pNvmeCmd->PRP1 >> 32, pNvmeCmd->PRP1, 401 | pNvmeCmd->PRP2 >> 32, pNvmeCmd->PRP2, 402 | (pSrbExtension->numberOfPrpEntries - 1)); 403 | 404 | for (i=0;i<(pSrbExtension->numberOfPrpEntries - 1);i++) { 405 | StorPortDebugPrint(INFO, 406 | "NVME: Process entry # 0x%x prp 0x%x 0x%x\n", 407 | i, 408 | pSrbExtension->prpList[i] >> 32, pSrbExtension->prpList[i] 409 | ); 410 | } 411 | } else if (pNvmeCmd->PRP1 != 0) { 412 | StorPortDebugPrint(INFO, 413 | "NVME: Process prp1 0x%x 0x%x prp2 0x%x 0x%x (no list)\n", 414 | pNvmeCmd->PRP1 >> 32, pNvmeCmd->PRP1, 415 | pNvmeCmd->PRP2 >> 32, pNvmeCmd->PRP2 416 | ); 417 | } 418 | #endif /* PRP_DBG */ 419 | #endif /* DBL_BUFF */ 420 | #ifdef HISTORY 421 | TracePathSubmit(PRE_ISSUE, SubQueue, pNvmeCmd->NSID, pNvmeCmd->CDW0, 422 | pNvmeCmd->PRP1, pNvmeCmd->PRP2, pSrbExtension->numberOfPrpEntries); 423 | #endif 424 | 425 | /* 4 - Issue the Command */ 426 | StorStatus = NVMeIssueCmd(pAdapterExtension, SubQueue, pNvmeCmd); 427 | 428 | if (StorStatus != STOR_STATUS_SUCCESS) { 429 | completeStatus = NVMeCompleteCmd(pAdapterExtension, 430 | SubQueue, 431 | NO_SQ_HEAD_CHANGE, 432 | pNvmeCmd->CDW0.CID, 433 | (PVOID)pSrbExtension); 434 | 435 | if (completeStatus == FALSE) { 436 | IoStatus = NOT_SUBMITTED; 437 | __leave; 438 | } 439 | else { 440 | IoStatus = BUSY; 441 | __leave; 442 | } 443 | 444 | } 445 | 446 | /* 447 | * In crashdump we poll on admin command completions 448 | * in order to allow our init state machine to function. 449 | * We don't poll on IO commands as storport will poll 450 | * for us and call our ISR. 451 | */ 452 | if ((pAdapterExtension->ntldrDump == TRUE) && 453 | (QueueType == NVME_QUEUE_TYPE_ADMIN) && 454 | (pAdapterExtension->DriverState.NextDriverState != NVMeStateFailed) && 455 | (pAdapterExtension->DriverState.NextDriverState != NVMeStartComplete) && 456 | (StorStatus == STOR_STATUS_SUCCESS)) { 457 | ULONG pollCount = 0; 458 | 459 | while (FALSE == NVMeIsrMsix(pAdapterExtension, NVME_ADMIN_MSG_ID)) { 460 | NVMeCrashDelay(pAdapterExtension->DriverState.CheckbackInterval, TRUE); 461 | if (++pollCount > DUMP_POLL_CALLS) { 462 | /* a polled admin command timeout is considered fatal */ 463 | pAdapterExtension->DriverState.DriverErrorStatus |= 464 | (1 << FATAL_POLLED_ADMIN_CMD_FAILURE); 465 | pAdapterExtension->DriverState.NextDriverState = NVMeStateFailed; 466 | /* 467 | * depending on whether the timer driven thread is dead or not 468 | * this error may get loggged twice 469 | */ 470 | NVMeLogError(pAdapterExtension, 471 | (ULONG)pAdapterExtension->DriverState.DriverErrorStatus); 472 | IoStatus = NOT_SUBMITTED; 473 | __leave; 474 | } 475 | } 476 | } 477 | 478 | } finally { 479 | 480 | if (AcquireLock == TRUE) { 481 | StorPortReleaseSpinLock(pAdapterExtension, &hStartIoLock); 482 | } 483 | 484 | if (IoStatus == BUSY) { 485 | #ifdef HISTORY 486 | TracePathSubmit(GETCMD_RETURN_BUSY, SubQueue, 487 | ((PNVMe_COMMAND)(&pSrbExtension->nvmeSqeUnit))->NSID, 488 | ((PNVMe_COMMAND)(&pSrbExtension->nvmeSqeUnit))->CDW0, 489 | 0, 0, 0); 490 | #endif 491 | if (pSrbExtension->pSrb != NULL) { 492 | pSrbExtension->pSrb->SrbStatus = SRB_STATUS_BUSY; 493 | IO_StorPortNotification(RequestComplete, 494 | pAdapterExtension, 495 | pSrbExtension->pSrb); 496 | } 497 | } 498 | 499 | if (IoStatus == NOT_SUBMITTED) { 500 | if (pSrbExtension->pSrb != NULL) { 501 | pSrbExtension->pSrb->SrbStatus = SRB_STATUS_ERROR; 502 | IO_StorPortNotification(RequestComplete, 503 | pAdapterExtension, 504 | pSrbExtension->pSrb); 505 | } 506 | } 507 | } 508 | 509 | return (IoStatus == SUBMITTED) ? TRUE : FALSE; 510 | 511 | } /* ProcessIo */ 512 | 513 | /******************************************************************************* 514 | * NVMeCompleteCmd 515 | * 516 | * @brief NVMeCompleteCmd gets called to recover the context saved in the 517 | * associated CMD_ENTRY structure with the specificed CmdID. Normally 518 | * this routine is called when the caller is about to complete the 519 | * request and notify StorPort. 520 | * 521 | * @param pAE - Pointer to hardware device extension. 522 | * @param QueueID - Which submission queue to recover the context from 523 | * @param CmdID - The acquired CmdID used to de-reference the CMD_ENTRY 524 | * @param pContext - Caller prepared buffer to save the original context 525 | * 526 | * @return BOOLEAN 527 | ******************************************************************************/ 528 | BOOLEAN NVMeCompleteCmd( 529 | PNVME_DEVICE_EXTENSION pAE, 530 | USHORT QueueID, 531 | SHORT NewHead, 532 | USHORT CmdID, 533 | PVOID pContext 534 | ) 535 | { 536 | PQUEUE_INFO pQI = &pAE->QueueInfo; 537 | PSUB_QUEUE_INFO pSQI = NULL; 538 | PCMD_ENTRY pCmdEntry = NULL; 539 | 540 | /* Make sure the parameters are valid */ 541 | ASSERT((QueueID <= pQI->NumSubIoQCreated) && (pContext != NULL)); 542 | 543 | /* 544 | * Identify the target submission queue/cmd entry 545 | * and update the head pointer for the SQ if needed 546 | */ 547 | pSQI = pQI->pSubQueueInfo + QueueID; 548 | 549 | pCmdEntry = ((PCMD_ENTRY)pSQI->pCmdEntry) + CmdID; 550 | 551 | if (NewHead != NO_SQ_HEAD_CHANGE) { 552 | pSQI->SubQHeadPtr = NewHead; 553 | } 554 | 555 | /* Ensure the command entry had been acquired */ 556 | ASSERT(pCmdEntry->Pending == TRUE); 557 | 558 | /* 559 | * Return the original context -- this is a pointer to srb extension 560 | * (sanity check first that it is not NULL) 561 | */ 562 | ASSERT(pCmdEntry->Context != NULL); 563 | 564 | if ((pCmdEntry->Pending == FALSE) || (pCmdEntry->Context == NULL)) { 565 | /* 566 | * Something bad happened so reset the adapter and hope for the best 567 | */ 568 | NVMeResetController(pAE, NULL); 569 | return FALSE; 570 | } 571 | 572 | *((ULONG_PTR *)pContext) = (ULONG_PTR)pCmdEntry->Context; 573 | 574 | #ifdef DUMB_DRIVER 575 | /* 576 | * For non admin command read, need to copy from the dbl buff to the 577 | * SRB data buff 578 | */ 579 | if ((QueueID > 0) && 580 | IS_CMD_DATA_IN(((PNVME_SRB_EXTENSION)pCmdEntry->Context)->nvmeSqeUnit.CDW0.OPC)) { 581 | PNVME_SRB_EXTENSION pSrbExt = (PNVME_SRB_EXTENSION)pCmdEntry->Context; 582 | 583 | ASSERT(pSrbExt); 584 | 585 | StorPortCopyMemory(pSrbExt->pSrbDataVir, 586 | pSrbExt->pDblVir, 587 | pSrbExt->dataLen); 588 | } 589 | #endif /* DUMB_DRIVER */ 590 | 591 | /* Clear the fields of CMD_ENTRY before appending back to free list */ 592 | pCmdEntry->Pending = FALSE; 593 | pCmdEntry->Context = 0; 594 | 595 | InsertTailList(&pSQI->FreeQList, &pCmdEntry->ListEntry); 596 | 597 | return TRUE; 598 | } /* NVMeCompleteCmd */ 599 | 600 | /******************************************************************************* 601 | * NVMeDetectPendingCmds 602 | * 603 | * @brief NVMeDetectPendingCmds gets called to check for commands that may still 604 | * be pending. Called when the caller is about to shutdown per S3 or S4. 605 | * 606 | * @param pAE - Pointer to hardware device extension. 607 | * @param completeCmd - determines if detected commands should be completed 608 | * @param SrbStatus - Srb Status value for the completing SRBs 609 | * 610 | * @return BOOLEAN 611 | * TRUE if commands are detected that are still pending 612 | * FALSE if no commands pending 613 | ******************************************************************************/ 614 | BOOLEAN NVMeDetectPendingCmds( 615 | PNVME_DEVICE_EXTENSION pAE, 616 | BOOLEAN completeCmd, 617 | UCHAR SrbStatus 618 | ) 619 | { 620 | PQUEUE_INFO pQI = &pAE->QueueInfo; 621 | PSUB_QUEUE_INFO pSQI = NULL; 622 | PCMD_ENTRY pCmdEntry = NULL; 623 | USHORT CmdID; 624 | USHORT QueueID = 0; 625 | PNVME_SRB_EXTENSION pSrbExtension = NULL; 626 | BOOLEAN retValue = FALSE; 627 | PNVMe_COMMAND pNVMeCmd = NULL; 628 | 629 | /* 630 | * there is a 0xD1 BSOD on shutdown/restart *with verifier on* 631 | * something to do with QEMU and IA emulation. Confirmed the 632 | * mem in question is safe (Q mem) and this doesn't happen with 633 | * real HW. So, if you use QEMU and verifier, uncomment this 634 | * line 635 | */ 636 | /* return FALSE; */ 637 | 638 | /* Simply return FALSE when buffer had been freed */ 639 | if (pQI->pSubQueueInfo == NULL) 640 | return retValue; 641 | 642 | /* Search all submission queues */ 643 | for (QueueID = 0; QueueID <= pQI->NumSubIoQCreated; QueueID++) { 644 | pSQI = pQI->pSubQueueInfo + QueueID; 645 | 646 | for (CmdID = 0; CmdID < pSQI->SubQEntries; CmdID++) { 647 | pCmdEntry = ((PCMD_ENTRY)pSQI->pCmdEntry) + CmdID; 648 | if (pCmdEntry->Pending == TRUE) { 649 | pSrbExtension = (PNVME_SRB_EXTENSION)pCmdEntry->Context; 650 | 651 | /* 652 | * Since pending is set, pSrbExtension should exist 653 | */ 654 | ASSERT(pSrbExtension != NULL); 655 | 656 | pNVMeCmd = &pSrbExtension->nvmeSqeUnit; 657 | 658 | /* 659 | * Internal cmd need to be completed 660 | */ 661 | if (pSrbExtension->pSrb == NULL) { 662 | NVMeCompleteCmd(pAE, 663 | pSQI->SubQueueID, 664 | NO_SQ_HEAD_CHANGE, 665 | pNVMeCmd->CDW0.CID, 666 | (PVOID)&pSrbExtension); 667 | continue; 668 | } 669 | 670 | #ifdef HISTORY 671 | TraceEvent(DETECTED_PENDING_CMD, 672 | QueueID, 673 | pNVMeCmd->CDW0.CID, 674 | pNVMeCmd->CDW0.OPC, 675 | pNVMeCmd->PRP1, 676 | pNVMeCmd->PRP2, 677 | pNVMeCmd->NSID); 678 | #endif 679 | 680 | #if DBG 681 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 682 | DPFLTR_ERROR_LEVEL, 683 | "NVMeDetectPendingCmds: cmdinfo cmd id 0x%x srbExt 0x%p srb 0x%p\n", 684 | pCmdEntry->CmdInfo.CmdID, pSrbExtension, pSrbExtension->pSrb); 685 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 686 | DPFLTR_ERROR_LEVEL, 687 | "\tnvme queue 0x%x OPC 0x%x\n", 688 | QueueID, pNVMeCmd->CDW0.OPC); 689 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 690 | DPFLTR_ERROR_LEVEL, 691 | "\tnvme cmd id 0x%x\n", 692 | pNVMeCmd->CDW0.CID); 693 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 694 | DPFLTR_ERROR_LEVEL, 695 | "\tnvme nsid 0x%x\n", 696 | pNVMeCmd->NSID); 697 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 698 | DPFLTR_ERROR_LEVEL, 699 | "\tnvme prp1 0x%x 0x%x\n", 700 | pNVMeCmd->PRP1 >> 32, 701 | pNVMeCmd->PRP1); 702 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 703 | DPFLTR_ERROR_LEVEL, 704 | "\tnvme prp2 0x%x 0x%x\n", 705 | pNVMeCmd->PRP2 >> 32, 706 | pNVMeCmd->PRP2); 707 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 708 | DPFLTR_ERROR_LEVEL, 709 | "\tnvme CDW10 0x%x\n", 710 | pNVMeCmd->CDW10); 711 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 712 | DPFLTR_ERROR_LEVEL, 713 | "\tnvme CDW11 0x%x\n", 714 | pNVMeCmd->CDW11); 715 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 716 | DPFLTR_ERROR_LEVEL, 717 | "\tnvme CDW12 0x%x\n", 718 | pNVMeCmd->CDW12); 719 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 720 | DPFLTR_ERROR_LEVEL, 721 | "\tnvme CDW13 0x%x\n", 722 | pNVMeCmd->CDW13); 723 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 724 | DPFLTR_ERROR_LEVEL, 725 | "\tnvme CDW14 0x%x\n", 726 | pNVMeCmd->CDW14); 727 | DbgPrintEx(DPFLTR_STORMINIPORT_ID, 728 | DPFLTR_ERROR_LEVEL, 729 | "\tnvme CDW15 0x%x\n", 730 | pNVMeCmd->CDW15); 731 | #endif 732 | 733 | /* don't count AER as an outstanding cmd */ 734 | if ((pNVMeCmd->CDW0.OPC != ADMIN_ASYNCHRONOUS_EVENT_REQUEST) && 735 | (pSrbExtension->pSrb != NULL)) { 736 | retValue = TRUE; 737 | } 738 | 739 | /* if requested, complete the command now */ 740 | if (completeCmd == TRUE) { 741 | 742 | NVMeCompleteCmd(pAE, 743 | pSQI->SubQueueID, 744 | NO_SQ_HEAD_CHANGE, 745 | pNVMeCmd->CDW0.CID, 746 | (PVOID)&pSrbExtension); 747 | 748 | if (pSrbExtension->pSrb != NULL) { 749 | #ifdef HISTORY 750 | NVMe_COMPLETION_QUEUE_ENTRY_DWORD_3 nullEntry = {0}; 751 | TracePathComplete(COMPLETE_CMD_RESET, 752 | pSQI->SubQueueID, 753 | pNVMeCmd->CDW0.CID, 0, nullEntry, 754 | (ULONGLONG)pSrbExtension->pNvmeCompletionRoutine, 755 | 0); 756 | #endif 757 | pSrbExtension->pSrb->SrbStatus = SrbStatus; 758 | IO_StorPortNotification(RequestComplete, 759 | pAE, 760 | pSrbExtension->pSrb); 761 | } /* has an Srb */ 762 | } /* complete the command? */ 763 | } /* if cmd is pending */ 764 | } /* for cmds on the SQ */ 765 | } /* for the SQ */ 766 | 767 | return retValue; 768 | } /* NVMeDetectPendingCmds */ 769 | -------------------------------------------------------------------------------- /source/nvmeIo.h: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: nvmeIo.h 46 | */ 47 | 48 | #ifndef __NVME_IO_H__ 49 | #define __NVME_IO_H__ 50 | 51 | typedef enum _IO_SUBMIT_STATUS 52 | { 53 | NOT_SUBMITTED = 0, 54 | SUBMITTED, 55 | BUSY 56 | } IO_SUBMIT_STATUS; 57 | 58 | BOOLEAN 59 | ProcessIo( 60 | __in PNVME_DEVICE_EXTENSION pAdapterExtension, 61 | __in PNVME_SRB_EXTENSION pSrbExtension, 62 | __in NVME_QUEUE_TYPE QueueType, 63 | __in BOOLEAN AcquireLock 64 | ); 65 | 66 | BOOLEAN 67 | NVMeCompleteCmd( 68 | __in PNVME_DEVICE_EXTENSION pAE, 69 | __in USHORT QueueID, 70 | __in SHORT NewHead, 71 | __in USHORT CmdID, 72 | __in PVOID Context 73 | ); 74 | 75 | BOOLEAN NVMeDetectPendingCmds( 76 | PNVME_DEVICE_EXTENSION pAE, 77 | BOOLEAN completeCmd, 78 | UCHAR SrbStatus 79 | ); 80 | 81 | #endif /* __NVME_IO_H__ */ 82 | -------------------------------------------------------------------------------- /source/nvmeIoctl.h: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /** 45 | * File: nvmeIoctl.h 46 | */ 47 | 48 | #ifndef __NVME_IOCTL_H__ 49 | #define __NVME_IOCTL_H__ 50 | 51 | #include "ntddscsi.h" 52 | 53 | #define NVME_STORPORT_DRIVER 0xE000 54 | 55 | 56 | /* the following are the NVME driver private IOCTL definitions */ 57 | #define NVME_PASS_THROUGH_SRB_IO_CODE \ 58 | CTL_CODE(NVME_STORPORT_DRIVER, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) 59 | 60 | #define NVME_RESET_DEVICE \ 61 | CTL_CODE(NVME_STORPORT_DRIVER, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) 62 | 63 | #define NVME_HOT_ADD_NAMESPACE \ 64 | CTL_CODE(NVME_STORPORT_DRIVER, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) 65 | 66 | #define NVME_HOT_REMOVE_NAMESPACE \ 67 | CTL_CODE(NVME_STORPORT_DRIVER, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS) 68 | 69 | 70 | #define NVME_SIG_STR "NvmeMini" 71 | #define NVME_SIG_STR_LEN 8 72 | #define SCSI_SIG_STR "SCSIDISK" 73 | #define SCSI_SIG_STR_LEN 8 74 | #define NVME_NO_DATA_TX 0 /* No data transfer involved */ 75 | #define NVME_FROM_HOST_TO_DEV 1 /* Transfer data from host to device */ 76 | #define NVME_FROM_DEV_TO_HOST 2 /* Transfer data from device to host */ 77 | #define NVME_BI_DIRECTION 3 /* Tx data from host to device and back */ 78 | 79 | #define NVME_IOCTL_VENDOR_SPECIFIC_DW_SIZE 6 /* Vendor sp qualifier (DWORDs) */ 80 | #define NVME_IOCTL_CMD_DW_SIZE 16 /* NVMe cmd entry size (DWORDs) */ 81 | #define NVME_IOCTL_COMPLETE_DW_SIZE 4 /* NVMe cpl entry size (DWORDs) */ 82 | 83 | /******************************************************************************* 84 | * NVMe Pass Through IOCTL return codes from Miniport driver. 85 | * 86 | * These numbers are returned in ReturnCode of SRB_IO_CONTROL structure. 87 | * When driver receives an IOCTL request, before issuing the associated NVMe 88 | * command, it examines all fields of NVME_PASS_THROUGH_IOCTL structure. 89 | * 90 | * Once certain error found, the error is interpreted and noted in ReturnCode 91 | * of SRB_IO_CONTROL structure. User applications can find out the specific 92 | * status after driver processes the request. 93 | ******************************************************************************/ 94 | enum _IOCTL_STATUS 95 | { 96 | NVME_IOCTL_SUCCESS, 97 | NVME_IOCTL_INTERNAL_ERROR, 98 | NVME_IOCTL_INVALID_IOCTL_CODE, 99 | NVME_IOCTL_INVALID_SIGNATURE, 100 | NVME_IOCTL_INSUFFICIENT_IN_BUFFER, 101 | NVME_IOCTL_INSUFFICIENT_OUT_BUFFER, 102 | NVME_IOCTL_UNSUPPORTED_ADMIN_CMD, 103 | NVME_IOCTL_UNSUPPORTED_NVM_CMD, 104 | NVME_IOCTL_UNSUPPORTED_OPERATION, 105 | NVME_IOCTL_INVALID_ADMIN_VENDOR_SPECIFIC_OPCODE, 106 | NVME_IOCTL_INVALID_NVM_VENDOR_SPECIFIC_OPCODE, 107 | NVME_IOCTL_ADMIN_VENDOR_SPECIFIC_NOT_SUPPORTED, // i.e., AVSCC = 0 108 | NVME_IOCTL_NVM_VENDOR_SPECIFIC_NOT_SUPPORTED, // i.e., NVSCC = 0 109 | NVME_IOCTL_INVALID_DIRECTION_SPECIFIED, // Direction > 3 110 | NVME_IOCTL_INVALID_META_BUFFER_LENGTH, 111 | NVME_IOCTL_PRP_TRANSLATION_ERROR, 112 | NVME_IOCTL_INVALID_PATH_TARGET_ID, 113 | NVME_IOCTL_FORMAT_NVM_PENDING, // Only one Format NVM at a time 114 | NVME_IOCTL_FORMAT_NVM_FAILED, 115 | NVME_IOCTL_INVALID_NAMESPACE_ID, 116 | NVME_IOCTL_MAX_SSD_NAMESPACES_REACHED, 117 | NVME_IOCTL_ZERO_DATA_TX_LENGTH_ERROR, 118 | NVME_IOCTL_MAX_AER_REACHED, 119 | NVME_IOCTL_ATTACH_NAMESPACE_FAILED 120 | }; 121 | 122 | #pragma pack(1) 123 | /****************************************************************************** 124 | * NVMe Pass Through IOCTL data structure. 125 | * 126 | * This structure contains WDK defined SRB_IO_CONTROL structure, 64-byte 127 | * NVMe command entry and 16-byte completion entry, and other important fields 128 | * that driver needs to reference when processing the requests. 129 | * 130 | * User applications need to allocate proper size of buffer(s) and populate the 131 | * fields to ensure the requests are being processed correctly after issuing. 132 | ******************************************************************************/ 133 | typedef struct _NVME_PASS_THROUGH_IOCTL 134 | { 135 | /* WDK defined SRB_IO_CONTROL structure */ 136 | SRB_IO_CONTROL SrbIoCtrl; 137 | 138 | /* Vendor unique qualifiers for vendor unique commands */ 139 | ULONG VendorSpecific[NVME_IOCTL_VENDOR_SPECIFIC_DW_SIZE]; 140 | 141 | /* 64-byte submission entry defined in NVMe Specification */ 142 | ULONG NVMeCmd[NVME_IOCTL_CMD_DW_SIZE]; 143 | 144 | /* DW[0..3] of completion entry */ 145 | ULONG CplEntry[NVME_IOCTL_COMPLETE_DW_SIZE]; 146 | 147 | /* Data transfer direction, from host to device or vice versa */ 148 | ULONG Direction; 149 | 150 | /* 0 means using Admin queue, otherwise, IO queue is used */ 151 | ULONG QueueId; 152 | 153 | /* Transfer byte length, including Metadata, starting at DataBuffer */ 154 | ULONG DataBufferLen; 155 | 156 | /* Set to 0 if not supported or interleaved with data */ 157 | ULONG MetaDataLen; 158 | 159 | /* 160 | * Returned byte length from device to host, at least the length of this 161 | * structure. When data transfer required, add the length of the data. 162 | */ 163 | ULONG ReturnBufferLen; 164 | 165 | /* Start with Metadata if present, and then regular data */ 166 | UCHAR DataBuffer[1]; 167 | } NVME_PASS_THROUGH_IOCTL, *PNVME_PASS_THROUGH_IOCTL; 168 | #pragma pack() 169 | 170 | #define DRIVE_TEMPERATURE_CODE 0xE7 171 | #define REALLOCATED_SECTORS_COUNT_CODE 0x05 172 | #define ENDURANCE_REMAINING_CODE 0xE8 173 | #define LBAS_READ_CODE 0xF2 174 | #define LBAS_WRITTEN_CODE 0xF1 175 | #define LOADED_HOURS_CODE 0xDE 176 | #define POWER_CYCLE_COUNT_CODE 0x0C 177 | #define POWER_ON_HOURS_CODE 0x09 178 | #define REPORTED_UNCORRECTABLE_ERRORS_CODE 0xBB 179 | 180 | #pragma pack(1) 181 | /****************************************************************************** 182 | * SMART Attribute structure. 183 | * 184 | * This structure contains the code and value pair for a SMART attribute 185 | ******************************************************************************/ 186 | typedef struct _NVME_SMART_ATTRIBUTES 187 | { 188 | UCHAR Code; 189 | UCHAR Value; 190 | 191 | } NVME_SMART_ATTRIBUTES, *PNVME_SMART_ATTRIBUTES; 192 | #pragma pack() 193 | 194 | #pragma pack(1) 195 | /****************************************************************************** 196 | * NVMe SMART READ ATTRIBUTES DATA structure. 197 | * 198 | * This structure contains the information about SMART passed back when a 199 | * IOCTL_SCSI_MINIPORT_SMART_READ_ATTRIBS is requested. 200 | * 201 | * User applications need to allocate proper size of buffer(s) and populate the 202 | * fields to ensure the requests are being processed correctly after issuing. 203 | ******************************************************************************/ 204 | typedef struct _NVME_SMART_READ_ATTRIBUTES_DATA 205 | { 206 | SRB_IO_CONTROL SrbIoCtrl; 207 | NVME_SMART_ATTRIBUTES DriveTemperature; 208 | NVME_SMART_ATTRIBUTES ReallocatedSectorsCount; 209 | NVME_SMART_ATTRIBUTES EnduranceRemaining; 210 | NVME_SMART_ATTRIBUTES LBAsRead; 211 | NVME_SMART_ATTRIBUTES LBAsWritten; 212 | NVME_SMART_ATTRIBUTES LoadedHours; 213 | NVME_SMART_ATTRIBUTES PowerCycleCount; 214 | NVME_SMART_ATTRIBUTES PowerOnHours; 215 | NVME_SMART_ATTRIBUTES ReportedUncorrectableErrors; 216 | } NVME_SMART_READ_ATTRIBUTES_DATA, *PNVME_SMART_READ_ATTRIBUTES_DATA; 217 | #pragma pack() 218 | 219 | #pragma pack(1) 220 | /****************************************************************************** 221 | * NVMe SMART READ THRESHOLDS DATA structure. 222 | * 223 | * This structure contains the information about SMART passed back when a 224 | * IOCTL_SCSI_MINIPORT_SMART_READ_THRESHOLDS is requested. 225 | * 226 | * User applications need to allocate proper size of buffer(s) and populate the 227 | * fields to ensure the requests are being processed correctly after issuing. 228 | ******************************************************************************/ 229 | typedef struct _NVME_SMART_READ_THRESHOLDS_DATA 230 | { 231 | SRB_IO_CONTROL SrbIoCtrl; 232 | NVME_SMART_ATTRIBUTES DriveTemperature; 233 | NVME_SMART_ATTRIBUTES ReallocatedSectorsCount; 234 | } NVME_SMART_READ_THRESHOLDS_DATA, *PNVME_SMART_READ_THRESHOLDS_DATA; 235 | #pragma pack() 236 | 237 | #endif // __NVME_IOCTL_H__ 238 | -------------------------------------------------------------------------------- /source/nvmeMofData.mof: -------------------------------------------------------------------------------- 1 | [WMI, 2 | guid("{C105BB0D-C2D8-415B-9B0D-91A29979EBDD}")] 3 | class NVMe_DataType 4 | { 5 | [WmiDataId(1)] sint32 Id; 6 | [WmiDataId(2)] uint64 u64; 7 | }; 8 | 9 | [WMI, 10 | Dynamic, 11 | Description("Sample to Query WMI data from the NVMe Device Driver"), 12 | Provider("WmiProv"), 13 | guid("{0F70DA81-FD3F-40CB-8EF1-52385F31DB2F}")] 14 | class NVMe_QueryDevInfo 15 | { 16 | [key] // providers always need these 3 fields 17 | string InstanceName; 18 | boolean Active; 19 | 20 | [WmiDataId(1)] uint32 maxDataXferSize; 21 | [WmiDataId(2)] uint32 numberOfNamespaces; 22 | [WmiDataId(3)] NVMe_DataType Data; 23 | }; 24 | 25 | [WMI, 26 | Dynamic, 27 | Description("Sample to invoke methods on WMI class"), 28 | Provider("WmiProv"), 29 | guid("{3865DDFA-7774-4CF4-B5CA-B7569A28FBB4}")] 30 | class NVMe_Method 31 | { 32 | [key] 33 | string InstanceName; 34 | boolean Active; 35 | 36 | [Implemented, WmiMethodId(1)] 37 | void GetControllerInfo( 38 | [out] uint16 pciVendorId, 39 | [out] uint16 pciSsVendId 40 | ); 41 | 42 | 43 | [Implemented, WmiMethodId(2)] 44 | void GetNameSpaceInfo( 45 | [in] uint32 lunId, 46 | [out] uint64 nSize, 47 | [out] uint64 nCap 48 | ); 49 | }; 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /source/nvmePwrMgmt.c: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: nvmePwrMgmt.c 46 | */ 47 | 48 | #include "precomp.h" 49 | #ifndef DBG 50 | #include "nvmePwrMgmt.tmh" 51 | #endif 52 | 53 | /******************************************************************************* 54 | * NVMeAdapterControlPowerUp 55 | * 56 | * @brief Routine for powering up the controller 57 | * 58 | * @param pAE - pointer to device extension 59 | * 60 | * @return BOOLEAN 61 | * TRUE - command was processed successfully 62 | * FALSE - If anything goes wrong 63 | ******************************************************************************/ 64 | BOOLEAN NVMeAdapterControlPowerUp( 65 | IN PNVME_DEVICE_EXTENSION pAE 66 | ) 67 | { 68 | BOOLEAN status = TRUE; 69 | 70 | /* Reset the controller */ 71 | if (NVMeReInitializeController(pAE) == FALSE) { 72 | NVMeFreeBuffers(pAE); 73 | return (FALSE); 74 | } 75 | 76 | pAE->ShutdownInProgress = FALSE; 77 | StorPortDebugPrint(INFO, "NvmeAdapterControlPowerUp: returning TRUE\n"); 78 | return status; 79 | } 80 | 81 | /******************************************************************************* 82 | * NVMeAdapterControlPowerDown 83 | * 84 | * @brief This function is called when srb function is SRB_FUNCTION_POWER or 85 | * from NVMeAdapterControl when Control type is ScsiStopAdapter. 86 | * 87 | * @param pAE - pointer to device extension 88 | * 89 | * @return BOOLEAN 90 | * TRUE - command was processed successfully 91 | * FALSE - If anything goes wrong 92 | ******************************************************************************/ 93 | BOOLEAN NVMeAdapterControlPowerDown( 94 | IN PNVME_DEVICE_EXTENSION pAE 95 | ) 96 | { 97 | BOOLEAN status = FALSE; 98 | 99 | ASSERT(pAE != NULL); 100 | 101 | /* 102 | * The controller is powered down when we get SRB_FUNCTION_POWER in 103 | * StartIo... nothing else to do, just return. 104 | */ 105 | if (pAE->ShutdownInProgress == TRUE) { 106 | /* Shutdown */ 107 | status = TRUE; 108 | } else { 109 | pAE->ShutdownInProgress = TRUE; 110 | 111 | /* Hibernate or Sleep - sanity check that there is no cmd pending */ 112 | if (NVMeDetectPendingCmds(pAE, FALSE, SRB_STATUS_BUS_RESET) == TRUE) 113 | return status; 114 | 115 | /* Stop the controller, but do not free the resources */ 116 | if (NVMeResetAdapter(pAE) != TRUE) { 117 | return (FALSE); 118 | } 119 | } 120 | 121 | StorPortDebugPrint(INFO, 122 | "NvmeAdapterControlPowerDown: returning %d\n", 123 | status); 124 | return status; 125 | } 126 | 127 | /******************************************************************************* 128 | * NVMePowerControl 129 | * 130 | * @brief This function handles the power requests srb from the storport. This 131 | * routine handles request from system to go to S3/S4 state or resume 132 | * from S3/S4 state. 133 | * 134 | * @param pAE - pointer to device extension 135 | * @param pPowerSrb - Power SRB pointer 136 | * 137 | * @return BOOLEAN 138 | * TRUE - command was processed successfully 139 | * FALSE - If anything goes wrong 140 | ******************************************************************************/ 141 | BOOLEAN NVMePowerControl( 142 | IN PNVME_DEVICE_EXTENSION pAE, 143 | IN PSCSI_REQUEST_BLOCK Srb 144 | ) 145 | { 146 | BOOLEAN status = FALSE; 147 | BOOLEAN powerActionValid = FALSE; 148 | NVME_PWR_ACTION nvmePwrAction = NVME_PWR_NONE; 149 | PSCSI_POWER_REQUEST_BLOCK pPowerSrb = (PSCSI_POWER_REQUEST_BLOCK)Srb; 150 | #if (NTDDI_VERSION > NTDDI_WIN7) 151 | PSRBEX_DATA_POWER pSrbExPower = NULL; 152 | #endif 153 | 154 | ULONG PowerAction = 0; 155 | UCHAR SrbPowerFlags = 0; 156 | ULONG DevicePowerState = 0; 157 | 158 | #if (NTDDI_VERSION > NTDDI_WIN7) 159 | pSrbExPower = (PSRBEX_DATA_POWER)SrbGetSrbExDataByType((PSTORAGE_REQUEST_BLOCK)Srb, 160 | SrbExDataTypePower); 161 | if (pSrbExPower != NULL) { 162 | PowerAction = pSrbExPower->PowerAction; 163 | SrbPowerFlags = pSrbExPower->SrbPowerFlags; 164 | DevicePowerState = pSrbExPower->DevicePowerState; 165 | } 166 | else { 167 | PowerAction = pPowerSrb->PowerAction; 168 | SrbPowerFlags = pPowerSrb->SrbPowerFlags; 169 | DevicePowerState = pPowerSrb->DevicePowerState; 170 | } 171 | #else 172 | PowerAction = pPowerSrb->PowerAction; 173 | SrbPowerFlags = pPowerSrb->SrbPowerFlags; 174 | DevicePowerState = pPowerSrb->DevicePowerState; 175 | #endif 176 | 177 | if ((SrbPowerFlags & SRB_POWER_FLAGS_ADAPTER_REQUEST) == FALSE) { 178 | /* 179 | * Storport should not send the device level request (i.e PathId, 180 | * TargetId, LUNID) but in case if it does then ignore it and return 181 | * success. 182 | */ 183 | Srb->SrbStatus = SRB_STATUS_SUCCESS; 184 | return FALSE; 185 | } 186 | 187 | switch (DevicePowerState) { 188 | case StorPowerDeviceD0: 189 | case StorPowerDeviceD3: 190 | StorPortDebugPrint(INFO, 191 | "Device Power State request %d\n", 192 | DevicePowerState); 193 | powerActionValid = TRUE; 194 | break; 195 | case StorPowerDeviceD1: 196 | case StorPowerDeviceD2: 197 | StorPortDebugPrint(INFO, 198 | "Device Power State request %d\n", 199 | DevicePowerState); 200 | powerActionValid = FALSE; 201 | status = TRUE; 202 | break; 203 | case StorPowerDeviceUnspecified: 204 | StorPortDebugPrint(WARNING, 205 | "Unsupported Device Power State received %d\n", 206 | DevicePowerState); 207 | powerActionValid = FALSE; 208 | break; 209 | default: 210 | ASSERT(FALSE); 211 | break; 212 | } 213 | 214 | /* 215 | * Based on power state validity, which we determined above, we will 216 | * transition into appropriate state. 217 | */ 218 | if (powerActionValid == TRUE) { 219 | switch (PowerAction) { 220 | case StorPowerActionNone: 221 | break; 222 | case StorPowerActionHibernate: 223 | case StorPowerActionSleep: 224 | switch (DevicePowerState) { 225 | case StorPowerDeviceD0: 226 | nvmePwrAction = NVME_PWR_ADAPTER_RESUME_FROM_S3_S4; 227 | break; 228 | case StorPowerDeviceD3: 229 | nvmePwrAction = NVME_PWR_ADAPTER_ENTER_S3_S4; 230 | 231 | /* 232 | * Save the PowerAction to prevent 233 | * SCSIOP_START_STOP_UNIT to issue any cmds if we are 234 | * waking from the Hibernate and before our controller 235 | * is ready. 236 | */ 237 | pAE->PowerAction = PowerAction; 238 | break; 239 | default: 240 | /* nvmePwrAction already initialized to NVME_PWR_NONE */ 241 | break; 242 | } /* end DevicePowerState switch */ 243 | break; 244 | case StorPowerActionShutdown: 245 | case StorPowerActionShutdownReset: 246 | case StorPowerActionShutdownOff: 247 | case StorPowerActionWarmEject: 248 | nvmePwrAction = NVME_PWR_ADAPTER_OFF; 249 | break; 250 | case StorPowerActionReserved: 251 | default: 252 | StorPortDebugPrint(ERROR, 253 | "Unsupported Power Action requested %d\n", 254 | PowerAction); 255 | break; 256 | } /* end PowerAction switch */ 257 | } /* end if (powerActionValid == TRUE) */ 258 | 259 | /* Now at this point we know what power action we need to take */ 260 | switch (nvmePwrAction) { 261 | case NVME_PWR_ADAPTER_OFF: 262 | status = NVMeNormalShutdown(pAE); 263 | break; 264 | case NVME_PWR_ADAPTER_ENTER_S3_S4: 265 | status = NVMeAdapterControlPowerDown(pAE); 266 | break; 267 | case NVME_PWR_ADAPTER_RESUME_FROM_S3_S4: 268 | status = NVMeAdapterControlPowerUp(pAE); 269 | break; 270 | case NVME_PWR_NONE: 271 | default: 272 | /* Do nothing, just complete */ 273 | Srb->SrbStatus= SRB_STATUS_SUCCESS; 274 | return FALSE; 275 | break; 276 | } /* end switch */ 277 | 278 | return status; 279 | } 280 | 281 | #if (NTDDI_VERSION > NTDDI_WIN7) 282 | /******************************************************************************* 283 | * NVMeAdapterPowerControl 284 | * 285 | * @brief This function handles the power requests srb from the storport. This 286 | * routine handles request from system to go to S3/S4 state or resume 287 | * from S3/S4 state. 288 | * 289 | * @param pAE - pointer to device extension 290 | * @param DevicePowerState - Device Power State 291 | * @param PowerAction - Power Action 292 | * 293 | * @return BOOLEAN 294 | * TRUE - command was processed successfully 295 | * FALSE - If anything goes wrong 296 | ******************************************************************************/ 297 | BOOLEAN NVMeAdapterPowerControl( 298 | IN PNVME_DEVICE_EXTENSION pAE, 299 | IN ULONG DevicePowerState, 300 | IN ULONG PowerAction 301 | ) 302 | { 303 | BOOLEAN status = FALSE; 304 | BOOLEAN powerActionValid = FALSE; 305 | NVME_PWR_ACTION nvmePwrAction = NVME_PWR_NONE; 306 | 307 | switch (DevicePowerState) { 308 | case StorPowerDeviceD0: 309 | case StorPowerDeviceD3: 310 | StorPortDebugPrint(INFO, "NVMePowerControl: Device Power State request %d\n", DevicePowerState); 311 | powerActionValid = TRUE; 312 | break; 313 | case StorPowerDeviceD1: 314 | case StorPowerDeviceD2: 315 | StorPortDebugPrint(INFO, "NVMePowerControl: Device Power State request %d\n", DevicePowerState); 316 | powerActionValid = FALSE; 317 | status = TRUE; 318 | break; 319 | case StorPowerDeviceUnspecified: 320 | StorPortDebugPrint(ERROR, "NVMePowerControl: Unsupported Device Power State received %d\n", DevicePowerState); 321 | powerActionValid = FALSE; 322 | break; 323 | default: 324 | ASSERT(FALSE); 325 | break; 326 | } 327 | 328 | /* 329 | * Based on power state validity, which we determined above, we will 330 | * transition into appropriate state. 331 | */ 332 | if (powerActionValid == TRUE) { 333 | switch (PowerAction) { 334 | case StorPowerActionNone: 335 | break; 336 | case StorPowerActionHibernate: 337 | case StorPowerActionSleep: 338 | switch (DevicePowerState) { 339 | case StorPowerDeviceD0: 340 | nvmePwrAction = NVME_PWR_ADAPTER_RESUME_FROM_S3_S4; 341 | break; 342 | case StorPowerDeviceD3: 343 | nvmePwrAction = NVME_PWR_ADAPTER_ENTER_S3_S4; 344 | 345 | /* 346 | * Save the PowerAction to prevent 347 | * SCSIOP_START_STOP_UNIT to issue any cmds if we are 348 | * waking from the Hibernate and before our controller 349 | * is ready. 350 | */ 351 | pAE->PowerAction = PowerAction; 352 | break; 353 | default: 354 | /* nvmePwrAction already initialized to NVME_PWR_NONE */ 355 | break; 356 | } /* end DevicePowerState switch */ 357 | break; 358 | case StorPowerActionShutdown: 359 | case StorPowerActionShutdownReset: 360 | case StorPowerActionShutdownOff: 361 | case StorPowerActionWarmEject: 362 | nvmePwrAction = NVME_PWR_ADAPTER_OFF; 363 | break; 364 | case StorPowerActionReserved: 365 | default: 366 | StorPortDebugPrint(ERROR, "NVMePowerControl: Unsupported Device Power Action requested %d\n", PowerAction); 367 | break; 368 | } /* end PowerAction switch */ 369 | } /* end if (powerActionValid == TRUE) */ 370 | 371 | /* Now at this point we know what power action we need to take */ 372 | switch (nvmePwrAction) { 373 | case NVME_PWR_ADAPTER_OFF: 374 | status = NVMeNormalShutdown(pAE); 375 | break; 376 | case NVME_PWR_ADAPTER_ENTER_S3_S4: 377 | StorPortPause(pAE, STOR_ALL_REQUESTS); 378 | status = NVMeAdapterControlPowerDown(pAE); 379 | break; 380 | case NVME_PWR_ADAPTER_RESUME_FROM_S3_S4: 381 | status = NVMeAdapterControlPowerUp(pAE); 382 | break; 383 | case NVME_PWR_NONE: 384 | default: 385 | return FALSE; 386 | break; 387 | } /* end switch */ 388 | 389 | return status; 390 | } 391 | #endif 392 | -------------------------------------------------------------------------------- /source/nvmePwrMgmt.h: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: nvmePwrMgmt.h 46 | */ 47 | 48 | #ifndef __NVME_PWRMGMT_H__ 49 | #define __NVME_PWRMGMT_H__ 50 | 51 | typedef enum _NVME_PWR_ACTION 52 | { 53 | NVME_PWR_NONE = 0, 54 | NVME_PWR_ADAPTER_OFF, 55 | NVME_PWR_ADAPTER_ENTER_S3_S4, 56 | NVME_PWR_ADAPTER_RESUME_FROM_S3_S4, 57 | NVME_PWR_ADAPTER_MAX_POWER_ACTION 58 | } NVME_PWR_ACTION; 59 | 60 | BOOLEAN NVMeAdapterControlPowerUp( 61 | IN PNVME_DEVICE_EXTENSION pAdapterExtension 62 | ); 63 | 64 | BOOLEAN NVMeAdapterControlPowerDown( 65 | IN PNVME_DEVICE_EXTENSION pAdapterExtension 66 | ); 67 | 68 | BOOLEAN NVMePowerControl( 69 | IN PNVME_DEVICE_EXTENSION pAdapterExtension, 70 | IN PSCSI_REQUEST_BLOCK Srb 71 | ); 72 | 73 | #if (NTDDI_VERSION > NTDDI_WIN7) 74 | BOOLEAN NVMeAdapterPowerControl( 75 | IN PNVME_DEVICE_EXTENSION pAE, 76 | IN ULONG DevicePowerState, 77 | IN ULONG PowerAction 78 | ); 79 | #endif 80 | 81 | #endif /* __NVME_PWRMGMT_H__ */ 82 | -------------------------------------------------------------------------------- /source/nvmeReg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/source/nvmeReg.h -------------------------------------------------------------------------------- /source/nvmeSnti.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/source/nvmeSnti.c -------------------------------------------------------------------------------- /source/nvmeSntiTypes.h: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: nvmeSntiTypes.h 46 | */ 47 | 48 | #ifndef __SNTI_TYPES_H__ 49 | #define __SNTI_TYPES_H__ 50 | 51 | /* SCSI SPC/SBC opcodes not defined by Storport.h (WDK) */ 52 | #define SCSIOP_COMPARE_AND_WRITE 0x89 53 | #define SCSIOP_SECURITY_PROTOCOL_IN 0xA2 54 | #define SCSIOP_SECURITY_PROTOCOL_OUT 0xB5 55 | #define SCSIOP_UNMAP 0x42 56 | #define SCSIOP_WRITE_LONG16 0x9F 57 | 58 | /* CDB offsets */ 59 | #define CDB_6_CONTROL_OFFSET 5 60 | #define CDB_10_CONTROL_OFFSET 9 61 | #define CDB_12_CONTROL_OFFSET 11 62 | #define CDB_16_CONTROL_OFFSET 15 63 | #define CDB_VAR_CONTROL_OFFSET 1 64 | #define CONTROL_BYTE_NACA_MASK 0x4 65 | #define READ_6_LBA_OFFSET 1 66 | #define READ_10_LBA_OFFSET 2 67 | #define READ_12_LBA_OFFSET 2 68 | #define READ_16_LBA_OFFSET_MSW 2 69 | #define READ_16_LBA_OFFSET_LSW 6 70 | #define READ_6_LENGTH_OFFSET 4 71 | #define READ_10_LENGTH_OFFSET 7 72 | #define READ_12_LENGTH_OFFSET 6 73 | #define READ_16_LENGTH_OFFSET 10 74 | #define WRITE_6_LBA_OFFSET 1 75 | #define WRITE_10_LBA_OFFSET 2 76 | #define WRITE_12_LBA_OFFSET 2 77 | #define WRITE_16_LBA_OFFSET 2 78 | #define INQ_EVPD_BYTE_OFFSET 1 79 | #define INQ_PAGE_CODE_BYTE_OFFSET 2 80 | #define INQ_EVPD_BIT_MASK 1 81 | #define INQ_CDB_ALLOCATION_LENGTH_OFFSET 3 82 | #define READ_CAP_10_DISK_CAPACITY_LSB 4 83 | #define READ_CAP_10_SECTOR_SIZE_LSB 8 84 | #define READ_CAP_10_SECTOR_SIZE_OFFSET 4 85 | #define READ_CAP_10_PARM_DATA_SIZE 8 86 | #define READ_CAP_16_PARM_DATA_SIZE 32 87 | #define REPORT_LUNS_CDB_ALLOC_LENGTH_OFFSET 6 88 | #define REPORT_LUNS_SELECT_REPORT_OFFSET 2 89 | #define READ_CAP_16_CDB_ALLOC_LENGTH_OFFSET 10 90 | #define READ_CAP_16_SERVICE_ACTION_OFFSET 1 91 | #define READ_CAP_16_SERVICE_ACTION_IN 0x10 92 | #define REQUEST_SENSE_CDB_ALLOC_LENGTH_OFFSET 4 93 | #define REQUEST_SENSE_DESCRIPTOR_FORMAT_OFFSET 1 94 | #define REQUEST_SENSE_DESCRIPTOR_FORMAT_MASK 0x01 95 | #define DESCRIPTOR_FORMAT_SENSE_DATA_TYPE 1 96 | #define INQUIRY_EVPD_BYTE_OFFSET 1 97 | #define INQUIRY_PAGE_CODE_BYTE_OFFSET 2 98 | #define INQUIRY_EVPD_BIT_MASK 1 99 | #define INQUIRY_CDB_ALLOCATION_LENGTH_OFFSET 3 100 | #define READ_CAP_10_DISK_CAPACITY_LSB 4 101 | #define READ_CAP_10_SECTOR_SIZE_LSB 8 102 | #define READ_CAP_10_SECTOR_SIZE_OFFSET 4 103 | #define RETURNED_LBA_OFFSET 0 104 | #define LBA_LENGTH_OFFSET 4 105 | #define START_STOP_UNIT_CDB_IMMED_OFFSET 1 106 | #define START_STOP_UNIT_CDB_IMMED_MASK 0x1 107 | #define START_STOP_UNIT_CDB_POWER_COND_MOD_OFFSET 3 108 | #define START_STOP_UNIT_CDB_POWER_COND_MOD_MASK 0xF 109 | #define START_STOP_UNIT_CDB_POWER_COND_OFFSET 4 110 | #define START_STOP_UNIT_CDB_POWER_COND_MASK 0xF0 111 | #define START_STOP_UNIT_CDB_NO_FLUSH_OFFSET 4 112 | #define START_STOP_UNIT_CDB_NO_FLUSH_MASK 0x4 113 | #define START_STOP_UNIT_CDB_LOAD_EJECT_OFFSET 4 114 | #define START_STOP_UNIT_CDB_LOAD_EJECT_MASK 0x2 115 | #define START_STOP_UNIT_CDB_START_OFFSET 4 116 | #define START_STOP_UNIT_CDB_START_MASK 0x1 117 | #define WRITE_BUFFER_CDB_MODE_OFFSET 1 118 | #define WRITE_BUFFER_CDB_MODE_MASK 0x1F 119 | #define WRITE_BUFFER_CDB_BUFFER_ID_OFFSET 2 120 | #define WRITE_BUFFER_CDB_BUFFER_OFFSET_OFFSET 3 121 | #define WRITE_BUFFER_CDB_PARAM_LIST_LENGTH_OFFSET 6 122 | #define FORMAT_UNIT_CDB_FORMAT_PROT_INFO_OFFSET 1 123 | #define FORMAT_UNIT_CDB_FORMAT_PROT_INFO_MASK 0xC0 124 | #define FORMAT_UNIT_CDB_FORMAT_PROT_INFO_SHIFT 6 125 | #define FORMAT_UNIT_CDB_LONG_LIST_OFFSET 1 126 | #define FORMAT_UNIT_CDB_LONG_LIST_MASK 0x20 127 | #define FORMAT_UNIT_CDB_FORMAT_DATA_OFFSET 1 128 | #define FORMAT_UNIT_CDB_FORMAT_DATA_MASK 0x10 129 | #define FORMAT_UNIT_CDB_COMPLETE_LIST_OFFSET 1 130 | #define FORMAT_UNIT_CDB_COMPLETE_LIST_MASK 0x8 131 | #define FORMAT_UNIT_CDB_DEFECT_LIST_FORMAT_OFFSET 1 132 | #define FORMAT_UNIT_CDB_DEFECT_LIST_FORMAT_MASK 0x7 133 | #define PROT_TYPE_0 0 134 | #define PROT_TYPE_1 1 135 | #define PROT_TYPE_2 2 136 | #define PROT_TYPE_3 3 137 | #define FORMAT_NVM_PROTECTION_INFO_SHIFT_MASK 5 138 | 139 | /* Misc. defines */ 140 | #define NVME_MAX_LEN 256 141 | #define SECTOR_SIZE 512 142 | #define STANDARD_INQUIRY_PAGE_SIZE (INQUIRYDATABUFFERSIZE) 143 | #define UNIT_SERIAL_NUMBER_PAGE_SIZE 24 144 | #define DEVICE_IDENTIFICATION_PAGE_SIZE 24 145 | #define EXTENDED_INQUIRY_DATA_PAGE_SIZE 64 146 | #define SUPPORTED_VPD_PAGES_PAGE_SIZE 7 147 | #define REPORT_LUNS_SIZE 16 148 | #define DWORD_SHIFT_MASK 32 149 | #define DWORD_MASK_BYTE_3 0xFF000000 150 | #define DWORD_MASK_BYTE_2 0x00FF0000 151 | #define DWORD_MASK_BYTE_1 0x0000FF00 152 | #define DWORD_MASK_BYTE_0 0x000000FF 153 | #define DWORD_MASK_LOW_WORD 0x0000FFFF 154 | #define DWORD_MASK_HIGH_WORD 0xFFFF0000 155 | #define NUM_BYTES_IN_DWORD 4 156 | #define BYTE_SHIFT_3 24 157 | #define BYTE_SHIFT_2 16 158 | #define BYTE_SHIFT_1 8 159 | #define NIBBLE_SHIFT 4 160 | #define ONE_OR_MORE_PHYSICAL_BLOCKS 0 161 | #define UNSPECIFIED 0 162 | #define SPECIFIED 1 163 | #define LBA_0 0 164 | #define PROTECTION_DISABLED 0 165 | #define PROTECTION_ENABLED 1 166 | #define FIXED_SENSE_DATA 0x70 167 | #define DESC_FORMAT_SENSE_DATA 0x72 168 | #define FIXED_SENSE_DATA_ADD_LENGTH 10 169 | #define RESERVED_FIELDS 0x0 170 | #define LUN_ENTRY_SIZE 8 171 | #define LUN_DATA_HEADER_SIZE 8 172 | #define LOGICAL_AND_SUBS_LUNS_RET 0x12 173 | #define ADMIN_AND_LOGICAL_LUNS_RET 0x11 174 | #define ADMIN_LUNS_RETURNED 0x10 175 | #define ALL_LUNS_RETURNED 0x02 176 | #define ALL_WELL_KNOWN_LUNS_RETURNED 0x01 177 | #define RESTRICTED_LUNS_RETURNED 0x00 178 | #define NVME_PAGE_SIZE 4096 179 | #define PRP_ENTRY_OFFSET_SHIFT_MASK 12 180 | #define PRP_ENTRY_BASE_ADDR_MASK 0xFFFFFFFFFFFFF000 181 | #define WORD_HIGH_BYTE_MASK 0xFF00 182 | #define WORD_LOW_BYTE_MASK 0xFF 183 | #define SINGLE_BYTE_SHIFT 0x8 184 | #define NVME_WRITE_PBAOFFSET_SHIFT 2 185 | #define NVME_WRITE_PBAOFFSET_MASK 0xFFFFFFFC 186 | #define IN_COMMAND_PRP_ENTRY_LIMIT 2 187 | #define PRP_ENTRY_LOW_2_BITS_MASK 0x3 188 | #define DWORD_BIT_MASK 0xFFFFFFFF 189 | #define NVME_POWER_STATE_START_VALID 0x00 190 | #define NVME_POWER_STATE_ACTIVE 0x01 191 | #define NVME_POWER_STATE_IDLE 0x02 192 | #define NVME_POWER_STATE_STANDBY 0x03 193 | #define NVME_POWER_STATE_LU_CONTROL 0x07 194 | #define POWER_STATE_0 0 195 | #define POWER_STATE_1 1 196 | #define POWER_STATE_2 2 197 | #define POWER_STATE_3 3 198 | #define POWER_STATE_4 4 199 | #define POWER_STATE_5 5 200 | #define POWER_STATE_6 6 201 | #define DOWNLOAD_SAVE_ACTIVATE 0x05 202 | #define DOWNLOAD_SAVE_DEFER_ACTIVATE 0x0E 203 | #define ACTIVATE_DEFERRED_MICROCODE 0x0F 204 | #define PROTECTION_FIELD_USAGE_MASK 0x7 205 | #define FORMAT_UNIT_IMMED_MASK 0x2 206 | #define PROTECTION_INTERVAL_EXPONENT_MASK 0xF 207 | #define SCSISTAT_TASK_ABORTED 0x40 208 | #define SCSI_ADSENSE_PERIPHERAL_DEV_WRITE_FAULT 0x03 209 | #define SCSI_ADSENSE_LOG_BLOCK_GUARD_CHECK_FAILED 0x10 210 | #define SCSI_ADSENSE_LOG_BLOCK_APPTAG_CHECK_FAILED 0x10 211 | #define SCSI_ADSENSE_LOG_BLOCK_REFTAG_CHECK_FAILED 0x10 212 | #define SCSI_ADSENSE_UNRECOVERED_READ_ERROR 0x11 213 | #define SCSI_ADSENSE_MISCOMPARE_DURING_VERIFY 0x1D 214 | #define SCSI_ADSENSE_ACCESS_DENIED_INVALID_LUN_ID 0x20 215 | #define SCSI_ADSENSE_INTERNAL_TARGET_FAILURE 0x44 216 | #define SCSI_ADSENSE_FORMAT_COMMAND_FAILED 0x31 217 | #define SCSI_SENSEQ_INVALID_LUN_ID 0x09 218 | #define SCSI_SENSEQ_FORMAT_COMMAND_FAILED 0x01 219 | #define SCSI_SENSEQ_LOG_BLOCK_GUARD_CHECK_FAILED 0x01 220 | #define SCSI_SENSEQ_LOG_BLOCK_APPTAG_CHECK_FAILED 0x02 221 | #define SCSI_SENSEQ_LOG_BLOCK_REFTAG_CHECK_FAILED 0x03 222 | #define SCSI_SENSEQ_ACCESS_DENIED_INVALID_LUN_ID 0x09 223 | #define NVM_CMD_SET_STATUS 0x80 224 | #define NVM_CMD_SET_GENERIC_STATUS_OFFSET 0x74 225 | #define NVM_CMD_SET_SPECIFIC_STATUS_OFFSET 0x75 226 | #define NVM_MEDIA_ERROR_STATUS_OFFSET 0x80 227 | #define KELVIN_TEMP_FACTOR 273 228 | #define UPPER_DWORD_BIT_MASK 0xFFFFFFFF00000000 229 | #define PRP_ENTRY_1 1 230 | #define PRP_ENTRY_2 2 231 | #define PRP_ENTRY_3 3 232 | #define PAGE_MASK (PAGE_SIZE - 1) 233 | #define NUM_SUPPORTED_INQ_PAGES 3 234 | #define BYTE_0 0 235 | #define BYTE_1 1 236 | #define BYTE_2 2 237 | #define BYTE_3 3 238 | #define BYTE_4 4 239 | #define BYTE_5 5 240 | #define BYTE_6 6 241 | #define BYTE_7 7 242 | /* 243 | Set the following to 1 if your NVMe controller returns zeros when LBAs 244 | that have been previously UNMAPED (via DSM dealloc) are read 245 | */ 246 | #define ZEROS_RETURNED_INDICATOR 1 247 | 248 | /* Diagnostig page codes */ 249 | #define DIAG_SUPPORTED_LOG 0x00 250 | #define DIAG_BUFFER_RUN 0x01 251 | #define DIAG_ERROR_WRITE 0x02 252 | #define DIAG_ERROR_READ 0x03 253 | #define DIAG_ERROR_VERIFY 0x05 254 | #define DIAG_NO_MEDIUM_ERRORS 0x06 255 | 256 | /* SCSI/NVMe defines and bit masks */ 257 | #define READ_6_LBA_MASK 0x1FFFFF 258 | #define LBA_MASK_LOWER_32_BITS 0xFFFFFFFF 259 | #define LSB_BYTE_MASK 0xF 260 | #define NAMESPACE_IDENTIFY_DATA_DPS_ENABLED_MASK 0x8 261 | #define NAMESPACE_IDENTIFY_DATA_DPS_MASK 0x7 262 | #define LIMITED_RETRY_ENABLED 0x80000000 263 | #define LIMITED_RETRY_DISABLED 0x00000000 264 | #define FUA_ENABLED 0x40000000 265 | #define FUA_DISABLED 0x00000000 266 | #define PROTECTION_INFO 0x00000000 267 | #define NVME_WRITE_PRINFO_BIT_OFFSET 26 268 | #define NVME_READ_PRINFO_BIT_OFFSET 26 269 | #define INQ_STANDARD_INQUIRY_PAGE 0x00 270 | #define INQ_SUPPORTED_VPD_PAGES_PAGE 0x00 271 | #define INQ_UNIT_SERIAL_NUMBER_PAGE 0x80 272 | #define INQ_DEVICE_IDENTIFICATION_PAGE 0x83 273 | #define INQ_EXTENDED_INQUIRY_DATA_PAGE 0x86 274 | #define INQ_SN_FROM_EUI64_LENGTH 0x14 275 | #define INQ_SN_FROM_NGUID_LENGTH 0x28 276 | #define INQ_V10_SN_LENGTH 0x1E 277 | 278 | #define INQ_SN_SUB_LENGTH 4 279 | /* For Win 8 UNMAP support, there are additional VPD pages 280 | we provide such as logical block provisioning 281 | */ 282 | #if (NTDDI_VERSION > NTDDI_WIN7) 283 | #define INQ_NUM_SUPPORTED_VPD_PAGES 6 284 | #else 285 | #define INQ_NUM_SUPPORTED_VPD_PAGES 3 286 | #endif 287 | #define INQ_RESERVED 0 288 | #define BLOCK_LIMITS_PAGE_LENGTH 0x3C 289 | #define BLOCK_DEVICE_CHAR_PAGE_LENGTH 0x3C 290 | #define LOGICAL_BLOCK_PROVISIONING_PAGE_LENGTH 0x04 291 | #define MAX_UNMAP_BLOCK_DESCRIPTOR_COUNT 256 292 | /* Rotation rate of 1 indicates non-rotating (SSD) */ 293 | #define MEDIUM_ROTATIONAL_RATE 0x0001 294 | #define FORM_FACTOR_NOT_REPORTED 0 295 | #define NO_THIN_PROVISIONING_THRESHHOLD 0 296 | #define WR_SAME_16_TO_UNMAP_NOT_SUPPORTED 0 297 | #define WR_SAME_10_TO_UNMAP_NOT_SUPPORTED 0 298 | #define ANC_NOT_SUPPORTED 0 299 | #define UNMAP_ANCHAR_BIT 1 300 | #define NO_PROVISIONING_GROUP_DESCRIPTOR 0 301 | #define UNREMOVABLE_MEDIA 0 302 | #define VERSION_SPC_4 0x06 303 | #define ACA_UNSUPPORTED 0 304 | #define HIERARCHAL_ADDR_UNSUPPORTED 0 305 | #define RESPONSE_DATA_FORMAT_SPC_4 2 306 | #define STANDARD_INQUIRY_LENGTH 36 307 | #define ADDITIONAL_STD_INQ_LENGTH 31 308 | #define EXTENDED_INQUIRY_DATA_PAGE_LENGTH 0x3C 309 | #define VENDOR_ID_LENGTH 0x8 310 | #define EMBEDDED_ENCLOSURE_SERVICES_UNSUPPORTED 0 311 | #define MEDIUM_CHANGER_UNSUPPORTED 0 312 | #define COMMAND_MANAGEMENT_MODEL 1 313 | #define WIDE_16_BIT_XFERS_UNSUPPORTED 0 314 | #define WIDE_16_BIT_ADDRESES_UNSUPPORTED 0 315 | #define SYNCHRONOUS_DATA_XFERS_UNSUPPORTED 0 316 | #define RESERVED_FIELD 0 317 | #define CLOCKING_UNSUPPORTED 0x0 318 | #define QAS_UNSUPPORTED 0 319 | #define IUS_UNSUPPORTED 0 320 | #define SBC_3_VERSION_DESCRIPTOR 0x04C0 321 | #define SPC_4_VERSION_DESCRIPTOR 0x0300 322 | #define VERSION_DESC_1 2 323 | #define VERSION_DESC_2 4 324 | #define EUI64_ID 0x84EB0AFFFF171500 325 | #define NAA_IEEE_EX 6 326 | 327 | // Device Identification defined in NVMe-SCSI Translation Spec 1.5, Section 6.1.4 328 | #define VPD_ID_DESCRIPTOR_HDR_LENGTH (sizeof(VPD_IDENTIFICATION_DESCRIPTOR)) 329 | #define EUI64_DATA_SIZE 8 330 | #define EUI64_ASCII_SIZE EUI64_DATA_SIZE*2 331 | #define NGUID_DATA_SIZE 16 332 | #define NGUID_ASCII_SIZE NGUID_DATA_SIZE*2 333 | #define PRODUCT_ID_ASCII_SIZE 16 334 | #define VENDOR_ID_DATA_SIZE 2 335 | #define VENDOR_ID_ASCII_SIZE VENDOR_ID_DATA_SIZE*2 336 | #define VENDOR_SPEC_V10_SN_ASCII_SIZE 13 337 | #define VENDOR_SPEC_V10_NSID_ASCII_SIZE 8 338 | 339 | 340 | // T10 Vendor Specific identifier defined in NVMe-SCSI Translation Spec 1.5 341 | #define T10_VID_DES_VID_FIELD_SIZE sizeof(SNTI_T10_VID_DESCRIPTOR) - 1 342 | 343 | 344 | // SCSI Name String defined in NVMe-SCSI Translation Spec 1.5 345 | /* SCSI name string defines for V1.0 */ 346 | #define ASCII_SPACE_CHAR_VALUE 0x20 347 | #define SCSI_NAME_PCI_VENDOR_ID_SIZE 4 348 | #define SCSI_NAME_NAMESPACE_ID_SIZE 4 349 | #define SCSI_NAME_MODEL_NUM_SIZE 40 350 | #define SCSI_NAME_SERIAL_NUM_SIZE 20 351 | 352 | /* SCSI name string defines for V1.1 */ 353 | #define EUI_ASCII_SIZE 4 354 | #define NGUID_ID_SIZE 4 355 | 356 | 357 | #define INQ_DEV_ID_DESCRIPTOR_RESERVED 0 358 | #define INQ_DEV_ID_DESCRIPTOR_OFFSET 0x8 359 | #define DATA_PROTECTION_CAPABILITIES_MASK 0xF 360 | #define DATA_PROTECTION_SETTINGS_MASK 0x7 361 | #define ACTIVATE_AFTER_HARD_RESET 0x2 362 | #define SENSE_KEY_SPECIFIC_DATA 1 363 | #define GROUPING_FUNCTION_UNSUPPORTED 0 364 | #define COMMAND_PRIORITY_UNSUPPORTED 0 365 | #define HEAD_OF_QUEUE_TASK_ATTR_UNSUPPORTED 0 366 | #define ORDERED_TASK_ATTR_UNSUPPORTED 0 367 | #define SIMPLE_TASK_ATTR_UNSUPPORTED 0 368 | #define WRITE_UNCORRECTABLE_UNSUPPORTED 0 369 | #define CORRECTION_DISABLE_UNSUPPORTED 0 370 | #define NON_VOLATILE_CACHE_UNSUPPORTED 0 371 | #define PROTECTION_INFO_INTERNALS_UNSUPPORTED 0 372 | #define LUN_UNIT_ATTENTIONS_CLEARED 1 373 | #define REFERRALS_UNSUPPORTED 0 374 | #define CAPABILITY_BASED_SECURITY_UNSUPPORTED 0 375 | #define MICROCODE_DOWNLOAD_VENDOR_SPECIFIC 0 376 | 377 | /* SCSI READ/WRITE Defines */ 378 | #define WRITE_CDB_WP_OFFSET 1 379 | #define WRITE_CDB_WP_MASK 0xE0 380 | #define WRITE_CDB_WP_SHIFT 5 381 | #define WRITE_CDB_FUA_OFFSET 1 382 | #define WRITE_CDB_FUA_MASK 0x8 383 | #define WRITE_6_CDB_LBA_OFFSET 1 384 | #define WRITE_6_CDB_LBA_MASK 0x001FFFFF 385 | #define WRITE_6_CDB_TX_LEN_OFFSET 4 386 | #define WRITE_10_CDB_LBA_OFFSET 2 387 | #define WRITE_10_CDB_TX_LEN_OFFSET 7 388 | #define WRITE_10_CDB_WP_OFFSET 1 389 | #define WRITE_10_CDB_WP_MASK 0xE0 390 | #define WRITE_10_CDB_DPO_OFFSET 1 391 | #define WRITE_10_CDB_DPO_MASK 0x10 392 | #define WRITE_10_CDB_FUA_OFFSET 1 393 | #define WRITE_10_CDB_FUA_MASK 0x8 394 | #define WRITE_10_CDB_FUA_NV_OFFSET 1 395 | #define WRITE_10_CDB_FUA_NV_MASK 0x2 396 | #define WRITE_10_CDB_GROUP_NUM_OFFSET 6 397 | #define WRITE_10_CDB_GROUP_NUM_MASK 0x1F 398 | #define WRITE_12_CDB_LBA_OFFSET 2 399 | #define WRITE_12_CDB_TX_LEN_OFFSET 6 400 | #define WRITE_12_CDB_WP_OFFSET 1 401 | #define WRITE_12_CDB_WP_MASK 0xE0 402 | #define WRITE_12_CDB_FUA_OFFSET 1 403 | #define WRITE_12_CDB_FUA_MASK 0x8 404 | #define WRITE_16_CDB_LBA_OFFSET 2 405 | #define WRITE_16_CDB_TX_LEN_OFFSET 10 406 | #define WRITE_16_CDB_FUA_OFFSET 1 407 | #define WRITE_PROTECTION_CODE_0 0 408 | #define WRITE_PROTECTION_CODE_1 1 409 | #define WRITE_PROTECTION_CODE_2 2 410 | #define WRITE_PROTECTION_CODE_3 3 411 | #define WRITE_PROTECTION_CODE_4 4 412 | #define WRITE_PROTECTION_CODE_5 5 413 | #define READ_CDB_RP_OFFSET 1 414 | #define READ_CDB_RP_MASK 0xE0 415 | #define READ_CDB_RP_SHIFT 5 416 | #define READ_CDB_FUA_OFFSET 1 417 | #define READ_CDB_FUA_MASK 0x8 418 | #define READ_6_CDB_LBA_OFFSET 1 419 | #define READ_6_CDB_TX_LEN_OFFSET 4 420 | #define READ_6_CDB_LBA_MASK 0x001FFFFF 421 | #define READ_10_CDB_LBA_OFFSET 2 422 | #define READ_10_CDB_TX_LEN_OFFSET 7 423 | #define READ_10_CDB_FUA_OFFSET 1 424 | #define READ_12_CDB_LBA_OFFSET 2 425 | #define READ_12_CDB_TX_LEN_OFFSET 6 426 | #define READ_16_CDB_LBA_OFFSET 2 427 | #define READ_16_CDB_TX_LEN_OFFSET 10 428 | #define READ_16_CDB_FUA_OFFSET 1 429 | #define READ_PROTECTION_CODE_0 0 430 | #define READ_PROTECTION_CODE_1 1 431 | #define READ_PROTECTION_CODE_2 2 432 | #define READ_PROTECTION_CODE_3 3 433 | #define READ_PROTECTION_CODE_4 4 434 | #define READ_PROTECTION_CODE_5 5 435 | #define READ_WRITE_6_MAX_LBA 256 436 | 437 | /* Security Protocol In/Out Defines */ 438 | #define SECURITY_PROTOCOL_CDB_SEC_PROT_OFFSET 1 439 | #define SECURITY_PROTOCOL_CDB_SEC_PROT_SP_OFFSET 2 440 | #define SECURITY_PROTOCOL_CDB_INC_512_OFFSET 4 441 | #define SECURITY_PROTOCOL_CDB_INC_512_MASK 0x80 442 | #define SECURITY_PROTOCOL_CDB_INC_512_SHIFT 7 443 | #define SECURITY_PROTOCOL_CDB_LENGTH_OFFSET 6 444 | #define SECURITY_RECEIVE_SEND_DWORD_10_SECP_SHIFT 24 445 | #define SECURITY_RECEIVE_SEND_DWORD_10_SPSP_SHIFT 8 446 | #define SECURITY_RECEIVE_SEND_DWORD_11_TL_SHIFT 16 447 | 448 | /* Persistent Reservation In/Out defines */ 449 | #define PERSISTENT_RES_CDB_SER_ACTION_OFFSET 1 450 | #define PERSISTENT_RES_CDB_RTYPE_OFFSET 2 451 | #define PERSISTENT_RES_CDB_RTYPE_MASK 0xF 452 | #define PERSISTENT_RES_CDB_SCOPE_OFFSET 2 453 | #define PERSISTENT_RES_CDB_SCOPE_MASK 0XF0 454 | #define PERSISTENT_RESIN_CDB_ALLOC_LEN_OFFSET 7 455 | #define PERSISTENT_RESOUT_CDB_ALLOC_LEN_OFFSET 5 456 | #define PERSISTENT_RESOUT_LU_SCOPE 0 457 | 458 | /* Persistent Reservation Actions*/ 459 | #define RESERVATION_ACTION_REPORT_CAPABILITIES 2 460 | #define RESERVATION_ACTION_READ_FULL_STATUS 3 461 | #define RESERVATION_ACTION_REGISTER_AND_MOVE 7 462 | 463 | /* Persistent Reservation Types */ 464 | #define RESERVATION_TYPE_NONE 0 465 | #define RESERVATION_TYPE_WRITE_EXCLUSIVE_ALL 7 466 | #define RESERVATION_TYPE_EXCLUSIVE_ACCESS_ALL 8 467 | #define RESERVATION_TYPE_MAX_VALUE 8 468 | 469 | /* Mode Sense/Select defines */ 470 | #define MODE_PAGE_READ_WRITE_ERROR_RECOVERY 0x01 471 | #define MODE_PAGE_DISCONNECT_RECONNECT 0x02 472 | #define MODE_PAGE_PROTOCOL_SPECIFIC_PORT 0x19 473 | #define MODE_PAGE_INFORMATIONAL_EXCEPTIONS_CONTROL 0x1C 474 | #define MODE_PAGE_RETURN_ALL 0x3F 475 | #define MODE_SENSE_6_PAGE_08_SIZE 32 476 | #define MODE_SENSE_6_PAGE_08_SIZE_DBD 24 477 | #define MODE_SENSE_6_PAGE_1C_SIZE 24 478 | #define MODE_SENSE_6_PAGE_1C_SIZE_DBD 16 479 | #define MODE_SENSE_6_PAGE_3F_SIZE 44 480 | #define MODE_SENSE_6_PAGE_3F_SIZE_DBD 36 481 | #define MODE_SENSE_6_CDB_ALLOC_LENGTH_OFFSET 4 482 | #define MODE_SENSE_CDB_PAGE_CONTROL_OFFSET 2 483 | #define MODE_SENSE_CDB_PAGE_CONTROL_MASK 0xC0 484 | #define MODE_SENSE_CDB_PAGE_CONTROL_SHIFT 6 485 | #define MODE_SENSE_CDB_PAGE_CODE_OFFSET 2 486 | #define MODE_SENSE_CDB_PAGE_CODE_MASK 0x3F 487 | #define MODE_SENSE_CDB_SUBPAGE_CODE_OFFSET 3 488 | #define MODE_SENSE_CDB_LLBAA_OFFSET 1 489 | #define MODE_SENSE_CDB_LLBAA_MASK 0x10 490 | #define MODE_SENSE_CDB_LLBAA_SHIFT 4 491 | #define MODE_SENSE_CDB_DBD_OFFSET 1 492 | #define MODE_SENSE_CDB_DBD_MASK 8 493 | #define MODE_SENSE_CDB_DBD_SHIFT 3 494 | 495 | #define MODE_SENSE_10_PAGE_08_SIZE 36 496 | #define MODE_SENSE_10_PAGE_08_SIZE_DBD 28 497 | #define MODE_SENSE_10_PAGE_1C_SIZE 28 498 | #define MODE_SENSE_10_PAGE_1C_SIZE_DBD 20 499 | #define MODE_SENSE_10_PAGE_3F_SIZE 48 500 | #define MODE_SENSE_10_PAGE_3F_SIZE_DBD 40 501 | #define MODE_SENSE_10_CDB_ALLOC_LENGTH_OFFSET 7 502 | #define MODE_SENSE_10_CDB_PAGE_CODE_OFFSET 2 503 | #define MODE_SENSE_10_CDB_PAGE_CODE_MASK 0x3F 504 | #define MODE_SENSE_10_CDB_DBD_OFFSET 1 505 | #define MODE_SENSE_10_CDB_DBD_MASK 8 506 | 507 | #define MODE_SELECT_CDB_PAGE_FORMAT_OFFSET 1 508 | #define MODE_SELECT_CDB_SAVE_PAGES_OFFSET 1 509 | #define MODE_SELECT_6_CDB_PARAM_LIST_LENGTH_OFFSET 4 510 | #define MODE_SELECT_10_CDB_PARAM_LIST_LENGTH_OFFSET 7 511 | #define MODE_SELECT_CDB_PAGE_FORMAT_MASK 0x10 512 | #define MODE_SELECT_CDB_SAVE_PAGES_MASK 0x1 513 | #define MODE_SELECT_PAGE_FORMAT_STANDARD 1 514 | #define MODE_SELECT_SAVE_PAGES_ENABLED 1 515 | 516 | #define MODE_SENSE_CDB_BLOCK_DESC_ENABLED 0 517 | #define CACHE_MODE_PAGE_PARAM_SAVEABLE_ENABLED 1 518 | #define MODE_PAGE_PARAM_SAVEABLE_ENABLED 1 519 | #define MODE_PAGE_PARAM_SAVEABLE_DISABLED 0 520 | #define MODE_SELECT_PAGE_CODE_MASK 0x3F 521 | #define ONE_TASK_SET 0x0 522 | #define ACA_UNSUPPORTED 0 523 | #define PROT_INFO_DISABLED_RDPROTECT_0 1 524 | #define SENSE_DATA_DESC_FORMAT 1 525 | #define LOG_PARMS_NOT_IMPLICITLY_SAVED_PER_LUN 1 526 | #define LOG_EXCP_COND_NOT_REPORTED 0 527 | #define CMD_REORDERING_SUPPORTED 1 528 | #define UA_NOT_SUPPORTED_ON_PR_RELEASE 1 529 | #define BUSY_RETURNS_ENABLED 0 530 | #define UA_CLEARED_AT_CC_STATUS 0x0 531 | #define SW_WRITE_PROTECT_UNSUPPORTED 0 532 | #define LBAT_LBRT_MODIFIABLE 0 533 | #define LBAT_LBRT_NOT_MODIFIABLE 1 534 | #define TASK_ABORTED_STATUS_FOR_ABORTED_CMDS 1 535 | #define MEDIUM_LOADED_FULL_ACCESS 0x0 536 | #define UNLIMITED_BUSY_TIMEOUT_HIGH 0xFF 537 | #define UNLIMITED_BUSY_TIMEOUT_LOW 0xFF 538 | #define SMART_SELF_TEST_UNSUPPORTED_HIGH 0x00 539 | #define SMART_SELF_TEST_UNSUPPORTED_LOW 0x00 540 | #define LONG_LBA_MASK 0x1 541 | #define SHORT_DESC_BLOCK 8 542 | #define LONG_DESC_BLOCK 16 543 | #define POWER_COND_MODE_PAGE_LENGTH 0x26 544 | #define INFO_EXCP_MODE_PAGE_LENGTH 0x0A 545 | #define CACHING_MODE_PAGE_LENGTH 0x12 546 | #define SUB_PAGE_CODE_NONE 0x00 547 | #define CONTROL_MODE_PAGE_SIZE 0x0A 548 | #define BLOCK_DESCRIPTORS_ENABLED 0 549 | #define MODE_SENSE_PC_CURRENT_VALUES 0 550 | #define MODE_SENSE_PC_CHANGEABLE_VALUES 1 551 | #define MODE_SENSE_PC_DEFAULT_VALUES 2 552 | #define MODE_SENSE_ALL_PAGES_LENGTH 0x64 553 | 554 | /* Log Sense defines */ 555 | #define LOG_PAGE_SUPPORTED_LOG_PAGES_PAGE 0x00 556 | #define LOG_PAGE_INFORMATIONAL_EXCEPTIONS_PAGE 0x2F 557 | #define LOG_PAGE_TEMPERATURE_PAGE 0x0D 558 | #define LOG_SENSE_CDB_SP_OFFSET 1 559 | #define LOG_SENSE_CDB_SP_MASK 0x01 560 | #define LOG_SENSE_CDB_SP_NOT_ENABLED 0 561 | #define LOG_SENSE_CDB_PC_OFFSET 2 562 | #define LOG_SENSE_CDB_PC_MASK 0xC0 563 | #define LOG_SENSE_CDB_PC_SHIFT 6 564 | #define LOG_SENSE_CDB_PC_CUMULATIVE_VALUES 1 565 | #define LOG_SENSE_CDB_PAGE_CODE_OFFSET 2 566 | #define LOG_SENSE_CDB_PAGE_CODE_MASK 0x3F 567 | #define LOG_SENSE_CDB_SUB_PAGE_CODE_OFFSET 3 568 | #define LOG_SENSE_CDB_PARM_PTR_OFFSET 5 569 | #define LOG_SENSE_CDB_ALLOC_LENGTH_OFFSET 7 570 | #define PC_CUMULATIVE_VALUES 1 571 | #define SUB_PAGE_FORMAT_UNSUPPORTED 0 572 | #define DISABLE_SAVE_UNSUPPORTED 0 573 | #define SUB_PAGE_CODE_UNSUPPORTED 0x00 574 | #define REMAINING_INFO_EXCP_PAGE_LENGTH 0x8 575 | #define REMAINING_TEMP_PAGE_LENGTH 0xC 576 | #define GENERAL_PARAMETER_DATA 0x0000 577 | #define TEMPERATURE_PARM_CODE 0x00 578 | #define REFERENCE_TEMPERATURE_PARM_CODE 0x01 579 | #define BINARY_FORMAT 0x1 580 | #define BINARY_FORMAT_LIST 0x3 581 | #define TMC_UNSUPPORTED 0 582 | #define ETC_UNSUPPORTED 0 583 | #define TSD_UNSUPPORTED 0 584 | #define LOG_PARAMETER_DISABLED 1 585 | #define DU_UNSUPPORTED 0 586 | #define INFO_EXCP_PARM_LENGTH 4 587 | #define INFO_EXCP_ASC_NONE 0x0 588 | #define INFO_EXCP_ASCQ_NONE 0x0 589 | #define TEMP_PARM_LENGTH 2 590 | #define REF_TEMP_PARM_LENGTH 2 591 | #define SUPPORTED_LOG_PAGES_PAGE_LENGTH 0x3 592 | 593 | /* NVMe Namespace and Command Defines */ 594 | #define MAX_NON_HIDDEN_NAMESPACE_SCSI_TARGETS 16 595 | #define MAX_NUMBER_OF_NAMESPACES 1024 596 | #define NAMESPACE_NAME_MAX_SIZE 100 597 | #define NAMESPACE_INVALID_MAP_INDEX 0xFF 598 | #define DEFAULT_SECTOR_SIZE 512 599 | #define PRODUCT_ID_SIZE 16 600 | #define VENDOR_ID_SIZE 8 601 | #define PRODUCT_REVISION_LEVEL_SIZE 4 602 | #define FUSE_NORMAL_OPERATION 0 603 | #define NVME_FLUSH 0x00 604 | #define NVME_WRITE 0x01 605 | #define NVME_READ 0x02 606 | #define NVME_FORMAT_NVM 0x80 607 | #define NVME_SECURITY_SEND 0x81 608 | #define NVME_SECURITY_RECEIVE 0x82 609 | #define NVME_GET_LOG_PAGE 0x02 610 | #define NVME_GET_FEATURES 0x0A 611 | #define VOLATILE_WRITE_CACHE_FEATURE 0 612 | #define VOLATILE_WRITE_CACHE_MASK 1 613 | 614 | /* Report LUNs defines */ 615 | #define REPORT_LUNS_FIRST_LUN_OFFSET 0x8 616 | 617 | /** 618 | * DEVICE_SPECIFIC_PARAMETER in mode parametr header (see sbc2r16) to 619 | * enable DPOFUA support type 0x10 value. 620 | */ 621 | #define DEVICE_SPECIFIC_PARAMETER 0 622 | #define NIBBLES_PER_LONGLONG 16 623 | #define NIBBLES_PER_LONG 8 624 | #define LOWER_NIBBLE_MASK 0xF 625 | #define UPPER_NIBBLE_MASK 0xF0 626 | 627 | #endif /* __SNTI_TYPES_H__ */ 628 | -------------------------------------------------------------------------------- /source/nvmeSntiUtils.h: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: nvmeSntitiUtils.h 46 | */ 47 | 48 | #ifndef __SNTI_UTILS_H__ 49 | #define __SNTI_UTILS_H__ 50 | 51 | /* MACROs to extrace infor from SRBs and CDBs */ 52 | #if (NTDDI_VERSION > NTDDI_WIN7) 53 | #define GET_SRB_EXTENSION(pSrb) (SrbGetMiniportContext((PVOID)pSrb)) 54 | #define GET_OPCODE(pSrb) (((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[0]) 55 | #define GET_DATA_BUFFER(pSrb) (SrbGetDataBuffer((PVOID)pSrb)) 56 | #define GET_DATA_LENGTH(pSrb) (SrbGetDataTransferLength((PVOID)pSrb)) 57 | #define SET_DATA_LENGTH(pSrb, len) (SrbSetDataTransferLength((PVOID)pSrb, len)) 58 | #define GET_PATH_ID(pSrb) (SrbGetPathId((PVOID)pSrb)) 59 | #define GET_TARGET_ID(pSrb) (SrbGetTargetId((PVOID)pSrb)) 60 | #define GET_LUN_ID(pSrb) (SrbGetLun((PVOID)pSrb)) 61 | #define GET_CDB_LENGTH(pSrb) (SrbGetCdbLength((PVOID)pSrb)) 62 | 63 | /* Extract fields from CDBs at offsets */ 64 | #define GET_U8_FROM_CDB(pSrb, index) (((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index]) 65 | 66 | #define GET_U16_FROM_CDB(pSrb, index) ((((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index] << 8) | \ 67 | (((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index+1] << 0)) 68 | 69 | #define GET_U24_FROM_CDB(pSrb, index) ((((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index] << 16)| \ 70 | (((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index+1] << 8) | \ 71 | (((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index+2] << 0)) 72 | 73 | #define GET_U32_FROM_CDB(pSrb, index) ((((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index] << 24)| \ 74 | (((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index+1] << 16)| \ 75 | (((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index+2] << 8) | \ 76 | (((PCDB)SrbGetCdb((PVOID)pSrb))->AsByte[index+3] << 0)) 77 | #else 78 | #define GET_SRB_EXTENSION(pSrb) (pSrb)->SrbExtension 79 | #define GET_OPCODE(pSrb) (pSrb)->Cdb[0] 80 | #define GET_DATA_BUFFER(pSrb) (pSrb)->DataBuffer 81 | #define GET_DATA_LENGTH(pSrb) (pSrb)->DataTransferLength 82 | #define SET_DATA_LENGTH(pSrb, len) ((pSrb)->DataTransferLength = len) 83 | #define GET_PATH_ID(pSrb) (pSrb)->PathId 84 | #define GET_TARGET_ID(pSrb) (pSrb)->TargetId 85 | #define GET_LUN_ID(pSrb) (pSrb)->Lun 86 | #define GET_CDB_LENGTH(pSrb) (pSrb)->CdbLength 87 | 88 | /* Extract fields from CDBs at offsets */ 89 | #define GET_U8_FROM_CDB(pSrb, index) ((pSrb)->Cdb[index] << 0) 90 | 91 | #define GET_U16_FROM_CDB(pSrb, index) (((pSrb)->Cdb[index] << 8) | \ 92 | ((pSrb)->Cdb[index + 1] << 0)) 93 | 94 | #define GET_U24_FROM_CDB(pSrb, index) (((pSrb)->Cdb[index] << 16) | \ 95 | ((pSrb)->Cdb[index + 1] << 8) | \ 96 | ((pSrb)->Cdb[index + 2] << 0)) 97 | 98 | #define GET_U32_FROM_CDB(pSrb, index) (((pSrb)->Cdb[index] << 24) | \ 99 | ((pSrb)->Cdb[index + 1] << 16) | \ 100 | ((pSrb)->Cdb[index + 2] << 8) | \ 101 | ((pSrb)->Cdb[index + 3] << 0)) 102 | #endif 103 | /* Inquiry Helper Macros */ 104 | #define GET_INQ_EVPD_BIT(pSrb) \ 105 | ((GET_U8_FROM_CDB(pSrb, INQUIRY_EVPD_BYTE_OFFSET) & \ 106 | INQUIRY_EVPD_BIT_MASK) ? TRUE : FALSE) 107 | 108 | #define GET_INQ_PAGE_CODE(pSrb) \ 109 | (GET_U8_FROM_CDB(pSrb, INQUIRY_PAGE_CODE_BYTE_OFFSET)) 110 | 111 | #define GET_INQ_ALLOC_LENGTH(pSrb) \ 112 | (GET_U16_FROM_CDB(pSrb, INQUIRY_CDB_ALLOCATION_LENGTH_OFFSET)) 113 | 114 | /* Report LUNs Helper Macros */ 115 | #define GET_REPORT_LUNS_ALLOC_LENGTH(pSrb) \ 116 | (GET_U32_FROM_CDB(pSrb, REPORT_LUNS_CDB_ALLOC_LENGTH_OFFSET)) 117 | 118 | /* Read Capacity Helper Macros */ 119 | #define GET_READ_CAP_16_ALLOC_LENGTH(pSrb) \ 120 | (GET_U32_FROM_CDB(pSrb, READ_CAP_16_CDB_ALLOC_LENGTH_OFFSET)) 121 | 122 | /* Request Sense Helper Macros */ 123 | #define GET_REQUEST_SENSE_ALLOC_LENGTH(pSrb) \ 124 | (GET_U8_FROM_CDB(pSrb, REQUEST_SENSE_CDB_ALLOC_LENGTH_OFFSET)) 125 | 126 | /* Generic SCSI Helper Macros */ 127 | #define GET_VALUE(cdb, index, len) (cdb->cmnd[index] & len) 128 | #define GET_LENGTH(cdb) ((cdb->cmnd[7] << 8) | cdb->cmnd[8]) 129 | 130 | #define GET_DPO(cdb, index) (GET_VALUE(cdb, index, 0x10) >> 4) 131 | #define GET_FUA(cdb, index) (GET_VALUE(cdb, index, 0x08) >> 3) 132 | #define GET_FUA_NV(cdb, index) (GET_VALUE(cdb, index, 0x02) >> 1) 133 | #define GET_PROTECT(cdb, index) (GET_VALUE(cdb, index, 0xE0) >> 5) 134 | #define GET_GROUP_NUMBER(cdb, index) (GET_VALUE(cdb, index, 0x1F)) 135 | 136 | #define GET_DATA(cdb_field_p, cdb, index1, index2) \ 137 | cdb_field_p.dpo = GET_DPO(cdb, index1); \ 138 | cdb_field_p.fua = GET_FUA(cdb, index1); \ 139 | cdb_field_p.fua_nv = GET_FUA_NV(cdb, index1); \ 140 | cdb_field_p.protect = GET_PROTECT(cdb, index1); \ 141 | cdb_field_p.group_number = GET_GROUP_NUMBER(cdb, index2); 142 | 143 | #define BYTE_SWAP_WORD(word) (((word & 0xFF) << 8) | \ 144 | ((word & 0xFF00) >> 8)) 145 | 146 | #define BYTE_SWAP_DWORD(dword) (((dword & 0xFF) << 24) | \ 147 | ((dword & 0xFF00) << 8) | \ 148 | ((dword & 0xFF0000) >> 8) | \ 149 | ((dword & 0xFF000000) >> 24)) 150 | 151 | #define BYTE_SWAP_KEY(key) (((key & 0xFF) << 56) | \ 152 | ((key & 0xFF00) << 40) | \ 153 | ((key & 0xFF0000) << 24) | \ 154 | ((key & 0xFF000000) << 8) | \ 155 | ((key & 0xFF00000000) >> 8) | \ 156 | ((key & 0xFF0000000000) >> 24) | \ 157 | ((key & 0xFF000000000000) >> 40) | \ 158 | ((key & 0xFF00000000000000) >> 56)) 159 | #endif /* __SNTI_UTILS_H__ */ 160 | -------------------------------------------------------------------------------- /source/nvmeStd.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gigaherz/nvmewin/82664e8626b71c4133cdc3d7601a0a4a0341d85f/source/nvmeStd.h -------------------------------------------------------------------------------- /source/nvmeWmi.c: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: nvmeWmi.c 46 | */ 47 | 48 | #include "precomp.h" 49 | #ifndef DBG 50 | #include "nvmeWmi.tmh" 51 | #endif 52 | #include 53 | 54 | 55 | SCSIWMIGUIDREGINFO WmiGuidList[] = // GUIDs supported. 56 | { 57 | {&NVMe_QueryDevInfo_GUID, 1, 0}, 58 | {&NVMe_Method_GUID, 1, 0} 59 | }; 60 | 61 | enum { 62 | NVMe_QueryDevInfo_Idx = 0, 63 | NVMe_Method_Idx = 1 64 | }; 65 | 66 | #define WmiGuidCount (sizeof(WmiGuidList) / sizeof(SCSIWMIGUIDREGINFO)) 67 | 68 | 69 | /**************************************************************************************************/ 70 | /* */ 71 | /* InitializeWmiContext. */ 72 | /* */ 73 | /* Build WMILIB block, with pointers to supported callbacks, GUIDs, etc. */ 74 | /* */ 75 | /**************************************************************************************************/ 76 | void 77 | InitializeWmiContext(__in PNVME_DEVICE_EXTENSION pHbaExtension) 78 | { 79 | PSCSI_WMILIB_CONTEXT pWmiLibContext = // Point to WMI context block. 80 | &(pHbaExtension->WmiLibContext); 81 | 82 | memset(pWmiLibContext, 0, sizeof(SCSI_WMILIB_CONTEXT)); // Clear WMI context block. 83 | 84 | pWmiLibContext->GuidCount = WmiGuidCount; 85 | pWmiLibContext->GuidList = WmiGuidList; 86 | 87 | // 88 | // Point to WMI callback routines. 89 | // 90 | pWmiLibContext->QueryWmiRegInfo = QueryWmiRegInfo; 91 | pWmiLibContext->QueryWmiDataBlock = QueryWmiDataBlock; 92 | pWmiLibContext->SetWmiDataBlock = NULL; 93 | pWmiLibContext->SetWmiDataItem = NULL; 94 | pWmiLibContext->ExecuteWmiMethod = ExecuteWmiMethod; 95 | pWmiLibContext->WmiFunctionControl = NULL; 96 | } /* InitializeWmiContext */ 97 | 98 | 99 | /**************************************************************************************************/ 100 | /* */ 101 | /* DispatchWmi. */ 102 | /* */ 103 | /* Initial handling of WMI SRB's */ 104 | /* */ 105 | /**************************************************************************************************/ 106 | VOID 107 | DispatchWmi( 108 | __in struct _nvme_device_extension* pDevExtension, 109 | #if (NTDDI_VERSION > NTDDI_WIN7) 110 | __in PSTORAGE_REQUEST_BLOCK pSrb 111 | #else 112 | __in PSCSI_REQUEST_BLOCK pSrb 113 | #endif 114 | ) 115 | { 116 | PNVME_SRB_EXTENSION pSrbExtension = (PNVME_SRB_EXTENSION)GET_SRB_EXTENSION(pSrb); 117 | PSCSIWMI_REQUEST_CONTEXT pRequestContext = &(pSrbExtension->WmiReqContext); 118 | BOOLEAN pending = TRUE; 119 | BOOLEAN adapterRequest = TRUE; 120 | 121 | #if (NTDDI_VERSION > NTDDI_WIN7) 122 | PSRBEX_DATA_WMI pSrbWmi = (PSRBEX_DATA_WMI)SrbGetSrbExDataByType((PSTORAGE_REQUEST_BLOCK)pSrb, 123 | SrbExDataTypeWmi); 124 | #else 125 | PSCSI_WMI_REQUEST_BLOCK pSrbWmi = (PSCSI_WMI_REQUEST_BLOCK)pSrb; 126 | #endif 127 | 128 | memset(pRequestContext, 0, sizeof(SCSIWMI_REQUEST_CONTEXT)); // Clear WMI context block. 129 | 130 | // 131 | // Save the pointer to the SRB in UserContext 132 | // of SCSIWMI_REQUEST_CONTEXT 133 | // 134 | pRequestContext->UserContext = pSrb; 135 | 136 | // 137 | // Check if the WMI SRB is targetted for 138 | // the iScsi adapter or one of the devices 139 | // 140 | adapterRequest = (pSrbWmi->WMIFlags & SRB_WMI_FLAGS_ADAPTER_REQUEST) == SRB_WMI_FLAGS_ADAPTER_REQUEST; 141 | 142 | if (adapterRequest) { 143 | // 144 | // Process the incoming WMI request. 145 | // 146 | StorPortDebugPrint(INFO, 147 | "Entering DispatchWmi. WMISubFunction: 0x%Ix WMI Flags: 0x%Ix\n", 148 | pSrbWmi->WMISubFunction, 149 | pSrbWmi->WMIFlags); 150 | 151 | pending = ScsiPortWmiDispatchFunction( 152 | &pDevExtension->WmiLibContext, 153 | pSrbWmi->WMISubFunction, 154 | pDevExtension, 155 | pRequestContext, 156 | pSrbWmi->DataPath, 157 | GET_DATA_LENGTH(pSrb), 158 | GET_DATA_BUFFER(pSrb)); 159 | } else { 160 | SET_DATA_LENGTH(pSrb, 0); 161 | pSrb->SrbStatus = SRB_STATUS_ERROR; 162 | 163 | StorPortDebugPrint(INFO, "Error: Wmi call not targeted at adapter. WMIFlags: 0x%Ix\n", pSrbWmi->WMIFlags); 164 | return; 165 | } 166 | 167 | if (pending) { 168 | SET_DATA_LENGTH(pSrb, 0); 169 | pSrb->SrbStatus = SRB_STATUS_ERROR; 170 | 171 | StorPortDebugPrint(INFO, "Error: Wmi cannot pend requests\n"); 172 | } else { 173 | pSrb->SrbStatus = ScsiPortWmiGetReturnStatus(pRequestContext); 174 | SET_DATA_LENGTH(pSrb, ScsiPortWmiGetReturnSize(pRequestContext)); 175 | } 176 | 177 | return; 178 | } /* DispatchWmi */ 179 | 180 | 181 | /**************************************************************************************************/ 182 | /* */ 183 | /* QueryWmiRegInfo. */ 184 | /* */ 185 | /* Answers query for WMI registration information. */ 186 | /* */ 187 | /**************************************************************************************************/ 188 | UCHAR 189 | QueryWmiRegInfo( 190 | _In_ PVOID pContext, 191 | _In_ PSCSIWMI_REQUEST_CONTEXT pRequestContext, 192 | _Out_ PWSTR *pMofResourceName 193 | ) 194 | { 195 | UNREFERENCED_PARAMETER(pContext); 196 | UNREFERENCED_PARAMETER(pRequestContext); 197 | 198 | *pMofResourceName = L"MofResource"; 199 | 200 | return SRB_STATUS_SUCCESS; 201 | } /* QueryWmiRegInfo */ 202 | 203 | /**************************************************************************************************/ 204 | /* */ 205 | /* QueryWmiDataBlock. */ 206 | /* */ 207 | /* Answers query for WMI data block. */ 208 | /* */ 209 | /**************************************************************************************************/ 210 | BOOLEAN 211 | QueryWmiDataBlock( 212 | _In_ PVOID pContext, 213 | _In_ PSCSIWMI_REQUEST_CONTEXT pDispatchContext, 214 | _In_ ULONG GuidIndex, 215 | _In_ ULONG InstanceIndex, 216 | _In_ ULONG InstanceCount, 217 | _Inout_ PULONG pInstanceLenArr, 218 | _In_ ULONG BufferAvail, 219 | _Out_writes_bytes_(BufferAvail) PUCHAR pBuffer 220 | ) 221 | { 222 | PNVME_DEVICE_EXTENSION pDevExtension = (PNVME_DEVICE_EXTENSION)pContext; 223 | PSCSI_WMI_REQUEST_BLOCK pSrb = (PSCSI_WMI_REQUEST_BLOCK)pDispatchContext->UserContext; 224 | ULONG sizeNeeded = 0; 225 | UCHAR status = SRB_STATUS_SUCCESS; 226 | if (BufferAvail > 0) { 227 | memset(pBuffer, 0, BufferAvail); 228 | } 229 | 230 | switch (GuidIndex) { 231 | case NVMe_QueryDevInfo_Idx: { 232 | PNVMe_QueryDevInfo pQueryDevInfo; 233 | sizeNeeded = NVMe_QueryDevInfo_SIZE; 234 | 235 | if (BufferAvail >= sizeNeeded){ 236 | *pInstanceLenArr = sizeNeeded; 237 | pQueryDevInfo = (PNVMe_QueryDevInfo)pBuffer; 238 | pQueryDevInfo->maxDataXferSize = pDevExtension->InitInfo.MaxTxSize; 239 | pQueryDevInfo->numberOfNamespaces = pDevExtension->controllerIdentifyData.NN; 240 | pQueryDevInfo->Data.Id = 0x01; 241 | pQueryDevInfo->Data.u64 = 0x02; 242 | status = SRB_STATUS_SUCCESS; 243 | } else { 244 | status = SRB_STATUS_DATA_OVERRUN; 245 | } 246 | } 247 | break; 248 | 249 | case NVMe_Method_Idx: 250 | // 251 | // Even though this class only has methods, we need to 252 | // respond to any queries for it since WMI expects that 253 | // there is an actual instance of the class on which to 254 | // execute the method 255 | // 256 | sizeNeeded = sizeof(ULONG); 257 | 258 | if (BufferAvail < sizeNeeded) { 259 | status = SRB_STATUS_DATA_OVERRUN; 260 | break; 261 | } else{ 262 | *pInstanceLenArr = sizeNeeded; 263 | status = SRB_STATUS_SUCCESS; 264 | } 265 | break; 266 | 267 | default: // Unsupported GUID. 268 | 269 | status = SRB_STATUS_ERROR; // Follow practice in iSCSI client. 270 | break; 271 | } // End switch(GuidIndex). 272 | 273 | SpUpdateWmiRequest(pDevExtension, pSrb, pDispatchContext, status, sizeNeeded); 274 | 275 | return status; 276 | } /* QueryWmiDataBlock */ 277 | 278 | 279 | /**************************************************************************************************/ 280 | /* */ 281 | /* ExecuteWmiMethod. */ 282 | /* */ 283 | /* Executes a WMI method. */ 284 | /* */ 285 | /* Note: The support for MSFC GUIDs is only illustrative, showing how to produce plausible */ 286 | /* results. */ 287 | /* */ 288 | /**************************************************************************************************/ 289 | UCHAR 290 | ExecuteWmiMethod( 291 | _In_ PVOID pContext, 292 | _In_ PSCSIWMI_REQUEST_CONTEXT pDispatchContext, 293 | _In_ ULONG GuidIndex, 294 | _In_ ULONG InstanceIndex, 295 | _In_ ULONG MethodId, 296 | _In_ ULONG InBufferSize, 297 | _In_ ULONG OutBufferSize, 298 | _Inout_updates_bytes_to_(InBufferSize, OutBufferSize) PUCHAR pBuffer 299 | ) 300 | { 301 | PNVME_DEVICE_EXTENSION pDevExtension = (PNVME_DEVICE_EXTENSION)pContext; 302 | PSCSI_WMI_REQUEST_BLOCK pSrb = (PSCSI_WMI_REQUEST_BLOCK)pDispatchContext->UserContext; 303 | ULONG sizeNeeded = 0; 304 | UCHAR status = SRB_STATUS_SUCCESS; 305 | UINT8 strSize = 0; 306 | 307 | UNREFERENCED_PARAMETER(InstanceIndex); 308 | 309 | switch (GuidIndex) { 310 | case NVMe_Method_Idx: 311 | { 312 | switch (MethodId) { 313 | case GetControllerInfo: { 314 | PGetControllerInfo_OUT pControllerOut = NULL; 315 | sizeNeeded = GetControllerInfo_OUT_SIZE; 316 | 317 | if (OutBufferSize < sizeNeeded) { 318 | status = SRB_STATUS_DATA_OVERRUN; 319 | break; 320 | } else{ 321 | pControllerOut = (PGetControllerInfo_OUT)pBuffer; 322 | pControllerOut->pciVendorId = pDevExtension->controllerIdentifyData.VID; 323 | pControllerOut->pciSsVendId = pDevExtension->controllerIdentifyData.SSVID; 324 | status = SRB_STATUS_SUCCESS; 325 | } 326 | } 327 | break; 328 | 329 | case GetNameSpaceInfo: { 330 | PGetNameSpaceInfo_IN pGetNsInfoIn; 331 | PGetNameSpaceInfo_OUT pGetNsInfoOut; 332 | UINT32 lunId = 0; 333 | 334 | if (InBufferSize < GetNameSpaceInfo_IN_SIZE) { 335 | status = SRB_STATUS_INVALID_REQUEST; 336 | break; 337 | } 338 | 339 | pGetNsInfoIn = (PGetNameSpaceInfo_IN)pBuffer; 340 | lunId = pGetNsInfoIn->lunId; 341 | 342 | if (lunId >= pDevExtension->controllerIdentifyData.NN) { 343 | status = SRB_STATUS_INVALID_REQUEST; 344 | break; 345 | } 346 | 347 | sizeNeeded = GetNameSpaceInfo_OUT_SIZE; 348 | 349 | if (OutBufferSize < sizeNeeded) { 350 | status = SRB_STATUS_DATA_OVERRUN; 351 | break; 352 | } 353 | pGetNsInfoOut = (PGetNameSpaceInfo_OUT)pBuffer; 354 | 355 | pGetNsInfoOut->nSize = pDevExtension->pLunExtensionTable[lunId]->identifyData.NSZE; 356 | pGetNsInfoOut->nCap = pDevExtension->pLunExtensionTable[lunId]->identifyData.NCAP; 357 | status = SRB_STATUS_SUCCESS; 358 | } 359 | break; 360 | 361 | default: 362 | status = SRB_STATUS_INVALID_REQUEST; 363 | break; 364 | } 365 | } 366 | break; 367 | 368 | 369 | default: // Unsupported GUID. 370 | status = SRB_STATUS_INVALID_REQUEST; 371 | break; 372 | } // End switch(GuidIndex). 373 | 374 | SpUpdateWmiRequest(pDevExtension, pSrb, pDispatchContext, status, sizeNeeded); 375 | 376 | return status; 377 | } /* ExecuteWmiMethod */ 378 | 379 | /**************************************************************************************************/ 380 | /* */ 381 | /**************************************************************************************************/ 382 | VOID 383 | SpUpdateWmiRequest( 384 | __in struct _nvme_device_extension* pHbaExtension, 385 | // __in PNVME_DEVICE_EXTENSION pHbaExtension, 386 | __in PSCSI_WMI_REQUEST_BLOCK pSrb, 387 | __in PSCSIWMI_REQUEST_CONTEXT pDispatchContext, 388 | __in UCHAR Status, 389 | __in ULONG SizeNeeded 390 | ) 391 | { 392 | UNREFERENCED_PARAMETER(pHbaExtension); 393 | 394 | // Update the request if the status is NOT pending or NOT already completed within the callback. 395 | 396 | if (SRB_STATUS_PENDING != Status) { 397 | // 398 | // Request completed successfully or there was an error. 399 | // 400 | ScsiPortWmiPostProcess(pDispatchContext, Status, SizeNeeded); 401 | 402 | pSrb->SrbStatus = ScsiPortWmiGetReturnStatus(pDispatchContext); 403 | pSrb->DataTransferLength = ScsiPortWmiGetReturnSize(pDispatchContext); 404 | } 405 | } /* SpUpdateWmiRequest */ 406 | -------------------------------------------------------------------------------- /source/nvmeWmi.h: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: nvmeWmi.h 46 | */ 47 | 48 | #ifndef __NVME_WMI_H__ 49 | #define __NVME_WMI_H__ 50 | 51 | VOID 52 | DispatchWmi( 53 | __in PNVME_DEVICE_EXTENSION pHbaExtension, 54 | #if (NTDDI_VERSION > NTDDI_WIN7) 55 | IN PSTORAGE_REQUEST_BLOCK Srb 56 | #else 57 | IN PSCSI_REQUEST_BLOCK Srb 58 | #endif 59 | ); 60 | 61 | VOID 62 | SpUpdateWmiRequest( 63 | __in PNVME_DEVICE_EXTENSION pHbaExtension, 64 | __in PSCSI_WMI_REQUEST_BLOCK pSrb, 65 | __in PSCSIWMI_REQUEST_CONTEXT pDispatchContext, 66 | __in UCHAR Status, 67 | __in ULONG SizeNeeded 68 | ); 69 | 70 | VOID 71 | InitializeWmiContext(__in PNVME_DEVICE_EXTENSION); 72 | 73 | BOOLEAN 74 | HandleWmiSrb( 75 | __in PNVME_DEVICE_EXTENSION, 76 | __in __out PSCSI_WMI_REQUEST_BLOCK 77 | ); 78 | UCHAR 79 | QueryWmiRegInfo( 80 | _In_ PVOID pContext, 81 | _In_ PSCSIWMI_REQUEST_CONTEXT pRequestContext, 82 | _Out_ PWSTR *pMofResourceName 83 | ); 84 | 85 | BOOLEAN 86 | QueryWmiDataBlock( 87 | _In_ PVOID pContext, 88 | _In_ PSCSIWMI_REQUEST_CONTEXT pDispatchContext, 89 | _In_ ULONG GuidIndex, 90 | _In_ ULONG InstanceIndex, 91 | _In_ ULONG InstanceCount, 92 | _Inout_ PULONG pInstanceLenArr, 93 | _In_ ULONG BufferAvail, 94 | _Out_writes_bytes_(BufferAvail) PUCHAR pBuffer 95 | ); 96 | 97 | 98 | UCHAR 99 | ExecuteWmiMethod( 100 | _In_ PVOID pContext, 101 | _In_ PSCSIWMI_REQUEST_CONTEXT pDispatchContext, 102 | _In_ ULONG GuidIndex, 103 | _In_ ULONG InstanceIndex, 104 | _In_ ULONG MethodId, 105 | _In_ ULONG InBufferSize, 106 | _In_ ULONG OutBufferSize, 107 | _Inout_updates_bytes_to_(InBufferSize, OutBufferSize) PUCHAR pBuffer 108 | ); 109 | 110 | #endif /* __NVME_WMI_H__ */ -------------------------------------------------------------------------------- /source/nvme_tracing.h: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | #pragma once 44 | #ifndef NVME_TRACING_H 45 | #define NVME_TRACING_H 46 | 47 | #include 48 | #include 49 | 50 | // Declare the WPP Trace Provider, which will be controlled by the WinCIL GUID. 51 | // NVMe control GUID = {0BD0EE0C-BB49-45F4-A798-80D221BE3DE1} 52 | #define WPP_CONTROL_GUIDS \ 53 | WPP_DEFINE_CONTROL_GUID(NVMe, (0F5937E9, FEAB, 40FF, BBAE, 9C2202C54B1F), \ 54 | WPP_DEFINE_BIT(Default) ) 55 | 56 | // This tracing setup currently uses the following levels (defined in evntrace.h): 57 | // TRACE_LEVEL_NONE 0 // Tracing is not on 58 | // TRACE_LEVEL_FATAL 1 // Abnormal exit or termination 59 | // TRACE_LEVEL_ERROR 2 // Severe errors that need logging 60 | // TRACE_LEVEL_WARNING 3 // Warnings such as allocation failure 61 | // TRACE_LEVEL_INFORMATION 4 // Includes non-error cases(for example, Entry-Exit) 62 | // TRACE_LEVEL_VERBOSE 5 // Detailed traces from intermediate steps 63 | // 64 | // Note: The tracing setup does NOT currently use any flags. To define level-specific 65 | // logging macros, we define custom WPP_LEVEL_ENABLED and WPP_LEVEL_LOGGER macros 66 | // below. See the 'sources' file as well for declarations of the tracing macros. 67 | // We are using custom tracing macros explicitly here, rather than the auto-generated 68 | // ones via WPP_USE_TRACE_LEVELS, so that we can add component flags in the future. 69 | #define WPP_LEVEL_LOGGER(Level) (WPP_CONTROL(WPP_BIT_ ## Default).Logger), 70 | #define WPP_LEVEL_ENABLED(lvl) (WPP_CONTROL(WPP_BIT_ ## Default).Level >= (lvl)) 71 | 72 | /* 73 | #ifndef DBG 74 | // For FRE / Retail builds, override StorPortDebugPrint to log ETW messages for 75 | // collection in usermode. 76 | // #define StorPortDebugPrint(lvl, Message, ...) DoTraceMessage((lvl), Message, __VA_ARGS__) 77 | #else 78 | // #define StorPortDebugPrint StorPortDebugPrint 79 | // For CHK / Debug builds, retain normal StorPortDebugPrint behavior. To view storport 80 | // debug messages, attach a kernel debugger to the target machine, then break in during 81 | // boot and run the following commands (requires correct symbol path from .symfix!) 82 | // > .reload /f ntoskrnl.exe 83 | // > ed nt!kd_STORMINIPORT_mask 0xf 84 | // > g 85 | #endif 86 | */ 87 | 88 | #define TraceFatal(Message, ...) DoTraceMessage(TRACE_LEVEL_FATAL, Message, __VA_ARGS__) 89 | #define TraceError(Message, ...) DoTraceMessage(TRACE_LEVEL_ERROR, Message, __VA_ARGS__) 90 | #define TraceWarning(Message, ...) DoTraceMessage(TRACE_LEVEL_WARNING, Message, __VA_ARGS__) 91 | #define TraceInformation(Message, ...) DoTraceMessage(TRACE_LEVEL_INFORMATION, Message, __VA_ARGS__) 92 | #define TraceVerbose(Message, ...) DoTraceMessage(TRACE_LEVEL_VERBOSE, Message, __VA_ARGS__) 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /source/precomp.h: -------------------------------------------------------------------------------- 1 | /** 2 | ******************************************************************************* 3 | ** Copyright (c) 2011-2012 ** 4 | ** ** 5 | ** Integrated Device Technology, Inc. ** 6 | ** Intel Corporation ** 7 | ** LSI Corporation ** 8 | ** ** 9 | ** All rights reserved. ** 10 | ** ** 11 | ******************************************************************************* 12 | ** ** 13 | ** Redistribution and use in source and binary forms, with or without ** 14 | ** modification, are permitted provided that the following conditions are ** 15 | ** met: ** 16 | ** ** 17 | ** 1. Redistributions of source code must retain the above copyright ** 18 | ** notice, this list of conditions and the following disclaimer. ** 19 | ** ** 20 | ** 2. Redistributions in binary form must reproduce the above copyright ** 21 | ** notice, this list of conditions and the following disclaimer in the ** 22 | ** documentation and/or other materials provided with the distribution. ** 23 | ** ** 24 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 25 | ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** 26 | ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 27 | ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 28 | ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 29 | ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 30 | ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 31 | ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 32 | ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 33 | ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 34 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 35 | ** ** 36 | ** The views and conclusions contained in the software and documentation ** 37 | ** are those of the authors and should not be interpreted as representing ** 38 | ** official policies, either expressed or implied, of Intel Corporation, ** 39 | ** Integrated Device Technology Inc., or Sandforce Corporation. ** 40 | ** ** 41 | ******************************************************************************* 42 | **/ 43 | 44 | /* 45 | * File: precomp.h 46 | */ 47 | 48 | #include "ntddk.h" 49 | #include "ntddscsi.h" 50 | #include "ntdddisk.h" 51 | #include "stdlib.h" 52 | #include 53 | #include 54 | #if (NTDDI_VERSION > NTDDI_WIN7) 55 | #include 56 | #endif 57 | #include 58 | #include 59 | #include 60 | #include "nvmeMofData.h" 61 | #include "nvme.h" 62 | #include "nvmeReg.h" 63 | #include "nvmeIoctl.h" 64 | #include "nvmeStd.h" 65 | #include "nvmePwrMgmt.h" 66 | #include "nvmeSnti.h" 67 | #include "nvmeSntiUtils.h" 68 | #include "nvmeSntiTypes.h" 69 | #include "nvmeIo.h" 70 | #include "nvmeWmi.h" 71 | 72 | #include "nvme_tracing.h" 73 | 74 | 75 | -------------------------------------------------------------------------------- /source/sources: -------------------------------------------------------------------------------- 1 | # ****************************************************************************** 2 | # ** Copyright (c) 2011-2012 ** 3 | # ** ** 4 | # ** Integrated Device Technology, Inc. ** 5 | # ** Intel Corporation ** 6 | # ** LSI Corporation ** 7 | # ** ** 8 | # ** All rights reserved. ** 9 | # ** ** 10 | # ****************************************************************************** 11 | # ** ** 12 | # ** Redistribution and use in source and binary forms, with or without ** 13 | # ** modification, are permitted provided that the following conditions are ** 14 | # ** met: ** 15 | # ** ** 16 | # ** 1. Redistributions of source code must retain the above copyright ** 17 | # ** notice, this list of conditions and the following disclaimer. ** 18 | # ** ** 19 | # ** 2. Redistributions in binary form must reproduce the above copyright ** 20 | # ** notice, this list of conditions and the following disclaimer in the ** 21 | # ** documentation and/or other materials provided with the distribution.** 22 | # ** ** 23 | # ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ** 24 | # ** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,** 25 | # ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** 26 | # ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ** 27 | # ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, ** 28 | # ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** 29 | # ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ** 30 | # ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ** 31 | # ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ** 32 | # ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** 33 | # ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 34 | # ** ** 35 | # ** The views and conclusions contained in the software and documentation ** 36 | # ** are those of the authors and should not be interpreted as representing ** 37 | # ** official policies, either expressed or implied, of Intel Corporation, ** 38 | # ** Integrated Device Technology Inc., or Sandforce Corporation. ** 39 | # ** ** 40 | # ****************************************************************************** 41 | TARGETNAME=nvme 42 | 43 | TARGETTYPE=MINIPORT 44 | TARGETPATH=$(TARGETNAME)\obj$(BUILD_ALT_DIR) 45 | 46 | # -DDUMB_DRIVER: Used ONLY FOR DEBUG. Double buffers all IOs, handy for any debug 47 | # situation where control over all host side buffers is needed 48 | # (alingment issues, etc). Be sure to step through before use, 49 | # doesn't get used/tested often! Also disables: 50 | # - learning mode 51 | # - SGL-PRP xlation (our buffre addresses are known) 52 | # - multiple queues NUMA opimized (uses only one Q by faking single proc) 53 | 54 | # -DCHATHAM2: Required for use with Chatham2 (aka Chatsberg) hardware 55 | 56 | # -DCOMPLETE_IN_DPC: Controls whether IOs are completed in the ISR ot in DPCs 57 | 58 | # -DHISTORY: Enables history buffers for debug, can be used in free or checked build 59 | 60 | # -DPRP_DBG: dumps all PRP info for every IO 61 | 62 | C_DEFINES = $(C_DEFINES) -D__KERNEL_ -D__MSWINDOWS__ 63 | 64 | TARGETLIBS=$(DDK_LIB_PATH)\storport.lib \ 65 | $(DDK_LIB_PATH)\Ntoskrnl.lib \ 66 | $(DDK_LIB_PATH)\wdm.lib 67 | 68 | SOURCES=nvmeStd.c \ 69 | nvmeStat.c \ 70 | nvmeInit.c \ 71 | nvmeSnti.c \ 72 | nvmeIo.c \ 73 | nvmePwrMgmt.c \ 74 | nvme.rc 75 | --------------------------------------------------------------------------------