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.
30 #if defined(_SCSIPORT_)
33 #define SCSIPORTAPI DECLSPEC_IMPORT
37 #define DebugPrint(x) ScsiDebugPrint x
42 typedef PHYSICAL_ADDRESS SCSI_PHYSICAL_ADDRESS
, *PSCSI_PHYSICAL_ADDRESS
;
44 #define SP_UNINITIALIZED_VALUE ((ULONG) ~0)
45 #define SP_UNTAGGED ((UCHAR) ~0)
47 #define SRB_SIMPLE_TAG_REQUEST 0x20
48 #define SRB_HEAD_OF_QUEUE_TAG_REQUEST 0x21
49 #define SRB_ORDERED_QUEUE_TAG_REQUEST 0x22
51 #define SRB_STATUS_QUEUE_FROZEN 0x40
52 #define SRB_STATUS_AUTOSENSE_VALID 0x80
54 #define SRB_STATUS(Status) \
55 (Status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
57 #define MAXIMUM_CDB_SIZE 12
60 #define SCSI_PORT_SIGNATURE 0x54524f50
64 #define SCSI_MAXIMUM_LOGICAL_UNITS 8
65 #define SCSI_MAXIMUM_TARGETS_PER_BUS 128
66 #define SCSI_MAXIMUM_LUNS_PER_TARGET 255
67 #define SCSI_MAXIMUM_BUSES 8
68 #define SCSI_MINIMUM_PHYSICAL_BREAKS 16
69 #define SCSI_MAXIMUM_PHYSICAL_BREAKS 255
70 #define SCSI_MAXIMUM_TARGETS 8
72 #define SRB_FUNCTION_WMI 0x17
74 #define SRB_WMI_FLAGS_ADAPTER_REQUEST 0x0001
76 #define SP_BUS_PARITY_ERROR 0x0001
77 #define SP_UNEXPECTED_DISCONNECT 0x0002
78 #define SP_INVALID_RESELECTION 0x0003
79 #define SP_BUS_TIME_OUT 0x0004
80 #define SP_PROTOCOL_ERROR 0x0005
81 #define SP_INTERNAL_ADAPTER_ERROR 0x0006
82 #define SP_REQUEST_TIMEOUT 0x0007
83 #define SP_IRQ_NOT_RESPONDING 0x0008
84 #define SP_BAD_FW_WARNING 0x0009
85 #define SP_BAD_FW_ERROR 0x000a
86 #define SP_LOST_WMI_MINIPORT_REQUEST 0x000b
88 /* SCSI_REQUEST_BLOCK.Function constants */
89 #define SRB_FUNCTION_EXECUTE_SCSI 0x00
90 #define SRB_FUNCTION_CLAIM_DEVICE 0x01
91 #define SRB_FUNCTION_IO_CONTROL 0x02
92 #define SRB_FUNCTION_RECEIVE_EVENT 0x03
93 #define SRB_FUNCTION_RELEASE_QUEUE 0x04
94 #define SRB_FUNCTION_ATTACH_DEVICE 0x05
95 #define SRB_FUNCTION_RELEASE_DEVICE 0x06
96 #define SRB_FUNCTION_SHUTDOWN 0x07
97 #define SRB_FUNCTION_FLUSH 0x08
98 #define SRB_FUNCTION_ABORT_COMMAND 0x10
99 #define SRB_FUNCTION_RELEASE_RECOVERY 0x11
100 #define SRB_FUNCTION_RESET_BUS 0x12
101 #define SRB_FUNCTION_RESET_DEVICE 0x13
102 #define SRB_FUNCTION_TERMINATE_IO 0x14
103 #define SRB_FUNCTION_FLUSH_QUEUE 0x15
104 #define SRB_FUNCTION_REMOVE_DEVICE 0x16
105 #define SRB_FUNCTION_WMI 0x17
106 #define SRB_FUNCTION_LOCK_QUEUE 0x18
107 #define SRB_FUNCTION_UNLOCK_QUEUE 0x19
108 #define SRB_FUNCTION_RESET_LOGICAL_UNIT 0x20
110 /* SCSI_REQUEST_BLOCK.SrbStatus constants */
111 #define SRB_STATUS_PENDING 0x00
112 #define SRB_STATUS_SUCCESS 0x01
113 #define SRB_STATUS_ABORTED 0x02
114 #define SRB_STATUS_ABORT_FAILED 0x03
115 #define SRB_STATUS_ERROR 0x04
116 #define SRB_STATUS_BUSY 0x05
117 #define SRB_STATUS_INVALID_REQUEST 0x06
118 #define SRB_STATUS_INVALID_PATH_ID 0x07
119 #define SRB_STATUS_NO_DEVICE 0x08
120 #define SRB_STATUS_TIMEOUT 0x09
121 #define SRB_STATUS_SELECTION_TIMEOUT 0x0A
122 #define SRB_STATUS_COMMAND_TIMEOUT 0x0B
123 #define SRB_STATUS_MESSAGE_REJECTED 0x0D
124 #define SRB_STATUS_BUS_RESET 0x0E
125 #define SRB_STATUS_PARITY_ERROR 0x0F
126 #define SRB_STATUS_REQUEST_SENSE_FAILED 0x10
127 #define SRB_STATUS_NO_HBA 0x11
128 #define SRB_STATUS_DATA_OVERRUN 0x12
129 #define SRB_STATUS_UNEXPECTED_BUS_FREE 0x13
130 #define SRB_STATUS_PHASE_SEQUENCE_FAILURE 0x14
131 #define SRB_STATUS_BAD_SRB_BLOCK_LENGTH 0x15
132 #define SRB_STATUS_REQUEST_FLUSHED 0x16
133 #define SRB_STATUS_INVALID_LUN 0x20
134 #define SRB_STATUS_INVALID_TARGET_ID 0x21
135 #define SRB_STATUS_BAD_FUNCTION 0x22
136 #define SRB_STATUS_ERROR_RECOVERY 0x23
137 #define SRB_STATUS_NOT_POWERED 0x24
138 #define SRB_STATUS_INTERNAL_ERROR 0x30
140 /* SCSI_REQUEST_BLOCK.SrbFlags constants */
141 #define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002
142 #define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004
143 #define SRB_FLAGS_DISABLE_SYNCH_TRANSFER 0x00000008
144 #define SRB_FLAGS_BYPASS_FROZEN_QUEUE 0x00000010
145 #define SRB_FLAGS_DISABLE_AUTOSENSE 0x00000020
146 #define SRB_FLAGS_DATA_IN 0x00000040
147 #define SRB_FLAGS_DATA_OUT 0x00000080
148 #define SRB_FLAGS_NO_DATA_TRANSFER 0x00000000
149 #define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)
150 #define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100
151 #define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200
152 #define SRB_FLAGS_FREE_SENSE_BUFFER 0x00000400
153 #define SRB_FLAGS_IS_ACTIVE 0x00010000
154 #define SRB_FLAGS_ALLOCATED_FROM_ZONE 0x00020000
155 #define SRB_FLAGS_SGLIST_FROM_POOL 0x00040000
156 #define SRB_FLAGS_BYPASS_LOCKED_QUEUE 0x00080000
157 #define SRB_FLAGS_NO_KEEP_AWAKE 0x00100000
158 #define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE 0x00200000
159 #define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT 0x00400000
160 #define SRB_FLAGS_DONT_START_NEXT_PACKET 0x00800000
161 #define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000
162 #define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000
164 /* Asynchronous events */
165 #define SRBEV_BUS_RESET 0x0001
166 #define SRBEV_SCSI_ASYNC_NOTIFICATION 0x0002
169 typedef struct _SCSI_REQUEST_BLOCK
{
180 UCHAR SenseInfoBufferLength
;
182 ULONG DataTransferLength
;
185 PVOID SenseInfoBuffer
;
186 struct _SCSI_REQUEST_BLOCK
*NextSrb
;
187 PVOID OriginalRequest
;
189 _ANONYMOUS_UNION
union {
190 ULONG InternalStatus
;
197 } SCSI_REQUEST_BLOCK
, *PSCSI_REQUEST_BLOCK
;
199 #define SCSI_REQUEST_BLOCK_SIZE sizeof(SCSI_REQUEST_BLOCK)
201 typedef struct _ACCESS_RANGE
{
202 SCSI_PHYSICAL_ADDRESS RangeStart
;
204 BOOLEAN RangeInMemory
;
205 } ACCESS_RANGE
, *PACCESS_RANGE
;
207 /* PORT_CONFIGURATION_INFORMATION.Dma64BitAddresses constants */
208 #define SCSI_DMA64_MINIPORT_SUPPORTED 0x01
209 #define SCSI_DMA64_SYSTEM_SUPPORTED 0x80
211 typedef struct _PORT_CONFIGURATION_INFORMATION
{
213 ULONG SystemIoBusNumber
;
214 INTERFACE_TYPE AdapterInterfaceType
;
215 ULONG BusInterruptLevel
;
216 ULONG BusInterruptVector
;
217 KINTERRUPT_MODE InterruptMode
;
218 ULONG MaximumTransferLength
;
219 ULONG NumberOfPhysicalBreaks
;
225 ULONG NumberOfAccessRanges
;
226 ACCESS_RANGE (*AccessRanges
)[];
229 UCHAR InitiatorBusId
[8];
230 BOOLEAN ScatterGather
;
233 BOOLEAN AdapterScansDown
;
234 BOOLEAN AtdiskPrimaryClaimed
;
235 BOOLEAN AtdiskSecondaryClaimed
;
236 BOOLEAN Dma32BitAddresses
;
239 BOOLEAN NeedPhysicalAddresses
;
240 BOOLEAN TaggedQueuing
;
241 BOOLEAN AutoRequestSense
;
242 BOOLEAN MultipleRequestPerLu
;
243 BOOLEAN ReceiveEvent
;
244 BOOLEAN RealModeInitialized
;
245 BOOLEAN BufferAccessScsiPortControlled
;
246 UCHAR MaximumNumberOfTargets
;
247 UCHAR ReservedUchars
[2];
249 ULONG BusInterruptLevel2
;
250 ULONG BusInterruptVector2
;
251 KINTERRUPT_MODE InterruptMode2
;
256 ULONG DeviceExtensionSize
;
257 ULONG SpecificLuExtensionSize
;
258 ULONG SrbExtensionSize
;
259 UCHAR Dma64BitAddresses
;
260 BOOLEAN ResetTargetSupported
;
261 UCHAR MaximumNumberOfLogicalUnits
;
262 BOOLEAN WmiDataProvider
;
263 } PORT_CONFIGURATION_INFORMATION
, *PPORT_CONFIGURATION_INFORMATION
;
265 #define CONFIG_INFO_VERSION_2 sizeof(PORT_CONFIGURATION_INFORMATION)
267 typedef enum _SCSI_NOTIFICATION_TYPE
{
272 CallDisableInterrupts
,
273 CallEnableInterrupts
,
278 } SCSI_NOTIFICATION_TYPE
, *PSCSI_NOTIFICATION_TYPE
;
281 __extension__
/* enums limited to range of integer */
283 typedef enum _SCSI_ADAPTER_CONTROL_TYPE
{
284 ScsiQuerySupportedControlTypes
= 0,
288 ScsiSetRunningConfig
,
289 ScsiAdapterControlMax
,
290 MakeAdapterControlTypeSizeOfUlong
= 0xffffffff
291 } SCSI_ADAPTER_CONTROL_TYPE
, *PSCSI_ADAPTER_CONTROL_TYPE
;
293 typedef enum _SCSI_ADAPTER_CONTROL_STATUS
{
294 ScsiAdapterControlSuccess
= 0,
295 ScsiAdapterControlUnsuccessful
296 } SCSI_ADAPTER_CONTROL_STATUS
, *PSCSI_ADAPTER_CONTROL_STATUS
;
298 typedef struct _SCSI_SUPPORTED_CONTROL_TYPE_LIST
{
299 ULONG MaxControlType
;
300 BOOLEAN SupportedTypeList
[0];
301 } SCSI_SUPPORTED_CONTROL_TYPE_LIST
, *PSCSI_SUPPORTED_CONTROL_TYPE_LIST
;
303 typedef SCSI_ADAPTER_CONTROL_STATUS
304 (NTAPI
*PHW_ADAPTER_CONTROL
)(
305 IN PVOID DeviceExtension
,
306 IN SCSI_ADAPTER_CONTROL_TYPE ControlType
,
307 IN PVOID Parameters
);
310 (NTAPI
*PHW_ADAPTER_STATE
)(
311 IN PVOID DeviceExtension
,
313 IN BOOLEAN SaveState
);
315 #define SP_RETURN_NOT_FOUND 0
316 #define SP_RETURN_FOUND 1
317 #define SP_RETURN_ERROR 2
318 #define SP_RETURN_BAD_CONFIG 3
321 (NTAPI
*PHW_FIND_ADAPTER
)(
322 IN PVOID DeviceExtension
,
324 IN PVOID BusInformation
,
325 IN PCHAR ArgumentString
,
326 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
330 (NTAPI
*PHW_INITIALIZE
)(
331 IN PVOID DeviceExtension
);
334 (NTAPI
*PHW_INTERRUPT
)(
335 IN PVOID DeviceExtension
);
338 (NTAPI
*PHW_RESET_BUS
)(
339 IN PVOID DeviceExtension
,
343 (NTAPI
*PHW_DMA_STARTED
)(
344 IN PVOID DeviceExtension
);
347 (NTAPI
*PHW_STARTIO
)(
348 IN PVOID DeviceExtension
,
349 IN PSCSI_REQUEST_BLOCK Srb
);
353 IN PVOID DeviceExtension
);
355 typedef struct _HW_INITIALIZATION_DATA
{
356 ULONG HwInitializationDataSize
;
357 INTERFACE_TYPE AdapterInterfaceType
;
358 PHW_INITIALIZE HwInitialize
;
359 PHW_STARTIO HwStartIo
;
360 PHW_INTERRUPT HwInterrupt
;
361 PHW_FIND_ADAPTER HwFindAdapter
;
362 PHW_RESET_BUS HwResetBus
;
363 PHW_DMA_STARTED HwDmaStarted
;
364 PHW_ADAPTER_STATE HwAdapterState
;
365 ULONG DeviceExtensionSize
;
366 ULONG SpecificLuExtensionSize
;
367 ULONG SrbExtensionSize
;
368 ULONG NumberOfAccessRanges
;
371 BOOLEAN NeedPhysicalAddresses
;
372 BOOLEAN TaggedQueuing
;
373 BOOLEAN AutoRequestSense
;
374 BOOLEAN MultipleRequestPerLu
;
375 BOOLEAN ReceiveEvent
;
376 USHORT VendorIdLength
;
378 USHORT ReservedUshort
;
379 USHORT DeviceIdLength
;
381 PHW_ADAPTER_CONTROL HwAdapterControl
;
382 } HW_INITIALIZATION_DATA
, *PHW_INITIALIZATION_DATA
;
387 ScsiPortCompleteRequest(
388 IN PVOID HwDeviceExtension
,
396 * ScsiPortConvertPhysicalAddressToUlong(
397 * IN SCSI_PHYSICAL_ADDRESS Address);
399 #define ScsiPortConvertPhysicalAddressToUlong(Address) ((Address).LowPart)
402 SCSI_PHYSICAL_ADDRESS
404 ScsiPortConvertUlongToPhysicalAddress(
405 IN ULONG UlongAddress
);
411 IN PVOID DeviceExtension
);
416 ScsiPortFreeDeviceBase(
417 IN PVOID HwDeviceExtension
,
418 IN PVOID MappedAddress
);
424 IN PVOID DeviceExtension
,
425 IN ULONG BusDataType
,
426 IN ULONG SystemIoBusNumber
,
434 ScsiPortGetDeviceBase(
435 IN PVOID HwDeviceExtension
,
436 IN INTERFACE_TYPE BusType
,
437 IN ULONG SystemIoBusNumber
,
438 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
439 IN ULONG NumberOfBytes
,
440 IN BOOLEAN InIoSpace
);
445 ScsiPortGetLogicalUnit(
446 IN PVOID HwDeviceExtension
,
452 SCSI_PHYSICAL_ADDRESS
454 ScsiPortGetPhysicalAddress(
455 IN PVOID HwDeviceExtension
,
456 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
457 IN PVOID VirtualAddress
,
464 IN PVOID DeviceExtension
,
473 ScsiPortGetUncachedExtension(
474 IN PVOID HwDeviceExtension
,
475 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
476 IN ULONG NumberOfBytes
);
481 ScsiPortGetVirtualAddress(
482 IN PVOID HwDeviceExtension
,
483 IN SCSI_PHYSICAL_ADDRESS PhysicalAddress
);
491 IN
struct _HW_INITIALIZATION_DATA
*HwInitializationData
,
492 IN PVOID HwContext OPTIONAL
);
497 ScsiPortIoMapTransfer(
498 IN PVOID HwDeviceExtension
,
499 IN PSCSI_REQUEST_BLOCK Srb
,
500 IN PVOID LogicalAddress
,
507 IN PVOID HwDeviceExtension
,
508 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
519 IN PVOID WriteBuffer
,
526 ScsiPortNotification(
527 IN SCSI_NOTIFICATION_TYPE NotificationType
,
528 IN PVOID HwDeviceExtension
,
534 ScsiPortQuerySystemTime(
535 OUT PLARGE_INTEGER CurrentTime
);
540 ScsiPortReadPortBufferUchar(
548 ScsiPortReadPortBufferUlong(
556 ScsiPortReadPortBufferUshort(
564 ScsiPortReadPortUchar(
570 ScsiPortReadPortUlong(
576 ScsiPortReadPortUshort(
582 ScsiPortReadRegisterBufferUchar(
590 ScsiPortReadRegisterBufferUlong(
598 ScsiPortReadRegisterBufferUshort(
606 ScsiPortReadRegisterUchar(
612 ScsiPortReadRegisterUlong(
618 ScsiPortReadRegisterUshort(
619 IN PUSHORT Register
);
624 ScsiPortSetBusDataByOffset(
625 IN PVOID DeviceExtension
,
626 IN ULONG BusDataType
,
627 IN ULONG SystemIoBusNumber
,
636 ScsiPortStallExecution(
642 ScsiPortValidateRange(
643 IN PVOID HwDeviceExtension
,
644 IN INTERFACE_TYPE BusType
,
645 IN ULONG SystemIoBusNumber
,
646 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
647 IN ULONG NumberOfBytes
,
648 IN BOOLEAN InIoSpace
);
653 ScsiPortWritePortBufferUchar(
661 ScsiPortWritePortBufferUlong(
669 ScsiPortWritePortBufferUshort(
677 ScsiPortWritePortUchar(
684 ScsiPortWritePortUlong(
691 ScsiPortWritePortUshort(
698 ScsiPortWriteRegisterBufferUchar(
706 ScsiPortWriteRegisterBufferUlong(
714 ScsiPortWriteRegisterBufferUshort(
722 ScsiPortWriteRegisterUchar(
729 ScsiPortWriteRegisterUlong(
736 ScsiPortWriteRegisterUshort(
744 IN ULONG DebugPrintLevel
,
745 IN PCCHAR DebugMessage
,