/*++ Copyright (C) 1993-99 Microsoft Corporation Module Name: port.h Abstract: --*/ #if !defined (___port_h___) #define ___port_h___ // // Notification Event Types // typedef enum _IDE_NOTIFICATION_TYPE { IdeRequestComplete, IdeNextRequest, IdeNextLuRequest, IdeResetDetected, IdeCallDisableInterrupts, IdeCallEnableInterrupts, IdeRequestTimerCall, IdeBusChangeDetected, /* New */ IdeWMIEvent, IdeWMIReregister, IdeAllDeviceMissing, IdeResetRequest } IDE_NOTIFICATION_TYPE, *PIDE_NOTIFICATION_TYPE; VOID IdePortNotification( IN IDE_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, ... ); struct _SRB_DATA; #define NUMBER_LOGICAL_UNIT_BINS 8 #define SP_NORMAL_PHYSICAL_BREAK_VALUE 17 #define IDE_NUM_RESERVED_PAGES 4 // // Define a pointer to the synchonize execution routine. // typedef BOOLEAN (*PSYNCHRONIZE_ROUTINE) ( IN PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext ); // // Adapter object transfer information. // typedef struct _ADAPTER_TRANSFER { struct _SRB_DATA *SrbData; ULONG SrbFlags; PVOID LogicalAddress; ULONG Length; }ADAPTER_TRANSFER, *PADAPTER_TRANSFER; /**++ Not used typedef struct _SRB_SCATTER_GATHER { // BUGBUG kenr 07-aug-92: PhysicalAddresses should be 64 bits ULONG PhysicalAddress; ULONG Length; }SRB_SCATTER_GATHER, *PSRB_SCATTER_GATHER; --**/ // // Port driver error logging // typedef struct _ERROR_LOG_ENTRY { UCHAR MajorFunctionCode; UCHAR PathId; UCHAR TargetId; UCHAR Lun; ULONG ErrorCode; ULONG UniqueId; ULONG ErrorLogRetryCount; ULONG SequenceNumber; } ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY; // // SCSI request extension for port driver. // typedef struct _SRB_DATA { LIST_ENTRY RequestList; PSCSI_REQUEST_BLOCK CurrentSrb; struct _SRB_DATA *CompletedRequests; ULONG ErrorLogRetryCount; ULONG SequenceNumber; PCHAR SrbDataOffset; #ifdef ENABLE_COMMAND_LOG PCOMMAND_LOG IdeCommandLog; ULONG IdeCommandLogIndex; #endif ULONG Flags; }SRB_DATA, *PSRB_DATA; #define SRB_DATA_RESERVED_PAGES 0x100 // // Define data storage for access at interrupt Irql. // typedef struct _PDO_EXTENSION * PPDO_EXTENSION; typedef PPDO_EXTENSION PLOGICAL_UNIT_EXTENSION; typedef struct _INTERRUPT_DATA { // // SCSI port interrupt flags // ULONG InterruptFlags; // // List head for singlely linked list of complete IRPs. // PSRB_DATA CompletedRequests; // // Adapter object transfer parameters. // ADAPTER_TRANSFER MapTransferParameters; // // Error log information. // ERROR_LOG_ENTRY LogEntry; // // Logical unit to start next. // PLOGICAL_UNIT_EXTENSION ReadyLogicalUnit; // // List of completed abort reqeusts. // PLOGICAL_UNIT_EXTENSION CompletedAbort; // // Miniport timer request routine. // PHW_INTERRUPT HwTimerRequest; // // Mini port timer request time in micro seconds. // ULONG MiniportTimerValue; // // The PDO that causes a bus reset // PPDO_EXTENSION PdoExtensionResetBus; } INTERRUPT_DATA, *PINTERRUPT_DATA; // // ACPI Firmware Settings // typedef struct _DEVICE_SETTINGS { ULONG NumEntries; IDEREGS FirmwareSettings[0]; } DEVICE_SETTINGS, *PDEVICE_SETTINGS; // // Fdo Power Context (pre-alloced) // typedef struct _FDO_POWER_CONTEXT { BOOLEAN TimingRestored; PIRP OriginalPowerIrp; POWER_STATE_TYPE newPowerType; POWER_STATE newPowerState; } FDO_POWER_CONTEXT, *PFDO_POWER_CONTEXT; typedef enum _IDE_DEBUG_EVENT{ CrcEvent =0, BusyEvent, RwEvent, MaxIdeEvent }IDE_DEBUG_EVENT; typedef struct _PDO_EXTENSION * PPDO_EXTENSION; typedef struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION; typedef struct _CONTROLLER_PARAMETERS * PCONTROLLER_PARAMETERS; typedef struct _IDE_REGISTERS_1 *PIDE_REGISTERS_1; typedef struct _IDE_REGISTERS_2 *PIDE_REGISTERS_2; typedef struct _ENUMERATION_STRUCT *PENUMERATION_STRUCT; // // Device extension // typedef struct _FDO_EXTENSION { EXTENSION_COMMON_HEADER; PCM_RESOURCE_LIST ResourceList; IDE_RESOURCE IdeResource; PCIIDE_SYNC_ACCESS_INTERFACE SyncAccessInterface; PCIIDE_XFER_MODE_INTERFACE TransferModeInterface; PCIIDE_REQUEST_PROPER_RESOURCES RequestProperResourceInterface; // // Device extension for miniport routines. // PHW_DEVICE_EXTENSION HwDeviceExtension; // // We are a child of a busmaster parent // BOOLEAN BoundWithBmParent; BOOLEAN SymbolicLinkCreated; ULONG IdePortNumber; // offset 0x0C ULONG ScsiPortNumber; // offset 0x0C // // Active requests count. This count is biased by -1 so a value of -1 // indicates there are no requests out standing. // //LONG ActiveRequestCount; // offset 0x10 // // SCSI port driver flags // ULONG Flags; // offset 0x14 ULONG FdoState; // // Srb flags to OR into all SRB. // ULONG SrbFlags; // offset 0x18 LONG PortTimeoutCounter; // offset 0x1C ULONG ResetCallAgain; PSCSI_REQUEST_BLOCK ResetSrb; // // Number of SCSI buses // UCHAR MaxLuCount; // offset 0x22 PKINTERRUPT InterruptObject; // offset 0x24 // // Global device sequence number. // ULONG SequenceNumber; // offset 0x30 KSPIN_LOCK SpinLock; // offset 0x34 PADAPTER_OBJECT DmaAdapterObject; ADAPTER_TRANSFER FlushAdapterParameters; // // Pointer to the per SRB data array. // //PSRB_DATA SrbData; // // Pointer to the per SRB free list. // //PSRB_DATA FreeSrbData; // // Miniport service routine pointers. // PHW_INTERRUPT HwTimerRequest; // // Spinlock that protects LogicalUnitList manipulation // KSPIN_LOCK LogicalUnitListSpinLock; // // Number of logical unit in LogicalUnitList[] // Protected by LogicalUnitListSpinLock // UCHAR NumberOfLogicalUnits; // // // CCHAR NumberOfLogicalUnitsPowerUp; BOOLEAN DeviceChanged; // // panasonic pcmcia ide controller // BOOLEAN panasonicController; // // non-pcmcia controller, this is always set // if pcmcia controller, it is not set unless // registry flag PCMCIA_IDE_CONTROLLER_HAS_SLAVE // is non-zero // ULONG MayHaveSlaveDevice; // // Array of logical unit extensions. // Protected by LogicalUnitListSpinLock // PLOGICAL_UNIT_EXTENSION LogicalUnitList[NUMBER_LOGICAL_UNIT_BINS]; // // Interrupt level data storage. // INTERRUPT_DATA InterruptData; // // SCSI Capabilities structure // IO_SCSI_CAPABILITIES Capabilities; // // Miniport timer object. // KTIMER MiniPortTimer; // // Miniport DPC for timer object. // KDPC MiniPortTimerDpc; // // channel timing from ACPI/BIOS // ACPI_IDE_TIMING BootAcpiTimingSettings; ACPI_IDE_TIMING AcpiTimingSettings; // // Transfermode cycle time // PULONG DefaultTransferModeTimingTable; // // User choice // IDE_DEVICETYPE UserChoiceDeviceType[MAX_IDE_DEVICE * MAX_IDE_LINE]; ULONG UserChoiceTransferMode[MAX_IDE_DEVICE * MAX_IDE_LINE]; ULONG UserChoiceTransferModeForAtapiDevice[MAX_IDE_DEVICE * MAX_IDE_LINE]; ULONG TimingModeAllowed[MAX_IDE_DEVICE * MAX_IDE_LINE]; // // Use aggressive DMA // DMADETECTIONLEVEL DmaDetectionLevel; // // Pre-alloced context structure for power routines // FDO_POWER_CONTEXT FdoPowerContext[2]; #if DBG // // Locks to synchronize access to the pre-alloced power context // ULONG PowerContextLock[2]; #endif #ifdef IDE_MEASURE_BUSSCAN_SPEED // // keep track of the time spent on the first busscan // ULONG BusScanTime; #endif // // Pre-alloced structs used during enumeration // #if DBG ULONG EnumStructLock; #endif PENUMERATION_STRUCT PreAllocEnumStruct; // // Reserved error log entry per device to be used to log // insufficient resources error // PVOID ReserveAllocFailureLogEntry[MAX_IDE_DEVICE]; // // Temporary: Should be removed once I check in the fix // for low memory condition // ULONG NumMemoryFailure; ULONG LastMemoryFailure; // // Reserve pages for use during low memory conditions // PVOID ReservedPages; #ifdef ENABLE_NATIVE_MODE // // Parent's interrupt interface // PCIIDE_INTERRUPT_INTERFACE InterruptInterface; #endif #ifdef ENABLE_48BIT_LBA ULONG EnableBigLba; #endif ULONG WaitOnPowerUp; #ifdef ENABLE_ATAPI_VERIFIER ULONG IdeVerifierFlags[MAX_IDE_DEVICE]; ULONG IdeDebugVerifierFlags[MAX_IDE_DEVICE]; ULONG IdeInternalVerifierFlags[MAX_IDE_DEVICE]; ULONG IdeVerifierEventCount[MAX_IDE_DEVICE][MaxIdeEvent]; ULONG IdeVerifierEventFrequency[MAX_IDE_DEVICE][MaxIdeEvent]; #endif } FDO_EXTENSION, *PFDO_EXTENSION; typedef struct _CONFIGURATION_CONTEXT { HANDLE BusKey; HANDLE ServiceKey; HANDLE DeviceKey; ULONG AdapterNumber; ULONG LastAdapterNumber; ULONG BusNumber; PVOID Parameter; PACCESS_RANGE AccessRanges; BOOLEAN DisableTaggedQueueing; BOOLEAN DisableMultipleLu; }CONFIGURATION_CONTEXT, *PCONFIGURATION_CONTEXT; typedef struct _INTERRUPT_CONTEXT { PFDO_EXTENSION DeviceExtension; PINTERRUPT_DATA SavedInterruptData; }INTERRUPT_CONTEXT, *PINTERRUPT_CONTEXT; typedef struct _RESET_CONTEXT { PFDO_EXTENSION DeviceExtension; UCHAR PathId; BOOLEAN NewResetSequence; PSCSI_REQUEST_BLOCK ResetSrb; }RESET_CONTEXT, *PRESET_CONTEXT; #define NEED_REQUEST_SENSE(Srb) (Srb->ScsiStatus == SCSISTAT_CHECK_CONDITION \ && !(Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) && \ Srb->SenseInfoBuffer && Srb->SenseInfoBufferLength ) #define LONG_ALIGN (sizeof(LONG) - 1) #define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION) // // Port driver extension flags. // // // This flag indicates that a request has been passed to the miniport and the // miniport has not indicated it is ready for another request. It is set by // IdeStartIoSynchronized. It is cleared by IdePortCompletionDpc when the // miniport asks for another request. Note the port driver will defer giving // the miniport driver a new request if the current request disabled disconnects. // #define PD_DEVICE_IS_BUSY 0X00001 // // Indicates that IdePortCompletionDpc needs to be run. This is set when // A miniport makes a request which must be done at DPC and is cleared when // when the request information is gotten by IdeGetInterruptState. // #define PD_NOTIFICATION_REQUIRED 0X00004 // // Indicates the miniport is ready for another request. Set by // ScsiPortNotification and cleared by IdeGetInterruptState. This flag is // stored in the interrupt data structure. // #define PD_READY_FOR_NEXT_REQUEST 0X00008 // // Indicates the miniport wants the adapter channel flushed. Set by // IdePortFlushDma and cleared by IdeGetInterruptState. This flag is // stored in the data interrupt structure. The flush adapter parameters // are saved in the device object. // #define PD_FLUSH_ADAPTER_BUFFERS 0X00010 // // Indicates the miniport wants the adapter channel programmed. Set by // IdePortIoMapTransfer and cleared by IdeGetInterruptState or // IdePortFlushDma. This flag is stored in the interrupt data structure. // The I/O map transfer parameters are saved in the interrupt data structure. // #define PD_MAP_TRANSFER 0X00020 // // Indicates the miniport wants to log an error. Set by // IdePortLogError and cleared by IdeGetInterruptState. This flag is // stored in the interrupt data structure. The error log parameters // are saved in the interrupt data structure. Note at most one error per DPC // can be logged. // #define PD_LOG_ERROR 0X00040 // // Indicates that no request should be sent to the miniport after // a bus reset. Set when the miniport reports a reset or the port driver // resets the bus. It is cleared by IdeTimeoutSynchronized. The // PortTimeoutCounter is used to time the length of the reset hold. This flag // is stored in the interrupt data structure. // #define PD_RESET_HOLD 0X00080 // // Indicates a request was stopped due to a reset hold. The held request is // stored in the current request of the device object. This flag is set by // IdeStartIoSynchronized and cleared by IdeTimeoutSynchronized which also // starts the held request when the reset hold has ended. This flag is stored // in the interrupt data structure. // #define PD_HELD_REQUEST 0X00100 // // Indicates the miniport has reported a bus reset. Set by // IdePortNotification and cleared by IdeGetInterruptState. This flag is // stored in the interrupt data structure. // #define PD_RESET_REPORTED 0X00200 // // Indicates there is a pending request for which resources // could not be allocated. This flag is set by IdeAllocateRequestStructures // which is called from IdePortStartIo. It is cleared by // IdeProcessCompletedRequest when a request completes which then calls // IdePortStartIo to try the request again. // #define PD_PENDING_DEVICE_REQUEST 0X00800 // // This flag indicates that there are currently no requests executing with // disconnects disabled. This flag is normally on. It is cleared by // IdeStartIoSynchronized when a request with disconnect disabled is started // and is set when that request completes. IdeProcessCompletedRequest will // start the next request for the miniport if PD_DEVICE_IS_BUSY is clear. // #define PD_DISCONNECT_RUNNING 0X01000 // // Indicates the miniport wants the system interrupts disabled. Set by // IdePortNofitication and cleared by IdePortCompletionDpc. This flag is // NOT stored in the interrupt data structure. The parameters are stored in // the device extension. // #define PD_DISABLE_CALL_REQUEST 0X02000 // // Indicates that system interrupts have been enabled and that the miniport // has disabled its adapter from interruptint. The miniport's interrupt // routine is not called while this flag is set. This flag is set by // IdePortNotification when a CallEnableInterrupts request is made and // cleared by IdeEnableInterruptSynchronized when the miniport requests that // system interrupts be disabled. This flag is stored in the interrupt data // structure. // #define PD_DISABLE_INTERRUPTS 0X04000 // // Indicates the miniport wants the system interrupt enabled. Set by // IdePortNotification and cleared by IdeGetInterruptState. This flag is // stored in the interrupt data structure. The call enable interrupts // parameters are saved in the device extension. // #define PD_ENABLE_CALL_REQUEST 0X08000 // // Indicates the miniport is wants a timer request. Set by // IdePortNotification and cleared by IdeGetInterruptState. This flag is // stored in the interrupt data structure. The timer request parameters are // stored in the interrupt data structure. // #define PD_TIMER_CALL_REQUEST 0X10000 // // channel looks empty // #define PD_ALL_DEVICE_MISSING 0X20000 // // Request a reset // #define PD_RESET_REQUEST 0x40000 // // Reserve pages are being used by another request // #define PD_RESERVED_PAGES_IN_USE 0x80000 // // The following flags should not be cleared from the interrupt data structure // by IdeGetInterruptState. // #define PD_INTERRUPT_FLAG_MASK (PD_RESET_HOLD | PD_HELD_REQUEST | PD_DISABLE_INTERRUPTS) // // Logical unit extension flags. // // // Indicates the logical unit queue is frozen. Set by // IdeProcessCompletedRequest when an error occurs and is cleared by the class // driver. // #define PD_QUEUE_FROZEN 0X0001 // // Indicates that the miniport has an active request for this logical unit. // Set by IdeStartIoSynchronized when the request is started and cleared by // GetNextLuRequest. This flag is used to track when it is ok to start another // request from the logical unit queue for this device. // #define PD_LOGICAL_UNIT_IS_ACTIVE 0X0002 // // Indicates that a request for this logical unit has failed and a REQUEST // SENSE command needs to be done. This flag prevents other requests from // being started until an untagged, by-pass queue command is started. This // flag is cleared in IdeStartIoSynchronized. It is set by // IdeGetInterruptState. // #define PD_NEED_REQUEST_SENSE 0X0004 // // Indicates that a request for this logical unit has completed with a status // of BUSY or QUEUE FULL. This flag is set by IdeProcessCompletedRequest and // the busy request is saved in the logical unit structure. This flag is // cleared by IdePortTickHandler which also restarts the request. Busy // request may also be requeued to the logical unit queue if an error occurs // on the device (This will only occur with command queueing.). Not busy // requests are nasty because they are restarted asynchronously by // IdePortTickHandler rather than GetNextLuRequest. This makes error recovery // more complex. // #define PD_LOGICAL_UNIT_IS_BUSY 0X0008 // // This flag indicates a queue full has been returned by the device. It is // similar to PD_LOGICAL_UNIT_IS_BUSY but is set in IdeGetInterruptState when // a QUEUE FULL status is returned. This flag is used to prevent other // requests from being started for the logical unit before // IdeProcessCompletedRequest has a chance to set the busy flag. // #define PD_QUEUE_IS_FULL 0X0010 // // Indicates that there is a request for this logical unit which cannot be // executed for now. This flag is set by IdeAllocateRequestStructures. It is // cleared by GetNextLuRequest when it detects that the pending request // can now be executed. The pending request is stored in the logical unit // structure. A new single non-queued reqeust cannot be executed on a logical // that is currently executing queued requests. Non-queued requests must wait // unit for all queued requests to complete. A non-queued requests is one // which is not tagged and does not have SRB_FLAGS_NO_QUEUE_FREEZE set. // Normally only read and write commands can be queued. // //#define PD_LOGICAL_UNIT_MUST_SLEEP 0X0020 //#define PD_LOGICAL_UNIT_STOP_READY 0X0040 //#define PD_LOGICAL_UNIT_REMOVE_READY 0X0080 //#define PD_LOGICAL_UNIT_ALWAYS_QUEUE (PD_LOGICAL_UNIT_STOP_READY | PD_LOGICAL_UNIT_REMOVE_READY) //#define PD_LOGICAL_UNIT_POWER_OK 0X0100 //#define PD_LOGICAL_IN_PAGING_PATH 0X2000 //#define PD_LOGICAL_UNIT_LEGACY_ATTACHER 0X4000 // // Indicates that the LogicalUnit has been allocated for a rescan request. // This flag prevents IOCTL_SCSI_MINIPORT requests from attaching to this // logical unit, since the possibility exists that it could be freed before // the IOCTL request is complete. // #define PD_RESCAN_ACTIVE 0x8000 // // FdoExtension FdoState // #define FDOS_DEADMEAT (1 << 0) #define FDOS_STARTED (1 << 1) #define FDOS_STOPPED (1 << 2) // // Port Timeout Counter values. // #define PD_TIMER_STOPPED -1 #define PD_TIMER_RESET_HOLD_TIME 1 // // Define the mimimum and maximum number of srb extensions which will be allocated. // #define MINIMUM_SRB_EXTENSIONS 16 #define MAXIMUM_SRB_EXTENSIONS 512 // // Size of the buffer used for registry operations. // #define SP_REG_BUFFER_SIZE 512 // // Number of times to retry when a BUSY status is returned. // #define BUSY_RETRY_COUNT 20 // // Number of times to retry an INQUIRY request. // #define INQUIRY_RETRY_COUNT 2 // // Function declarations // IO_ALLOCATION_ACTION CallIdeStartIoSynchronized ( IN PVOID Reserved1, IN PVOID Reserved2, IN PVOID Reserved3, IN PVOID DeviceObject ); NTSTATUS IdePortCreateClose ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS IdePortDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID IdePortAllocateAccessToken ( IN PDEVICE_OBJECT DeviceObject ); VOID IdePortStartIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); BOOLEAN IdePortInterrupt( IN PKINTERRUPT InterruptObject, IN PDEVICE_OBJECT DeviceObject ); VOID IdePortCompletionDpc( IN PKDPC Dpc, IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS IdePortDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID IdePortTickHandler( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); BOOLEAN AtapiRestartBusyRequest ( PFDO_EXTENSION DeviceExtension, PPDO_EXTENSION LogicalUnit ); VOID IssueRequestSense( IN PPDO_EXTENSION PdoExtension, IN PSCSI_REQUEST_BLOCK FailingSrb ); VOID IdePortLogError( IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb OPTIONAL, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN ULONG ErrorCode, IN ULONG UniqueId ); NTSTATUS IdePortInternalCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ); BOOLEAN IdeStartIoSynchronized ( PVOID ServiceContext ); BOOLEAN IdeResetBusSynchronized ( PVOID ServiceContext ); BOOLEAN IdeTimeoutSynchronized ( PVOID ServiceContext ); VOID IssueAbortRequest( IN PFDO_EXTENSION DeviceExtension, IN PLOGICAL_UNIT_EXTENSION LogicalUnit ); BOOLEAN IdeGetInterruptState( IN PVOID ServiceContext ); VOID LogErrorEntry( IN PFDO_EXTENSION DeviceExtension, IN PERROR_LOG_ENTRY LogEntry ); VOID GetNextLuPendingRequest( IN PFDO_EXTENSION DeviceExtension, IN PLOGICAL_UNIT_EXTENSION LogicalUnit ); #if DBG #define GetNextLuRequest(x, y) GetNextLuRequest2(x, y, __FILE__, __LINE__) VOID GetNextLuRequest2( IN PFDO_EXTENSION DeviceExtension, IN PLOGICAL_UNIT_EXTENSION LogicalUnit, IN PUCHAR FileName, IN ULONG LineNumber ); #else VOID GetNextLuRequest( IN PFDO_EXTENSION DeviceExtension, IN PLOGICAL_UNIT_EXTENSION LogicalUnit ); #endif VOID IdeLogTimeoutError( IN PFDO_EXTENSION DeviceExtension, IN PIRP Irp, IN ULONG UniqueId ); NTSTATUS IdeTranslateSrbStatus( IN PSCSI_REQUEST_BLOCK Srb ); VOID IdeProcessCompletedRequest( IN PFDO_EXTENSION DeviceExtension, IN PSRB_DATA SrbData, OUT PBOOLEAN CallStartIo ); PSRB_DATA IdeGetSrbData( IN PFDO_EXTENSION DeviceExtension, IN PSCSI_REQUEST_BLOCK Srb ); VOID IdeCompleteRequest( IN PFDO_EXTENSION DeviceExtension, IN PSRB_DATA SrbData, IN UCHAR SrbStatus ); NTSTATUS IdeSendMiniPortIoctl( IN PFDO_EXTENSION DeviceExtension, IN PIRP RequestIrp ); NTSTATUS IdeGetInquiryData( IN PFDO_EXTENSION DeviceExtension, IN PIRP Irp ); NTSTATUS IdeSendPassThrough( IN PFDO_EXTENSION DeviceExtension, IN PIRP Irp ); NTSTATUS IdeClaimLogicalUnit( IN PFDO_EXTENSION DeviceExtension, IN PIRP Irp ); VOID IdeMiniPortTimerDpc( IN struct _KDPC *Dpc, IN PVOID DeviceObject, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); BOOLEAN IdeSynchronizeExecution ( IN PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext ); NTSTATUS IdeGetCommonBuffer( PFDO_EXTENSION DeviceExtension, ULONG NonCachedExtensionSize ); VOID IdeDeviceCleanup( PFDO_EXTENSION DeviceExtension ); NTSTATUS IdeInitializeConfiguration( IN PFDO_EXTENSION DeviceExtension, IN PCONFIGURATION_CONTEXT Context ); #define IDEPORT_PUT_LUNEXT_IN_IRP(IrpStack, LogUnitExt) (IrpStack->Parameters.Others.Argument4 = LogUnitExt) #define IDEPORT_GET_LUNEXT_IN_IRP(IrpStack) ((PLOGICAL_UNIT_EXTENSION) (IrpStack->Parameters.Others.Argument4)) VOID IdePortCompleteRequest( IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR SrbStatus ); NTSTATUS IdePortFlushLogicalUnit ( PFDO_EXTENSION FdoExtension, PLOGICAL_UNIT_EXTENSION LogUnitExtension, BOOLEAN Forced ); typedef VOID (*ASYNC_PASS_THROUGH_COMPLETION) ( IN PDEVICE_OBJECT DeviceObject, PVOID Context, NTSTATUS Status ); NTSTATUS IssueAsyncAtaPassThroughSafe ( IN PFDO_EXTENSION DeviceExtension, IN PLOGICAL_UNIT_EXTENSION LogUnitExtension, IN OUT PATA_PASS_THROUGH AtaPassThroughData, IN BOOLEAN DataIn, IN ASYNC_PASS_THROUGH_COMPLETION Completion, IN PVOID Context, IN BOOLEAN PowerRelated, IN ULONG TimeOut, IN BOOLEAN MustSucceed ); typedef struct _ATA_PASSTHROUGH_CONTEXT { PDEVICE_OBJECT DeviceObject; ASYNC_PASS_THROUGH_COMPLETION CallerCompletion; PVOID CallerContext; PSCSI_REQUEST_BLOCK Srb; PSENSE_DATA SenseInfoBuffer; BOOLEAN MustSucceed; PATA_PASS_THROUGH DataBuffer; } ATA_PASSTHROUGH_CONTEXT, *PATA_PASSTHROUGH_CONTEXT; NTSTATUS AtaPassThroughCompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ); typedef struct _SYNC_ATA_PASSTHROUGH_CONTEXT { KEVENT Event; NTSTATUS Status; } SYNC_ATA_PASSTHROUGH_CONTEXT, *PSYNC_ATA_PASSTHROUGH_CONTEXT; typedef struct _FLUSH_ATA_PASSTHROUGH_CONTEXT { PIRP FlushIrp; PATA_PASS_THROUGH ataPassThroughData; } FLUSH_ATA_PASSTHROUGH_CONTEXT, *PFLUSH_ATA_PASSTHROUGH_CONTEXT; NTSTATUS IssueSyncAtaPassThroughSafe ( IN PFDO_EXTENSION DeviceExtension, IN PLOGICAL_UNIT_EXTENSION LogUnitExtension, IN OUT PATA_PASS_THROUGH AtaPassThroughData, IN BOOLEAN DataIn, IN BOOLEAN PowerRelated, IN ULONG TimeOut, IN BOOLEAN MustSucceed ); VOID SyncAtaPassThroughCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context, IN NTSTATUS Status ); VOID IdeUnmapReservedMapping ( IN PFDO_EXTENSION DeviceExtension, IN PSRB_DATA SrbData, IN PMDL Mdl ); PVOID IdeMapLockedPagesWithReservedMapping ( IN PFDO_EXTENSION DeviceExtension, IN PSRB_DATA SrbData, IN PMDL Mdl ); BOOLEAN TestForEnumProbing ( IN PSCSI_REQUEST_BLOCK Srb ); #define DEFAULT_ATA_PASS_THROUGH_TIMEOUT 15 #define INIT_IDE_SRB_FLAGS(Srb) (Srb->SrbExtension = NULL) #define SANITY_CHECK_SRB(Srb) {ASSERT(!(((ULONG_PTR)Srb->SrbExtension) & ~7));} #define MARK_SRB_AS_PIO_CANDIDATE(Srb) {SANITY_CHECK_SRB(Srb); ((ULONG_PTR)Srb->SrbExtension) |= 1;} #define MARK_SRB_AS_DMA_CANDIDATE(Srb) {SANITY_CHECK_SRB(Srb); ((ULONG_PTR)Srb->SrbExtension) &= ~1;} #define MARK_SRB_FOR_DMA(Srb) {SANITY_CHECK_SRB(Srb); ((ULONG_PTR)Srb->SrbExtension) |= 2;} #define MARK_SRB_FOR_PIO(Srb) {SANITY_CHECK_SRB(Srb); ((ULONG_PTR)Srb->SrbExtension) &= ~2;} #define SRB_IS_DMA_CANDIDATE(Srb) (!(((ULONG_PTR)Srb->SrbExtension) & 1)) #define SRB_USES_DMA(Srb) (((ULONG_PTR)Srb->SrbExtension) & 2) #define TEST_AND_SET_SRB_FOR_RDP(ScsiDeviceType, Srb) \ if ((ScsiDeviceType == SEQUENTIAL_ACCESS_DEVICE) &&\ ((Srb->Cdb[0] == SCSIOP_ERASE) || (Srb->Cdb[0] == SCSIOP_LOAD_UNLOAD)||\ (Srb->Cdb[0] == SCSIOP_LOCATE) || (Srb->Cdb[0] == SCSIOP_REWIND) ||\ (Srb->Cdb[0] == SCSIOP_SPACE) || (Srb->Cdb[0] == SCSIOP_SEEK)||\ (Srb->Cdb[0] == SCSIOP_WRITE_FILEMARKS))) {\ SANITY_CHECK_SRB(Srb);\ ((ULONG_PTR)Srb->SrbExtension) |= 4;\ } else if ((ScsiDeviceType == READ_ONLY_DIRECT_ACCESS_DEVICE) && \ (Srb->Cdb[0]==SCSIOP_SEEK) ) {\ SANITY_CHECK_SRB(Srb);\ ((ULONG_PTR)Srb->SrbExtension) |= 4;\ } else {\ SANITY_CHECK_SRB(Srb);\ ((ULONG_PTR)Srb->SrbExtension) &= ~4;\ } #define SRB_IS_RDP(Srb) (((ULONG_PTR)Srb->SrbExtension) & 4) #define ERRLOGID_TOO_MANY_DMA_TIMEOUT 0x80000001 #define ERRLOGID_LYING_DMA_SYSTEM 0x80000002 #define ERRLOGID_TOO_MANY_CRC_ERROR 0x80000003 #define DEFAULT_SPINUP_TIME (30) //#define PUT_IRP_TRACKER(irpStack, num) if ((irpStack)->Parameters.Others.Argument2) {\ // (ULONG_PTR)((irpStack)->Parameters.Others.Argument2) |= (1<