windows-nt/Source/XPSP1/NT/drivers/storage/mpath/control/mpio.h
2020-09-26 16:20:57 +08:00

1047 lines
20 KiB
C

#ifndef _MPATH_H_
#define _MPATH_H_
#include <ntddk.h>
#include <wmilib.h>
#include <ntdddisk.h>
#include "dsm.h"
#include "mpspf.h"
#include "mpdevf.h"
#include "mplib.h"
#include "wmi.h"
#include "stdarg.h"
#include "stdio.h"
//#define USE_BINARY_MOF_QUERY
#define DD_MULTIPATH_CONTROL_DEVICE_NAME L"\\Device\\MPathControl"
#define DD_MULTIPATH_CONTROL_DOS_NAME L"\\DosDevices\\MPathControl"
#define MULTIPATH_CONTROL ((ULONG) 'mp')
//
// Internal IOCTL that control sends to it's children.
//
#define IOCTL_MPCTL_DEVFLTR_ARRIVED CTL_CODE (MULTIPATH_CONTROL, 0x20, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_MPCTL_DEVFLTR_REMOVED CTL_CODE (MULTIPATH_CONTROL, 0x21, METHOD_BUFFERED, FILE_ANY_ACCESS)
//
// Internal device types.
//
#define MPIO_CONTROL 0x00000001
#define MPIO_MPDISK 0x00000002
//
// State Values.
//
#define MPIO_STATE_NORMAL 0x00000001
#define MPIO_STATE_WAIT1 0x00000002
#define MPIO_STATE_WAIT2 0x00000003
#define MPIO_STATE_WAIT3 0x00000004
#define MPIO_STATE_DEGRADED 0x00000005
#define MPIO_STATE_IN_FO 0x00000006
//
// Arbitrarly Maximum Paths handled by one MPDisk
//
#define MAX_NUMBER_PATHS 0x00000008
#define MAX_EMERGENCY_CONTEXT 32
//
// Inquiry data defines
//
#define VENDOR_ID_LENGTH 8
#define PRODUCT_ID_LENGTH 16
#define REVISION_LENGTH 4
#define PDO_NAME_LENGTH 100
#define FDO_NAME_LENGTH 128
#define MPIO_STRING_LENGTH (sizeof(WCHAR)*63)
//
// Various thread operations.
//
#define INITIATE_FAILOVER 0x00000001
#define SHUTDOWN 0x00000002
#define FORCE_RESCAN 0x00000003
#define PATH_REMOVAL 0x00000004
#define DEVICE_REMOVAL 0x00000005
extern PVOID CurrentFailurePath;
typedef struct _MP_QUEUE {
LIST_ENTRY ListEntry;
ULONG QueuedItems;
KSPIN_LOCK SpinLock;
ULONG QueueIndicator;
} MP_QUEUE, *PMP_QUEUE;
typedef struct _MPIO_ADDRESS {
UCHAR Bus;
UCHAR Device;
UCHAR Function;
UCHAR Pad;
} MPIO_ADDRESS, *PMPIO_ADDRESS;
typedef struct _ID_ENTRY {
LIST_ENTRY ListEntry;
//
// This is the path id. returned
// from the DSM.
//
PVOID PathID;
//
// The port driver fdo.
//
PDEVICE_OBJECT PortFdo;
//
// The filter DO
//
PDEVICE_OBJECT AdapterFilter;
//
// Constructed 64-bit value to pass
// to user-mode for path Identification
//
LONGLONG UID;
//
// The PCI Bus, Device, Function.
//
MPIO_ADDRESS Address;
//
// It's name.
//
UNICODE_STRING AdapterName;
//
// Indicates whether UID is valid.
//
BOOLEAN UIDValid;
UCHAR Pad[3];
} ID_ENTRY, *PID_ENTRY;
typedef struct _DSM_ENTRY {
LIST_ENTRY ListEntry;
DSM_INQUIRE_DRIVER InquireDriver;
DSM_COMPARE_DEVICES CompareDevices;
DSM_SET_DEVICE_INFO SetDeviceInfo;
DSM_GET_CONTROLLER_INFO GetControllerInfo;
DSM_IS_PATH_ACTIVE IsPathActive;
DSM_PATH_VERIFY PathVerify;
DSM_INVALIDATE_PATH InvalidatePath;
DSM_REMOVE_PENDING RemovePending;
DSM_REMOVE_DEVICE RemoveDevice;
DSM_REMOVE_PATH RemovePath;
DSM_SRB_DEVICE_CONTROL SrbDeviceControl;
DSM_REENABLE_PATH ReenablePath;
DSM_LB_GET_PATH GetPath;
DSM_INTERPRET_ERROR InterpretError;
DSM_UNLOAD Unload;
DSM_SET_COMPLETION SetCompletion;
DSM_CATEGORIZE_REQUEST CategorizeRequest;
DSM_BROADCAST_SRB BroadcastSrb;
DSM_WMILIB_CONTEXT WmiContext;
PVOID DsmContext;
UNICODE_STRING DisplayName;
} DSM_ENTRY, *PDSM_ENTRY;
typedef struct _REAL_DEV_INFO {
//
// The adapter filter. Used as PathId.
//
PDEVICE_OBJECT AdapterFilter;
//
// Port driver FDO.
//
PDEVICE_OBJECT PortFdo;
//
// Optionally, the DSM can update 'path', so
// this PVOID contains either the DSM value
// or AdapterFilter.
//
PVOID PathId;
//
// Number of requests on this device.
//
LONG Requests;
//
// Used to enable upper-layers to match
// adapters/paths/luns
//
ULONGLONG Identifier;
//
// The associated controller's id.
//
ULONGLONG ControllerId;
//
// The real scsiport PDO.
//
PDEVICE_OBJECT PortPdo;
//
// The device filter DO. Requests get sent
// here.
//
PDEVICE_OBJECT DevFilter;
//
// The DSM's ID for the real DO
//
PVOID DsmID;
//
// Indicates whether this is an active or passive path.
//
BOOLEAN PathActive;
BOOLEAN PathFailed;
BOOLEAN DSMInit;
BOOLEAN PathUIDValue;
BOOLEAN NeedsRemoval;
UCHAR Pad[3];
SCSI_ADDRESS ScsiAddress;
} REAL_DEV_INFO, *PREAL_DEV_INFO;
typedef struct _MPDISK_EXTENSION {
//
// MPCtl's deviceObject.
//
PDEVICE_OBJECT ControlObject;
//
// The MPIO Disk Ordinal. Used in construction
// of the device object and PnP IDs
//
ULONG DeviceOrdinal;
//
// Flags indicating:
// whether a class driver has claimed the MPDisk.
// Whether to run the State checking code.
// Whether the device property name has been acquired (mpiowmi.c )
// Whether the fail-over completed, and a new path has been set by the DSM.
// Whether a transition to IN_FO is necessary.
// Whether a missing path has come back.
//
BOOLEAN IsClaimed;
BOOLEAN CheckState;
BOOLEAN HasName;
BOOLEAN NewPathSet;
BOOLEAN FailOver;
BOOLEAN PathBackOnLine;
UCHAR Pad[2];
//
// Ref count of requests sent.
//
LONG OutstandingRequests;
LONG ResubmitRequests;
LONG FailOverRequests;
//
// List of requests that were outstanding at the time
// that a Fail-Over event occurred. As each comes back
// they are put on this queue.
//
MP_QUEUE ResubmitQueue;
//
// All new requests that arrive during the Fail-Over
// operations are put on this queue.
//
MP_QUEUE FailOverQueue;
//
// Used to queue things to the thread.
//
LIST_ENTRY PendingWorkList;
LIST_ENTRY WorkList;
KSPIN_LOCK WorkListLock;
KEVENT ThreadEvent;
HANDLE Handle;
//
// Counter of items in the pending list.
//
ULONG PendingItems;
//
// Re-hash of the inquiry data + any serial number stuff
// Used for PnP ID stuff and various WMI/IOCTLs
// Just use the first one, as the other paths PDO all
// are the same device.
//
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
//
// Indicates the max. number of paths that this
// device object has seen.
//
ULONG MaxPaths;
//
// Bitmap used to show which array locations
// are currently occupied.
//
ULONG DeviceMap;
//
// Indicates the path where the last request was sent.
//
PVOID CurrentPath;
//
// The most current failed path value.
// Used to re-start the state machine after a F.O. completes.
//
PVOID FailedPath;
//
// Generic timer value inced by 1 sec. timer.
//
ULONG TickCount;
//
// Indicates the base time for doing
// a rescan on adapters with failed devices.
//
ULONG RescanCount;
PVOID FailedAdapter;
//
// G.P. SpinLock.
//
KSPIN_LOCK SpinLock;
//
// Array of Dsm IDs. Passed to several
// DSM functions. Though a copy of what's in TargetInfo,
// it speeds up handling requests.
//
DSM_IDS DsmIdList;
ULONG Buffer[32];
//
// Number of valid TargetInfo elements in the following array.
//
ULONG TargetInfoCount;
//
// This is a list of the device filter DO's and scsiport PDO's
// being handled by this MPIO PDO.
//
REAL_DEV_INFO TargetInfo[MAX_NUMBER_PATHS];
DSM_ENTRY DsmInfo;
UNICODE_STRING PdoName;
} MPDISK_EXTENSION, *PMPDISK_EXTENSION;
typedef struct _DISK_ENTRY {
LIST_ENTRY ListEntry;
//
// The MPDisk D.O.
//
PDEVICE_OBJECT PdoObject;
} DISK_ENTRY, *PDISK_ENTRY;
#define FLTR_FLAGS_QDR 0x00000001
#define FLTR_FLAGS_QDR_COMPLETE 0x00000002
#define FLTR_FLAGS_NEED_RESCAN 0x00000004
#define FLTR_FLAGS_RESCANNING 0x00000008
typedef struct _FLTR_ENTRY {
LIST_ENTRY ListEntry;
//
// The D.O. of the filter
//
PDEVICE_OBJECT FilterObject;
PDEVICE_OBJECT PortFdo;
PDEVICE_RELATIONS CachedRelations;
PFLTR_DEVICE_LIST FltrGetDeviceList;
ULONG Flags;
} FLTR_ENTRY, *PFLTR_ENTRY;
typedef struct _CONTROLLER_ENTRY {
LIST_ENTRY ListEntry;
//
// The DSM controlling the controller.
//
PDSM_ENTRY Dsm;
//
// The actual info returned from the DSM.
//
PCONTROLLER_INFO ControllerInfo;
} CONTROLLER_ENTRY, *PCONTROLLER_ENTRY;
typedef struct _CONTROL_EXTENSION {
//
// Current number of MPDisk's
//
ULONG NumberDevices;
//
// Number Registered Adapter Filters.
//
ULONG NumberFilters;
//
// Number registers DSMs.
//
ULONG NumberDSMs;
//
// Number of paths that have been
// discovered. Note that this isn't
// necessarily the real state of the world, due
// to when the value is updated.
//
ULONG NumberPaths;
//
// The number of controllers found from all DSM's.
//
ULONG NumberControllers;
//
// The of fail-over packets currently being
// handled.
//
ULONG NumberFOPackets;
//
// SpinLock for list manipulations.
//
KSPIN_LOCK SpinLock;
//
// List of MPDisks.
//
LIST_ENTRY DeviceList;
//
// List of Filters
//
LIST_ENTRY FilterList;
//
// List of DSM's.
//
LIST_ENTRY DsmList;
//
// List of PathIdentifer structs.
//
LIST_ENTRY IdList;
//
// List of controller structs.
//
LIST_ENTRY ControllerList;
//
// List of failover packets.
//
LIST_ENTRY FailPacketList;
} CONTROL_EXTENSION, *PCONTROL_EXTENSION;
typedef struct _DEVICE_EXTENSION {
//
// Pointer to the device object.
//
PDEVICE_OBJECT DeviceObject;
//
// The dev filter device object if this is a PDO.
// The PnP PDO, if this is the FDO.
// The object to which requests get sent.
//
PDEVICE_OBJECT LowerDevice;
//
// Pdo (root)
//
PDEVICE_OBJECT Pdo;
//
// The driver object.
//
PDRIVER_OBJECT DriverObject;
//
// Identifies what type this is:
// Control or pseudo disk.
//
ULONG Type;
//
// DeviceExtension - Either PDO or FDO depending
// on value of Type.
//
PVOID TypeExtension;
//
// Request tracking tag.
//
LONG SequenceNumber;
//
// Current State of the world.
// See defines above.
//
ULONG State;
ULONG LastState;
ULONG CompletionState;
//
// Some WMI stuff.
//
BOOLEAN FireLogEvent;
UCHAR Reserved[3];
WMILIB_CONTEXT WmiLib;
//
// Saved registry path string.
//
UNICODE_STRING RegistryPath;
//
// List of Completion Context structures.
//
NPAGED_LOOKASIDE_LIST ContextList;
//
// SpinLock for Emergency buffer handling.
//
KSPIN_LOCK EmergencySpinLock;
//
// Array of emergency context buffers.
//
PVOID EmergencyContext[MAX_EMERGENCY_CONTEXT];
//
// Bitmap of buffer usage.
//
ULONG EmergencyContextMap;
//
// Remove lock.
//
IO_REMOVE_LOCK RemoveLock;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef
NTSTATUS
(*PMPIO_COMPLETION_ROUTINE)(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PSCSI_REQUEST_BLOCK Srb,
IN PVOID Context,
IN OUT PBOOLEAN Retry,
IN OUT PBOOLEAN Fatal
);
typedef
VOID
(*MPIO_CALLBACK)(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG Operation,
IN NTSTATUS Status
);
typedef struct _MPIO_CONTEXT {
ULONG CurrentState;
ULONG OriginalState;
ULONG QueuedInto;
BOOLEAN Allocated;
BOOLEAN Freed;
BOOLEAN ReIssued;
UCHAR Reserved;
ULONG EmergencyIndex;
PIRP Irp;
DSM_COMPLETION_INFO DsmCompletion;
PREAL_DEV_INFO TargetInfo;
SCSI_REQUEST_BLOCK Srb;
} MPIO_CONTEXT, *PMPIO_CONTEXT;
typedef struct _MPIO_THREAD_CONTEXT {
PDEVICE_OBJECT DeviceObject;
PKEVENT Event;
} MPIO_THREAD_CONTEXT, *PMPIO_THREAD_CONTEXT;
typedef struct _MPIO_REQUEST_INFO {
LIST_ENTRY ListEntry;
MPIO_CALLBACK RequestComplete;
ULONG Operation;
PVOID OperationSpecificInfo;
ULONG ErrorMask;
} MPIO_REQUEST_INFO, *PMPIO_REQUEST_INFO;
typedef struct _MPIO_DEVICE_REMOVAL {
PDEVICE_OBJECT DeviceObject;
PREAL_DEV_INFO TargetInfo;
} MPIO_DEVICE_REMOVAL, *PMPIO_DEVICE_REMOVAL;
typedef struct _MPIO_FAILOVER_INFO {
LIST_ENTRY ListEntry;
PDEVICE_OBJECT DeviceObject;
PVOID PathId;
} MPIO_FAILOVER_INFO, *PMPIO_FAILOVER_INFO;
NTSTATUS
MPPdoGlobalCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
NTSTATUS
MPIOResubmitCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
//
// Routines in utils.c
//
NTSTATUS
MPIOForwardRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOSyncCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
PREAL_DEV_INFO
MPIOGetTargetInfo(
IN PMPDISK_EXTENSION DiskExtension,
IN PVOID PathId,
IN PDEVICE_OBJECT Filter
);
PDISK_ENTRY
MPIOGetDiskEntry(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskIndex
);
BOOLEAN
MPIOFindLowerDevice(
IN PDEVICE_OBJECT MPDiskObject,
IN PDEVICE_OBJECT LowerDevice
);
PDSM_ENTRY
MPIOGetDsm(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG DsmIndex
);
PFLTR_ENTRY
MPIOGetFltrEntry(
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT PortFdo,
IN PDEVICE_OBJECT AdapterFilter
);
NTSTATUS
MPIOHandleNewDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT FilterObject,
IN PDEVICE_OBJECT PortObject,
IN PADP_DEVICE_INFO DeviceInfo,
IN PDSM_ENTRY DsmEntry,
IN PVOID DsmExtension
);
NTSTATUS
MPIOGetScsiAddress(
IN PDEVICE_OBJECT DeviceObject,
OUT PSCSI_ADDRESS *ScsiAddress
);
PMPIO_CONTEXT
MPIOAllocateContext(
IN PDEVICE_EXTENSION DeviceExtension
);
VOID
MPIOFreeContext(
IN PDEVICE_EXTENSION DeviceExtension,
IN PMPIO_CONTEXT Context
);
VOID
MPIOCopyMemory(
IN PVOID Destination,
IN PVOID Source,
IN ULONG Length
);
VOID
MPIOCompleteRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN CCHAR Boost
);
NTSTATUS
MPIOQueueRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PMPIO_CONTEXT Context,
IN PMP_QUEUE Queue
);
NTSTATUS
MPIOFailOverHandler(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG ErrorMask,
IN PREAL_DEV_INFO FailingDevice
);
VOID
MPIOSetRequestBusy(
IN PSCSI_REQUEST_BLOCK Srb
);
PDEVICE_RELATIONS
MPIOHandleDeviceRemovals(
IN PDEVICE_OBJECT DeviceObject,
IN PADP_DEVICE_LIST DeviceList,
IN PDEVICE_RELATIONS Relations
);
NTSTATUS
MPIOHandleDeviceArrivals(
IN PDEVICE_OBJECT DeviceObject,
IN PADP_DEVICE_LIST DeviceList,
IN PDEVICE_RELATIONS CachedRelations,
IN PDEVICE_RELATIONS Relations,
IN PDEVICE_OBJECT PortObject,
IN PDEVICE_OBJECT FilterObject,
IN BOOLEAN NewList
);
NTSTATUS
MPIORemoveDeviceAsync(
IN PDEVICE_OBJECT DeviceObject,
IN PREAL_DEV_INFO TargetInfo
);
NTSTATUS
MPIOHandleRemoveAsync(
IN PDEVICE_OBJECT DeviceObject,
IN PREAL_DEV_INFO TargetInfo
);
NTSTATUS
MPIORemoveSingleDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT Pdo
);
NTSTATUS
MPIORemoveDevices(
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT AdapterFilter
);
NTSTATUS
MPIOSetNewPath(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID PathId
);
VOID
MPIOSetFailed(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID PathId
);
VOID
MPIOSetState(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID PathId,
IN ULONG State
);
NTSTATUS
MPIOCreatePathEntry(
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT FilterObject,
IN PDEVICE_OBJECT PortFdo,
IN PVOID PathID
);
NTSTATUS
MPIOGetAdapterAddress(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PMPIO_ADDRESS Address
);
LONGLONG
MPIOCreateUID(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID PathID
);
ULONGLONG
MPIOBuildControllerInfo(
IN PDEVICE_OBJECT ControlObect,
IN PDSM_ENTRY Dsm,
IN PVOID DsmID
);
ULONG
MPIOHandleStateTransition(
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
MPIOForceRescan(
IN PDEVICE_OBJECT AdapterFilter
);
NTSTATUS
MPIOCheckState(
IN PDEVICE_OBJECT DeviceObject
);
//
// Routines defined in fdo.c
//
NTSTATUS
MPIOFdoPnP(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOFdoPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOFdoInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
PDEVICE_RELATIONS
MPIOBuildRelations(
IN PADP_DEVICE_LIST DeviceList
);
//
// Routines defined in pdo.c
//
NTSTATUS
MPIOPdoRegistration(
IN PDEVICE_OBJECT MPDiskObject,
IN PDEVICE_OBJECT FilterObject,
IN PDEVICE_OBJECT LowerDevice,
IN OUT PMPIO_PDO_INFO PdoInformation
);
BOOLEAN
MPIOFindMatchingDevice(
IN PDEVICE_OBJECT MPDiskObject,
IN PADP_DEVICE_INFO DeviceInfo,
IN PDSM_ENTRY DsmEntry,
IN PVOID DsmId
);
NTSTATUS
MPIOUpdateDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT AdapterFilter,
IN PDEVICE_OBJECT PortObject,
IN PADP_DEVICE_INFO DeviceInfo,
IN PVOID DsmId
);
NTSTATUS
MPIOCreateDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT FilterObject,
IN PDEVICE_OBJECT PortObject,
IN PADP_DEVICE_INFO DeviceInfo,
IN PDSM_ENTRY DsmEntry,
IN PVOID DsmId,
IN OUT PDEVICE_OBJECT *NewDeviceObject
);
NTSTATUS
MPIOPdoCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOPdoDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOPdoInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOPdoShutdownFlush(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOPdoPnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOPdoPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOPdoUnhandled(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
//
// Routines in pnp.c
//
NTSTATUS
MPIOPdoQdr(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOPdoQueryId(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOQueryDeviceText(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
//
// Structs and Routines in queue.c
//
typedef struct _MPQUEUE_ENTRY {
LIST_ENTRY ListEntry;
PIRP Irp;
} MPQUEUE_ENTRY, *PMPQUEUE_ENTRY;
VOID
MPIOInitQueue(
IN PMP_QUEUE Queue,
IN ULONG QueueTag
);
VOID
MPIOInsertQueue(
IN PMP_QUEUE Queue,
IN PMPQUEUE_ENTRY QueueEntry
);
PMPQUEUE_ENTRY
MPIORemoveQueue(
IN PMP_QUEUE Queue
);
NTSTATUS
MPIOIssueQueuedRequests(
IN PREAL_DEV_INFO TargetInfo,
IN PMP_QUEUE Queue,
IN ULONG State,
IN PULONG RequestCount
);
//
// Thread.c
//
VOID
MPIORecoveryThread(
IN PVOID Context
);
//
// Wmi.c
//
VOID
MPIOSetupWmi(
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
MPIOFdoWmi(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOPdoWmi(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MPIOFireEvent(
IN PDEVICE_OBJECT DeviceObject,
IN PWCHAR ComponentName,
IN PWCHAR EventDescription,
IN ULONG Severity
);
#endif // _MPATH_H