Source code of Windows XP (NT5)
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.

1224 lines
30 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. dsm.h
  5. Abstract:
  6. This file defines the interface between Multipath Device-Specific drivers and the
  7. Main Multipath driver.
  8. Author:
  9. Notes:
  10. Revision History:
  11. --*/
  12. #ifndef _DSM_H_
  13. #define _DSM_H_
  14. #include <ntddk.h>
  15. #include <scsi.h>
  16. #include <ntddscsi.h>
  17. #include <ntddstor.h>
  18. #include <wmistr.h>
  19. #include <wmiguid.h>
  20. #include <wmilib.h>
  21. //
  22. // List of DSM Identifiers passed to several
  23. // of the dsm entry-points.
  24. //
  25. typedef struct _DSM_IDS {
  26. //
  27. // Number of ID's in the List.
  28. //
  29. ULONG Count;
  30. //
  31. // Array of DsmIdentiifiers
  32. //
  33. PVOID IdList[1];
  34. } DSM_IDS, *PDSM_IDS;
  35. //
  36. // Identification and initialization routines (other than DSM registration with MPCTL.sys)
  37. //
  38. typedef
  39. NTSTATUS
  40. (*DSM_INQUIRE_DRIVER) (
  41. IN PVOID DsmContext,
  42. IN PDEVICE_OBJECT TargetDevice,
  43. IN PDEVICE_OBJECT PortFdo,
  44. IN PSTORAGE_DEVICE_DESCRIPTOR Descriptor,
  45. IN PSTORAGE_DEVICE_ID_DESCRIPTOR DeviceIdList,
  46. OUT PVOID *DsmIdentifier
  47. );
  48. /*++
  49. Routine Description:
  50. This routine is used to determine if TargetDevice belongs to the DSM.
  51. If the device is owned by the driver, then DsmIdentifier will be updated with a
  52. DSM-derived value.
  53. Arguments:
  54. DsmContext - Context value given to the multipath driver during registration.
  55. TargetDevice - DeviceObject for the child device.
  56. PortFdo - The Port driver FDO on which TargetDevice resides.
  57. Descriptor - Pointer the device descriptor corresponding to TargetDevice. Rehash of inquiry
  58. data, plus serial number information (if applicable).
  59. DeviceIdList - VPD Page 0x83 information.
  60. DsmIdentifier - Pointer to be filled in by the DSM on success.
  61. Return Value:
  62. NTSTATUS of the operation. This may be STATUS_SUCCESS even if the disk is not owned by the DSM.
  63. --*/
  64. typedef
  65. BOOLEAN
  66. (*DSM_COMPARE_DEVICES) (
  67. IN PVOID DsmContext,
  68. IN PVOID DsmId1,
  69. IN PVOID DsmId2
  70. );
  71. /*++
  72. Routine Description:
  73. This routine is called to determine if the device ids represent the same underlying
  74. physical device.
  75. Additional ids (more than 2) can be tested by repeatedly calling this function.
  76. It is the DSM responsibility to keep the necessary information to identify the device(s).
  77. Arguments:
  78. DsmContext - Context value given to the multipath driver during registration.
  79. DsmId1/2 - Identifers returned from DMS_INQUIRE_DRIVER.
  80. Return Value:
  81. TRUE if DsmIds correspond to the same underlying device.
  82. --*/
  83. //
  84. // This controller is active.
  85. //
  86. #define DSM_CONTROLLER_ACTIVE 0x00000001
  87. //
  88. // This controller is a stand-by controller.
  89. //
  90. #define DSM_CONTROLLER_STANDBY 0x00000002
  91. //
  92. // This controller has failed.
  93. //
  94. #define DSM_CONTROLLER_FAILED 0x00000003
  95. //
  96. // There are no controllers (JBOD, for example)
  97. //
  98. #define DSM_CONTROLLER_NO_CNTRL 0x00000004
  99. typedef struct _CONTROLLER_INFO {
  100. //
  101. // The device object of the controller.
  102. // Retrieved by DsmGetAssociatedDevices.
  103. //
  104. PDEVICE_OBJECT DeviceObject;
  105. //
  106. // 64-bit identifier. WWN, for example.
  107. //
  108. ULONGLONG ControllerIdentifier;
  109. //
  110. // Controller state. See above.
  111. //
  112. ULONG State;
  113. } CONTROLLER_INFO, *PCONTROLLER_INFO;
  114. //
  115. // Informs the DSM that ControllerInfo must be allocated.
  116. //
  117. #define DSM_CNTRL_FLAGS_ALLOCATE 0x00000001
  118. //
  119. // ControllerInfo is valid. The DSM should update 'State'.
  120. //
  121. #define DSM_CNTRL_FLAGS_CHECK_STATE 0x00000002
  122. //
  123. // Possible future expansion.
  124. //
  125. #define DSM_CNTRL_FLAGS_RESERVED 0xFFFFFFFC
  126. typedef
  127. NTSTATUS
  128. (*DSM_GET_CONTROLLER_INFO) (
  129. IN PVOID DsmContext,
  130. IN PVOID DsmId,
  131. IN ULONG Flags,
  132. IN OUT PCONTROLLER_INFO *ControllerInfo
  133. );
  134. /*++
  135. Routine Description:
  136. This routine is used to get information about the controller that the device
  137. corresponding to DsmId in on.
  138. The Dsm shall allocate the necessary memory for the buffer (mpio has the responsibility
  139. to free it) and fill in the information.
  140. If the DSM controls hardware that uses no controllers, set State to NO_CNTRL.
  141. This information is used mainly by whatever WMI admin. utilities want if.
  142. This routine will be called initially after SetDeviceInfo, but also to retrieve
  143. the controller's state when an WMI request is received, after a fail-over/fail-back, etc.
  144. Arguments:
  145. DsmContext - Context value given to the multipath driver during registration.
  146. DsmId - Identifer returned from DMS_INQUIRE_DRIVER.
  147. Flags - Bitfield of modifiers. If ALLOCATE is not set, ControllerInfo will have
  148. a valid buffer for the DSM to operate on.
  149. ControllerInfo - Pointer for the DSM to place the allocated controller info
  150. pertaining to DsmId
  151. Return Value:
  152. NTSTATUS
  153. --*/
  154. typedef
  155. NTSTATUS
  156. (*DSM_SET_DEVICE_INFO) (
  157. IN PVOID DsmContext,
  158. IN PDEVICE_OBJECT TargetObject,
  159. IN PVOID DsmId,
  160. IN OUT PVOID *PathId
  161. );
  162. /*++
  163. Routine Description:
  164. This routine associates a returned DsmId to the controlling MPDisk PDO
  165. the targetObject for DSM-initiated requests, and to a Path (given by PathId).
  166. The Path ID is a unique per-path value and will be the same value for ALL devices that
  167. are on the same physical path.
  168. Arguments:
  169. DsmContext - Context value given to the multipath driver during registration.
  170. TargetObject - The D.O. to which DSM-initiated requests should be sent.
  171. This is the Filter D.O. over the port PDO.
  172. DsmId - Value returned from DMSInquireDriver.
  173. PathId - Id that represents the path. The value passed in may be used as is, or the DSM
  174. optionally can update it if it requires additional state info to be kept.
  175. Return Value:
  176. DSM should return SUCCESS. Other errors may be returned in event of failed
  177. allocations, etc. These other errors are fatal.
  178. --*/
  179. typedef
  180. BOOLEAN
  181. (*DSM_IS_PATH_ACTIVE) (
  182. IN PVOID DsmContext,
  183. IN PVOID PathId
  184. );
  185. /*++
  186. Routine Description:
  187. This routine is used to determine whether the path is active (ie. able to handle requests
  188. without a failover).
  189. NOTE: This is used by the main module to determine load balance groups. If multiple
  190. paths are active to the same device then it is considered that requests can be
  191. submitted freely to ALL active paths, though the DSM is the determinator for path
  192. selection.
  193. In addition, after a failover, the path validity will be queried. If the path error
  194. was transitory and the DSM feels that the path is good, then this request will be
  195. re-issued to determine it's ACTIVE/PASSIVE state.
  196. Arguments:
  197. DsmContext - Context value given to the multipath driver during registration.
  198. PathId - Value set in SetPathId.
  199. Return Value:
  200. TRUE - if path is active. Otherwise, FALSE.
  201. --*/
  202. //
  203. // Error Handling, Failover and recovery routines.
  204. //
  205. // When a fatal error occurs, the Path is invalidated and a new one
  206. // selected.
  207. // After the fail-over is complete, mpctl will invoke the DSM's Recovery routine
  208. // (if one is specified). Once the error has been dealt with, the DSM should notify
  209. // mpctl of the success of the operation.
  210. // PathVerify will be called with each DsmId that was on the path.
  211. // If this is successful, ReenablePath is invoked to allow the DSM any final preperations
  212. // before considering the path normal.
  213. // IsActive is called to build the load-balance associations.
  214. //
  215. #define DSM_FATAL_ERROR 0x80000000
  216. #define DSM_ADMIN_FO 0x40000000
  217. #define DSM_FATAL_ERROR_OEM_MASK 0x0000FFFF
  218. #define DSM_FATAL_ERROR_RESERVED 0x7FFF0000
  219. typedef
  220. ULONG
  221. (*DSM_INTERPRET_ERROR) (
  222. IN PVOID DsmContext,
  223. IN PVOID DsmId,
  224. IN PSCSI_REQUEST_BLOCK Srb,
  225. IN OUT PNTSTATUS Status,
  226. OUT PBOOLEAN Retry
  227. );
  228. /*++
  229. Routine Description:
  230. This routine informs the DSM that Srb has an error indicated with Srb->SrbStatus and/or Status.
  231. IF Srb->SrbFlags & SRB_FLAGS_AUTOSENSE_VALID is set, sense data will be available.
  232. The DSM should examine these, carry out any vendor-unique activities and update Retry and Status
  233. (if applicable). A determination should be made whether these errors constitute a fail over.
  234. Setting the high-bit of the return value indicates a fatal error. The DSM may additionally
  235. set any of the bits in the lower USHORT to facilitate information passing between this and
  236. the InvalidatePath routine.
  237. The Multipath driver (mpctl) will not override these return values.
  238. Arguments:
  239. DsmId - Identifers returned from DMS_INQUIRE_DRIVER.
  240. Srb - The Srb with an error.
  241. Status - NTSTATUS of the operation. Can be updated.
  242. Retry - Allows the DSM to indicate whether to retry the IO.
  243. Return Value:
  244. Setting DSM_FATAL_ERROR indicates a fatal error. DSM-specific info. can be kept in
  245. the lower WORD, which will be passed to InvalidatePath.
  246. --*/
  247. typedef
  248. NTSTATUS
  249. (*DSM_INVALIDATE_PATH) (
  250. IN PVOID DsmContext,
  251. IN ULONG ErrorMask,
  252. IN PVOID PathId,
  253. IN OUT PVOID *NewPathId
  254. );
  255. /*++
  256. Routine Description:
  257. This routine invalidates the given path and assigns the devices to the new path.
  258. NewPath is set to either an existing path or if all paths are dead, NULL.
  259. After this call, the DSM can attempt any recovery operations it can. Mpctl will start
  260. a recovery thread and if the DSM supports it (indication via the init data) will call
  261. the DSM autorecovery routine. After the timeout specified (in init data) or via
  262. DSMNotification, reenable path will be called. If this fails, mpctl will initiate
  263. teardown of the failed path's stack.
  264. Arguments:
  265. DsmContext - Context value given to the multipath driver during registration.
  266. ErrorMask - Value returned from InterpretError.
  267. PathId - The failing path.
  268. NewPathId - Pointer to the new path.
  269. Return Value:
  270. NTSTATUS of the operation.
  271. --*/
  272. typedef
  273. NTSTATUS
  274. (*DSM_PATH_VERIFY) (
  275. IN PVOID DsmContext,
  276. IN PVOID DsmId,
  277. IN PVOID PathId
  278. );
  279. /*++
  280. Routine Description:
  281. This routine is polled at a configurable interval and is used to determine the
  282. health of the device indicated by DsmId on PathId. The DSM makes the determination of
  283. validity using supplied library functions, or by issuing vendor-unique commands.
  284. After a fail-over condition has been dealt with, this is used as part of the fail-back
  285. mechanism.
  286. Arguments:
  287. DsmContext - Context value given to the multipath driver during registration.
  288. DsmId - Value returned from DMSInquireDriver.
  289. PathId - Value set in SetPathId.
  290. Return Value:
  291. NTSTATUS
  292. --*/
  293. typedef
  294. NTSTATUS
  295. (*DSM_PATH_RECOVERY) (
  296. IN PVOID DsmContext,
  297. IN PVOID PathId
  298. );
  299. /*++
  300. Routine Description:
  301. This OPTIONAL routine allows the DSM to carry out whatever path recovery logic it deems
  302. appropriate. It is up to the DSM to determine what constitutes the repair:
  303. private Admin WMI notification,
  304. vendor-unique commands to controller, device, adapter,
  305. ...
  306. Note that DsmNotification can be used in place of this routine to indicate a path
  307. repair, and is the preferred method.
  308. Arguments:
  309. DsmContext - Context value given to the multipath driver during registration.
  310. PathId - Path to re-enable.
  311. Return Value:
  312. NTSTATUS - STATUS_SUCCESS if condition that led to the fail-over has been repaired.
  313. Otherwise appropriate status.
  314. --*/
  315. typedef
  316. NTSTATUS
  317. (*DSM_REENABLE_PATH) (
  318. IN PVOID DsmContext,
  319. IN PVOID PathId,
  320. OUT PULONG DSMErrorId
  321. );
  322. /*++
  323. Routine Description:
  324. This routine allows the DSM to bring a previously failed path back online.
  325. Mpctl has determined that it believes the error condition was transitory (via an admin utility
  326. of DSMNotification) or has been repaired.
  327. The DSM should return success, only if the path can handle requests to it's devices.
  328. This will be issued after a failover and subsequent autorecovery/admin notification.
  329. If the error was transitory, or the DSM/Device was able to repair
  330. the problem, this gives the DSM the opportunity to bring the failed path back online
  331. (as far as mpctl is concerned).
  332. Arguments:
  333. DsmContext - Context value given to the multipath driver during registration.
  334. PathId - Path to re-enable.
  335. DSMErrorId - DSM specific error value - not interpreted, rather used for logging.
  336. Return Value:
  337. NTSTATUS - STATUS_SUCCESS if path is now capable of handling requests.
  338. Otherwise appropriate status.
  339. --*/
  340. //
  341. // PERMANENT indicates that SuggestedPath should be the device's preferred path.
  342. // PENDING_REMOVAL indicates that the path is about to go away.
  343. // OEM_MASK values specific to the DSM
  344. // RESERVED future expansion
  345. // ADMIN_REQUEST indicates that the request originated from some user-mode utility.
  346. //
  347. #define DSM_MOVE_PERMANENT 0x00000001
  348. #define DSM_MOVE_PENDING_REMOVAL 0x00000002
  349. #define DSM_MOVE_OEM_MASK 0x0000FF00
  350. #define DSM_MOVE_RESERVED 0x7FFF0000
  351. #define DSM_MOVE_ADMIN_REQUEST 0x80000000
  352. typedef
  353. NTSTATUS
  354. (*DSM_MOVE_DEVICE) (
  355. IN PVOID DsmContext,
  356. IN PDSM_IDS DsmIds,
  357. IN PVOID MPIOPath,
  358. IN PVOID SuggestedPath,
  359. IN ULONG Flags
  360. );
  361. /*++
  362. Routine Description:
  363. This routine is invoked (usually) in response to an administrative request.
  364. The DSM will associate the Device described by DsmId to the SuggestedPath, or may
  365. select another available. As this request will usually be followed by an adapter
  366. removal, or can be used to set-up static load-balancing.
  367. Arguments:
  368. DsmContext - Context value given to the multipath driver during registration.
  369. DsmIds - The collection of DSM IDs that pertain to the MPDisk.
  370. MPIOPath - The original path value passed to SetDeviceInfo.
  371. SuggestedPath - The path which should become the active path.
  372. Flags - Bitmask indicating the intent of the move.
  373. Return Value:
  374. NTSTATUS - STATUS_SUCCESS, some error status if there are no good alternate paths.
  375. --*/
  376. typedef
  377. NTSTATUS
  378. (*DSM_REMOVE_PENDING) (
  379. IN PVOID DsmContext,
  380. IN PVOID DsmId
  381. );
  382. /*++
  383. Routine Description:
  384. This routine indicates that the device represented by DsmId will be removed, though
  385. due to outstanding I/Os or other conditions, it can't be removed immediately.
  386. The DSM_ID list passed to other functions will no longer contain DsmId, so internal
  387. structures should be updated accordingly.
  388. Arguments:
  389. DsmContext - Context value given to the multipath driver during registration.
  390. DsmId - Value referring to the failed device.
  391. Return Value:
  392. NTSTATUS of the operation.
  393. --*/
  394. typedef
  395. NTSTATUS
  396. (*DSM_REMOVE_DEVICE) (
  397. IN PVOID DsmContext,
  398. IN PVOID DsmId,
  399. IN PVOID PathId
  400. );
  401. /*++
  402. Routine Description:
  403. This routine indicates that the main path has determined or been notified that thedevice
  404. has failed and should be removed from PathId.
  405. Arguments:
  406. DsmContext - Context value given to the multipath driver during registration.
  407. DsmId - Value referring to the failed device.
  408. PathId - The path on which the Device lives.
  409. Return Value:
  410. NTSTATUS of the operation.
  411. --*/
  412. typedef
  413. NTSTATUS
  414. (*DSM_REMOVE_PATH) (
  415. IN PVOID DsmContext,
  416. IN PVOID PathId
  417. );
  418. /*++
  419. Routine Description:
  420. This routine indicates that the path is no longer valid, and that the DSM should update
  421. it's internal state appropriately (tear down the structure, free allocations, ...).
  422. It is the responsibility of mpctl.sys to have already removed the devices (via RemoveDevice)
  423. that are attached to this path.
  424. Arguments:
  425. DsmContext - Context value given to the multipath driver during registration.
  426. PathId - The path to remove.
  427. Return Value:
  428. NTSTATUS of the operation.
  429. --*/
  430. #define DSM_BROADCAST 0x00000001
  431. #define DSM_WILL_HANDLE 0x00000002
  432. #define DSM_PATH_SET 0x00000003
  433. #define DSM_ERROR 0x00000004
  434. //
  435. // IOCTL handling routines.
  436. //
  437. typedef
  438. ULONG
  439. (*DSM_CATEGORIZE_REQUEST) (
  440. IN PVOID DsmContext,
  441. IN PDSM_IDS DsmIds,
  442. IN PIRP Irp,
  443. IN PSCSI_REQUEST_BLOCK Srb,
  444. IN PVOID CurrentPath,
  445. OUT PVOID *PathId,
  446. OUT NTSTATUS *Status
  447. );
  448. /*++
  449. Routine Description:
  450. The routine is called when a request other than R/W is being handled.
  451. The DSM indicates whether the request should be handled by it's DsmBroadcastRequest,
  452. DsmSrbDeviceControl, or that the PathID indicated should be used.
  453. Arguments:
  454. DsmIds - The collection of DSM IDs that pertain to the MPDisk.
  455. Irp - The Irp containing Srb.
  456. Srb - Scsi request block
  457. CurrentPath - Path to which last request was sent
  458. PathId - Updated to the PathId where the request should be sent if return value
  459. is DSM_PATH_SET.
  460. Status - Storage for status in the event that DSM_ERROR is returned.
  461. Return Value:
  462. DSM_BROADCAST - If BroadcastRequest should be used.
  463. DSM_WILL_HANDLE - If SrbDeviceControl should be used.
  464. DSM_PATH_SET - If the Srb should just be sent to PathId
  465. DSM_ERROR - Indicates that an error occurred where by the request can't be handled.
  466. Status is updated, along with Srb->SrbStatus.
  467. --*/
  468. typedef
  469. NTSTATUS
  470. (*DSM_BROADCAST_SRB) (
  471. IN PVOID DsmContext,
  472. IN PDSM_IDS DsmIds,
  473. IN PIRP Irp,
  474. IN PSCSI_REQUEST_BLOCK Srb,
  475. IN PKEVENT Event
  476. );
  477. /*++
  478. Routine Description:
  479. This routine is called when the DSM has indicated that Srb should be sent to the device
  480. down all paths. The DSM will update IoStatus information and status, but not complete the
  481. request.
  482. Arguments:
  483. DsmIds - The collection of DSM IDs that pertain to the MPDisk.
  484. Irp - Irp containing SRB.
  485. Srb - Scsi request block
  486. Event - DSM sets this once all sub-requests have completed and the original request's
  487. IoStatus has been setup.
  488. Return Value:
  489. NTSTATUS of the operation.
  490. --*/
  491. typedef
  492. NTSTATUS
  493. (*DSM_SRB_DEVICE_CONTROL) (
  494. IN PVOID DsmContext,
  495. IN PDSM_IDS DsmIds,
  496. IN PIRP Irp,
  497. IN PSCSI_REQUEST_BLOCK Srb,
  498. IN PKEVENT Event
  499. );
  500. /*++
  501. Routine Description:
  502. This routine is called when the DSM has indicated that it wants to handle it internally
  503. (via CATEGORIZE_REQUEST).
  504. It should set IoStatus (Status and Information) and the Event, but not complete the request.
  505. Arguments:
  506. DsmIds - The collection of DSM IDs that pertain to the MPDISK.
  507. Irp - Irp containing SRB.
  508. Srb - Scsi request block
  509. Event - Event to be set when the DSM is finished if DsmHandled is TRUE
  510. Return Value:
  511. NTSTATUS of the request.
  512. --*/
  513. typedef
  514. VOID
  515. (*DSM_COMPLETION_ROUTINE) (
  516. IN PVOID DsmId,
  517. IN PIRP Irp,
  518. IN PSCSI_REQUEST_BLOCK Srb,
  519. IN PVOID DsmContext
  520. );
  521. typedef struct _DSM_COMPLETION_INFO {
  522. //
  523. // Routine to be invoked on request completion.
  524. //
  525. DSM_COMPLETION_ROUTINE DsmCompletionRoutine;
  526. //
  527. // Context to be supplied.
  528. //
  529. PVOID DsmContext;
  530. } DSM_COMPLETION_INFO, *PDSM_COMPLETION_INFO;
  531. typedef
  532. VOID
  533. (*DSM_SET_COMPLETION) (
  534. IN PVOID DsmContext,
  535. IN PVOID DsmId,
  536. IN PIRP Irp,
  537. IN PSCSI_REQUEST_BLOCK Srb,
  538. IN OUT PDSM_COMPLETION_INFO DsmCompletion
  539. );
  540. /*++
  541. Routine Description:
  542. This routine is called before the actual submission of a request, but after the categorisation
  543. of the I/O. This will be called only for those requests not handled by the DSM directly:
  544. Read/Write
  545. Other requests not handled by SrbControl or Broadcast
  546. The DSM can supply a completion routine and context which will be invoked when the
  547. request completion is being handled. It is not necessary to set completions on any or all
  548. requests.
  549. Arguments:
  550. DsmId - Identifer that was indicated when the request was categorized (or be LBGetPath)
  551. Irp - Irp containing Srb.
  552. Srb - The request
  553. DsmCompletion - Completion info structure to be filled out by DSM.
  554. Return Value:
  555. None
  556. --*/
  557. #define NUMA_MAX_WEIGHT 10
  558. typedef
  559. PVOID
  560. (*DSM_LB_GET_PATH) (
  561. IN PVOID DsmContext,
  562. IN PSCSI_REQUEST_BLOCK Srb,
  563. IN PDSM_IDS DsmList,
  564. IN PVOID CurrentPath,
  565. OUT NTSTATUS *Status
  566. );
  567. /*++
  568. Routine Description:
  569. This routine is called once per I/O and gives the DSM the ability to indicate
  570. to which path the request should be submitted. If the DSM returns a Path that was
  571. not active, this constitutes a Fail-over condition.
  572. Arguments:
  573. Srb - The request that needs to be submitted
  574. DsmList - Ids of the devices that make up the multipath group.
  575. CurrentPath - Path to which last request was sent
  576. Status - Storage for an error status, if returning NULL path.
  577. Return Value:
  578. PathId to where the request should be sent. NULL if all current paths are failed.
  579. --*/
  580. //
  581. // WMI structs, defines, routines.
  582. //
  583. typedef
  584. NTSTATUS
  585. (*DSM_QUERY_DATABLOCK) (
  586. IN PVOID DsmContext,
  587. IN PIRP Irp,
  588. IN ULONG GuidIndex,
  589. IN ULONG InstanceIndex,
  590. IN ULONG InstanceCount,
  591. IN OUT PULONG InstanceLengthArray,
  592. IN ULONG BufferAvail,
  593. OUT PUCHAR Buffer,
  594. OUT PULONG DsmDataLength
  595. );
  596. /*++
  597. Routine Description:
  598. Arguments:
  599. Return Value:
  600. status
  601. --*/
  602. typedef
  603. NTSTATUS
  604. (*DSM_SET_DATABLOCK) (
  605. IN PVOID DsmContext,
  606. IN PIRP Irp,
  607. IN ULONG GuidIndex,
  608. IN ULONG InstanceIndex,
  609. IN ULONG BufferSize,
  610. IN PUCHAR Buffer
  611. );
  612. typedef
  613. NTSTATUS
  614. (*DSM_SET_DATAITEM) (
  615. IN PVOID DsmContext,
  616. IN PIRP Irp,
  617. IN ULONG GuidIndex,
  618. IN ULONG InstanceIndex,
  619. IN ULONG DataItemId,
  620. IN ULONG BufferSize,
  621. IN PUCHAR Buffer
  622. );
  623. typedef
  624. NTSTATUS
  625. (*DSM_EXECUTE_METHOD) (
  626. IN PVOID DsmContext,
  627. IN PIRP Irp,
  628. IN ULONG GuidIndex,
  629. IN ULONG InstanceIndex,
  630. IN ULONG MethodId,
  631. IN ULONG InBufferSize,
  632. IN ULONG OutBufferSize,
  633. IN OUT PUCHAR Buffer
  634. );
  635. typedef
  636. NTSTATUS
  637. (*DSM_FUNCTION_CONTROL) (
  638. IN PVOID DsmContext,
  639. IN PIRP Irp,
  640. IN ULONG GuidIndex,
  641. IN WMIENABLEDISABLECONTROL Function,
  642. IN BOOLEAN Enable
  643. );
  644. typedef struct _DSM_WMILIB_CONTEXT {
  645. ULONG GuidCount;
  646. PWMIGUIDREGINFO GuidList;
  647. DSM_QUERY_DATABLOCK QueryWmiDataBlock;
  648. DSM_SET_DATABLOCK SetWmiDataBlock;
  649. DSM_SET_DATAITEM SetWmiDataItem;
  650. DSM_EXECUTE_METHOD ExecuteWmiMethod;
  651. DSM_FUNCTION_CONTROL WmiFunctionControl;
  652. } DSM_WMILIB_CONTEXT, *PDSM_WMILIB_CONTEXT;
  653. //
  654. // Unload routine.
  655. //
  656. typedef
  657. NTSTATUS
  658. (*DSM_UNLOAD) (
  659. IN PVOID DsmContext
  660. );
  661. /*++
  662. Routine Description:
  663. This routine is called when the main module requires the DSM to be unloaded
  664. (ie. prior to the main module unload).
  665. Arguments:
  666. DsmContext - Context value passed to DsmInitialize()
  667. Return Value:
  668. NTSTATUS - Had best be STATUS_SUCCESS;
  669. --*/
  670. //
  671. // Registration routines.
  672. //
  673. // Called in the DSM's DriverEntry.
  674. // The DSM will register with the main module by filling in the following structure
  675. // and sending the REGISTER IOCTL
  676. //
  677. typedef struct _DSM_INIT_DATA {
  678. //
  679. // Size, in bytes.
  680. //
  681. ULONG InitDataSize;
  682. //
  683. // DSM entry points.
  684. //
  685. DSM_INQUIRE_DRIVER DsmInquireDriver;
  686. DSM_COMPARE_DEVICES DsmCompareDevices;
  687. DSM_GET_CONTROLLER_INFO DsmGetControllerInfo;
  688. DSM_SET_DEVICE_INFO DsmSetDeviceInfo;
  689. DSM_IS_PATH_ACTIVE DsmIsPathActive;
  690. DSM_PATH_VERIFY DsmPathVerify;
  691. DSM_INVALIDATE_PATH DsmInvalidatePath;
  692. DSM_MOVE_DEVICE DsmMoveDevice;
  693. DSM_REMOVE_PENDING DsmRemovePending;
  694. DSM_REMOVE_DEVICE DsmRemoveDevice;
  695. DSM_REMOVE_PATH DsmRemovePath;
  696. DSM_SRB_DEVICE_CONTROL DsmSrbDeviceControl;
  697. DSM_REENABLE_PATH DsmReenablePath;
  698. DSM_LB_GET_PATH DsmLBGetPath;
  699. DSM_INTERPRET_ERROR DsmInterpretError;
  700. DSM_UNLOAD DsmUnload;
  701. DSM_SET_COMPLETION DsmSetCompletion;
  702. DSM_CATEGORIZE_REQUEST DsmCategorizeRequest;
  703. DSM_BROADCAST_SRB DsmBroadcastSrb;
  704. //
  705. // Wmi entry point and guid information.
  706. //
  707. DSM_WMILIB_CONTEXT DsmWmiInfo;
  708. //
  709. // Context value.
  710. //
  711. PVOID DsmContext;
  712. //
  713. // DriverObject for the DSM.
  714. //
  715. PDRIVER_OBJECT DriverObject;
  716. //
  717. // Friendly name for the DSM.
  718. //
  719. UNICODE_STRING DisplayName;
  720. //
  721. // Reserved.
  722. //
  723. ULONG Reserved;
  724. } DSM_INIT_DATA, *PDSM_INIT_DATA;
  725. //
  726. // Output structure for the registration. The DSM needs to keep this value for certain
  727. // routines such as DsmNotification and DsmGetTargetObject.
  728. //
  729. typedef struct _DSM_MPIO_CONTEXT {
  730. PVOID MPIOContext;
  731. } DSM_MPIO_CONTEXT, *PDSM_MPIO_CONTEXT;
  732. #define MPIO_DSM ((ULONG) 'dsm')
  733. //
  734. // IOCTL handled by the DSM that the MultiPath Control driver sends to get entry point info.
  735. // Output structure defined above (DSM_INIT_DATA).
  736. //
  737. #define IOCTL_MPDSM_REGISTER CTL_CODE (MPIO_DSM, 0x01, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
  738. //
  739. // DSM library routines.
  740. //
  741. VOID
  742. DsmSendDeviceIoControlSynchronous(
  743. IN ULONG IoControlCode,
  744. IN PDEVICE_OBJECT TargetDeviceObject,
  745. IN PVOID InputBuffer OPTIONAL,
  746. IN OUT PVOID OutputBuffer OPTIONAL,
  747. IN ULONG InputBufferLength,
  748. IN ULONG OutputBufferLength,
  749. IN BOOLEAN InternalDeviceIoControl,
  750. OUT PIO_STATUS_BLOCK IoStatus
  751. );
  752. /*++
  753. Routine Description:
  754. This routine is used by the DSM to send IoDeviceControls.
  755. Buffer must be of the appropriate size to encapsulate both input and output.
  756. This routine handles errors/retries.
  757. Arguments:
  758. IoControlCode - The DeviceIoControl code.
  759. TargetDevice - DeviceObject to which the request should be sent.
  760. Buffer - The input/output buffer for the request.
  761. InputBufferLength - Length of the input parameters buffer.
  762. OutputBufferLength - Length of the output buffer
  763. InternalDeviceIoControl - Indicates whether the IOCTL is marked as Internal or public.
  764. IoStatus - IO STATUS BLOCK to receive the final status/information fields.
  765. Return Value:
  766. NONE
  767. --*/
  768. NTSTATUS
  769. DsmGetDescriptor(
  770. IN PDEVICE_OBJECT DeviceObject,
  771. IN PSTORAGE_PROPERTY_ID PropertyId,
  772. OUT PSTORAGE_DESCRIPTOR_HEADER *Descriptor
  773. );
  774. NTSTATUS
  775. DsmSendPassThroughDirect(
  776. IN PDEVICE_OBJECT DeviceObject,
  777. IN PSCSI_PASS_THROUGH_DIRECT ScsiPassThrough,
  778. IN ULONG InputBufferLength,
  779. IN ULONG OutputBufferLength
  780. );
  781. PDSM_IDS
  782. DsmGetAssociatedDevice(
  783. IN PVOID MPIOContext,
  784. IN PDEVICE_OBJECT PortFdo,
  785. IN UCHAR DeviceType
  786. );
  787. /*++
  788. Routine Description:
  789. If the DSM needs to acquire information from other devices (such as a controller), this
  790. routine can be used to get a list of the PDO's associated with PortFdo.
  791. Arguments:
  792. PortFdo - Port driver FDO passed to InquireDriver.
  793. DeviceType - Indicates the SCSI DeviceType to return.
  794. Return Value:
  795. Pointer to a DSM_ID structure, where IdList entries are PDEVICE_OBJECT. It is the
  796. reponsibility of the DSM to free the buffer.
  797. --*/
  798. NTSTATUS
  799. DsmReleaseQueue(
  800. IN PDEVICE_OBJECT TargetDevice
  801. );
  802. /*++
  803. Routine Description:
  804. In the event that a DSM-originated request freezes the queue (SRB_STATUS_QUEUE_FROZEN), this
  805. must be used to un-freeze the queue.
  806. DSM's must check the SRB_STATUS_XXX values upon request completion for those requests that
  807. they sent.
  808. Arguments:
  809. TargetDevice - DeviceObject to which the release queue should be sent.
  810. Return Value:
  811. Status of of the ReleaseQueue IOCTL.
  812. --*/
  813. NTSTATUS
  814. DsmSendTUR(
  815. IN PDEVICE_OBJECT TargetDevice
  816. );
  817. /*++
  818. Routine Description:
  819. Sends a Test Unit Ready to TargetDevice.
  820. Arguments:
  821. TargetDevice - DeviceObject to which the TUR should be sent.
  822. Return Value:
  823. Status of of the TUR.
  824. --*/
  825. NTSTATUS
  826. DsmSendRequest(
  827. IN PDEVICE_OBJECT TargetDevice,
  828. IN PIRP Irp,
  829. IN PVOID DsmId
  830. );
  831. /*++
  832. Routine Description:
  833. This routine is used by the DSM to send it's OOB, Broadcast, or any other DSM built requests
  834. to TargetDevice. Not to be used for Irps sent to the DSM by the MPIO driver. Using this
  835. routine allows MPIO to maintain the necessary state info so that Power and PnP requests
  836. can be handled correctly.
  837. Arguments:
  838. TargetDevice - DeviceObject to which Irp should be sent.
  839. Irp - The request to send.
  840. DsmId - DSM value referring to the port PDO.
  841. Return Value:
  842. Status of IoCallDriver or an error status if one is detected.
  843. --*/
  844. ULONG
  845. DsmGetSystemWeight(
  846. IN PVOID MPIOContext,
  847. IN PIRP Irp,
  848. IN PVOID PathId
  849. );
  850. /*++
  851. Routine Description:
  852. This routine is used by the DSM to determine the cost associated with issuing the
  853. request to PathId for the system. For example, cross node accesses on a NUMA system.
  854. Arguments:
  855. MPIOContext - Value given to the DSM during initialization.
  856. Irp - The request to send.
  857. PathId - One of the PathId values for the MPDisk. (SetDeviceInfo).
  858. Return Value:
  859. Relative system cost of issuing Irp to PathId. (ULONG)-1 indicates this Path is
  860. unreachable.
  861. --*/
  862. typedef enum _DSM_NOTIFICATION_TYPE {
  863. DeviceFailure,
  864. PathFailure,
  865. PathOnLine,
  866. ThrottleIO,
  867. ResumeIO,
  868. MaxDsmNotificationType
  869. } DSM_NOTIFICATION_TYPE, *PDSM_NOTIFICATION_TYPE;
  870. VOID
  871. DsmNotification(
  872. IN PVOID MpctlContext,
  873. IN DSM_NOTIFICATION_TYPE NotificationType,
  874. IN PVOID AdditionalParameters
  875. );
  876. /*++
  877. Routine Description:
  878. This routine is called by the DSM to inform mpctl of certain events such as
  879. Device/Path failure, Device/Path coming back online after a failure, WMI Events, or TBD....
  880. Arguments:
  881. MpctlContext - Value given to the DSM during initialization.
  882. NotificationType - Specifies the type of notification.
  883. Additional Parameters depend on NotificationType
  884. DeviceFailure - DsmId
  885. PathFailure - PathId
  886. PathOnLine - PathId
  887. ThrottleIO - PathId
  888. ResumeIO - PathId
  889. Return Value:
  890. None
  891. --*/
  892. NTSTATUS
  893. DsmWriteEvent(
  894. IN PVOID MPIOContext,
  895. IN PWCHAR ComponentName,
  896. IN PWCHAR EventDescription,
  897. IN ULONG Severity
  898. );
  899. /*++
  900. Routine Description:
  901. The will cause a WMI Event to be fired, containing the Paramter information as
  902. the event data.
  903. Arguments:
  904. MpctlContext - Value given to the DSM during initialization.
  905. ComponentName - Name of the object effected.
  906. EventDescription - Description of the event.
  907. Severity - Lower is worse.
  908. Return Value:
  909. None
  910. --*/
  911. #endif // _DSM_H_