525 lines
9.8 KiB
C
525 lines
9.8 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1990 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
scsiboot.h
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file defines the necessary structures, defines, and functions for
|
||
|
the common SCSI boot port driver.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Jeff Havens (jhavens) 28-Feb-1991
|
||
|
Mike Glass
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "ntddscsi.h"
|
||
|
|
||
|
//
|
||
|
// SCSI Get Configuration Information
|
||
|
//
|
||
|
// LUN Information
|
||
|
//
|
||
|
|
||
|
typedef struct _LUNINFO {
|
||
|
UCHAR PathId;
|
||
|
UCHAR TargetId;
|
||
|
UCHAR Lun;
|
||
|
BOOLEAN DeviceClaimed;
|
||
|
PVOID DeviceObject;
|
||
|
struct _LUNINFO *NextLunInfo;
|
||
|
UCHAR InquiryData[INQUIRYDATABUFFERSIZE];
|
||
|
} LUNINFO, *PLUNINFO;
|
||
|
|
||
|
typedef struct _SCSI_BUS_SCAN_DATA {
|
||
|
USHORT Length;
|
||
|
UCHAR InitiatorBusId;
|
||
|
UCHAR NumberOfLogicalUnits;
|
||
|
PLUNINFO LunInfoList;
|
||
|
} SCSI_BUS_SCAN_DATA, *PSCSI_BUS_SCAN_DATA;
|
||
|
|
||
|
typedef struct _SCSI_CONFIGURATION_INFO {
|
||
|
UCHAR NumberOfBuses;
|
||
|
PSCSI_BUS_SCAN_DATA BusScanData[1];
|
||
|
} SCSI_CONFIGURATION_INFO, *PSCSI_CONFIGURATION_INFO;
|
||
|
|
||
|
#define MAXIMUM_RETRIES 4
|
||
|
|
||
|
//
|
||
|
// SCSI device timeout values in seconds
|
||
|
//
|
||
|
|
||
|
#define SCSI_DISK_TIMEOUT 10
|
||
|
#define SCSI_CDROM_TIMEOUT 10
|
||
|
#define SCSI_TAPE_TIMEOUT 120
|
||
|
|
||
|
//
|
||
|
// Adapter object transfer information.
|
||
|
//
|
||
|
|
||
|
typedef struct _ADAPTER_TRANSFER {
|
||
|
PSCSI_REQUEST_BLOCK Srb;
|
||
|
PVOID LogicalAddress;
|
||
|
ULONG Length;
|
||
|
}ADAPTER_TRANSFER, *PADAPTER_TRANSFER;
|
||
|
|
||
|
typedef struct _SRB_SCATTER_GATHER {
|
||
|
ULONG PhysicalAddress;
|
||
|
ULONG Length;
|
||
|
}SRB_SCATTER_GATHER, *PSRB_SCATTER_GATHER;
|
||
|
|
||
|
//
|
||
|
// Srb Structure plus extra storage for the port driver.
|
||
|
//
|
||
|
|
||
|
#define IRP_STACK_SIZE 2
|
||
|
|
||
|
typedef struct _FULL_SCSI_REQUEST_BLOCK {
|
||
|
SCSI_REQUEST_BLOCK Srb;
|
||
|
PVOID PreviousIrp;
|
||
|
IRP Irp;
|
||
|
IO_STACK_LOCATION IrpStack[IRP_STACK_SIZE];
|
||
|
ULONG SrbExtensionSize;
|
||
|
MDL Mdl;
|
||
|
ULONG PageFrame[20];
|
||
|
}FULL_SCSI_REQUEST_BLOCK, *PFULL_SCSI_REQUEST_BLOCK;
|
||
|
|
||
|
//
|
||
|
// Logical unit extension
|
||
|
//
|
||
|
|
||
|
typedef struct _LOGICAL_UNIT_EXTENSION {
|
||
|
UCHAR PathId;
|
||
|
UCHAR TargetId;
|
||
|
UCHAR Lun;
|
||
|
ULONG Flags;
|
||
|
PIRP CurrentRequest;
|
||
|
KSPIN_LOCK CurrentRequestSpinLock;
|
||
|
PVOID SpecificLuExtension;
|
||
|
struct _LOGICAL_UNIT_EXTENSION *NextLogicalUnit;
|
||
|
KDEVICE_QUEUE RequestQueue;
|
||
|
KSPIN_LOCK RequestQueueSpinLock;
|
||
|
LONG RequestTimeoutCounter;
|
||
|
ULONG RetryCount;
|
||
|
UCHAR NumberOfLogicalUnits;
|
||
|
PVOID MapRegisterBase;
|
||
|
ULONG NumberOfMapRegisters;
|
||
|
SRB_SCATTER_GATHER ScatterGather[17];
|
||
|
} LOGICAL_UNIT_EXTENSION, *PLOGICAL_UNIT_EXTENSION;
|
||
|
|
||
|
//
|
||
|
// Device extension
|
||
|
//
|
||
|
|
||
|
typedef struct _DEVICE_EXTENSION {
|
||
|
|
||
|
PDEVICE_OBJECT DeviceObject;
|
||
|
|
||
|
//
|
||
|
// Dma Adapter information.
|
||
|
//
|
||
|
|
||
|
PVOID MapRegisterBase;
|
||
|
PADAPTER_OBJECT DmaAdapterObject;
|
||
|
ADAPTER_TRANSFER FlushAdapterParameters;
|
||
|
|
||
|
//
|
||
|
// Number of SCSI buses
|
||
|
//
|
||
|
|
||
|
UCHAR NumberOfBuses;
|
||
|
|
||
|
//
|
||
|
// Maximum targets per bus
|
||
|
//
|
||
|
|
||
|
UCHAR MaximumTargetIds;
|
||
|
|
||
|
//
|
||
|
// SCSI Capabilities structure
|
||
|
//
|
||
|
|
||
|
IO_SCSI_CAPABILITIES Capabilities;
|
||
|
|
||
|
//
|
||
|
// SCSI port driver flags
|
||
|
//
|
||
|
|
||
|
ULONG Flags;
|
||
|
|
||
|
//
|
||
|
// SCSI port interrupt flags
|
||
|
//
|
||
|
|
||
|
ULONG InterruptFlags;
|
||
|
|
||
|
//
|
||
|
// List head for singlely linked list of complete IRPs.
|
||
|
//
|
||
|
|
||
|
PIRP CompletedRequests;
|
||
|
|
||
|
//
|
||
|
// Adapter object transfer parameters.
|
||
|
//
|
||
|
|
||
|
ADAPTER_TRANSFER MapTransferParameters;
|
||
|
|
||
|
KSPIN_LOCK SpinLock;
|
||
|
|
||
|
//
|
||
|
// Miniport Initialization Routine
|
||
|
//
|
||
|
|
||
|
PHW_INITIALIZE HwInitialize;
|
||
|
|
||
|
//
|
||
|
// Miniport Start IO Routine
|
||
|
//
|
||
|
|
||
|
PHW_STARTIO HwStartIo;
|
||
|
|
||
|
//
|
||
|
// Miniport Interrupt Service Routine
|
||
|
//
|
||
|
|
||
|
PHW_INTERRUPT HwInterrupt;
|
||
|
|
||
|
//
|
||
|
// Miniport Reset Routine
|
||
|
//
|
||
|
|
||
|
PHW_RESET_BUS HwReset;
|
||
|
|
||
|
//
|
||
|
// Miniport DMA started Routine
|
||
|
//
|
||
|
|
||
|
PHW_DMA_STARTED HwDmaStarted;
|
||
|
|
||
|
//
|
||
|
// Buffers must be mapped into system space.
|
||
|
//
|
||
|
|
||
|
BOOLEAN MapBuffers;
|
||
|
|
||
|
//
|
||
|
// Is this device a bus master and does it require map registers.
|
||
|
//
|
||
|
|
||
|
BOOLEAN MasterWithAdapter;
|
||
|
//
|
||
|
// Device extension for miniport routines.
|
||
|
//
|
||
|
|
||
|
PVOID HwDeviceExtension;
|
||
|
|
||
|
//
|
||
|
// Miniport request interrupt enabled/disable routine.
|
||
|
//
|
||
|
|
||
|
PHW_INTERRUPT HwRequestInterrupt;
|
||
|
|
||
|
//
|
||
|
// Miniport timer request routine.
|
||
|
//
|
||
|
|
||
|
PHW_INTERRUPT HwTimerRequest;
|
||
|
|
||
|
//
|
||
|
// Adapter control routine.
|
||
|
//
|
||
|
|
||
|
PHW_ADAPTER_CONTROL HwAdapterControl;
|
||
|
|
||
|
//
|
||
|
// SCSI configuration information from inquiries.
|
||
|
//
|
||
|
|
||
|
PSCSI_CONFIGURATION_INFO ScsiInfo;
|
||
|
|
||
|
//
|
||
|
// Miniport noncached device extension
|
||
|
//
|
||
|
|
||
|
PVOID NonCachedExtension;
|
||
|
|
||
|
//
|
||
|
// The length of the non-cached extension
|
||
|
//
|
||
|
|
||
|
ULONG NonCachedExtensionSize;
|
||
|
|
||
|
//
|
||
|
// SrbExtension Zone Pool
|
||
|
//
|
||
|
|
||
|
PVOID SrbExtensionZonePool;
|
||
|
PCHAR SrbExtensionPointer;
|
||
|
|
||
|
//
|
||
|
// Physical address of zone pool
|
||
|
//
|
||
|
|
||
|
ULONG PhysicalZoneBase;
|
||
|
|
||
|
//
|
||
|
// Size of Srb extension.
|
||
|
//
|
||
|
|
||
|
ULONG SrbExtensionSize;
|
||
|
|
||
|
//
|
||
|
// Spinlock for zoned hash table entries
|
||
|
//
|
||
|
|
||
|
KSPIN_LOCK ZoneSpinLock;
|
||
|
|
||
|
//
|
||
|
// Logical Unit Extension
|
||
|
//
|
||
|
|
||
|
ULONG HwLogicalUnitExtensionSize;
|
||
|
|
||
|
PLOGICAL_UNIT_EXTENSION LogicalUnitList;
|
||
|
|
||
|
|
||
|
ULONG TimerValue;
|
||
|
|
||
|
//
|
||
|
// Port timing count.
|
||
|
//
|
||
|
|
||
|
LONG PortTimeoutCounter;
|
||
|
|
||
|
//
|
||
|
// Shutdown Information.
|
||
|
//
|
||
|
|
||
|
BOOLEAN HasShutdown;
|
||
|
BOOLEAN HasSetBoot;
|
||
|
|
||
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||
|
|
||
|
#define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION)
|
||
|
|
||
|
//
|
||
|
// Port driver extension flags.
|
||
|
//
|
||
|
|
||
|
#define PD_CURRENT_IRP_VALID 0X0001
|
||
|
#define PD_RESET_DETECTED 0X0002
|
||
|
#define PD_NOTIFICATION_IN_PROGRESS 0X0004
|
||
|
#define PD_READY_FOR_NEXT_REQUEST 0X0008
|
||
|
#define PD_FLUSH_ADAPTER_BUFFERS 0X0010
|
||
|
#define PD_MAP_TRANSFER 0X0020
|
||
|
#define PD_CALL_DMA_STARTED 0X01000
|
||
|
#define PD_DISABLE_CALL_REQUEST 0X02000
|
||
|
#define PD_DISABLE_INTERRUPTS 0X04000
|
||
|
#define PD_ENABLE_CALL_REQUEST 0X08000
|
||
|
#define PD_TIMER_CALL_REQUEST 0X10000
|
||
|
|
||
|
//
|
||
|
// Logical unit extension flags.
|
||
|
//
|
||
|
|
||
|
#define PD_QUEUE_FROZEN 0X0001
|
||
|
#define PD_LOGICAL_UNIT_IS_ACTIVE 0X0002
|
||
|
#define PD_CURRENT_REQUEST_COMPLETE 0X0004
|
||
|
#define PD_LOGICAL_UNIT_IS_BUSY 0X0008
|
||
|
|
||
|
//
|
||
|
// The timer interval for the miniport timer routine specified in
|
||
|
// units of 100 nanoseconds.
|
||
|
//
|
||
|
#define PD_TIMER_INTERVAL (250 * 1000 * 10) // 250 ms
|
||
|
|
||
|
#define PD_TIMER_RESET_HOLD_TIME 4
|
||
|
|
||
|
//
|
||
|
// The define the interloop stall.
|
||
|
//
|
||
|
|
||
|
#define PD_INTERLOOP_STALL 5
|
||
|
|
||
|
#define MINIMUM_SRB_EXTENSIONS 8
|
||
|
#define COMPLETION_DELAY 10
|
||
|
|
||
|
//
|
||
|
// Port driver error logging
|
||
|
//
|
||
|
|
||
|
#define ERROR_LOG_ENTRY_LENGTH 8
|
||
|
|
||
|
typedef struct _ERROR_LOG_ENTRY {
|
||
|
UCHAR PathId;
|
||
|
UCHAR TargetId;
|
||
|
UCHAR Lun;
|
||
|
ULONG ErrorCode;
|
||
|
ULONG UniqueId;
|
||
|
} ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Define global data structures
|
||
|
//
|
||
|
|
||
|
extern ULONG ScsiPortCount;
|
||
|
extern FULL_SCSI_REQUEST_BLOCK PrimarySrb;
|
||
|
extern FULL_SCSI_REQUEST_BLOCK AbortSrb;
|
||
|
|
||
|
#define MAXIMUM_NUMBER_OF_SCSIPORT_OBJECTS 16
|
||
|
extern PDEVICE_OBJECT ScsiPortDeviceObject[MAXIMUM_NUMBER_OF_SCSIPORT_OBJECTS];
|
||
|
|
||
|
extern PREAD_CAPACITY_DATA ReadCapacityBuffer;
|
||
|
extern PUCHAR SenseInfoBuffer;
|
||
|
|
||
|
//
|
||
|
// Support routine.
|
||
|
//
|
||
|
|
||
|
PIRP
|
||
|
InitializeIrp(
|
||
|
PFULL_SCSI_REQUEST_BLOCK FullSrb,
|
||
|
CCHAR MajorFunction,
|
||
|
PVOID DeviceObject,
|
||
|
PVOID BufferPointer,
|
||
|
ULONG BufferSize
|
||
|
);
|
||
|
|
||
|
|
||
|
ARC_STATUS
|
||
|
GetAdapterCapabilities(
|
||
|
IN PDEVICE_OBJECT PortDeviceObject,
|
||
|
OUT PIO_SCSI_CAPABILITIES *PortCapabilities
|
||
|
);
|
||
|
|
||
|
ARC_STATUS
|
||
|
GetInquiryData(
|
||
|
IN PDEVICE_OBJECT PortDeviceObject,
|
||
|
IN PSCSI_CONFIGURATION_INFO *ConfigInfo
|
||
|
);
|
||
|
|
||
|
ARC_STATUS
|
||
|
ReadDriveCapacity(
|
||
|
IN PPARTITION_CONTEXT PartitionContext
|
||
|
);
|
||
|
|
||
|
ARC_STATUS
|
||
|
ScsiClassIoComplete(
|
||
|
IN PPARTITION_CONTEXT PartitionContext,
|
||
|
IN PIRP Irp,
|
||
|
IN PVOID Context
|
||
|
);
|
||
|
|
||
|
ARC_STATUS
|
||
|
SendSrbSynchronous(
|
||
|
PPARTITION_CONTEXT PartitionContext,
|
||
|
PSCSI_REQUEST_BLOCK Srb,
|
||
|
PVOID BufferAddress,
|
||
|
ULONG BufferLength,
|
||
|
BOOLEAN WriteToDevice
|
||
|
);
|
||
|
|
||
|
BOOLEAN
|
||
|
InterpretSenseInfo(
|
||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||
|
OUT ARC_STATUS *Status,
|
||
|
PPARTITION_CONTEXT PartitionContext
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
RetryRequest(
|
||
|
PPARTITION_CONTEXT PartitionContext,
|
||
|
PIRP Irp
|
||
|
);
|
||
|
|
||
|
PIRP
|
||
|
BuildRequest(
|
||
|
IN PPARTITION_CONTEXT PartitionContext,
|
||
|
IN PMDL Mdl,
|
||
|
IN ULONG LogicalBlockAddress,
|
||
|
IN BOOLEAN Operation
|
||
|
);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Define the necessary functions to simulate the I/O environment.
|
||
|
//
|
||
|
|
||
|
#define ExAllocatePool(Type, Size) FwAllocatePool(Size)
|
||
|
|
||
|
#if !defined(_MIPS_) && !defined(_ALPHA_) && !defined(_PPC_)
|
||
|
#define PAUSE while (!GET_KEY());
|
||
|
|
||
|
typedef struct _DRIVER_LOOKUP_ENTRY {
|
||
|
PCHAR DevicePath;
|
||
|
PBL_DEVICE_ENTRY_TABLE DispatchTable;
|
||
|
} DRIVER_LOOKUP_ENTRY, *PDRIVER_LOOKUP_ENTRY;
|
||
|
#undef ASSERT
|
||
|
#define ASSERT( exp ) { \
|
||
|
if (!(#exp)) { \
|
||
|
BlPrint("ASSERT File: %s line: %lx\n", __FILE__, __LINE__); \
|
||
|
PAUSE; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ScsiPortExecute(
|
||
|
IN PDEVICE_OBJECT DeviceObject,
|
||
|
IN PIRP Irp
|
||
|
);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if defined ExFreePool
|
||
|
#undef ExFreePool
|
||
|
#endif
|
||
|
#define ExFreePool(Size)
|
||
|
|
||
|
#ifdef IoCallDriver
|
||
|
#undef IoCallDriver
|
||
|
#endif
|
||
|
#define IoCallDriver(DeviceObject, Irp) ( \
|
||
|
DeviceObject->CurrentIrp = Irp, \
|
||
|
Irp->Tail.Overlay.CurrentStackLocation--, \
|
||
|
ScsiPortExecute(DeviceObject, Irp), \
|
||
|
Irp->Tail.Overlay.CurrentStackLocation++ )
|
||
|
#ifdef IoCompleteRequest
|
||
|
#undef IoCompleteRequest
|
||
|
#endif
|
||
|
#define IoCompleteRequest(Irp, Boost) Irp->PendingReturned = FALSE
|
||
|
#define IoAllocateErrorLogEntry(DeviceObject, Length) NULL
|
||
|
#define IoWriteErrorLogEntry(Entry)
|
||
|
#ifdef KeAcquireSpinLock
|
||
|
#undef KeAcquireSpinLock
|
||
|
#endif
|
||
|
#define KeAcquireSpinLock(Lock, Irql)
|
||
|
#ifdef KeReleaseSpinLock
|
||
|
#undef KeReleaseSpinLock
|
||
|
#endif
|
||
|
#define KeReleaseSpinLock(Lock, Irql)
|
||
|
#define KiAcquireSpinLock(Lock)
|
||
|
#ifdef KiReleaseSpinLock
|
||
|
#undef KiReleaseSpinLock
|
||
|
#endif
|
||
|
#define KiReleaseSpinLock(Lock)
|
||
|
#define KeSynchronizeExecution(InterruptObject, ExecutionRoutine, Context) \
|
||
|
(ExecutionRoutine)(Context)
|
||
|
|
||
|
#ifdef KeRaiseIrql
|
||
|
#undef KeRaiseIrql
|
||
|
#endif
|
||
|
#define KeRaiseIrql(NewLevel, OldLevel)
|
||
|
#ifdef KeLowerIrql
|
||
|
#undef KeLowerIrql
|
||
|
#endif
|
||
|
#define KeLowerIrql(Level)
|