1 /* 2 * SCSI_PORT_TIMER_STATES 3 * 4 * DESCRIPTION 5 * An enumeration containing the states in the timer DFA 6 */ 7 8 #pragma once 9 10 #include <ntifs.h> 11 #include <stdio.h> 12 #include <scsi.h> 13 #include <ntddscsi.h> 14 #include <ntdddisk.h> 15 #include <mountdev.h> 16 17 #ifdef DBG 18 #include <debug/driverdbg.h> 19 #endif 20 21 #define TAG_SCSIPORT 'ISCS' 22 23 /* Defines how many logical unit arrays will be in a device extension */ 24 #define LUS_NUMBER 8 25 26 #define MAX_SG_LIST 17 27 28 /* Flags */ 29 #define SCSI_PORT_DEVICE_BUSY 0x00001 30 #define SCSI_PORT_LU_ACTIVE 0x00002 31 #define SCSI_PORT_NOTIFICATION_NEEDED 0x00004 32 #define SCSI_PORT_NEXT_REQUEST_READY 0x00008 33 #define SCSI_PORT_FLUSH_ADAPTERS 0x00010 34 #define SCSI_PORT_MAP_TRANSFER 0x00020 35 #define SCSI_PORT_RESET 0x00080 36 #define SCSI_PORT_RESET_REQUEST 0x00100 37 #define SCSI_PORT_RESET_REPORTED 0x00200 38 #define SCSI_PORT_REQUEST_PENDING 0x00800 39 #define SCSI_PORT_DISCONNECT_ALLOWED 0x01000 40 #define SCSI_PORT_DISABLE_INT_REQUESET 0x02000 41 #define SCSI_PORT_DISABLE_INTERRUPTS 0x04000 42 #define SCSI_PORT_ENABLE_INT_REQUEST 0x08000 43 #define SCSI_PORT_TIMER_NEEDED 0x10000 44 45 /* LUN Extension flags*/ 46 #define LUNEX_FROZEN_QUEUE 0x0001 47 #define LUNEX_NEED_REQUEST_SENSE 0x0004 48 #define LUNEX_BUSY 0x0008 49 #define LUNEX_FULL_QUEUE 0x0010 50 #define LUNEX_REQUEST_PENDING 0x0020 51 #define SCSI_PORT_SCAN_IN_PROGRESS 0x8000 52 53 // we need this to be compatible with ReactOS' classpnp (which is compiled with NTDDI_WIN8) 54 typedef struct _STORAGE_ADAPTER_DESCRIPTOR_WIN8 { 55 ULONG Version; 56 ULONG Size; 57 ULONG MaximumTransferLength; 58 ULONG MaximumPhysicalPages; 59 ULONG AlignmentMask; 60 BOOLEAN AdapterUsesPio; 61 BOOLEAN AdapterScansDown; 62 BOOLEAN CommandQueueing; 63 BOOLEAN AcceleratedTransfer; 64 UCHAR BusType; 65 USHORT BusMajorVersion; 66 USHORT BusMinorVersion; 67 UCHAR SrbType; 68 UCHAR AddressType; 69 } STORAGE_ADAPTER_DESCRIPTOR_WIN8, *PSTORAGE_ADAPTER_DESCRIPTOR_WIN8; 70 71 typedef enum _SCSI_PORT_TIMER_STATES 72 { 73 IDETimerIdle, 74 IDETimerCmdWait, 75 IDETimerResetWaitForBusyNegate, 76 IDETimerResetWaitForDrdyAssert 77 } SCSI_PORT_TIMER_STATES; 78 79 typedef struct _CONFIGURATION_INFO 80 { 81 /* Identify info */ 82 ULONG AdapterNumber; 83 ULONG LastAdapterNumber; 84 ULONG BusNumber; 85 86 /* Registry related */ 87 HANDLE BusKey; 88 HANDLE ServiceKey; 89 HANDLE DeviceKey; 90 91 /* Features */ 92 BOOLEAN DisableTaggedQueueing; 93 BOOLEAN DisableMultipleLun; 94 95 /* Parameters */ 96 PVOID Parameter; 97 PACCESS_RANGE AccessRanges; 98 } CONFIGURATION_INFO, *PCONFIGURATION_INFO; 99 100 typedef struct _SCSI_PORT_DEVICE_BASE 101 { 102 LIST_ENTRY List; 103 104 PVOID MappedAddress; 105 ULONG NumberOfBytes; 106 SCSI_PHYSICAL_ADDRESS IoAddress; 107 ULONG SystemIoBusNumber; 108 } SCSI_PORT_DEVICE_BASE, *PSCSI_PORT_DEVICE_BASE; 109 110 typedef struct _SCSI_SG_ADDRESS 111 { 112 PHYSICAL_ADDRESS PhysicalAddress; 113 ULONG Length; 114 } SCSI_SG_ADDRESS, *PSCSI_SG_ADDRESS; 115 116 typedef struct _SCSI_REQUEST_BLOCK_INFO 117 { 118 LIST_ENTRY Requests; 119 PSCSI_REQUEST_BLOCK Srb; 120 PCHAR DataOffset; 121 PVOID SaveSenseRequest; 122 123 ULONG SequenceNumber; 124 125 /* DMA stuff */ 126 PVOID BaseOfMapRegister; 127 ULONG NumberOfMapRegisters; 128 129 struct _SCSI_REQUEST_BLOCK_INFO *CompletedRequests; 130 131 /* Scatter-gather list */ 132 PSCSI_SG_ADDRESS ScatterGather; 133 SCSI_SG_ADDRESS ScatterGatherList[MAX_SG_LIST]; 134 } SCSI_REQUEST_BLOCK_INFO, *PSCSI_REQUEST_BLOCK_INFO; 135 136 typedef struct _SCSI_PORT_COMMON_EXTENSION 137 { 138 PDEVICE_OBJECT DeviceObject; 139 PDEVICE_OBJECT LowerDevice; 140 BOOLEAN IsFDO; 141 } SCSI_PORT_COMMON_EXTENSION, *PSCSI_PORT_COMMON_EXTENSION; 142 143 // PDO device 144 typedef struct _SCSI_PORT_LUN_EXTENSION 145 { 146 SCSI_PORT_COMMON_EXTENSION Common; 147 148 UCHAR PathId; 149 UCHAR TargetId; 150 UCHAR Lun; 151 152 ULONG Flags; 153 154 LIST_ENTRY LunEntry; 155 156 BOOLEAN DeviceClaimed; 157 158 INQUIRYDATA InquiryData; 159 160 KDEVICE_QUEUE DeviceQueue; 161 ULONG SortKey; 162 ULONG QueueCount; 163 ULONG MaxQueueCount; 164 165 ULONG AttemptCount; 166 LONG RequestTimeout; 167 168 PIRP BusyRequest; 169 PIRP PendingRequest; 170 171 struct _SCSI_PORT_LUN_EXTENSION *ReadyLun; 172 struct _SCSI_PORT_LUN_EXTENSION *CompletedAbortRequests; 173 174 SCSI_REQUEST_BLOCK_INFO SrbInfo; 175 176 HANDLE RegistryMapKey; 177 178 /* More data? */ 179 180 UCHAR MiniportLunExtension[1]; /* must be the last entry */ 181 } SCSI_PORT_LUN_EXTENSION, *PSCSI_PORT_LUN_EXTENSION; 182 183 /* Structures for inquiries support */ 184 185 typedef struct _SCSI_BUS_INFO 186 { 187 LIST_ENTRY LunsListHead; 188 UCHAR LogicalUnitsCount; 189 UCHAR TargetsCount; 190 UCHAR BusIdentifier; 191 HANDLE RegistryMapKey; 192 } SCSI_BUS_INFO, *PSCSI_BUS_INFO; 193 194 typedef struct _SCSI_PORT_INTERRUPT_DATA 195 { 196 ULONG Flags; /* Interrupt-time flags */ 197 PSCSI_REQUEST_BLOCK_INFO CompletedRequests; /* Linked list of Srb info data */ 198 PSCSI_PORT_LUN_EXTENSION CompletedAbort; 199 PSCSI_PORT_LUN_EXTENSION ReadyLun; 200 PHW_TIMER HwScsiTimer; 201 ULONG MiniportTimerValue; 202 } SCSI_PORT_INTERRUPT_DATA, *PSCSI_PORT_INTERRUPT_DATA; 203 204 205 /* Only for interrupt data saving function */ 206 typedef struct _SCSI_PORT_SAVE_INTERRUPT 207 { 208 PSCSI_PORT_INTERRUPT_DATA InterruptData; 209 struct _SCSI_PORT_DEVICE_EXTENSION *DeviceExtension; 210 } SCSI_PORT_SAVE_INTERRUPT, *PSCSI_PORT_SAVE_INTERRUPT; 211 212 /* 213 * SCSI_PORT_DEVICE_EXTENSION 214 * 215 * DESCRIPTION 216 * First part of the port objects device extension. The second 217 * part is the miniport-specific device extension. 218 */ 219 220 #ifdef _WIN64 221 #define ALIGNAS_PTR DECLSPEC_ALIGN(8) 222 #else 223 #define ALIGNAS_PTR DECLSPEC_ALIGN(4) 224 #endif 225 226 // FDO 227 typedef struct _SCSI_PORT_DEVICE_EXTENSION 228 { 229 SCSI_PORT_COMMON_EXTENSION Common; 230 231 ULONG Length; 232 ULONG MiniPortExtensionSize; 233 PPORT_CONFIGURATION_INFORMATION PortConfig; 234 PSCSI_BUS_INFO Buses; // children LUNs are stored here 235 PVOID NonCachedExtension; 236 ULONG PortNumber; 237 238 LONG ActiveRequestCounter; 239 ULONG SrbFlags; 240 ULONG Flags; 241 242 UCHAR NumberOfBuses; 243 ULONG MaxTargedIds; 244 ULONG MaxLunCount; 245 246 KSPIN_LOCK IrqLock; /* Used when there are 2 irqs */ 247 ULONG SequenceNumber; /* Global sequence number for packets */ 248 KSPIN_LOCK SpinLock; 249 PKINTERRUPT Interrupt[2]; 250 PIRP CurrentIrp; 251 ULONG IrpFlags; 252 253 SCSI_PORT_TIMER_STATES TimerState; 254 LONG TimerCount; 255 256 KTIMER MiniportTimer; 257 KDPC MiniportTimerDpc; 258 259 PMAPPED_ADDRESS MappedAddressList; 260 261 ULONG LunExtensionSize; 262 263 SCSI_PORT_INTERRUPT_DATA InterruptData; 264 265 /* SRB extension stuff*/ 266 ULONG SrbExtensionSize; 267 PVOID SrbExtensionBuffer; 268 PVOID FreeSrbExtensions; 269 270 /* SRB information */ 271 PSCSI_REQUEST_BLOCK_INFO SrbInfo; 272 PSCSI_REQUEST_BLOCK_INFO FreeSrbInfo; 273 ULONG SrbDataCount; 274 275 IO_SCSI_CAPABILITIES PortCapabilities; 276 277 PCONTROLLER_OBJECT ControllerObject; 278 279 PHW_INITIALIZE HwInitialize; 280 PHW_STARTIO HwStartIo; 281 PHW_INTERRUPT HwInterrupt; 282 PHW_RESET_BUS HwResetBus; 283 PHW_DMA_STARTED HwDmaStarted; 284 PHW_TIMER HwScsiTimer; 285 286 PSCSI_REQUEST_BLOCK OriginalSrb; 287 SCSI_REQUEST_BLOCK InternalSrb; 288 SENSE_DATA InternalSenseData; 289 290 /* DMA related stuff */ 291 PADAPTER_OBJECT AdapterObject; 292 ULONG MapRegisterCount; 293 BOOLEAN MapBuffers; 294 BOOLEAN MapRegisters; 295 PVOID MapRegisterBase; 296 297 /* Features */ 298 BOOLEAN CachesData; 299 BOOLEAN SupportsTaggedQueuing; 300 BOOLEAN SupportsAutoSense; 301 BOOLEAN MultipleReqsPerLun; 302 BOOLEAN ReceiveEvent; 303 304 PHYSICAL_ADDRESS PhysicalAddress; 305 ULONG CommonBufferLength; 306 ULONG InterruptLevel[2]; 307 ULONG IoAddress; 308 309 BOOLEAN NeedSrbExtensionAlloc; 310 BOOLEAN NeedSrbDataAlloc; 311 312 ULONG RequestsNumber; 313 314 ULONG InterruptCount; 315 316 UNICODE_STRING DeviceName; 317 UNICODE_STRING InterfaceName; 318 BOOLEAN DeviceStarted; 319 UINT8 TotalLUCount; 320 321 // use the pointer alignment here, some miniport drivers rely on this 322 // moreover, it has to be the last member 323 ALIGNAS_PTR UCHAR MiniPortDeviceExtension[]; 324 } SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION; 325 326 typedef struct _RESETBUS_PARAMS 327 { 328 ULONG PathId; 329 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension; 330 } RESETBUS_PARAMS, *PRESETBUS_PARAMS; 331 332 typedef struct _SCSIPORT_DRIVER_EXTENSION 333 { 334 PDRIVER_OBJECT DriverObject; 335 UNICODE_STRING RegistryPath; 336 BOOLEAN IsLegacyDriver; 337 } SCSI_PORT_DRIVER_EXTENSION, *PSCSI_PORT_DRIVER_EXTENSION; 338 339 FORCEINLINE 340 BOOLEAN 341 VerifyIrpOutBufferSize( 342 _In_ PIRP Irp, 343 _In_ SIZE_T Size) 344 { 345 PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp); 346 if (ioStack->Parameters.DeviceIoControl.OutputBufferLength < Size) 347 { 348 Irp->IoStatus.Information = Size; 349 return FALSE; 350 } 351 return TRUE; 352 } 353 354 FORCEINLINE 355 BOOLEAN 356 VerifyIrpInBufferSize( 357 _In_ PIRP Irp, 358 _In_ SIZE_T Size) 359 { 360 PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp); 361 if (ioStack->Parameters.DeviceIoControl.InputBufferLength < Size) 362 { 363 Irp->IoStatus.Information = Size; 364 return FALSE; 365 } 366 return TRUE; 367 } 368 369 // ioctl.c 370 371 NTSTATUS 372 NTAPI 373 ScsiPortDeviceControl( 374 _In_ PDEVICE_OBJECT DeviceObject, 375 _In_ PIRP Irp); 376 377 // fdo.c 378 379 VOID 380 FdoScanAdapter( 381 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension); 382 383 NTSTATUS 384 FdoCallHWInitialize( 385 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension); 386 387 NTSTATUS 388 FdoRemoveAdapter( 389 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension); 390 391 NTSTATUS 392 FdoStartAdapter( 393 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension); 394 395 NTSTATUS 396 FdoDispatchPnp( 397 _In_ PDEVICE_OBJECT DeviceObject, 398 _Inout_ PIRP Irp); 399 400 // pdo.c 401 402 PDEVICE_OBJECT 403 PdoCreateLunDevice( 404 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension); 405 406 PSCSI_PORT_LUN_EXTENSION 407 GetLunByPath( 408 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, 409 _In_ UCHAR PathId, 410 _In_ UCHAR TargetId, 411 _In_ UCHAR Lun); 412 413 PSCSI_REQUEST_BLOCK_INFO 414 SpiGetSrbData( 415 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, 416 _In_ PSCSI_PORT_LUN_EXTENSION LunExtension, 417 _In_ UCHAR QueueTag); 418 419 NTSTATUS 420 PdoDispatchPnp( 421 _In_ PDEVICE_OBJECT DeviceObject, 422 _Inout_ PIRP Irp); 423 424 // power.c 425 426 DRIVER_DISPATCH ScsiPortDispatchPower; 427 428 // registry.c 429 430 VOID 431 SpiInitOpenKeys( 432 _Inout_ PCONFIGURATION_INFO ConfigInfo, 433 _In_ PSCSI_PORT_DRIVER_EXTENSION DriverExtension); 434 435 NTSTATUS 436 RegistryInitAdapterKey( 437 _Inout_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension); 438 439 NTSTATUS 440 RegistryInitLunKey( 441 _Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension); 442 443 // scsi.c 444 445 VOID 446 SpiGetNextRequestFromLun( 447 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, 448 _Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension, 449 _Inout_opt_ PKIRQL OldIrql); 450 451 IO_DPC_ROUTINE ScsiPortDpcForIsr; 452 DRIVER_DISPATCH ScsiPortDispatchScsi; 453 KSYNCHRONIZE_ROUTINE ScsiPortStartPacket; 454 DRIVER_STARTIO ScsiPortStartIo; 455 456 457 // scsiport.c 458 459 KSERVICE_ROUTINE ScsiPortIsr; 460 461 IO_ALLOCATION_ACTION 462 NTAPI 463 SpiAdapterControl( 464 _In_ PDEVICE_OBJECT DeviceObject, 465 _In_ PIRP Irp, 466 _In_ PVOID MapRegisterBase, 467 _In_ PVOID Context); 468 469 IO_ALLOCATION_ACTION 470 NTAPI 471 ScsiPortAllocateAdapterChannel( 472 _In_ PDEVICE_OBJECT DeviceObject, 473 _In_ PIRP Irp, 474 _In_ PVOID MapRegisterBase, 475 _In_ PVOID Context); 476