/*++ Copyright (c) 1999 Microsoft Corporation Module Name: dsm.h Abstract: This file defines the interface between Multipath Device-Specific drivers and the Main Multipath driver. Author: Notes: Revision History: --*/ #ifndef _DSM_H_ #define _DSM_H_ #include #include #include #include #include #include #include // // List of DSM Identifiers passed to several // of the dsm entry-points. // typedef struct _DSM_IDS { // // Number of ID's in the List. // ULONG Count; // // Array of DsmIdentiifiers // PVOID IdList[1]; } DSM_IDS, *PDSM_IDS; // // Identification and initialization routines (other than DSM registration with MPCTL.sys) // typedef NTSTATUS (*DSM_INQUIRE_DRIVER) ( IN PVOID DsmContext, IN PDEVICE_OBJECT TargetDevice, IN PDEVICE_OBJECT PortFdo, IN PSTORAGE_DEVICE_DESCRIPTOR Descriptor, IN PSTORAGE_DEVICE_ID_DESCRIPTOR DeviceIdList, OUT PVOID *DsmIdentifier ); /*++ Routine Description: This routine is used to determine if TargetDevice belongs to the DSM. If the device is owned by the driver, then DsmIdentifier will be updated with a DSM-derived value. Arguments: DsmContext - Context value given to the multipath driver during registration. TargetDevice - DeviceObject for the child device. PortFdo - The Port driver FDO on which TargetDevice resides. Descriptor - Pointer the device descriptor corresponding to TargetDevice. Rehash of inquiry data, plus serial number information (if applicable). DeviceIdList - VPD Page 0x83 information. DsmIdentifier - Pointer to be filled in by the DSM on success. Return Value: NTSTATUS of the operation. This may be STATUS_SUCCESS even if the disk is not owned by the DSM. --*/ typedef BOOLEAN (*DSM_COMPARE_DEVICES) ( IN PVOID DsmContext, IN PVOID DsmId1, IN PVOID DsmId2 ); /*++ Routine Description: This routine is called to determine if the device ids represent the same underlying physical device. Additional ids (more than 2) can be tested by repeatedly calling this function. It is the DSM responsibility to keep the necessary information to identify the device(s). Arguments: DsmContext - Context value given to the multipath driver during registration. DsmId1/2 - Identifers returned from DMS_INQUIRE_DRIVER. Return Value: TRUE if DsmIds correspond to the same underlying device. --*/ // // This controller is active. // #define DSM_CONTROLLER_ACTIVE 0x00000001 // // This controller is a stand-by controller. // #define DSM_CONTROLLER_STANDBY 0x00000002 // // This controller has failed. // #define DSM_CONTROLLER_FAILED 0x00000003 // // There are no controllers (JBOD, for example) // #define DSM_CONTROLLER_NO_CNTRL 0x00000004 typedef struct _CONTROLLER_INFO { // // The device object of the controller. // Retrieved by DsmGetAssociatedDevices. // PDEVICE_OBJECT DeviceObject; // // 64-bit identifier. WWN, for example. // ULONGLONG ControllerIdentifier; // // Controller state. See above. // ULONG State; } CONTROLLER_INFO, *PCONTROLLER_INFO; // // Informs the DSM that ControllerInfo must be allocated. // #define DSM_CNTRL_FLAGS_ALLOCATE 0x00000001 // // ControllerInfo is valid. The DSM should update 'State'. // #define DSM_CNTRL_FLAGS_CHECK_STATE 0x00000002 // // Possible future expansion. // #define DSM_CNTRL_FLAGS_RESERVED 0xFFFFFFFC typedef NTSTATUS (*DSM_GET_CONTROLLER_INFO) ( IN PVOID DsmContext, IN PVOID DsmId, IN ULONG Flags, IN OUT PCONTROLLER_INFO *ControllerInfo ); /*++ Routine Description: This routine is used to get information about the controller that the device corresponding to DsmId in on. The Dsm shall allocate the necessary memory for the buffer (mpio has the responsibility to free it) and fill in the information. If the DSM controls hardware that uses no controllers, set State to NO_CNTRL. This information is used mainly by whatever WMI admin. utilities want if. This routine will be called initially after SetDeviceInfo, but also to retrieve the controller's state when an WMI request is received, after a fail-over/fail-back, etc. Arguments: DsmContext - Context value given to the multipath driver during registration. DsmId - Identifer returned from DMS_INQUIRE_DRIVER. Flags - Bitfield of modifiers. If ALLOCATE is not set, ControllerInfo will have a valid buffer for the DSM to operate on. ControllerInfo - Pointer for the DSM to place the allocated controller info pertaining to DsmId Return Value: NTSTATUS --*/ typedef NTSTATUS (*DSM_SET_DEVICE_INFO) ( IN PVOID DsmContext, IN PDEVICE_OBJECT TargetObject, IN PVOID DsmId, IN OUT PVOID *PathId ); /*++ Routine Description: This routine associates a returned DsmId to the controlling MPDisk PDO the targetObject for DSM-initiated requests, and to a Path (given by PathId). The Path ID is a unique per-path value and will be the same value for ALL devices that are on the same physical path. Arguments: DsmContext - Context value given to the multipath driver during registration. TargetObject - The D.O. to which DSM-initiated requests should be sent. This is the Filter D.O. over the port PDO. DsmId - Value returned from DMSInquireDriver. PathId - Id that represents the path. The value passed in may be used as is, or the DSM optionally can update it if it requires additional state info to be kept. Return Value: DSM should return SUCCESS. Other errors may be returned in event of failed allocations, etc. These other errors are fatal. --*/ typedef BOOLEAN (*DSM_IS_PATH_ACTIVE) ( IN PVOID DsmContext, IN PVOID PathId ); /*++ Routine Description: This routine is used to determine whether the path is active (ie. able to handle requests without a failover). NOTE: This is used by the main module to determine load balance groups. If multiple paths are active to the same device then it is considered that requests can be submitted freely to ALL active paths, though the DSM is the determinator for path selection. In addition, after a failover, the path validity will be queried. If the path error was transitory and the DSM feels that the path is good, then this request will be re-issued to determine it's ACTIVE/PASSIVE state. Arguments: DsmContext - Context value given to the multipath driver during registration. PathId - Value set in SetPathId. Return Value: TRUE - if path is active. Otherwise, FALSE. --*/ // // Error Handling, Failover and recovery routines. // // When a fatal error occurs, the Path is invalidated and a new one // selected. // After the fail-over is complete, mpctl will invoke the DSM's Recovery routine // (if one is specified). Once the error has been dealt with, the DSM should notify // mpctl of the success of the operation. // PathVerify will be called with each DsmId that was on the path. // If this is successful, ReenablePath is invoked to allow the DSM any final preperations // before considering the path normal. // IsActive is called to build the load-balance associations. // #define DSM_FATAL_ERROR 0x80000000 #define DSM_ADMIN_FO 0x40000000 #define DSM_FATAL_ERROR_OEM_MASK 0x0000FFFF #define DSM_FATAL_ERROR_RESERVED 0x7FFF0000 typedef ULONG (*DSM_INTERPRET_ERROR) ( IN PVOID DsmContext, IN PVOID DsmId, IN PSCSI_REQUEST_BLOCK Srb, IN OUT PNTSTATUS Status, OUT PBOOLEAN Retry ); /*++ Routine Description: This routine informs the DSM that Srb has an error indicated with Srb->SrbStatus and/or Status. IF Srb->SrbFlags & SRB_FLAGS_AUTOSENSE_VALID is set, sense data will be available. The DSM should examine these, carry out any vendor-unique activities and update Retry and Status (if applicable). A determination should be made whether these errors constitute a fail over. Setting the high-bit of the return value indicates a fatal error. The DSM may additionally set any of the bits in the lower USHORT to facilitate information passing between this and the InvalidatePath routine. The Multipath driver (mpctl) will not override these return values. Arguments: DsmId - Identifers returned from DMS_INQUIRE_DRIVER. Srb - The Srb with an error. Status - NTSTATUS of the operation. Can be updated. Retry - Allows the DSM to indicate whether to retry the IO. Return Value: Setting DSM_FATAL_ERROR indicates a fatal error. DSM-specific info. can be kept in the lower WORD, which will be passed to InvalidatePath. --*/ typedef NTSTATUS (*DSM_INVALIDATE_PATH) ( IN PVOID DsmContext, IN ULONG ErrorMask, IN PVOID PathId, IN OUT PVOID *NewPathId ); /*++ Routine Description: This routine invalidates the given path and assigns the devices to the new path. NewPath is set to either an existing path or if all paths are dead, NULL. After this call, the DSM can attempt any recovery operations it can. Mpctl will start a recovery thread and if the DSM supports it (indication via the init data) will call the DSM autorecovery routine. After the timeout specified (in init data) or via DSMNotification, reenable path will be called. If this fails, mpctl will initiate teardown of the failed path's stack. Arguments: DsmContext - Context value given to the multipath driver during registration. ErrorMask - Value returned from InterpretError. PathId - The failing path. NewPathId - Pointer to the new path. Return Value: NTSTATUS of the operation. --*/ typedef NTSTATUS (*DSM_PATH_VERIFY) ( IN PVOID DsmContext, IN PVOID DsmId, IN PVOID PathId ); /*++ Routine Description: This routine is polled at a configurable interval and is used to determine the health of the device indicated by DsmId on PathId. The DSM makes the determination of validity using supplied library functions, or by issuing vendor-unique commands. After a fail-over condition has been dealt with, this is used as part of the fail-back mechanism. Arguments: DsmContext - Context value given to the multipath driver during registration. DsmId - Value returned from DMSInquireDriver. PathId - Value set in SetPathId. Return Value: NTSTATUS --*/ typedef NTSTATUS (*DSM_PATH_RECOVERY) ( IN PVOID DsmContext, IN PVOID PathId ); /*++ Routine Description: This OPTIONAL routine allows the DSM to carry out whatever path recovery logic it deems appropriate. It is up to the DSM to determine what constitutes the repair: private Admin WMI notification, vendor-unique commands to controller, device, adapter, ... Note that DsmNotification can be used in place of this routine to indicate a path repair, and is the preferred method. Arguments: DsmContext - Context value given to the multipath driver during registration. PathId - Path to re-enable. Return Value: NTSTATUS - STATUS_SUCCESS if condition that led to the fail-over has been repaired. Otherwise appropriate status. --*/ typedef NTSTATUS (*DSM_REENABLE_PATH) ( IN PVOID DsmContext, IN PVOID PathId, OUT PULONG DSMErrorId ); /*++ Routine Description: This routine allows the DSM to bring a previously failed path back online. Mpctl has determined that it believes the error condition was transitory (via an admin utility of DSMNotification) or has been repaired. The DSM should return success, only if the path can handle requests to it's devices. This will be issued after a failover and subsequent autorecovery/admin notification. If the error was transitory, or the DSM/Device was able to repair the problem, this gives the DSM the opportunity to bring the failed path back online (as far as mpctl is concerned). Arguments: DsmContext - Context value given to the multipath driver during registration. PathId - Path to re-enable. DSMErrorId - DSM specific error value - not interpreted, rather used for logging. Return Value: NTSTATUS - STATUS_SUCCESS if path is now capable of handling requests. Otherwise appropriate status. --*/ // // PERMANENT indicates that SuggestedPath should be the device's preferred path. // PENDING_REMOVAL indicates that the path is about to go away. // OEM_MASK values specific to the DSM // RESERVED future expansion // ADMIN_REQUEST indicates that the request originated from some user-mode utility. // #define DSM_MOVE_PERMANENT 0x00000001 #define DSM_MOVE_PENDING_REMOVAL 0x00000002 #define DSM_MOVE_OEM_MASK 0x0000FF00 #define DSM_MOVE_RESERVED 0x7FFF0000 #define DSM_MOVE_ADMIN_REQUEST 0x80000000 typedef NTSTATUS (*DSM_MOVE_DEVICE) ( IN PVOID DsmContext, IN PDSM_IDS DsmIds, IN PVOID MPIOPath, IN PVOID SuggestedPath, IN ULONG Flags ); /*++ Routine Description: This routine is invoked (usually) in response to an administrative request. The DSM will associate the Device described by DsmId to the SuggestedPath, or may select another available. As this request will usually be followed by an adapter removal, or can be used to set-up static load-balancing. Arguments: DsmContext - Context value given to the multipath driver during registration. DsmIds - The collection of DSM IDs that pertain to the MPDisk. MPIOPath - The original path value passed to SetDeviceInfo. SuggestedPath - The path which should become the active path. Flags - Bitmask indicating the intent of the move. Return Value: NTSTATUS - STATUS_SUCCESS, some error status if there are no good alternate paths. --*/ typedef NTSTATUS (*DSM_REMOVE_PENDING) ( IN PVOID DsmContext, IN PVOID DsmId ); /*++ Routine Description: This routine indicates that the device represented by DsmId will be removed, though due to outstanding I/Os or other conditions, it can't be removed immediately. The DSM_ID list passed to other functions will no longer contain DsmId, so internal structures should be updated accordingly. Arguments: DsmContext - Context value given to the multipath driver during registration. DsmId - Value referring to the failed device. Return Value: NTSTATUS of the operation. --*/ typedef NTSTATUS (*DSM_REMOVE_DEVICE) ( IN PVOID DsmContext, IN PVOID DsmId, IN PVOID PathId ); /*++ Routine Description: This routine indicates that the main path has determined or been notified that thedevice has failed and should be removed from PathId. Arguments: DsmContext - Context value given to the multipath driver during registration. DsmId - Value referring to the failed device. PathId - The path on which the Device lives. Return Value: NTSTATUS of the operation. --*/ typedef NTSTATUS (*DSM_REMOVE_PATH) ( IN PVOID DsmContext, IN PVOID PathId ); /*++ Routine Description: This routine indicates that the path is no longer valid, and that the DSM should update it's internal state appropriately (tear down the structure, free allocations, ...). It is the responsibility of mpctl.sys to have already removed the devices (via RemoveDevice) that are attached to this path. Arguments: DsmContext - Context value given to the multipath driver during registration. PathId - The path to remove. Return Value: NTSTATUS of the operation. --*/ #define DSM_BROADCAST 0x00000001 #define DSM_WILL_HANDLE 0x00000002 #define DSM_PATH_SET 0x00000003 #define DSM_ERROR 0x00000004 // // IOCTL handling routines. // typedef ULONG (*DSM_CATEGORIZE_REQUEST) ( IN PVOID DsmContext, IN PDSM_IDS DsmIds, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb, IN PVOID CurrentPath, OUT PVOID *PathId, OUT NTSTATUS *Status ); /*++ Routine Description: The routine is called when a request other than R/W is being handled. The DSM indicates whether the request should be handled by it's DsmBroadcastRequest, DsmSrbDeviceControl, or that the PathID indicated should be used. Arguments: DsmIds - The collection of DSM IDs that pertain to the MPDisk. Irp - The Irp containing Srb. Srb - Scsi request block CurrentPath - Path to which last request was sent PathId - Updated to the PathId where the request should be sent if return value is DSM_PATH_SET. Status - Storage for status in the event that DSM_ERROR is returned. Return Value: DSM_BROADCAST - If BroadcastRequest should be used. DSM_WILL_HANDLE - If SrbDeviceControl should be used. DSM_PATH_SET - If the Srb should just be sent to PathId DSM_ERROR - Indicates that an error occurred where by the request can't be handled. Status is updated, along with Srb->SrbStatus. --*/ typedef NTSTATUS (*DSM_BROADCAST_SRB) ( IN PVOID DsmContext, IN PDSM_IDS DsmIds, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb, IN PKEVENT Event ); /*++ Routine Description: This routine is called when the DSM has indicated that Srb should be sent to the device down all paths. The DSM will update IoStatus information and status, but not complete the request. Arguments: DsmIds - The collection of DSM IDs that pertain to the MPDisk. Irp - Irp containing SRB. Srb - Scsi request block Event - DSM sets this once all sub-requests have completed and the original request's IoStatus has been setup. Return Value: NTSTATUS of the operation. --*/ typedef NTSTATUS (*DSM_SRB_DEVICE_CONTROL) ( IN PVOID DsmContext, IN PDSM_IDS DsmIds, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb, IN PKEVENT Event ); /*++ Routine Description: This routine is called when the DSM has indicated that it wants to handle it internally (via CATEGORIZE_REQUEST). It should set IoStatus (Status and Information) and the Event, but not complete the request. Arguments: DsmIds - The collection of DSM IDs that pertain to the MPDISK. Irp - Irp containing SRB. Srb - Scsi request block Event - Event to be set when the DSM is finished if DsmHandled is TRUE Return Value: NTSTATUS of the request. --*/ typedef VOID (*DSM_COMPLETION_ROUTINE) ( IN PVOID DsmId, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb, IN PVOID DsmContext ); typedef struct _DSM_COMPLETION_INFO { // // Routine to be invoked on request completion. // DSM_COMPLETION_ROUTINE DsmCompletionRoutine; // // Context to be supplied. // PVOID DsmContext; } DSM_COMPLETION_INFO, *PDSM_COMPLETION_INFO; typedef VOID (*DSM_SET_COMPLETION) ( IN PVOID DsmContext, IN PVOID DsmId, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb, IN OUT PDSM_COMPLETION_INFO DsmCompletion ); /*++ Routine Description: This routine is called before the actual submission of a request, but after the categorisation of the I/O. This will be called only for those requests not handled by the DSM directly: Read/Write Other requests not handled by SrbControl or Broadcast The DSM can supply a completion routine and context which will be invoked when the request completion is being handled. It is not necessary to set completions on any or all requests. Arguments: DsmId - Identifer that was indicated when the request was categorized (or be LBGetPath) Irp - Irp containing Srb. Srb - The request DsmCompletion - Completion info structure to be filled out by DSM. Return Value: None --*/ #define NUMA_MAX_WEIGHT 10 typedef PVOID (*DSM_LB_GET_PATH) ( IN PVOID DsmContext, IN PSCSI_REQUEST_BLOCK Srb, IN PDSM_IDS DsmList, IN PVOID CurrentPath, OUT NTSTATUS *Status ); /*++ Routine Description: This routine is called once per I/O and gives the DSM the ability to indicate to which path the request should be submitted. If the DSM returns a Path that was not active, this constitutes a Fail-over condition. Arguments: Srb - The request that needs to be submitted DsmList - Ids of the devices that make up the multipath group. CurrentPath - Path to which last request was sent Status - Storage for an error status, if returning NULL path. Return Value: PathId to where the request should be sent. NULL if all current paths are failed. --*/ // // WMI structs, defines, routines. // typedef NTSTATUS (*DSM_QUERY_DATABLOCK) ( IN PVOID DsmContext, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG InstanceCount, IN OUT PULONG InstanceLengthArray, IN ULONG BufferAvail, OUT PUCHAR Buffer, OUT PULONG DsmDataLength ); /*++ Routine Description: Arguments: Return Value: status --*/ typedef NTSTATUS (*DSM_SET_DATABLOCK) ( IN PVOID DsmContext, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG BufferSize, IN PUCHAR Buffer ); typedef NTSTATUS (*DSM_SET_DATAITEM) ( IN PVOID DsmContext, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG DataItemId, IN ULONG BufferSize, IN PUCHAR Buffer ); typedef NTSTATUS (*DSM_EXECUTE_METHOD) ( IN PVOID DsmContext, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG MethodId, IN ULONG InBufferSize, IN ULONG OutBufferSize, IN OUT PUCHAR Buffer ); typedef NTSTATUS (*DSM_FUNCTION_CONTROL) ( IN PVOID DsmContext, IN PIRP Irp, IN ULONG GuidIndex, IN WMIENABLEDISABLECONTROL Function, IN BOOLEAN Enable ); typedef struct _DSM_WMILIB_CONTEXT { ULONG GuidCount; PWMIGUIDREGINFO GuidList; DSM_QUERY_DATABLOCK QueryWmiDataBlock; DSM_SET_DATABLOCK SetWmiDataBlock; DSM_SET_DATAITEM SetWmiDataItem; DSM_EXECUTE_METHOD ExecuteWmiMethod; DSM_FUNCTION_CONTROL WmiFunctionControl; } DSM_WMILIB_CONTEXT, *PDSM_WMILIB_CONTEXT; // // Unload routine. // typedef NTSTATUS (*DSM_UNLOAD) ( IN PVOID DsmContext ); /*++ Routine Description: This routine is called when the main module requires the DSM to be unloaded (ie. prior to the main module unload). Arguments: DsmContext - Context value passed to DsmInitialize() Return Value: NTSTATUS - Had best be STATUS_SUCCESS; --*/ // // Registration routines. // // Called in the DSM's DriverEntry. // The DSM will register with the main module by filling in the following structure // and sending the REGISTER IOCTL // typedef struct _DSM_INIT_DATA { // // Size, in bytes. // ULONG InitDataSize; // // DSM entry points. // DSM_INQUIRE_DRIVER DsmInquireDriver; DSM_COMPARE_DEVICES DsmCompareDevices; DSM_GET_CONTROLLER_INFO DsmGetControllerInfo; DSM_SET_DEVICE_INFO DsmSetDeviceInfo; DSM_IS_PATH_ACTIVE DsmIsPathActive; DSM_PATH_VERIFY DsmPathVerify; DSM_INVALIDATE_PATH DsmInvalidatePath; DSM_MOVE_DEVICE DsmMoveDevice; DSM_REMOVE_PENDING DsmRemovePending; DSM_REMOVE_DEVICE DsmRemoveDevice; DSM_REMOVE_PATH DsmRemovePath; DSM_SRB_DEVICE_CONTROL DsmSrbDeviceControl; DSM_REENABLE_PATH DsmReenablePath; DSM_LB_GET_PATH DsmLBGetPath; DSM_INTERPRET_ERROR DsmInterpretError; DSM_UNLOAD DsmUnload; DSM_SET_COMPLETION DsmSetCompletion; DSM_CATEGORIZE_REQUEST DsmCategorizeRequest; DSM_BROADCAST_SRB DsmBroadcastSrb; // // Wmi entry point and guid information. // DSM_WMILIB_CONTEXT DsmWmiInfo; // // Context value. // PVOID DsmContext; // // DriverObject for the DSM. // PDRIVER_OBJECT DriverObject; // // Friendly name for the DSM. // UNICODE_STRING DisplayName; // // Reserved. // ULONG Reserved; } DSM_INIT_DATA, *PDSM_INIT_DATA; // // Output structure for the registration. The DSM needs to keep this value for certain // routines such as DsmNotification and DsmGetTargetObject. // typedef struct _DSM_MPIO_CONTEXT { PVOID MPIOContext; } DSM_MPIO_CONTEXT, *PDSM_MPIO_CONTEXT; #define MPIO_DSM ((ULONG) 'dsm') // // IOCTL handled by the DSM that the MultiPath Control driver sends to get entry point info. // Output structure defined above (DSM_INIT_DATA). // #define IOCTL_MPDSM_REGISTER CTL_CODE (MPIO_DSM, 0x01, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // // DSM library routines. // VOID DsmSendDeviceIoControlSynchronous( IN ULONG IoControlCode, IN PDEVICE_OBJECT TargetDeviceObject, IN PVOID InputBuffer OPTIONAL, IN OUT PVOID OutputBuffer OPTIONAL, IN ULONG InputBufferLength, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, OUT PIO_STATUS_BLOCK IoStatus ); /*++ Routine Description: This routine is used by the DSM to send IoDeviceControls. Buffer must be of the appropriate size to encapsulate both input and output. This routine handles errors/retries. Arguments: IoControlCode - The DeviceIoControl code. TargetDevice - DeviceObject to which the request should be sent. Buffer - The input/output buffer for the request. InputBufferLength - Length of the input parameters buffer. OutputBufferLength - Length of the output buffer InternalDeviceIoControl - Indicates whether the IOCTL is marked as Internal or public. IoStatus - IO STATUS BLOCK to receive the final status/information fields. Return Value: NONE --*/ NTSTATUS DsmGetDescriptor( IN PDEVICE_OBJECT DeviceObject, IN PSTORAGE_PROPERTY_ID PropertyId, OUT PSTORAGE_DESCRIPTOR_HEADER *Descriptor ); NTSTATUS DsmSendPassThroughDirect( IN PDEVICE_OBJECT DeviceObject, IN PSCSI_PASS_THROUGH_DIRECT ScsiPassThrough, IN ULONG InputBufferLength, IN ULONG OutputBufferLength ); PDSM_IDS DsmGetAssociatedDevice( IN PVOID MPIOContext, IN PDEVICE_OBJECT PortFdo, IN UCHAR DeviceType ); /*++ Routine Description: If the DSM needs to acquire information from other devices (such as a controller), this routine can be used to get a list of the PDO's associated with PortFdo. Arguments: PortFdo - Port driver FDO passed to InquireDriver. DeviceType - Indicates the SCSI DeviceType to return. Return Value: Pointer to a DSM_ID structure, where IdList entries are PDEVICE_OBJECT. It is the reponsibility of the DSM to free the buffer. --*/ NTSTATUS DsmReleaseQueue( IN PDEVICE_OBJECT TargetDevice ); /*++ Routine Description: In the event that a DSM-originated request freezes the queue (SRB_STATUS_QUEUE_FROZEN), this must be used to un-freeze the queue. DSM's must check the SRB_STATUS_XXX values upon request completion for those requests that they sent. Arguments: TargetDevice - DeviceObject to which the release queue should be sent. Return Value: Status of of the ReleaseQueue IOCTL. --*/ NTSTATUS DsmSendTUR( IN PDEVICE_OBJECT TargetDevice ); /*++ Routine Description: Sends a Test Unit Ready to TargetDevice. Arguments: TargetDevice - DeviceObject to which the TUR should be sent. Return Value: Status of of the TUR. --*/ NTSTATUS DsmSendRequest( IN PDEVICE_OBJECT TargetDevice, IN PIRP Irp, IN PVOID DsmId ); /*++ Routine Description: This routine is used by the DSM to send it's OOB, Broadcast, or any other DSM built requests to TargetDevice. Not to be used for Irps sent to the DSM by the MPIO driver. Using this routine allows MPIO to maintain the necessary state info so that Power and PnP requests can be handled correctly. Arguments: TargetDevice - DeviceObject to which Irp should be sent. Irp - The request to send. DsmId - DSM value referring to the port PDO. Return Value: Status of IoCallDriver or an error status if one is detected. --*/ ULONG DsmGetSystemWeight( IN PVOID MPIOContext, IN PIRP Irp, IN PVOID PathId ); /*++ Routine Description: This routine is used by the DSM to determine the cost associated with issuing the request to PathId for the system. For example, cross node accesses on a NUMA system. Arguments: MPIOContext - Value given to the DSM during initialization. Irp - The request to send. PathId - One of the PathId values for the MPDisk. (SetDeviceInfo). Return Value: Relative system cost of issuing Irp to PathId. (ULONG)-1 indicates this Path is unreachable. --*/ typedef enum _DSM_NOTIFICATION_TYPE { DeviceFailure, PathFailure, PathOnLine, ThrottleIO, ResumeIO, MaxDsmNotificationType } DSM_NOTIFICATION_TYPE, *PDSM_NOTIFICATION_TYPE; VOID DsmNotification( IN PVOID MpctlContext, IN DSM_NOTIFICATION_TYPE NotificationType, IN PVOID AdditionalParameters ); /*++ Routine Description: This routine is called by the DSM to inform mpctl of certain events such as Device/Path failure, Device/Path coming back online after a failure, WMI Events, or TBD.... Arguments: MpctlContext - Value given to the DSM during initialization. NotificationType - Specifies the type of notification. Additional Parameters depend on NotificationType DeviceFailure - DsmId PathFailure - PathId PathOnLine - PathId ThrottleIO - PathId ResumeIO - PathId Return Value: None --*/ NTSTATUS DsmWriteEvent( IN PVOID MPIOContext, IN PWCHAR ComponentName, IN PWCHAR EventDescription, IN ULONG Severity ); /*++ Routine Description: The will cause a WMI Event to be fired, containing the Paramter information as the event data. Arguments: MpctlContext - Value given to the DSM during initialization. ComponentName - Name of the object effected. EventDescription - Description of the event. Severity - Lower is worse. Return Value: None --*/ #endif // _DSM_H_