425 lines
7.7 KiB
C
425 lines
7.7 KiB
C
|
|
||
|
#ifndef _HP_DSM_H_
|
||
|
#define _HP_DSM_H_
|
||
|
|
||
|
#include <ntddscsi.h>
|
||
|
#include <scsi.h>
|
||
|
#include "dsm.h"
|
||
|
|
||
|
//
|
||
|
// Set an arbitrary limit of 4 paths.
|
||
|
//
|
||
|
#define MAX_PATHS 4
|
||
|
|
||
|
//
|
||
|
// Device State defines.
|
||
|
//
|
||
|
#define DEV_ACTIVE 0x00000001
|
||
|
#define DEV_PASSIVE 0x00000002
|
||
|
#define DEV_FAILED 0x00000003
|
||
|
|
||
|
//
|
||
|
// Multi-path Group State
|
||
|
//
|
||
|
//
|
||
|
// Fail-Over Group State
|
||
|
//
|
||
|
#define FG_NORMAL 0x00000001
|
||
|
#define FG_PENDING 0x00000002
|
||
|
#define FG_FAILBACK 0x00000003
|
||
|
#define FG_FAILED 0x00000004
|
||
|
|
||
|
//
|
||
|
// Load-Balance Types
|
||
|
//
|
||
|
#define LB_ACTIVE_PASSIVE 0x01
|
||
|
#define LB_STATIC 0x02
|
||
|
#define LB_MIN_QUEUE 0x03
|
||
|
#define LB_ROUNDROBIN 0x04
|
||
|
|
||
|
//
|
||
|
// Internal structures.
|
||
|
//
|
||
|
//
|
||
|
// Statistics structure. Used by the device
|
||
|
// and path routines.
|
||
|
//
|
||
|
typedef struct _DSM_STATS {
|
||
|
ULONG NumberReads;
|
||
|
LARGE_INTEGER BytesRead;
|
||
|
ULONG NumberWrites;
|
||
|
LARGE_INTEGER BytesWritten;
|
||
|
} DSM_STATS, *PDSM_STATS;
|
||
|
|
||
|
//
|
||
|
// Dsm Context is the global driver
|
||
|
// context that gets pushed to each of
|
||
|
// the dsm entry points.
|
||
|
//
|
||
|
typedef struct _DSM_CONTEXT {
|
||
|
KSPIN_LOCK SpinLock;
|
||
|
ULONG NumberDevices;
|
||
|
ULONG NumberGroups;
|
||
|
ULONG NumberFOGroups;
|
||
|
LIST_ENTRY DeviceList;
|
||
|
LIST_ENTRY GroupList;
|
||
|
LIST_ENTRY FailGroupList;
|
||
|
PVOID MPIOContext;
|
||
|
NPAGED_LOOKASIDE_LIST ContextList;
|
||
|
} DSM_CONTEXT, *PDSM_CONTEXT;
|
||
|
|
||
|
typedef struct _GROUP_ENTRY;
|
||
|
typedef struct _FAILOVER_GROUP;
|
||
|
|
||
|
//
|
||
|
// Information about each device that's
|
||
|
// supported.
|
||
|
//
|
||
|
typedef struct _DEVICE_INFO {
|
||
|
LIST_ENTRY ListEntry;
|
||
|
PVOID DsmContext;
|
||
|
PDEVICE_OBJECT PortPdo;
|
||
|
PDEVICE_OBJECT TargetObject;
|
||
|
struct _GROUP_ENTRY *Group;
|
||
|
struct _FAILOVER_GROUP *FailGroup;
|
||
|
ULONG State;
|
||
|
ULONG Controller;
|
||
|
BOOLEAN NeedsVerification;
|
||
|
UCHAR Reserved[3];
|
||
|
LONG Requests;
|
||
|
DSM_STATS Stats;
|
||
|
UCHAR SerialNumber[20];
|
||
|
STORAGE_DEVICE_DESCRIPTOR Descriptor;
|
||
|
} DEVICE_INFO, *PDEVICE_INFO;
|
||
|
|
||
|
//
|
||
|
// Information about multi-path groups:
|
||
|
// The same device found via multiple paths.
|
||
|
//
|
||
|
typedef struct _GROUP_ENTRY {
|
||
|
LIST_ENTRY ListEntry;
|
||
|
ULONG GroupNumber;
|
||
|
BOOLEAN LoadBalanceInit;
|
||
|
UCHAR LoadBalanceType;
|
||
|
UCHAR Reserved[2];
|
||
|
ULONG NumberDevices;
|
||
|
PDEVICE_INFO DeviceList[MAX_PATHS];
|
||
|
} GROUP_ENTRY, *PGROUP_ENTRY;
|
||
|
|
||
|
//
|
||
|
// The collection of devices on one path.
|
||
|
// These fail-over as a unit.
|
||
|
//
|
||
|
typedef struct _FAILOVER_GROUP {
|
||
|
LIST_ENTRY ListEntry;
|
||
|
PVOID PathId;
|
||
|
ULONG State;
|
||
|
ULONG Count;
|
||
|
|
||
|
//
|
||
|
// BUGBUG: Revisit using an array
|
||
|
//
|
||
|
PDEVICE_INFO DeviceList[32];
|
||
|
} FAILOVER_GROUP, *PFAILOVER_GROUP;
|
||
|
|
||
|
//
|
||
|
// Completion context structure.
|
||
|
//
|
||
|
typedef struct _COMPLETION_CONTEXT {
|
||
|
LARGE_INTEGER TickCount;
|
||
|
PDEVICE_INFO DeviceInfo;
|
||
|
PDSM_CONTEXT DsmContext;
|
||
|
} COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT;
|
||
|
|
||
|
//
|
||
|
// Direct-Commands
|
||
|
//
|
||
|
#pragma pack(1)
|
||
|
|
||
|
typedef struct _HP_ENQUIRY {
|
||
|
UCHAR NumberSysDrives;
|
||
|
UCHAR SDFlags;
|
||
|
UCHAR EventChangeCounter;
|
||
|
UCHAR Reserved;
|
||
|
UCHAR DriveSizes[32];
|
||
|
UCHAR ROMProgCount[2];
|
||
|
UCHAR StatusFlag;
|
||
|
UCHAR FreeStateChangeCount;
|
||
|
UCHAR FwMinorRev;
|
||
|
UCHAR FwMajorRev;
|
||
|
UCHAR Fill[56];
|
||
|
} HP_ENQUIRY, *PHP_ENQUIRY;
|
||
|
|
||
|
typedef struct _HP_DAC_STATUS {
|
||
|
UCHAR Format;
|
||
|
UCHAR LUN;
|
||
|
UCHAR SysDrive;
|
||
|
UCHAR InformationLength;
|
||
|
UCHAR MasterSlaveState[4];
|
||
|
UCHAR MSAdditionalInfo[4];
|
||
|
UCHAR PartnerStatus[4];
|
||
|
UCHAR DACInfo[4];
|
||
|
} HP_DAC_STATUS, *PHP_DAC_STATUS;
|
||
|
|
||
|
#pragma pack()
|
||
|
|
||
|
#define DCMD_ENQUIRY 0x05
|
||
|
#define DCMD_GET_DAC_STATUS 0x55
|
||
|
|
||
|
NTSTATUS
|
||
|
HPSendDirectCommand(
|
||
|
IN PDEVICE_OBJECT DeviceObject,
|
||
|
IN PUCHAR Buffer,
|
||
|
IN ULONG BufferSize,
|
||
|
IN UCHAR Opcode
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPSendScsiCommand(
|
||
|
IN PDEVICE_OBJECT DeviceObject,
|
||
|
IN PUCHAR Buffer,
|
||
|
IN ULONG BufferSize,
|
||
|
IN ULONG CdbLength,
|
||
|
IN PCDB Cdb,
|
||
|
IN BOOLEAN DataIn
|
||
|
);
|
||
|
//
|
||
|
// Export functions.
|
||
|
//
|
||
|
NTSTATUS
|
||
|
HPInquire (
|
||
|
IN PVOID DsmContext,
|
||
|
IN PDEVICE_OBJECT TargetDevice,
|
||
|
IN PDEVICE_OBJECT PortObject,
|
||
|
IN PSTORAGE_DEVICE_DESCRIPTOR Descriptor,
|
||
|
IN PSTORAGE_DEVICE_ID_DESCRIPTOR DeviceIdList,
|
||
|
OUT PVOID *DsmIdentifier
|
||
|
);
|
||
|
|
||
|
BOOLEAN
|
||
|
HPCompareDevices(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PVOID DsmId1,
|
||
|
IN PVOID DsmId2
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPSetDeviceInfo(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PDEVICE_OBJECT TargetObject,
|
||
|
IN PVOID DsmId,
|
||
|
IN OUT PVOID *PathId
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPGetControllerInfo(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PVOID DsmId,
|
||
|
IN ULONG Flags,
|
||
|
IN OUT PCONTROLLER_INFO *ControllerInfo
|
||
|
);
|
||
|
|
||
|
BOOLEAN
|
||
|
HPIsPathActive(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PVOID PathId
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPPathVerify(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PVOID DsmId,
|
||
|
IN PVOID PathId
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPInvalidatePath(
|
||
|
IN PVOID DsmContext,
|
||
|
IN ULONG ErrorMask,
|
||
|
IN PVOID PathId,
|
||
|
IN OUT PVOID *NewPathId
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPRemoveDevice(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PVOID DsmId,
|
||
|
IN PVOID PathId
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPRemovePath(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PVOID PathId
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPBringPathOnLine(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PVOID PathId,
|
||
|
OUT PULONG DSMError
|
||
|
);
|
||
|
|
||
|
PVOID
|
||
|
HPLBGetPath(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||
|
IN PDSM_IDS DsmList,
|
||
|
IN PVOID CurrentPath,
|
||
|
OUT NTSTATUS *Status
|
||
|
);
|
||
|
|
||
|
ULONG
|
||
|
HPCategorizeRequest(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PDSM_IDS DsmIds,
|
||
|
IN PIRP Irp,
|
||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||
|
IN PVOID CurrentPath,
|
||
|
OUT PVOID *PathId,
|
||
|
OUT NTSTATUS *Status
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPBroadcastRequest(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PDSM_IDS DsmIds,
|
||
|
IN PIRP Irp,
|
||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||
|
IN PKEVENT Event
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPSrbDeviceControl(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PDSM_IDS DsmIds,
|
||
|
IN PIRP Irp,
|
||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||
|
IN PKEVENT Event
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
HPSetCompletion(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PVOID DsmId,
|
||
|
IN PIRP Irp,
|
||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||
|
IN OUT PDSM_COMPLETION_INFO DsmCompletion
|
||
|
);
|
||
|
|
||
|
ULONG
|
||
|
HPInterpretError(
|
||
|
IN PVOID DsmContext,
|
||
|
IN PVOID DsmId,
|
||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||
|
IN OUT NTSTATUS *Status,
|
||
|
OUT PBOOLEAN Retry
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
HPUnload(
|
||
|
IN PVOID DsmContext
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Various utility functions.
|
||
|
//
|
||
|
PGROUP_ENTRY
|
||
|
FindDevice(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PDEVICE_INFO DeviceInfo
|
||
|
);
|
||
|
|
||
|
PGROUP_ENTRY
|
||
|
BuildGroupEntry (
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PDEVICE_INFO deviceInfo
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
AddGroupEntry(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PGROUP_ENTRY Group
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
AddDeviceEntry(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PGROUP_ENTRY Group,
|
||
|
IN PDEVICE_INFO DeviceInfo,
|
||
|
IN ULONG DeviceState
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
RemoveDeviceEntry(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PGROUP_ENTRY Group,
|
||
|
IN PDEVICE_INFO DeviceInfo
|
||
|
);
|
||
|
|
||
|
PFAILOVER_GROUP
|
||
|
FindFOGroup(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PVOID PathId
|
||
|
);
|
||
|
|
||
|
PFAILOVER_GROUP
|
||
|
BuildFOGroup(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PDEVICE_INFO DeviceInfo,
|
||
|
IN PVOID PathId
|
||
|
);
|
||
|
|
||
|
NTSTATUS
|
||
|
UpdateFOGroup(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PFAILOVER_GROUP FailGroup,
|
||
|
IN PDEVICE_INFO DeviceInfo
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
RemoveDeviceFailGroup(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PFAILOVER_GROUP FailGroup,
|
||
|
IN PDEVICE_INFO DeviceInfo
|
||
|
);
|
||
|
|
||
|
PFAILOVER_GROUP
|
||
|
SetNewPath(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PGROUP_ENTRY Group,
|
||
|
IN PDEVICE_INFO FailingDevice,
|
||
|
IN PFAILOVER_GROUP SelectedPath
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
LBInit(
|
||
|
IN PDSM_CONTEXT DsmContext,
|
||
|
IN PGROUP_ENTRY Group
|
||
|
);
|
||
|
|
||
|
|
||
|
VOID
|
||
|
HPConvertHexToAscii(
|
||
|
IN PUCHAR HexString,
|
||
|
IN OUT PUCHAR AsciiString,
|
||
|
IN ULONG Count
|
||
|
);
|
||
|
|
||
|
|
||
|
#define DEBUG_BUFFER_LENGTH 255
|
||
|
UCHAR DebugBuffer[DEBUG_BUFFER_LENGTH + 1];
|
||
|
ULONG HPDSMDebug = 1;
|
||
|
VOID
|
||
|
DsmDebugPrint(
|
||
|
ULONG DebugPrintLevel,
|
||
|
PCCHAR DebugMessage,
|
||
|
...
|
||
|
);
|
||
|
#ifdef DebugPrint
|
||
|
#undef DebugPrint
|
||
|
#define DebugPrint(x) DsmDebugPrint x
|
||
|
#endif
|
||
|
#endif // _HP_DSM_H
|
||
|
|