Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1212 lines
31 KiB

  1. /*++
  2. Copyright (C) 1993-99 Microsoft Corporation
  3. Module Name:
  4. port.h
  5. Abstract:
  6. --*/
  7. #if !defined (___port_h___)
  8. #define ___port_h___
  9. //
  10. // Notification Event Types
  11. //
  12. typedef enum _IDE_NOTIFICATION_TYPE {
  13. IdeRequestComplete,
  14. IdeNextRequest,
  15. IdeNextLuRequest,
  16. IdeResetDetected,
  17. IdeCallDisableInterrupts,
  18. IdeCallEnableInterrupts,
  19. IdeRequestTimerCall,
  20. IdeBusChangeDetected, /* New */
  21. IdeWMIEvent,
  22. IdeWMIReregister,
  23. IdeAllDeviceMissing,
  24. IdeResetRequest
  25. } IDE_NOTIFICATION_TYPE, *PIDE_NOTIFICATION_TYPE;
  26. VOID
  27. IdePortNotification(
  28. IN IDE_NOTIFICATION_TYPE NotificationType,
  29. IN PVOID HwDeviceExtension,
  30. ...
  31. );
  32. struct _SRB_DATA;
  33. #define NUMBER_LOGICAL_UNIT_BINS 8
  34. #define SP_NORMAL_PHYSICAL_BREAK_VALUE 17
  35. #define IDE_NUM_RESERVED_PAGES 4
  36. #ifdef LOG_GET_NEXT_CALLER
  37. #define GET_NEXT_LOG_LENGTH 4
  38. #endif
  39. //
  40. // Define a pointer to the synchonize execution routine.
  41. //
  42. typedef
  43. BOOLEAN
  44. (*PSYNCHRONIZE_ROUTINE) (
  45. IN PKINTERRUPT Interrupt,
  46. IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
  47. IN PVOID SynchronizeContext
  48. );
  49. //
  50. // Adapter object transfer information.
  51. //
  52. typedef struct _ADAPTER_TRANSFER {
  53. struct _SRB_DATA *SrbData;
  54. ULONG SrbFlags;
  55. PVOID LogicalAddress;
  56. ULONG Length;
  57. }ADAPTER_TRANSFER, *PADAPTER_TRANSFER;
  58. //
  59. // Port driver error logging
  60. //
  61. typedef struct _ERROR_LOG_ENTRY {
  62. UCHAR MajorFunctionCode;
  63. UCHAR PathId;
  64. UCHAR TargetId;
  65. UCHAR Lun;
  66. ULONG ErrorCode;
  67. ULONG UniqueId;
  68. ULONG ErrorLogRetryCount;
  69. ULONG SequenceNumber;
  70. } ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY;
  71. //
  72. // SCSI request extension for port driver.
  73. //
  74. typedef struct _SRB_DATA {
  75. LIST_ENTRY RequestList;
  76. PSCSI_REQUEST_BLOCK CurrentSrb;
  77. struct _SRB_DATA *CompletedRequests;
  78. ULONG ErrorLogRetryCount;
  79. ULONG SequenceNumber;
  80. PCHAR SrbDataOffset;
  81. #ifdef ENABLE_COMMAND_LOG
  82. PCOMMAND_LOG IdeCommandLog;
  83. ULONG IdeCommandLogIndex;
  84. #endif
  85. ULONG Flags;
  86. }SRB_DATA, *PSRB_DATA;
  87. #define SRB_DATA_RESERVED_PAGES 0x100
  88. //
  89. // Define data storage for access at interrupt Irql.
  90. //
  91. typedef struct _PDO_EXTENSION * PPDO_EXTENSION;
  92. typedef PPDO_EXTENSION PLOGICAL_UNIT_EXTENSION;
  93. typedef struct _INTERRUPT_DATA {
  94. //
  95. // SCSI port interrupt flags
  96. //
  97. ULONG InterruptFlags;
  98. //
  99. // List head for singlely linked list of complete IRPs.
  100. //
  101. PSRB_DATA CompletedRequests;
  102. //
  103. // Adapter object transfer parameters.
  104. //
  105. ADAPTER_TRANSFER MapTransferParameters;
  106. //
  107. // Error log information.
  108. //
  109. ERROR_LOG_ENTRY LogEntry;
  110. //
  111. // Logical unit to start next.
  112. //
  113. PLOGICAL_UNIT_EXTENSION ReadyLogicalUnit;
  114. //
  115. // List of completed abort reqeusts.
  116. //
  117. PLOGICAL_UNIT_EXTENSION CompletedAbort;
  118. //
  119. // Miniport timer request routine.
  120. //
  121. PHW_INTERRUPT HwTimerRequest;
  122. //
  123. // Mini port timer request time in micro seconds.
  124. //
  125. ULONG MiniportTimerValue;
  126. //
  127. // The PDO that causes a bus reset
  128. //
  129. PPDO_EXTENSION PdoExtensionResetBus;
  130. } INTERRUPT_DATA, *PINTERRUPT_DATA;
  131. //
  132. // ACPI Firmware Settings
  133. //
  134. typedef struct _DEVICE_SETTINGS {
  135. ULONG NumEntries;
  136. IDEREGS FirmwareSettings[0];
  137. } DEVICE_SETTINGS, *PDEVICE_SETTINGS;
  138. //
  139. // Fdo Power Context (pre-alloced)
  140. //
  141. typedef struct _FDO_POWER_CONTEXT {
  142. BOOLEAN TimingRestored;
  143. PIRP OriginalPowerIrp;
  144. POWER_STATE_TYPE newPowerType;
  145. POWER_STATE newPowerState;
  146. } FDO_POWER_CONTEXT, *PFDO_POWER_CONTEXT;
  147. typedef enum _IDE_DEBUG_EVENT{
  148. CrcEvent =0,
  149. BusyEvent,
  150. RwEvent,
  151. MaxIdeEvent
  152. }IDE_DEBUG_EVENT;
  153. typedef struct _LAST_REQUEST {
  154. SCSI_REQUEST_BLOCK Srb;
  155. } LAST_REQUEST, *PLAST_REQUEST;
  156. typedef struct _PDO_EXTENSION * PPDO_EXTENSION;
  157. typedef struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION;
  158. typedef struct _CONTROLLER_PARAMETERS * PCONTROLLER_PARAMETERS;
  159. typedef struct _IDE_REGISTERS_1 *PIDE_REGISTERS_1;
  160. typedef struct _IDE_REGISTERS_2 *PIDE_REGISTERS_2;
  161. typedef struct _ENUMERATION_STRUCT *PENUMERATION_STRUCT;
  162. //
  163. // Device extension
  164. //
  165. typedef struct _FDO_EXTENSION {
  166. EXTENSION_COMMON_HEADER;
  167. PCM_RESOURCE_LIST ResourceList;
  168. IDE_RESOURCE IdeResource;
  169. PCIIDE_SYNC_ACCESS_INTERFACE SyncAccessInterface;
  170. PCIIDE_XFER_MODE_INTERFACE TransferModeInterface;
  171. PCIIDE_REQUEST_PROPER_RESOURCES RequestProperResourceInterface;
  172. //
  173. // Device extension for miniport routines.
  174. //
  175. PHW_DEVICE_EXTENSION HwDeviceExtension;
  176. //
  177. // We are a child of a busmaster parent
  178. //
  179. BOOLEAN BoundWithBmParent;
  180. BOOLEAN SymbolicLinkCreated;
  181. ULONG IdePortNumber; // offset 0x0C
  182. ULONG ScsiPortNumber; // offset 0x0C
  183. //
  184. // Active requests count. This count is biased by -1 so a value of -1
  185. // indicates there are no requests out standing.
  186. //
  187. //LONG ActiveRequestCount; // offset 0x10
  188. //
  189. // SCSI port driver flags
  190. //
  191. ULONG Flags; // offset 0x14
  192. ULONG FdoState;
  193. //
  194. // Srb flags to OR into all SRB.
  195. //
  196. ULONG SrbFlags; // offset 0x18
  197. LONG PortTimeoutCounter; // offset 0x1C
  198. ULONG ResetCallAgain;
  199. PSCSI_REQUEST_BLOCK ResetSrb;
  200. //
  201. // Number of SCSI buses
  202. //
  203. UCHAR MaxLuCount; // offset 0x22
  204. PKINTERRUPT InterruptObject; // offset 0x24
  205. //
  206. // Global device sequence number.
  207. //
  208. ULONG SequenceNumber; // offset 0x30
  209. KSPIN_LOCK SpinLock; // offset 0x34
  210. PADAPTER_OBJECT DmaAdapterObject;
  211. ADAPTER_TRANSFER FlushAdapterParameters;
  212. //
  213. // Pointer to the per SRB data array.
  214. //
  215. //PSRB_DATA SrbData;
  216. //
  217. // Pointer to the per SRB free list.
  218. //
  219. //PSRB_DATA FreeSrbData;
  220. //
  221. // Miniport service routine pointers.
  222. //
  223. PHW_INTERRUPT HwTimerRequest;
  224. //
  225. // Spinlock that protects LogicalUnitList manipulation
  226. //
  227. KSPIN_LOCK LogicalUnitListSpinLock;
  228. //
  229. // Number of logical unit in LogicalUnitList[]
  230. // Protected by LogicalUnitListSpinLock
  231. //
  232. UCHAR NumberOfLogicalUnits;
  233. //
  234. //
  235. //
  236. CCHAR NumberOfLogicalUnitsPowerUp;
  237. BOOLEAN DeviceChanged;
  238. //
  239. // panasonic pcmcia ide controller
  240. //
  241. BOOLEAN panasonicController;
  242. //
  243. // non-pcmcia controller, this is always set
  244. // if pcmcia controller, it is not set unless
  245. // registry flag PCMCIA_IDE_CONTROLLER_HAS_SLAVE
  246. // is non-zero
  247. //
  248. ULONG MayHaveSlaveDevice;
  249. //
  250. // Array of logical unit extensions.
  251. // Protected by LogicalUnitListSpinLock
  252. //
  253. PLOGICAL_UNIT_EXTENSION LogicalUnitList[NUMBER_LOGICAL_UNIT_BINS];
  254. //
  255. // Interrupt level data storage.
  256. //
  257. INTERRUPT_DATA InterruptData;
  258. //
  259. // SCSI Capabilities structure
  260. //
  261. IO_SCSI_CAPABILITIES Capabilities;
  262. //
  263. // Miniport timer object.
  264. //
  265. KTIMER MiniPortTimer;
  266. //
  267. // Miniport DPC for timer object.
  268. //
  269. KDPC MiniPortTimerDpc;
  270. //
  271. // channel timing from ACPI/BIOS
  272. //
  273. ACPI_IDE_TIMING BootAcpiTimingSettings;
  274. ACPI_IDE_TIMING AcpiTimingSettings;
  275. //
  276. // Transfermode cycle time
  277. //
  278. PULONG DefaultTransferModeTimingTable;
  279. //
  280. // User choice
  281. //
  282. IDE_DEVICETYPE UserChoiceDeviceType[MAX_IDE_DEVICE * MAX_IDE_LINE];
  283. ULONG UserChoiceTransferMode[MAX_IDE_DEVICE * MAX_IDE_LINE];
  284. ULONG UserChoiceTransferModeForAtapiDevice[MAX_IDE_DEVICE * MAX_IDE_LINE];
  285. ULONG TimingModeAllowed[MAX_IDE_DEVICE * MAX_IDE_LINE];
  286. //
  287. // Use aggressive DMA
  288. //
  289. DMADETECTIONLEVEL DmaDetectionLevel;
  290. //
  291. // Pre-alloced context structure for power routines
  292. //
  293. FDO_POWER_CONTEXT FdoPowerContext[2];
  294. #if DBG
  295. //
  296. // Locks to synchronize access to the pre-alloced power context
  297. //
  298. ULONG PowerContextLock[2];
  299. #endif
  300. #ifdef IDE_MEASURE_BUSSCAN_SPEED
  301. //
  302. // keep track of the time spent on the first busscan
  303. //
  304. ULONG BusScanTime;
  305. #endif
  306. //
  307. // Pre-alloced structs used during enumeration
  308. //
  309. #if DBG
  310. ULONG EnumStructLock;
  311. #endif
  312. PENUMERATION_STRUCT PreAllocEnumStruct;
  313. //
  314. // Reserved error log entry per device to be used to log
  315. // insufficient resources error
  316. //
  317. PVOID ReserveAllocFailureLogEntry[MAX_IDE_DEVICE];
  318. //
  319. // Temporary: Should be removed once I check in the fix
  320. // for low memory condition
  321. //
  322. ULONG NumMemoryFailure;
  323. ULONG LastMemoryFailure;
  324. //
  325. // Reserve pages for use during low memory conditions
  326. //
  327. PVOID ReservedPages;
  328. #ifdef ENABLE_NATIVE_MODE
  329. //
  330. // Parent's interrupt interface
  331. //
  332. PCIIDE_INTERRUPT_INTERFACE InterruptInterface;
  333. #endif
  334. #ifdef ENABLE_48BIT_LBA
  335. ULONG EnableBigLba;
  336. #endif
  337. ULONG WaitOnPowerUp;
  338. #ifdef LOG_GET_NEXT_CALLER
  339. ULONG GetNextLuIndex;
  340. ULONG GetNextLuCallerLineNumber[GET_NEXT_LOG_LENGTH];
  341. ULONG GetNextLuCallerFlags[GET_NEXT_LOG_LENGTH];
  342. UCHAR GetNextLuCallerFileName[GET_NEXT_LOG_LENGTH][256];
  343. ULONG CompletedCommandIndex;
  344. LAST_REQUEST CompletedCommandQueue[GET_NEXT_LOG_LENGTH];
  345. #endif
  346. #ifdef ENABLE_ATAPI_VERIFIER
  347. ULONG IdeVerifierFlags[MAX_IDE_DEVICE];
  348. ULONG IdeDebugVerifierFlags[MAX_IDE_DEVICE];
  349. ULONG IdeInternalVerifierFlags[MAX_IDE_DEVICE];
  350. ULONG IdeVerifierEventCount[MAX_IDE_DEVICE][MaxIdeEvent];
  351. ULONG IdeVerifierEventFrequency[MAX_IDE_DEVICE][MaxIdeEvent];
  352. #endif
  353. //
  354. // List link for FDO list.
  355. //
  356. LIST_ENTRY NextFdoLink;
  357. } FDO_EXTENSION, *PFDO_EXTENSION;
  358. typedef struct _CONFIGURATION_CONTEXT {
  359. HANDLE BusKey;
  360. HANDLE ServiceKey;
  361. HANDLE DeviceKey;
  362. ULONG AdapterNumber;
  363. ULONG LastAdapterNumber;
  364. ULONG BusNumber;
  365. PVOID Parameter;
  366. PACCESS_RANGE AccessRanges;
  367. BOOLEAN DisableTaggedQueueing;
  368. BOOLEAN DisableMultipleLu;
  369. }CONFIGURATION_CONTEXT, *PCONFIGURATION_CONTEXT;
  370. typedef struct _INTERRUPT_CONTEXT {
  371. PFDO_EXTENSION DeviceExtension;
  372. PINTERRUPT_DATA SavedInterruptData;
  373. }INTERRUPT_CONTEXT, *PINTERRUPT_CONTEXT;
  374. typedef struct _RESET_CONTEXT {
  375. PFDO_EXTENSION DeviceExtension;
  376. UCHAR PathId;
  377. BOOLEAN NewResetSequence;
  378. PSCSI_REQUEST_BLOCK ResetSrb;
  379. }RESET_CONTEXT, *PRESET_CONTEXT;
  380. #define NEED_REQUEST_SENSE(Srb) (Srb->ScsiStatus == SCSISTAT_CHECK_CONDITION \
  381. && !(Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) && \
  382. Srb->SenseInfoBuffer && Srb->SenseInfoBufferLength )
  383. #define LONG_ALIGN (sizeof(LONG) - 1)
  384. #define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION)
  385. //
  386. // Port driver extension flags.
  387. //
  388. //
  389. // This flag indicates that a request has been passed to the miniport and the
  390. // miniport has not indicated it is ready for another request. It is set by
  391. // IdeStartIoSynchronized. It is cleared by IdePortCompletionDpc when the
  392. // miniport asks for another request. Note the port driver will defer giving
  393. // the miniport driver a new request if the current request disabled disconnects.
  394. //
  395. #define PD_DEVICE_IS_BUSY 0X00001
  396. //
  397. // Indicates that IdePortCompletionDpc needs to be run. This is set when
  398. // A miniport makes a request which must be done at DPC and is cleared when
  399. // when the request information is gotten by IdeGetInterruptState.
  400. //
  401. #define PD_NOTIFICATION_REQUIRED 0X00004
  402. //
  403. // Indicates the miniport is ready for another request. Set by
  404. // ScsiPortNotification and cleared by IdeGetInterruptState. This flag is
  405. // stored in the interrupt data structure.
  406. //
  407. #define PD_READY_FOR_NEXT_REQUEST 0X00008
  408. //
  409. // Indicates the miniport wants the adapter channel flushed. Set by
  410. // IdePortFlushDma and cleared by IdeGetInterruptState. This flag is
  411. // stored in the data interrupt structure. The flush adapter parameters
  412. // are saved in the device object.
  413. //
  414. #define PD_FLUSH_ADAPTER_BUFFERS 0X00010
  415. //
  416. // Indicates the miniport wants the adapter channel programmed. Set by
  417. // IdePortIoMapTransfer and cleared by IdeGetInterruptState or
  418. // IdePortFlushDma. This flag is stored in the interrupt data structure.
  419. // The I/O map transfer parameters are saved in the interrupt data structure.
  420. //
  421. #define PD_MAP_TRANSFER 0X00020
  422. //
  423. // Indicates the miniport wants to log an error. Set by
  424. // IdePortLogError and cleared by IdeGetInterruptState. This flag is
  425. // stored in the interrupt data structure. The error log parameters
  426. // are saved in the interrupt data structure. Note at most one error per DPC
  427. // can be logged.
  428. //
  429. #define PD_LOG_ERROR 0X00040
  430. //
  431. // Indicates that no request should be sent to the miniport after
  432. // a bus reset. Set when the miniport reports a reset or the port driver
  433. // resets the bus. It is cleared by IdeTimeoutSynchronized. The
  434. // PortTimeoutCounter is used to time the length of the reset hold. This flag
  435. // is stored in the interrupt data structure.
  436. //
  437. #define PD_RESET_HOLD 0X00080
  438. //
  439. // Indicates a request was stopped due to a reset hold. The held request is
  440. // stored in the current request of the device object. This flag is set by
  441. // IdeStartIoSynchronized and cleared by IdeTimeoutSynchronized which also
  442. // starts the held request when the reset hold has ended. This flag is stored
  443. // in the interrupt data structure.
  444. //
  445. #define PD_HELD_REQUEST 0X00100
  446. //
  447. // Indicates the miniport has reported a bus reset. Set by
  448. // IdePortNotification and cleared by IdeGetInterruptState. This flag is
  449. // stored in the interrupt data structure.
  450. //
  451. #define PD_RESET_REPORTED 0X00200
  452. //
  453. // Indicates there is a pending request for which resources
  454. // could not be allocated. This flag is set by IdeAllocateRequestStructures
  455. // which is called from IdePortStartIo. It is cleared by
  456. // IdeProcessCompletedRequest when a request completes which then calls
  457. // IdePortStartIo to try the request again.
  458. //
  459. #define PD_PENDING_DEVICE_REQUEST 0X00800
  460. //
  461. // This flag indicates that there are currently no requests executing with
  462. // disconnects disabled. This flag is normally on. It is cleared by
  463. // IdeStartIoSynchronized when a request with disconnect disabled is started
  464. // and is set when that request completes. IdeProcessCompletedRequest will
  465. // start the next request for the miniport if PD_DEVICE_IS_BUSY is clear.
  466. //
  467. #define PD_DISCONNECT_RUNNING 0X01000
  468. //
  469. // Indicates the miniport wants the system interrupts disabled. Set by
  470. // IdePortNofitication and cleared by IdePortCompletionDpc. This flag is
  471. // NOT stored in the interrupt data structure. The parameters are stored in
  472. // the device extension.
  473. //
  474. #define PD_DISABLE_CALL_REQUEST 0X02000
  475. //
  476. // Indicates that system interrupts have been enabled and that the miniport
  477. // has disabled its adapter from interruptint. The miniport's interrupt
  478. // routine is not called while this flag is set. This flag is set by
  479. // IdePortNotification when a CallEnableInterrupts request is made and
  480. // cleared by IdeEnableInterruptSynchronized when the miniport requests that
  481. // system interrupts be disabled. This flag is stored in the interrupt data
  482. // structure.
  483. //
  484. #define PD_DISABLE_INTERRUPTS 0X04000
  485. //
  486. // Indicates the miniport wants the system interrupt enabled. Set by
  487. // IdePortNotification and cleared by IdeGetInterruptState. This flag is
  488. // stored in the interrupt data structure. The call enable interrupts
  489. // parameters are saved in the device extension.
  490. //
  491. #define PD_ENABLE_CALL_REQUEST 0X08000
  492. //
  493. // Indicates the miniport is wants a timer request. Set by
  494. // IdePortNotification and cleared by IdeGetInterruptState. This flag is
  495. // stored in the interrupt data structure. The timer request parameters are
  496. // stored in the interrupt data structure.
  497. //
  498. #define PD_TIMER_CALL_REQUEST 0X10000
  499. //
  500. // channel looks empty
  501. //
  502. #define PD_ALL_DEVICE_MISSING 0X20000
  503. //
  504. // Request a reset
  505. //
  506. #define PD_RESET_REQUEST 0x40000
  507. //
  508. // Reserve pages are being used by another request
  509. //
  510. #define PD_RESERVED_PAGES_IN_USE 0x80000
  511. //
  512. // The following flags should not be cleared from the interrupt data structure
  513. // by IdeGetInterruptState.
  514. //
  515. #define PD_INTERRUPT_FLAG_MASK (PD_RESET_HOLD | PD_HELD_REQUEST | PD_DISABLE_INTERRUPTS)
  516. //
  517. // Logical unit extension flags.
  518. //
  519. //
  520. // Indicates the logical unit queue is frozen. Set by
  521. // IdeProcessCompletedRequest when an error occurs and is cleared by the class
  522. // driver.
  523. //
  524. #define PD_QUEUE_FROZEN 0X0001
  525. //
  526. // Indicates that the miniport has an active request for this logical unit.
  527. // Set by IdeStartIoSynchronized when the request is started and cleared by
  528. // GetNextLuRequest. This flag is used to track when it is ok to start another
  529. // request from the logical unit queue for this device.
  530. //
  531. #define PD_LOGICAL_UNIT_IS_ACTIVE 0X0002
  532. //
  533. // Indicates that a request for this logical unit has failed and a REQUEST
  534. // SENSE command needs to be done. This flag prevents other requests from
  535. // being started until an untagged, by-pass queue command is started. This
  536. // flag is cleared in IdeStartIoSynchronized. It is set by
  537. // IdeGetInterruptState.
  538. //
  539. #define PD_NEED_REQUEST_SENSE 0X0004
  540. //
  541. // Indicates that a request for this logical unit has completed with a status
  542. // of BUSY or QUEUE FULL. This flag is set by IdeProcessCompletedRequest and
  543. // the busy request is saved in the logical unit structure. This flag is
  544. // cleared by IdePortTickHandler which also restarts the request. Busy
  545. // request may also be requeued to the logical unit queue if an error occurs
  546. // on the device (This will only occur with command queueing.). Not busy
  547. // requests are nasty because they are restarted asynchronously by
  548. // IdePortTickHandler rather than GetNextLuRequest. This makes error recovery
  549. // more complex.
  550. //
  551. #define PD_LOGICAL_UNIT_IS_BUSY 0X0008
  552. //
  553. // This flag indicates a queue full has been returned by the device. It is
  554. // similar to PD_LOGICAL_UNIT_IS_BUSY but is set in IdeGetInterruptState when
  555. // a QUEUE FULL status is returned. This flag is used to prevent other
  556. // requests from being started for the logical unit before
  557. // IdeProcessCompletedRequest has a chance to set the busy flag.
  558. //
  559. #define PD_QUEUE_IS_FULL 0X0010
  560. //
  561. // Indicates that there is a request for this logical unit which cannot be
  562. // executed for now. This flag is set by IdeAllocateRequestStructures. It is
  563. // cleared by GetNextLuRequest when it detects that the pending request
  564. // can now be executed. The pending request is stored in the logical unit
  565. // structure. A new single non-queued reqeust cannot be executed on a logical
  566. // that is currently executing queued requests. Non-queued requests must wait
  567. // unit for all queued requests to complete. A non-queued requests is one
  568. // which is not tagged and does not have SRB_FLAGS_NO_QUEUE_FREEZE set.
  569. // Normally only read and write commands can be queued.
  570. //
  571. //#define PD_LOGICAL_UNIT_MUST_SLEEP 0X0020
  572. //#define PD_LOGICAL_UNIT_STOP_READY 0X0040
  573. //#define PD_LOGICAL_UNIT_REMOVE_READY 0X0080
  574. //#define PD_LOGICAL_UNIT_ALWAYS_QUEUE (PD_LOGICAL_UNIT_STOP_READY | PD_LOGICAL_UNIT_REMOVE_READY)
  575. //#define PD_LOGICAL_UNIT_POWER_OK 0X0100
  576. //#define PD_LOGICAL_IN_PAGING_PATH 0X2000
  577. //#define PD_LOGICAL_UNIT_LEGACY_ATTACHER 0X4000
  578. //
  579. // Indicates that the LogicalUnit has been allocated for a rescan request.
  580. // This flag prevents IOCTL_SCSI_MINIPORT requests from attaching to this
  581. // logical unit, since the possibility exists that it could be freed before
  582. // the IOCTL request is complete.
  583. //
  584. #define PD_RESCAN_ACTIVE 0x8000
  585. //
  586. // FdoExtension FdoState
  587. //
  588. #define FDOS_DEADMEAT (1 << 0)
  589. #define FDOS_STARTED (1 << 1)
  590. #define FDOS_STOPPED (1 << 2)
  591. //
  592. // Port Timeout Counter values.
  593. //
  594. #define PD_TIMER_STOPPED -1
  595. #define PD_TIMER_RESET_HOLD_TIME 1
  596. //
  597. // Define the mimimum and maximum number of srb extensions which will be allocated.
  598. //
  599. #define MINIMUM_SRB_EXTENSIONS 16
  600. #define MAXIMUM_SRB_EXTENSIONS 512
  601. //
  602. // Size of the buffer used for registry operations.
  603. //
  604. #define SP_REG_BUFFER_SIZE 512
  605. //
  606. // Number of times to retry when a BUSY status is returned.
  607. //
  608. #define BUSY_RETRY_COUNT 20
  609. //
  610. // Number of times to retry an INQUIRY request.
  611. //
  612. #define INQUIRY_RETRY_COUNT 2
  613. //
  614. // Function declarations
  615. //
  616. IO_ALLOCATION_ACTION
  617. CallIdeStartIoSynchronized (
  618. IN PVOID Reserved1,
  619. IN PVOID Reserved2,
  620. IN PVOID Reserved3,
  621. IN PVOID DeviceObject
  622. );
  623. NTSTATUS
  624. IdePortCreateClose (
  625. IN PDEVICE_OBJECT DeviceObject,
  626. IN PIRP Irp
  627. );
  628. NTSTATUS
  629. IdePortDispatch(
  630. IN PDEVICE_OBJECT DeviceObject,
  631. IN PIRP Irp
  632. );
  633. VOID
  634. IdePortAllocateAccessToken (
  635. IN PDEVICE_OBJECT DeviceObject
  636. );
  637. VOID
  638. IdePortStartIo(
  639. IN PDEVICE_OBJECT DeviceObject,
  640. IN PIRP Irp
  641. );
  642. BOOLEAN
  643. IdePortInterrupt(
  644. IN PKINTERRUPT InterruptObject,
  645. IN PDEVICE_OBJECT DeviceObject
  646. );
  647. VOID
  648. IdePortCompletionDpc(
  649. IN PKDPC Dpc,
  650. IN PDEVICE_OBJECT DeviceObject,
  651. IN PIRP Irp,
  652. IN PVOID Context
  653. );
  654. NTSTATUS
  655. IdePortDeviceControl(
  656. IN PDEVICE_OBJECT DeviceObject,
  657. IN PIRP Irp
  658. );
  659. VOID
  660. IdePortTickHandler(
  661. IN PDEVICE_OBJECT DeviceObject,
  662. IN PVOID Context
  663. );
  664. BOOLEAN
  665. AtapiRestartBusyRequest (
  666. PFDO_EXTENSION DeviceExtension,
  667. PPDO_EXTENSION LogicalUnit
  668. );
  669. VOID
  670. IssueRequestSense(
  671. IN PPDO_EXTENSION PdoExtension,
  672. IN PSCSI_REQUEST_BLOCK FailingSrb
  673. );
  674. VOID
  675. IdePortLogError(
  676. IN PVOID HwDeviceExtension,
  677. IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
  678. IN UCHAR PathId,
  679. IN UCHAR TargetId,
  680. IN UCHAR Lun,
  681. IN ULONG ErrorCode,
  682. IN ULONG UniqueId
  683. );
  684. NTSTATUS
  685. IdePortInternalCompletion(
  686. PDEVICE_OBJECT DeviceObject,
  687. PIRP Irp,
  688. PVOID Context
  689. );
  690. BOOLEAN
  691. IdeStartIoSynchronized (
  692. PVOID ServiceContext
  693. );
  694. BOOLEAN
  695. IdeResetBusSynchronized (
  696. PVOID ServiceContext
  697. );
  698. BOOLEAN
  699. IdeTimeoutSynchronized (
  700. PVOID ServiceContext
  701. );
  702. VOID
  703. IssueAbortRequest(
  704. IN PFDO_EXTENSION DeviceExtension,
  705. IN PLOGICAL_UNIT_EXTENSION LogicalUnit
  706. );
  707. BOOLEAN
  708. IdeGetInterruptState(
  709. IN PVOID ServiceContext
  710. );
  711. VOID
  712. LogErrorEntry(
  713. IN PFDO_EXTENSION DeviceExtension,
  714. IN PERROR_LOG_ENTRY LogEntry
  715. );
  716. VOID
  717. GetNextLuPendingRequest(
  718. IN PFDO_EXTENSION DeviceExtension,
  719. IN PLOGICAL_UNIT_EXTENSION LogicalUnit
  720. );
  721. #ifdef LOG_GET_NEXT_CALLER
  722. #define GetNextLuRequest(x, y) GetNextLuRequest2(x, y, __FILE__, __LINE__)
  723. VOID
  724. GetNextLuRequest2(
  725. IN PFDO_EXTENSION DeviceExtension,
  726. IN PLOGICAL_UNIT_EXTENSION LogicalUnit,
  727. IN PUCHAR FileName,
  728. IN ULONG LineNumber
  729. );
  730. #else
  731. VOID
  732. GetNextLuRequest(
  733. IN PFDO_EXTENSION DeviceExtension,
  734. IN PLOGICAL_UNIT_EXTENSION LogicalUnit
  735. );
  736. #endif
  737. VOID
  738. IdeLogTimeoutError(
  739. IN PFDO_EXTENSION DeviceExtension,
  740. IN PIRP Irp,
  741. IN ULONG UniqueId
  742. );
  743. NTSTATUS
  744. IdeTranslateSrbStatus(
  745. IN PSCSI_REQUEST_BLOCK Srb
  746. );
  747. VOID
  748. IdeProcessCompletedRequest(
  749. IN PFDO_EXTENSION DeviceExtension,
  750. IN PSRB_DATA SrbData,
  751. OUT PBOOLEAN CallStartIo
  752. );
  753. PSRB_DATA
  754. IdeGetSrbData(
  755. IN PFDO_EXTENSION DeviceExtension,
  756. IN PSCSI_REQUEST_BLOCK Srb
  757. );
  758. VOID
  759. IdeCompleteRequest(
  760. IN PFDO_EXTENSION DeviceExtension,
  761. IN PSRB_DATA SrbData,
  762. IN UCHAR SrbStatus
  763. );
  764. NTSTATUS
  765. IdeSendMiniPortIoctl(
  766. IN PFDO_EXTENSION DeviceExtension,
  767. IN PIRP RequestIrp
  768. );
  769. NTSTATUS
  770. IdeGetInquiryData(
  771. IN PFDO_EXTENSION DeviceExtension,
  772. IN PIRP Irp
  773. );
  774. NTSTATUS
  775. IdeSendPassThrough(
  776. IN PFDO_EXTENSION DeviceExtension,
  777. IN PIRP Irp
  778. );
  779. #if defined (_WIN64)
  780. NTSTATUS
  781. IdeTranslatePassThrough32To64(
  782. IN PSCSI_PASS_THROUGH32 SrbControl32,
  783. IN OUT PSCSI_PASS_THROUGH SrbControl64
  784. );
  785. VOID
  786. IdeTranslatePassThrough64To32(
  787. IN PSCSI_PASS_THROUGH SrbControl64,
  788. IN OUT PSCSI_PASS_THROUGH32 SrbControl32
  789. );
  790. #endif
  791. NTSTATUS
  792. IdeClaimLogicalUnit(
  793. IN PFDO_EXTENSION DeviceExtension,
  794. IN PIRP Irp
  795. );
  796. VOID
  797. IdeMiniPortTimerDpc(
  798. IN struct _KDPC *Dpc,
  799. IN PVOID DeviceObject,
  800. IN PVOID SystemArgument1,
  801. IN PVOID SystemArgument2
  802. );
  803. BOOLEAN
  804. IdeSynchronizeExecution (
  805. IN PKINTERRUPT Interrupt,
  806. IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
  807. IN PVOID SynchronizeContext
  808. );
  809. NTSTATUS
  810. IdeGetCommonBuffer(
  811. PFDO_EXTENSION DeviceExtension,
  812. ULONG NonCachedExtensionSize
  813. );
  814. VOID
  815. IdeDeviceCleanup(
  816. PFDO_EXTENSION DeviceExtension
  817. );
  818. NTSTATUS
  819. IdeInitializeConfiguration(
  820. IN PFDO_EXTENSION DeviceExtension,
  821. IN PCONFIGURATION_CONTEXT Context
  822. );
  823. #define IDEPORT_PUT_LUNEXT_IN_IRP(IrpStack, LogUnitExt) (IrpStack->Parameters.Others.Argument4 = LogUnitExt)
  824. #define IDEPORT_GET_LUNEXT_IN_IRP(IrpStack) ((PLOGICAL_UNIT_EXTENSION) (IrpStack->Parameters.Others.Argument4))
  825. VOID
  826. IdePortCompleteRequest(
  827. IN PVOID HwDeviceExtension,
  828. IN PSCSI_REQUEST_BLOCK Srb,
  829. IN UCHAR SrbStatus
  830. );
  831. NTSTATUS
  832. IdePortFlushLogicalUnit (
  833. PFDO_EXTENSION FdoExtension,
  834. PLOGICAL_UNIT_EXTENSION LogUnitExtension,
  835. BOOLEAN Forced
  836. );
  837. typedef VOID (*ASYNC_PASS_THROUGH_COMPLETION) (
  838. IN PDEVICE_OBJECT DeviceObject,
  839. PVOID Context,
  840. NTSTATUS Status
  841. );
  842. NTSTATUS
  843. IssueAsyncAtaPassThroughSafe (
  844. IN PFDO_EXTENSION DeviceExtension,
  845. IN PLOGICAL_UNIT_EXTENSION LogUnitExtension,
  846. IN OUT PATA_PASS_THROUGH AtaPassThroughData,
  847. IN BOOLEAN DataIn,
  848. IN ASYNC_PASS_THROUGH_COMPLETION Completion,
  849. IN PVOID Context,
  850. IN BOOLEAN PowerRelated,
  851. IN ULONG TimeOut,
  852. IN BOOLEAN MustSucceed
  853. );
  854. typedef struct _ATA_PASSTHROUGH_CONTEXT {
  855. PDEVICE_OBJECT DeviceObject;
  856. ASYNC_PASS_THROUGH_COMPLETION CallerCompletion;
  857. PVOID CallerContext;
  858. PSCSI_REQUEST_BLOCK Srb;
  859. PSENSE_DATA SenseInfoBuffer;
  860. BOOLEAN MustSucceed;
  861. PATA_PASS_THROUGH DataBuffer;
  862. } ATA_PASSTHROUGH_CONTEXT, *PATA_PASSTHROUGH_CONTEXT;
  863. NTSTATUS
  864. AtaPassThroughCompletionRoutine(
  865. PDEVICE_OBJECT DeviceObject,
  866. PIRP Irp,
  867. PVOID Context
  868. );
  869. typedef struct _SYNC_ATA_PASSTHROUGH_CONTEXT {
  870. KEVENT Event;
  871. NTSTATUS Status;
  872. } SYNC_ATA_PASSTHROUGH_CONTEXT, *PSYNC_ATA_PASSTHROUGH_CONTEXT;
  873. typedef struct _FLUSH_ATA_PASSTHROUGH_CONTEXT {
  874. PIRP FlushIrp;
  875. PATA_PASS_THROUGH ataPassThroughData;
  876. } FLUSH_ATA_PASSTHROUGH_CONTEXT, *PFLUSH_ATA_PASSTHROUGH_CONTEXT;
  877. NTSTATUS
  878. IssueSyncAtaPassThroughSafe (
  879. IN PFDO_EXTENSION DeviceExtension,
  880. IN PLOGICAL_UNIT_EXTENSION LogUnitExtension,
  881. IN OUT PATA_PASS_THROUGH AtaPassThroughData,
  882. IN BOOLEAN DataIn,
  883. IN BOOLEAN PowerRelated,
  884. IN ULONG TimeOut,
  885. IN BOOLEAN MustSucceed
  886. );
  887. VOID
  888. SyncAtaPassThroughCompletionRoutine (
  889. IN PDEVICE_OBJECT DeviceObject,
  890. IN PVOID Context,
  891. IN NTSTATUS Status
  892. );
  893. VOID
  894. IdeUnmapReservedMapping (
  895. IN PFDO_EXTENSION DeviceExtension,
  896. IN PSRB_DATA SrbData,
  897. IN PMDL Mdl
  898. );
  899. PVOID
  900. IdeMapLockedPagesWithReservedMapping (
  901. IN PFDO_EXTENSION DeviceExtension,
  902. IN PSRB_DATA SrbData,
  903. IN PMDL Mdl
  904. );
  905. BOOLEAN
  906. TestForEnumProbing (
  907. IN PSCSI_REQUEST_BLOCK Srb
  908. );
  909. #define DEFAULT_ATA_PASS_THROUGH_TIMEOUT 15
  910. #define INIT_IDE_SRB_FLAGS(Srb) (Srb->SrbExtension = NULL)
  911. #define SANITY_CHECK_SRB(Srb) {ASSERT(!(((ULONG_PTR)Srb->SrbExtension) & ~7));}
  912. #define MARK_SRB_AS_PIO_CANDIDATE(Srb) {SANITY_CHECK_SRB(Srb); ((ULONG_PTR)Srb->SrbExtension) |= 1;}
  913. #define MARK_SRB_AS_DMA_CANDIDATE(Srb) {SANITY_CHECK_SRB(Srb); ((ULONG_PTR)Srb->SrbExtension) &= ~1;}
  914. #define MARK_SRB_FOR_DMA(Srb) {SANITY_CHECK_SRB(Srb); ((ULONG_PTR)Srb->SrbExtension) |= 2;}
  915. #define MARK_SRB_FOR_PIO(Srb) {SANITY_CHECK_SRB(Srb); ((ULONG_PTR)Srb->SrbExtension) &= ~2;}
  916. #define SRB_IS_DMA_CANDIDATE(Srb) (!(((ULONG_PTR)Srb->SrbExtension) & 1))
  917. #define SRB_USES_DMA(Srb) (((ULONG_PTR)Srb->SrbExtension) & 2)
  918. #define TEST_AND_SET_SRB_FOR_RDP(ScsiDeviceType, Srb) \
  919. if ((ScsiDeviceType == SEQUENTIAL_ACCESS_DEVICE) &&\
  920. ((Srb->Cdb[0] == SCSIOP_ERASE) || (Srb->Cdb[0] == SCSIOP_LOAD_UNLOAD)||\
  921. (Srb->Cdb[0] == SCSIOP_LOCATE) || (Srb->Cdb[0] == SCSIOP_REWIND) ||\
  922. (Srb->Cdb[0] == SCSIOP_SPACE) || (Srb->Cdb[0] == SCSIOP_SEEK)||\
  923. (Srb->Cdb[0] == SCSIOP_WRITE_FILEMARKS))) {\
  924. SANITY_CHECK_SRB(Srb);\
  925. ((ULONG_PTR)Srb->SrbExtension) |= 4;\
  926. } else if ((ScsiDeviceType == READ_ONLY_DIRECT_ACCESS_DEVICE) && \
  927. (Srb->Cdb[0]==SCSIOP_SEEK) ) {\
  928. SANITY_CHECK_SRB(Srb);\
  929. ((ULONG_PTR)Srb->SrbExtension) |= 4;\
  930. } else {\
  931. SANITY_CHECK_SRB(Srb);\
  932. ((ULONG_PTR)Srb->SrbExtension) &= ~4;\
  933. }
  934. #define SRB_IS_RDP(Srb) (((ULONG_PTR)Srb->SrbExtension) & 4)
  935. #define ERRLOGID_TOO_MANY_DMA_TIMEOUT 0x80000001
  936. #define ERRLOGID_LYING_DMA_SYSTEM 0x80000002
  937. #define ERRLOGID_TOO_MANY_CRC_ERROR 0x80000003
  938. #define DEFAULT_SPINUP_TIME (30)
  939. //#define PUT_IRP_TRACKER(irpStack, num) if ((irpStack)->Parameters.Others.Argument2) {\
  940. // (ULONG_PTR)((irpStack)->Parameters.Others.Argument2) |= (1<<num);}
  941. #define PUT_IRP_TRACKER(irpStack, num)
  942. #define FREE_IRP_TRACKER(irpStack)
  943. #endif // ___port_h___