4 * Interface between SCSI miniport drivers and the SCSI port driver.
6 * This file is part of the w32api package.
9 * Created by Casper S. Hornstrup <chorns@users.sourceforge.net>
11 * THIS SOFTWARE IS NOT COPYRIGHTED
13 * This source code is offered for use in the public domain. You may
14 * use, modify or distribute it freely.
16 * This code is distributed in the hope that it will be useful but
17 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
18 * DISCLAIMED. This includes but is not limited to warranties of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27 #pragma GCC system_header
36 #if defined(_SCSIPORT_)
37 #define SCSIPORTAPI DECLSPEC_EXPORT
39 #define SCSIPORTAPI DECLSPEC_IMPORT
43 #define DebugPrint(x) ScsiDebugPrint x
48 typedef PHYSICAL_ADDRESS SCSI_PHYSICAL_ADDRESS
, *PSCSI_PHYSICAL_ADDRESS
;
50 #define SP_UNINITIALIZED_VALUE ((ULONG) ~0)
51 #define SP_UNTAGGED ((UCHAR) ~0)
53 #define SRB_SIMPLE_TAG_REQUEST 0x20
54 #define SRB_HEAD_OF_QUEUE_TAG_REQUEST 0x21
55 #define SRB_ORDERED_QUEUE_TAG_REQUEST 0x22
57 #define SRB_STATUS_QUEUE_FROZEN 0x40
58 #define SRB_STATUS_AUTOSENSE_VALID 0x80
60 #define SRB_STATUS(Status) \
61 (Status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
63 #define MAXIMUM_CDB_SIZE 12
66 #define SCSI_PORT_SIGNATURE 0x54524f50
70 #define SCSI_MAXIMUM_LOGICAL_UNITS 8
71 #define SCSI_MAXIMUM_TARGETS_PER_BUS 128
72 #define SCSI_MAXIMUM_LUNS_PER_TARGET 255
73 #define SCSI_MAXIMUM_BUSES 8
74 #define SCSI_MINIMUM_PHYSICAL_BREAKS 16
75 #define SCSI_MAXIMUM_PHYSICAL_BREAKS 255
76 #define SCSI_MAXIMUM_TARGETS 8
78 #define SRB_FUNCTION_WMI 0x17
80 #define SRB_WMI_FLAGS_ADAPTER_REQUEST 0x0001
82 #define SP_BUS_PARITY_ERROR 0x0001
83 #define SP_UNEXPECTED_DISCONNECT 0x0002
84 #define SP_INVALID_RESELECTION 0x0003
85 #define SP_BUS_TIME_OUT 0x0004
86 #define SP_PROTOCOL_ERROR 0x0005
87 #define SP_INTERNAL_ADAPTER_ERROR 0x0006
88 #define SP_REQUEST_TIMEOUT 0x0007
89 #define SP_IRQ_NOT_RESPONDING 0x0008
90 #define SP_BAD_FW_WARNING 0x0009
91 #define SP_BAD_FW_ERROR 0x000a
92 #define SP_LOST_WMI_MINIPORT_REQUEST 0x000b
94 /* SCSI_REQUEST_BLOCK.Function constants */
95 #define SRB_FUNCTION_EXECUTE_SCSI 0x00
96 #define SRB_FUNCTION_CLAIM_DEVICE 0x01
97 #define SRB_FUNCTION_IO_CONTROL 0x02
98 #define SRB_FUNCTION_RECEIVE_EVENT 0x03
99 #define SRB_FUNCTION_RELEASE_QUEUE 0x04
100 #define SRB_FUNCTION_ATTACH_DEVICE 0x05
101 #define SRB_FUNCTION_RELEASE_DEVICE 0x06
102 #define SRB_FUNCTION_SHUTDOWN 0x07
103 #define SRB_FUNCTION_FLUSH 0x08
104 #define SRB_FUNCTION_ABORT_COMMAND 0x10
105 #define SRB_FUNCTION_RELEASE_RECOVERY 0x11
106 #define SRB_FUNCTION_RESET_BUS 0x12
107 #define SRB_FUNCTION_RESET_DEVICE 0x13
108 #define SRB_FUNCTION_TERMINATE_IO 0x14
109 #define SRB_FUNCTION_FLUSH_QUEUE 0x15
110 #define SRB_FUNCTION_REMOVE_DEVICE 0x16
111 #define SRB_FUNCTION_WMI 0x17
112 #define SRB_FUNCTION_LOCK_QUEUE 0x18
113 #define SRB_FUNCTION_UNLOCK_QUEUE 0x19
114 #define SRB_FUNCTION_RESET_LOGICAL_UNIT 0x20
116 /* SCSI_REQUEST_BLOCK.SrbStatus constants */
117 #define SRB_STATUS_PENDING 0x00
118 #define SRB_STATUS_SUCCESS 0x01
119 #define SRB_STATUS_ABORTED 0x02
120 #define SRB_STATUS_ABORT_FAILED 0x03
121 #define SRB_STATUS_ERROR 0x04
122 #define SRB_STATUS_BUSY 0x05
123 #define SRB_STATUS_INVALID_REQUEST 0x06
124 #define SRB_STATUS_INVALID_PATH_ID 0x07
125 #define SRB_STATUS_NO_DEVICE 0x08
126 #define SRB_STATUS_TIMEOUT 0x09
127 #define SRB_STATUS_SELECTION_TIMEOUT 0x0A
128 #define SRB_STATUS_COMMAND_TIMEOUT 0x0B
129 #define SRB_STATUS_MESSAGE_REJECTED 0x0D
130 #define SRB_STATUS_BUS_RESET 0x0E
131 #define SRB_STATUS_PARITY_ERROR 0x0F
132 #define SRB_STATUS_REQUEST_SENSE_FAILED 0x10
133 #define SRB_STATUS_NO_HBA 0x11
134 #define SRB_STATUS_DATA_OVERRUN 0x12
135 #define SRB_STATUS_UNEXPECTED_BUS_FREE 0x13
136 #define SRB_STATUS_PHASE_SEQUENCE_FAILURE 0x14
137 #define SRB_STATUS_BAD_SRB_BLOCK_LENGTH 0x15
138 #define SRB_STATUS_REQUEST_FLUSHED 0x16
139 #define SRB_STATUS_INVALID_LUN 0x20
140 #define SRB_STATUS_INVALID_TARGET_ID 0x21
141 #define SRB_STATUS_BAD_FUNCTION 0x22
142 #define SRB_STATUS_ERROR_RECOVERY 0x23
143 #define SRB_STATUS_NOT_POWERED 0x24
144 #define SRB_STATUS_INTERNAL_ERROR 0x30
146 /* SCSI_REQUEST_BLOCK.SrbFlags constants */
147 #define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002
148 #define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004
149 #define SRB_FLAGS_DISABLE_SYNCH_TRANSFER 0x00000008
150 #define SRB_FLAGS_BYPASS_FROZEN_QUEUE 0x00000010
151 #define SRB_FLAGS_DISABLE_AUTOSENSE 0x00000020
152 #define SRB_FLAGS_DATA_IN 0x00000040
153 #define SRB_FLAGS_DATA_OUT 0x00000080
154 #define SRB_FLAGS_NO_DATA_TRANSFER 0x00000000
155 #define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)
156 #define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100
157 #define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200
158 #define SRB_FLAGS_FREE_SENSE_BUFFER 0x00000400
159 #define SRB_FLAGS_IS_ACTIVE 0x00010000
160 #define SRB_FLAGS_ALLOCATED_FROM_ZONE 0x00020000
161 #define SRB_FLAGS_SGLIST_FROM_POOL 0x00040000
162 #define SRB_FLAGS_BYPASS_LOCKED_QUEUE 0x00080000
163 #define SRB_FLAGS_NO_KEEP_AWAKE 0x00100000
164 #define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE 0x00200000
165 #define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT 0x00400000
166 #define SRB_FLAGS_DONT_START_NEXT_PACKET 0x00800000
167 #define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000
168 #define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000
170 typedef struct _SCSI_REQUEST_BLOCK
{
181 UCHAR SenseInfoBufferLength
;
183 ULONG DataTransferLength
;
186 PVOID SenseInfoBuffer
;
187 struct _SCSI_REQUEST_BLOCK
*NextSrb
;
188 PVOID OriginalRequest
;
190 _ANONYMOUS_UNION
union {
191 ULONG InternalStatus
;
198 } SCSI_REQUEST_BLOCK
, *PSCSI_REQUEST_BLOCK
;
200 #define SCSI_REQUEST_BLOCK_SIZE sizeof(SCSI_REQUEST_BLOCK)
202 typedef struct _ACCESS_RANGE
{
203 SCSI_PHYSICAL_ADDRESS RangeStart
;
205 BOOLEAN RangeInMemory
;
206 } ACCESS_RANGE
, *PACCESS_RANGE
;
208 /* PORT_CONFIGURATION_INFORMATION.Dma64BitAddresses constants */
209 #define SCSI_DMA64_MINIPORT_SUPPORTED 0x01
210 #define SCSI_DMA64_SYSTEM_SUPPORTED 0x80
212 typedef struct _PORT_CONFIGURATION_INFORMATION
{
214 ULONG SystemIoBusNumber
;
215 INTERFACE_TYPE AdapterInterfaceType
;
216 ULONG BusInterruptLevel
;
217 ULONG BusInterruptVector
;
218 KINTERRUPT_MODE InterruptMode
;
219 ULONG MaximumTransferLength
;
220 ULONG NumberOfPhysicalBreaks
;
226 ULONG NumberOfAccessRanges
;
227 ACCESS_RANGE (*AccessRanges
)[];
230 UCHAR InitiatorBusId
[8];
231 BOOLEAN ScatterGather
;
234 BOOLEAN AdapterScansDown
;
235 BOOLEAN AtdiskPrimaryClaimed
;
236 BOOLEAN AtdiskSecondaryClaimed
;
237 BOOLEAN Dma32BitAddresses
;
240 BOOLEAN NeedPhysicalAddresses
;
241 BOOLEAN TaggedQueuing
;
242 BOOLEAN AutoRequestSense
;
243 BOOLEAN MultipleRequestPerLu
;
244 BOOLEAN ReceiveEvent
;
245 BOOLEAN RealModeInitialized
;
246 BOOLEAN BufferAccessScsiPortControlled
;
247 UCHAR MaximumNumberOfTargets
;
248 UCHAR ReservedUchars
[2];
250 ULONG BusInterruptLevel2
;
251 ULONG BusInterruptVector2
;
252 KINTERRUPT_MODE InterruptMode2
;
257 ULONG DeviceExtensionSize
;
258 ULONG SpecificLuExtensionSize
;
259 ULONG SrbExtensionSize
;
260 UCHAR Dma64BitAddresses
;
261 BOOLEAN ResetTargetSupported
;
262 UCHAR MaximumNumberOfLogicalUnits
;
263 BOOLEAN WmiDataProvider
;
264 } PORT_CONFIGURATION_INFORMATION
, *PPORT_CONFIGURATION_INFORMATION
;
266 #define CONFIG_INFO_VERSION_2 sizeof(PORT_CONFIGURATION_INFORMATION)
268 typedef enum _SCSI_NOTIFICATION_TYPE
{
273 CallDisableInterrupts
,
274 CallEnableInterrupts
,
279 } SCSI_NOTIFICATION_TYPE
, *PSCSI_NOTIFICATION_TYPE
;
282 __extension__
/* enums limited to range of integer */
284 typedef enum _SCSI_ADAPTER_CONTROL_TYPE
{
285 ScsiQuerySupportedControlTypes
= 0,
289 ScsiSetRunningConfig
,
290 ScsiAdapterControlMax
,
291 MakeAdapterControlTypeSizeOfUlong
= 0xffffffff
292 } SCSI_ADAPTER_CONTROL_TYPE
, *PSCSI_ADAPTER_CONTROL_TYPE
;
294 typedef enum _SCSI_ADAPTER_CONTROL_STATUS
{
295 ScsiAdapterControlSuccess
= 0,
296 ScsiAdapterControlUnsuccessful
297 } SCSI_ADAPTER_CONTROL_STATUS
, *PSCSI_ADAPTER_CONTROL_STATUS
;
299 typedef struct _SCSI_SUPPORTED_CONTROL_TYPE_LIST
{
300 ULONG MaxControlType
;
301 BOOLEAN SupportedTypeList
[0];
302 } SCSI_SUPPORTED_CONTROL_TYPE_LIST
, *PSCSI_SUPPORTED_CONTROL_TYPE_LIST
;
304 typedef SCSI_ADAPTER_CONTROL_STATUS DDKAPI
305 (*PHW_ADAPTER_CONTROL
)(
306 /*IN*/ PVOID DeviceExtension
,
307 /*IN*/ SCSI_ADAPTER_CONTROL_TYPE ControlType
,
308 /*IN*/ PVOID Parameters
);
310 typedef BOOLEAN DDKAPI
311 (*PHW_ADAPTER_STATE
)(
312 /*IN*/ PVOID DeviceExtension
,
313 /*IN*/ PVOID Context
,
314 /*IN*/ BOOLEAN SaveState
);
316 #define SP_RETURN_NOT_FOUND 0
317 #define SP_RETURN_FOUND 1
318 #define SP_RETURN_ERROR 2
319 #define SP_RETURN_BAD_CONFIG 3
323 /*IN*/ PVOID DeviceExtension
,
324 /*IN*/ PVOID HwContext
,
325 /*IN*/ PVOID BusInformation
,
326 /*IN*/ PCHAR ArgumentString
,
327 /*IN OUT*/ PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
328 /*OUT*/ PBOOLEAN Again
);
330 typedef BOOLEAN DDKAPI
332 /*IN*/ PVOID DeviceExtension
);
334 typedef BOOLEAN DDKAPI
336 /*IN*/ PVOID DeviceExtension
);
338 typedef BOOLEAN DDKAPI
340 /*IN*/ PVOID DeviceExtension
,
341 /*IN*/ ULONG PathId
);
345 /*IN*/ PVOID DeviceExtension
);
347 typedef BOOLEAN DDKAPI
349 /*IN*/ PVOID DeviceExtension
,
350 /*IN*/ PSCSI_REQUEST_BLOCK Srb
);
354 /*IN*/ PVOID DeviceExtension
);
356 typedef struct _HW_INITIALIZATION_DATA
{
357 ULONG HwInitializationDataSize
;
358 INTERFACE_TYPE AdapterInterfaceType
;
359 PHW_INITIALIZE HwInitialize
;
360 PHW_STARTIO HwStartIo
;
361 PHW_INTERRUPT HwInterrupt
;
362 PHW_FIND_ADAPTER HwFindAdapter
;
363 PHW_RESET_BUS HwResetBus
;
364 PHW_DMA_STARTED HwDmaStarted
;
365 PHW_ADAPTER_STATE HwAdapterState
;
366 ULONG DeviceExtensionSize
;
367 ULONG SpecificLuExtensionSize
;
368 ULONG SrbExtensionSize
;
369 ULONG NumberOfAccessRanges
;
372 BOOLEAN NeedPhysicalAddresses
;
373 BOOLEAN TaggedQueuing
;
374 BOOLEAN AutoRequestSense
;
375 BOOLEAN MultipleRequestPerLu
;
376 BOOLEAN ReceiveEvent
;
377 USHORT VendorIdLength
;
379 USHORT ReservedUshort
;
380 USHORT DeviceIdLength
;
382 PHW_ADAPTER_CONTROL HwAdapterControl
;
383 } HW_INITIALIZATION_DATA
, *PHW_INITIALIZATION_DATA
;
388 ScsiPortCompleteRequest(
389 /*IN*/ PVOID HwDeviceExtension
,
391 /*IN*/ UCHAR TargetId
,
393 /*IN*/ UCHAR SrbStatus
);
397 * ScsiPortConvertPhysicalAddressToUlong(
398 * IN SCSI_PHYSICAL_ADDRESS Address);
400 #define ScsiPortConvertPhysicalAddressToUlong(Address) ((Address).LowPart)
403 SCSI_PHYSICAL_ADDRESS
405 ScsiPortConvertUlongToPhysicalAddress(
406 /*IN*/ ULONG UlongAddress
);
412 /*IN*/ PVOID DeviceExtension
);
417 ScsiPortFreeDeviceBase(
418 /*IN*/ PVOID HwDeviceExtension
,
419 /*IN*/ PVOID MappedAddress
);
425 /*IN*/ PVOID DeviceExtension
,
426 /*IN*/ ULONG BusDataType
,
427 /*IN*/ ULONG SystemIoBusNumber
,
428 /*IN*/ ULONG SlotNumber
,
430 /*IN*/ ULONG Length
);
435 ScsiPortGetDeviceBase(
436 /*IN*/ PVOID HwDeviceExtension
,
437 /*IN*/ INTERFACE_TYPE BusType
,
438 /*IN*/ ULONG SystemIoBusNumber
,
439 /*IN*/ SCSI_PHYSICAL_ADDRESS IoAddress
,
440 /*IN*/ ULONG NumberOfBytes
,
441 /*IN*/ BOOLEAN InIoSpace
);
446 ScsiPortGetLogicalUnit(
447 /*IN*/ PVOID HwDeviceExtension
,
449 /*IN*/ UCHAR TargetId
,
453 SCSI_PHYSICAL_ADDRESS
455 ScsiPortGetPhysicalAddress(
456 /*IN*/ PVOID HwDeviceExtension
,
457 /*IN*/ PSCSI_REQUEST_BLOCK Srb
/*OPTIONAL*/,
458 /*IN*/ PVOID VirtualAddress
,
459 /*OUT*/ ULONG
*Length
);
465 /*IN*/ PVOID DeviceExtension
,
467 /*IN*/ UCHAR TargetId
,
469 /*IN*/ LONG QueueTag
);
474 ScsiPortGetUncachedExtension(
475 /*IN*/ PVOID HwDeviceExtension
,
476 /*IN*/ PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
477 /*IN*/ ULONG NumberOfBytes
);
482 ScsiPortGetVirtualAddress(
483 /*IN*/ PVOID HwDeviceExtension
,
484 /*IN*/ SCSI_PHYSICAL_ADDRESS PhysicalAddress
);
490 /*IN*/ PVOID Argument1
,
491 /*IN*/ PVOID Argument2
,
492 /*IN*/ struct _HW_INITIALIZATION_DATA
*HwInitializationData
,
493 /*IN*/ PVOID HwContext
/*OPTIONAL*/);
498 ScsiPortIoMapTransfer(
499 /*IN*/ PVOID HwDeviceExtension
,
500 /*IN*/ PSCSI_REQUEST_BLOCK Srb
,
501 /*IN*/ ULONG LogicalAddress
,
502 /*IN*/ ULONG Length
);
508 /*IN*/ PVOID HwDeviceExtension
,
509 /*IN*/ PSCSI_REQUEST_BLOCK Srb
/*OPTIONAL*/,
511 /*IN*/ UCHAR TargetId
,
513 /*IN*/ ULONG ErrorCode
,
514 /*IN*/ ULONG UniqueId
);
520 /*IN*/ PVOID WriteBuffer
,
521 /*IN*/ PVOID ReadBuffer
,
522 /*IN*/ ULONG Length
);
527 ScsiPortNotification(
528 /*IN*/ SCSI_NOTIFICATION_TYPE NotificationType
,
529 /*IN*/ PVOID HwDeviceExtension
,
535 ScsiPortQuerySystemTime(
536 /*OUT*/ PLARGE_INTEGER CurrentTime
);
541 ScsiPortReadPortBufferUchar(
543 /*IN*/ PUCHAR Buffer
,
549 ScsiPortReadPortBufferUlong(
551 /*IN*/ PULONG Buffer
,
557 ScsiPortReadPortBufferUshort(
559 /*IN*/ PUSHORT Buffer
,
565 ScsiPortReadPortUchar(
571 ScsiPortReadPortUlong(
577 ScsiPortReadPortUshort(
578 /*IN*/ PUSHORT Port
);
583 ScsiPortReadRegisterBufferUchar(
584 /*IN*/ PUCHAR Register
,
585 /*IN*/ PUCHAR Buffer
,
591 ScsiPortReadRegisterBufferUlong(
592 /*IN*/ PULONG Register
,
593 /*IN*/ PULONG Buffer
,
599 ScsiPortReadRegisterBufferUshort(
600 /*IN*/ PUSHORT Register
,
601 /*IN*/ PUSHORT Buffer
,
607 ScsiPortReadRegisterUchar(
608 /*IN*/ PUCHAR Register
);
613 ScsiPortReadRegisterUlong(
614 /*IN*/ PULONG Register
);
619 ScsiPortReadRegisterUshort(
620 /*IN*/ PUSHORT Register
);
625 ScsiPortSetBusDataByOffset(
626 /*IN*/ PVOID DeviceExtension
,
627 /*IN*/ ULONG BusDataType
,
628 /*IN*/ ULONG SystemIoBusNumber
,
629 /*IN*/ ULONG SlotNumber
,
632 /*IN*/ ULONG Length
);
637 ScsiPortStallExecution(
643 ScsiPortValidateRange(
644 /*IN*/ PVOID HwDeviceExtension
,
645 /*IN*/ INTERFACE_TYPE BusType
,
646 /*IN*/ ULONG SystemIoBusNumber
,
647 /*IN*/ SCSI_PHYSICAL_ADDRESS IoAddress
,
648 /*IN*/ ULONG NumberOfBytes
,
649 /*IN*/ BOOLEAN InIoSpace
);
654 ScsiPortWritePortBufferUchar(
656 /*IN*/ PUCHAR Buffer
,
662 ScsiPortWritePortBufferUlong(
664 /*IN*/ PULONG Buffer
,
670 ScsiPortWritePortBufferUshort(
672 /*IN*/ PUSHORT Buffer
,
678 ScsiPortWritePortUchar(
685 ScsiPortWritePortUlong(
692 ScsiPortWritePortUshort(
694 /*IN*/ USHORT Value
);
699 ScsiPortWriteRegisterBufferUchar(
700 /*IN*/ PUCHAR Register
,
701 /*IN*/ PUCHAR Buffer
,
707 ScsiPortWriteRegisterBufferUlong(
708 /*IN*/ PULONG Register
,
709 /*IN*/ PULONG Buffer
,
715 ScsiPortWriteRegisterBufferUshort(
716 /*IN*/ PUSHORT Register
,
717 /*IN*/ PUSHORT Buffer
,
723 ScsiPortWriteRegisterUchar(
724 /*IN*/ PUCHAR Register
,
730 ScsiPortWriteRegisterUlong(
731 /*IN*/ PULONG Register
,
737 ScsiPortWriteRegisterUshort(
738 /*IN*/ PUSHORT Register
,
739 /*IN*/ USHORT Value
);
745 /*IN*/ ULONG DebugPrintLevel
,
746 /*IN*/ PCCHAR DebugMessage
,