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

/*++
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
#ifdef LOG_GET_NEXT_CALLER
#define GET_NEXT_LOG_LENGTH 4
#endif
//
// 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;
//
// 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 _LAST_REQUEST {
SCSI_REQUEST_BLOCK Srb;
} LAST_REQUEST, *PLAST_REQUEST;
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 LOG_GET_NEXT_CALLER
ULONG GetNextLuIndex;
ULONG GetNextLuCallerLineNumber[GET_NEXT_LOG_LENGTH];
ULONG GetNextLuCallerFlags[GET_NEXT_LOG_LENGTH];
UCHAR GetNextLuCallerFileName[GET_NEXT_LOG_LENGTH][256];
ULONG CompletedCommandIndex;
LAST_REQUEST CompletedCommandQueue[GET_NEXT_LOG_LENGTH];
#endif
#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
//
// List link for FDO list.
//
LIST_ENTRY NextFdoLink;
} 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
);
#ifdef LOG_GET_NEXT_CALLER
#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
);
#if defined (_WIN64)
NTSTATUS
IdeTranslatePassThrough32To64(
IN PSCSI_PASS_THROUGH32 SrbControl32,
IN OUT PSCSI_PASS_THROUGH SrbControl64
);
VOID
IdeTranslatePassThrough64To32(
IN PSCSI_PASS_THROUGH SrbControl64,
IN OUT PSCSI_PASS_THROUGH32 SrbControl32
);
#endif
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<<num);}
#define PUT_IRP_TRACKER(irpStack, num)
#define FREE_IRP_TRACKER(irpStack)
#endif // ___port_h___