Leaked source code of windows server 2003
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.

1405 lines
29 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. raid.c
  5. Abstract:
  6. Extensions for RAID port driver.
  7. Author:
  8. Matthew D Hendel (math) 14-June-2000
  9. Revision History:
  10. !raid.help
  11. !raid.help
  12. adapter - Dump an adapter object.
  13. unit - Dump a unit object.
  14. Type !raid.help "command" for more information about the command.
  15. NAME:
  16. unit
  17. USAGE:
  18. unit [UNIT-OBJECT [DETAIL]]
  19. ARGUMENTS:
  20. UNIT-OBJECT -
  21. DETAIL -
  22. ----------------------------------------------------------------------------
  23. !raid.adapter
  24. RAID Adapters:
  25. Name DO Ext
  26. -------------------------------------
  27. dac960nt 84000000 84100000
  28. foobar 84000000 84100000
  29. ami95044 84000000 84100000
  30. XXAABB 84000000 84100000
  31. RAID Units:
  32. Product SCSI ID DO Ext Reqs
  33. --------------------------------------------------------------------
  34. MYLEX DAC960 3 1 1 84000000 84100000 200
  35. AMI DDD5455 200 200 200 84000000 84100000 0
  36. !raid.unit
  37. Dump a raid unit
  38. !raid.adapter
  39. Dump a raid adapter
  40. --*/
  41. #include "pch.h"
  42. #include "precomp.h"
  43. //
  44. // Prototypes
  45. //
  46. VOID
  47. DumpUnit(
  48. IN ULONG64 Unit,
  49. IN ULONG Level
  50. );
  51. VOID
  52. DumpAdapter(
  53. IN ULONG64 Adapter,
  54. IN ULONG Level
  55. );
  56. //
  57. // Data
  58. //
  59. PCHAR StateTable [] = {
  60. "Removed", // not present
  61. "Working", // working
  62. "Stopped", // stopped
  63. "P-Stop", // pending stop
  64. "P-Remove", // pending remove
  65. "Surprise", // surprise remove
  66. };
  67. BOOLEAN Verbose = FALSE;
  68. //
  69. // Functions
  70. //
  71. BOOLEAN
  72. CheckRaidObject(
  73. IN ULONG64 Object,
  74. IN RAID_OBJECT_TYPE ObjectType
  75. )
  76. {
  77. ULONG Ret;
  78. if (Object == 0) {
  79. return FALSE;
  80. }
  81. Ret = GetFieldData (Object,
  82. "raidport!RAID_COMMON_EXTENSION",
  83. "ObjectType",
  84. sizeof (ObjectType),
  85. &ObjectType);
  86. if (Ret != 0 || ObjectType != ObjectType) {
  87. return FALSE;
  88. }
  89. return TRUE;
  90. }
  91. ULONG64
  92. GetListHead(
  93. IN ULONG64 Object,
  94. IN PSZ ObjectType,
  95. IN PSZ FieldName,
  96. OUT PULONG64 ListHead
  97. )
  98. {
  99. ULONG64 NextEntry;
  100. ULONG Offset;
  101. ULONG Ret;
  102. Ret = GetFieldOffset (ObjectType, FieldName, &Offset);
  103. if (Ret != 0) {
  104. return 0;
  105. }
  106. *ListHead = (Object + Offset);
  107. ReadPointer (*ListHead, &NextEntry);
  108. return NextEntry;
  109. }
  110. ULONG64
  111. GetNextListEntry(
  112. IN ULONG64 ListElement
  113. )
  114. {
  115. ULONG64 NextEntry;
  116. ULONG Ret;
  117. Ret = GetFieldData (ListElement,
  118. "raidport!LIST_ENTRY",
  119. "Flink",
  120. sizeof (NextEntry),
  121. &NextEntry);
  122. if (Ret != 0) {
  123. dprintf ("ERROR: Couldn't get next list entry for element %08x\n", ListElement);
  124. return 0;
  125. }
  126. return NextEntry;
  127. }
  128. ULONG64
  129. ContainingRecord(
  130. IN ULONG64 Object,
  131. IN PSZ ObjectType,
  132. IN PSZ FieldName
  133. )
  134. {
  135. ULONG Offset;
  136. ULONG Ret;
  137. Ret = GetFieldOffset (ObjectType, FieldName, &Offset);
  138. if (Ret != 0) {
  139. return 0;
  140. }
  141. return (Object - Offset);
  142. }
  143. VOID
  144. ListDriverAdapters(
  145. IN ULONG64 Driver,
  146. IN ULONG Level
  147. )
  148. {
  149. ULONG64 ListHead;
  150. ULONG64 Adapter;
  151. ULONG64 NextEntry;
  152. #if 0
  153. BOOLEAN Succ;
  154. Succ = GetDriverInformation (Driver,
  155. DriverName,
  156. &BaseAddress,
  157. &CreationTime);
  158. if (!Succ) {
  159. return;
  160. }
  161. GetFieldOffset ("raidport!RAID_DRIVER_EXTENSION",
  162. "AdapterList.List",
  163. &Offset);
  164. ListHead = Driver + Offset;
  165. #endif
  166. NextEntry = GetListHead (Driver,
  167. "raidport!RAID_DRIVER_EXTENSION",
  168. "AdapterList.List.Flink",
  169. &ListHead);
  170. if (Verbose) {
  171. dprintf ("VERBOSE: ListHead = %08x, NextEntry = %08x\n",
  172. (ULONG)ListHead, (ULONG)NextEntry);
  173. }
  174. for ( /* NOTHING */ ;
  175. NextEntry != 0 && NextEntry != ListHead;
  176. NextEntry = GetNextListEntry (NextEntry)) {
  177. if (Verbose) {
  178. dprintf ("VERBOSE: Adapter ListEntry %08x\n", NextEntry);
  179. }
  180. Adapter = ContainingRecord (NextEntry,
  181. "raidport!RAID_ADAPTER_EXTENSION",
  182. "NextAdapter");
  183. if (!CheckRaidObject (Adapter, RaidAdapterObject)) {
  184. dprintf ("ERROR: Object at %08x not an raid adapter\n", Adapter);
  185. return;
  186. }
  187. if (CheckControlC()) {
  188. return;
  189. }
  190. DumpAdapter (Adapter, Level);
  191. }
  192. }
  193. ULONG64
  194. GetPortData(
  195. )
  196. {
  197. ULONG Ret;
  198. ULONG64 PortDataPtr;
  199. ULONG64 PortData;
  200. PortDataPtr = GetExpression ("raidport!RaidpPortData");
  201. if (PortDataPtr == 0) {
  202. dprintf ("ERROR: couldn't get raidport!RaidpPortData\n");
  203. return 0;
  204. }
  205. ReadPointer (PortDataPtr, &PortData);
  206. return PortData;
  207. }
  208. VOID
  209. ListAllAdapters(
  210. IN ULONG Level
  211. )
  212. {
  213. ULONG Ret;
  214. ULONG64 PortDataPtr;
  215. ULONG64 PortData;
  216. ULONG64 ListHead;
  217. ULONG64 NextEntry;
  218. ULONG64 Driver;
  219. ULONG Offset;
  220. PortDataPtr = GetExpression ("raidport!RaidpPortData");
  221. if (PortDataPtr == 0) {
  222. dprintf ("ERROR: couldn't get raidport!RaidpPortData\n");
  223. return;
  224. }
  225. ReadPointer (PortDataPtr, &PortData);
  226. Ret = GetFieldOffset ("raidport!RAID_PORT_DATA",
  227. "DriverList.List",
  228. &Offset);
  229. if (Ret != 0) {
  230. dprintf ("ERROR: Could lookup RAID_PORT_DATA structure\n");
  231. return ;
  232. }
  233. ListHead = PortData + Offset;
  234. if (Verbose) {
  235. dprintf ("VERBOSE: dumping adapter list at %I64x\n", ListHead);
  236. }
  237. dprintf ("Driver Object Ext State\n");
  238. dprintf ("--------------------------------------------------------\n");
  239. for (GetFieldValue (ListHead, "raidport!LIST_ENTRY", "Flink", NextEntry);
  240. NextEntry != 0 && NextEntry != ListHead;
  241. GetFieldValue (NextEntry, "raidport!LIST_ENTRY", "Flink", NextEntry)) {
  242. GetFieldOffset ("raidport!RAID_DRIVER_EXTENSION", "DriverLink", &Offset);
  243. if (Verbose) {
  244. dprintf ("VERBOSE: ListEntry at %08x\n", NextEntry);
  245. }
  246. Driver = NextEntry - Offset;
  247. if (Verbose) {
  248. dprintf ("VERBOSE: Driver at %08x\n", Driver);
  249. }
  250. if (!CheckRaidObject (Driver, RaidDriverObject)) {
  251. dprintf ("ERROR: %08x is not a driver object\n", Driver);
  252. return;
  253. }
  254. if (CheckControlC()) {
  255. return;
  256. }
  257. if (Verbose) {
  258. dprintf ("VERBOSE: dumping driver at %I64x\n", Driver);
  259. }
  260. ListDriverAdapters (Driver, Level);
  261. }
  262. dprintf ("\n");
  263. }
  264. VOID
  265. ListAdapterUnits(
  266. IN ULONG64 Adapter,
  267. IN ULONG Level
  268. )
  269. {
  270. ULONG64 NextEntry;
  271. ULONG64 Unit;
  272. ULONG64 ListHead;
  273. NextEntry = GetListHead (Adapter,
  274. "raidport!RAID_ADAPTER_EXTENSION",
  275. "UnitList.List.Flink",
  276. &ListHead);
  277. for ( ;
  278. NextEntry != 0 && NextEntry != ListHead;
  279. NextEntry = GetNextListEntry (NextEntry)) {
  280. Unit = ContainingRecord (NextEntry,
  281. "raidport!RAID_UNIT_EXTENSION",
  282. "NextUnit");
  283. if (!CheckRaidObject (Unit, RaidUnitObject)) {
  284. dprintf ("ERROR: Object at %08x is not a raid unit object\n", Unit);
  285. return;
  286. }
  287. if (CheckControlC()) {
  288. return;
  289. }
  290. DumpUnit (Unit, Level);
  291. }
  292. }
  293. VOID
  294. ListDriverUnits(
  295. IN ULONG64 Driver,
  296. IN ULONG Level
  297. )
  298. {
  299. ULONG64 ListHead;
  300. ULONG64 Adapter;
  301. ULONG64 NextEntry;
  302. NextEntry = GetListHead (Driver,
  303. "raidport!RAID_DRIVER_EXTENSION",
  304. "AdapterList.List.Flink",
  305. &ListHead);
  306. if (Verbose) {
  307. dprintf ("VERBOSE: ListHead = %08x, NextEntry = %08x\n",
  308. (ULONG)ListHead, (ULONG)NextEntry);
  309. }
  310. for ( ;
  311. NextEntry != 0 && NextEntry != ListHead;
  312. NextEntry = GetNextListEntry (NextEntry)) {
  313. if (Verbose) {
  314. dprintf ("VERBOSE: Adapter ListEntry %08x\n", NextEntry);
  315. }
  316. Adapter = ContainingRecord (NextEntry,
  317. "raidport!RAID_ADAPTER_EXTENSION",
  318. "NextAdapter");
  319. if (!CheckRaidObject (Adapter, RaidAdapterObject)) {
  320. dprintf ("ERROR: Object at %08x not an raid adapter\n", Adapter);
  321. return;
  322. }
  323. if (CheckControlC()) {
  324. return;
  325. }
  326. ListAdapterUnits (Adapter, Level);
  327. }
  328. }
  329. VOID
  330. ListAllUnits(
  331. IN ULONG Level
  332. )
  333. {
  334. ULONG64 PortData;
  335. ULONG64 NextEntry;
  336. ULONG64 Driver;
  337. ULONG64 ListHead;
  338. PortData = GetPortData ();
  339. NextEntry = GetListHead (PortData,
  340. "raidport!RAID_PORT_DATA",
  341. "DriverList.List.Flink",
  342. &ListHead);
  343. dprintf ("Product SCSI ID OBJ EXT Reqs State\n");
  344. dprintf ("--------------------------------------------------------------\n");
  345. for ( ;
  346. NextEntry != 0 && NextEntry != ListHead;
  347. NextEntry = GetNextListEntry (NextEntry)) {
  348. Driver = ContainingRecord (NextEntry,
  349. "raidport!RAID_DRIVER_EXTENSION",
  350. "DriverLink");
  351. if (Verbose) {
  352. dprintf ("VERBOSE: dumping driver %08x\n", Driver);
  353. }
  354. if (!CheckRaidObject (Driver, RaidDriverObject)) {
  355. dprintf ("ERROR: Object at %08x not a raid driver\n", Driver);
  356. return;
  357. }
  358. if (CheckControlC()) {
  359. return;
  360. }
  361. ListDriverUnits (Driver, Level);
  362. }
  363. dprintf ("\n");
  364. }
  365. PCHAR
  366. StateToString(
  367. IN ULONG State
  368. )
  369. {
  370. if (State > 5) {
  371. return "invalid state";
  372. }
  373. return StateTable[State];
  374. }
  375. ULONG64
  376. GetDriverObject(
  377. IN ULONG64 Driver
  378. )
  379. {
  380. ULONG Ret;
  381. CSHORT Type;
  382. ULONG64 DriverObject;
  383. if (CheckRaidObject (Driver, RaidDriverObject)) {
  384. Ret = GetFieldData (Driver,
  385. "raidport!RAID_DRIVER_EXTENSION",
  386. "DriverObject",
  387. sizeof (DriverObject),
  388. &DriverObject);
  389. if (Ret != 0) {
  390. DriverObject = 0;
  391. }
  392. } else {
  393. DriverObject = Driver;
  394. }
  395. Ret = GetFieldValue (DriverObject, "raidport!DRIVER_OBJECT", "Type", Type);
  396. if (Ret != 0 || Type != IO_TYPE_DRIVER) {
  397. DriverObject = 0;
  398. if (Verbose) {
  399. dprintf ("VERBOSE: %08x is not a RAID_DRIVER_EXTENSION or DRIVER_OBJECT\n");
  400. }
  401. }
  402. return DriverObject;
  403. }
  404. VOID
  405. GetDriverName(
  406. IN ULONG64 Driver,
  407. IN PUCHAR Buffer
  408. )
  409. {
  410. ULONG Count;
  411. ULONG Offset;
  412. WCHAR UnicodeBuffer[256];
  413. ULONG Ret;
  414. ULONG BytesRead;
  415. ULONG64 DriverObject;
  416. ULONG64 String;
  417. PWCHAR DriverName;
  418. DriverObject = GetDriverObject (Driver);
  419. if (DriverObject == 0) {
  420. dprintf ("ERROR: %08x is not a driver\n", DriverObject);
  421. return;
  422. }
  423. if (Verbose) {
  424. dprintf ("VERBOSE: Getting driver name for DRIVER_OBJECT %08x\n", DriverObject);
  425. }
  426. Ret = GetFieldData (DriverObject,
  427. "raidport!DRIVER_OBJECT",
  428. "DriverName.Length",
  429. sizeof (Count),
  430. &Count);
  431. if (Ret != 0) {
  432. dprintf ("ERROR: couldn't get field of DRIVER_OBJECT. Symbols may be bad.\n");
  433. return;
  434. }
  435. Ret = GetFieldOffset("raidport!DRIVER_OBJECT",
  436. "DriverName.Buffer",
  437. &Offset);
  438. if (Ret != 0) {
  439. dprintf ("ERROR: couldn't get field of DRIVER_OBJECT. Symbols may be bad.\n");
  440. return;
  441. }
  442. if (Count > 0 && Count <= 256) {
  443. ReadPointer (DriverObject + Offset, &String);
  444. ReadMemory (String, UnicodeBuffer, Count, &BytesRead);
  445. }
  446. UnicodeBuffer[Count++] = '\000';
  447. DriverName = wcsrchr (UnicodeBuffer, L'\\');
  448. if (DriverName == NULL) {
  449. DriverName = UnicodeBuffer;
  450. } else {
  451. DriverName++;
  452. }
  453. sprintf (Buffer, "%ws", DriverName);
  454. }
  455. BOOLEAN
  456. IsDeviceObject(
  457. IN ULONG64 DeviceObject
  458. )
  459. {
  460. CSHORT Type;
  461. GetFieldValue (DeviceObject, "raidport!DEVICE_OBJECT", "Type", Type);
  462. return (Type == IO_TYPE_DEVICE);
  463. }
  464. ULONG64
  465. GetDeviceExtension(
  466. IN ULONG64 DeviceObject
  467. )
  468. {
  469. ULONG Ret;
  470. ULONG Offset;
  471. ULONG64 Extension = -1;
  472. Ret = GetFieldOffset ("raidport!DEVICE_OBJECT",
  473. "DeviceExtension",
  474. &Offset);
  475. if (Ret != 0) {
  476. if (Verbose) {
  477. dprintf ("VERBOSE: couldn't read DeviceExtension\n");
  478. }
  479. return 0;
  480. }
  481. ReadPointer (DeviceObject + Offset, &Extension);
  482. return Extension;
  483. }
  484. ULONG
  485. GetEmbeddedRemlockCount(
  486. IN ULONG64 ObjectPtr,
  487. IN PSZ ObjectType,
  488. IN PSZ FieldName
  489. )
  490. {
  491. ULONG Ret;
  492. ULONG Remlock_IoCount;
  493. ULONG Remlock_Offset;
  494. ULONG Remlock_Common_Offset;
  495. Remlock_IoCount = -1;
  496. Ret = GetFieldOffset (ObjectType,
  497. FieldName,
  498. &Remlock_Offset);
  499. if (Ret == STATUS_SUCCESS) {
  500. Ret = GetFieldOffset ("raidport!IO_REMOVE_LOCK",
  501. "Common",
  502. &Remlock_Common_Offset);
  503. if (Ret == STATUS_SUCCESS) {
  504. GetFieldData (ObjectPtr + Remlock_Offset + Remlock_Common_Offset,
  505. "raidport!IO_REMOVE_LOCK_COMMON_BLOCK",
  506. "IoCount",
  507. sizeof (Remlock_IoCount),
  508. &Remlock_IoCount);
  509. }
  510. }
  511. if (Ret != STATUS_SUCCESS) {
  512. printf ("WARN: couldn't get IO_REMOVE_LOCK status\n");
  513. }
  514. return Remlock_IoCount;
  515. }
  516. ULONG64
  517. GetAdapterExtension(
  518. IN ULONG64 Adapter
  519. )
  520. {
  521. ULONG64 Temp;
  522. ULONG64 AdapterExt;
  523. ULONG64 DeviceObject;
  524. if (CheckRaidObject (Adapter, RaidAdapterObject)) {
  525. AdapterExt = Adapter;
  526. InitTypeRead (AdapterExt, raidport!RAID_ADAPTER_EXTENSION);
  527. DeviceObject = ReadField (DeviceObject);
  528. if (Verbose) {
  529. dprintf ("VERBOSE: Checking if %08x is a device object\n", DeviceObject);
  530. }
  531. if (IsDeviceObject (DeviceObject)) {
  532. Temp = GetDeviceExtension (DeviceObject);
  533. if (Verbose) {
  534. dprintf ("VERBOSE: Ext = %08x, Computed Ext = %08x\n",
  535. AdapterExt, Temp);
  536. }
  537. if (Temp == AdapterExt) {
  538. return AdapterExt;
  539. }
  540. } else {
  541. if (Verbose) {
  542. dprintf ("VERBOSE: %08x is not a device object\n", DeviceObject);
  543. }
  544. }
  545. } else {
  546. if (Verbose) {
  547. dprintf ("VERBOSE: %08x not a RaidAdapterObject\n");
  548. }
  549. }
  550. if (IsDeviceObject (Adapter)) {
  551. AdapterExt = GetDeviceExtension (Adapter);
  552. if (Verbose) {
  553. dprintf ("VERBOSE: Checking if %08x is an adapter extension\n", AdapterExt);
  554. }
  555. if (CheckRaidObject (AdapterExt, RaidAdapterObject)) {
  556. InitTypeRead (AdapterExt, raidport!RAID_ADAPTER_EXTENSION);
  557. DeviceObject = ReadField (DeviceObject);
  558. if (DeviceObject == Adapter) {
  559. return AdapterExt;
  560. } else if (Verbose) {
  561. dprintf ("VERBOSE: DO %I64x != Adapter %I64x\n",
  562. (ULONG)DeviceObject,
  563. (ULONG)Adapter);
  564. }
  565. } else if (Verbose) {
  566. dprintf ("VERBOSE: Ext %08x not RaidAdapterObject\n",
  567. (ULONG)AdapterExt);
  568. }
  569. }
  570. return 0;
  571. }
  572. VOID
  573. DumpMiniport(
  574. IN ULONG64 AdapterPtr
  575. )
  576. {
  577. ULONG Ret;
  578. ULONG Offset;
  579. ULONG64 HwDeviceExt;
  580. ULONG64 DeviceExtPtr;
  581. ULONG64 MiniportPtr;
  582. ULONG64 HwInitData;
  583. //
  584. // PortConfig 80000000 HwInitData 77000000 HwDeviceExt a0000000 27 bytes
  585. // LuExt 32 bytes SrbExt 32 bytes
  586. //
  587. GetFieldOffset ("raidport!RAID_ADAPTER_EXTENSION",
  588. "Miniport",
  589. &Offset);
  590. MiniportPtr = AdapterPtr + Offset;
  591. InitTypeRead (MiniportPtr, raidport!RAID_MINIPORT);
  592. HwInitData = ReadField (HwInitializationData);
  593. GetFieldOffset ("raidport!RAID_MINIPORT",
  594. "PortConfiguration",
  595. &Offset);
  596. dprintf (" PortConfig %08x HwInit %08x\n", (ULONG)(MiniportPtr + Offset),
  597. (ULONG)HwInitData);
  598. DeviceExtPtr = ReadField (PrivateDeviceExt);
  599. if (DeviceExtPtr == 0) {
  600. HwDeviceExt = 0;
  601. } else {
  602. Ret = GetFieldOffset ("raidport!RAID_HW_DEVICE_EXT",
  603. "HwDeviceExtension",
  604. &Offset);
  605. if (Ret != 0) {
  606. HwDeviceExt = 0;
  607. } else {
  608. HwDeviceExt = DeviceExtPtr + Offset;
  609. }
  610. }
  611. InitTypeRead (HwInitData, raidport!HW_INITIALIZATION_DATA);
  612. dprintf (" HwDeviceExt %08x %d bytes\n",
  613. (ULONG)HwDeviceExt, (ULONG)ReadField (DeviceExtensionSize));
  614. dprintf (" LuExt %d bytes SrbExt %d bytes\n",
  615. (ULONG)ReadField (SpecificLuExtensionSize),
  616. (ULONG)ReadField (SrbExtensionSize));
  617. }
  618. VOID
  619. DumpAdapter(
  620. IN ULONG64 Adapter,
  621. IN ULONG Level
  622. )
  623. /*++
  624. ADAPTER f0345600
  625. Ext 8e000000 Driver 8000000 Next 8000000 Working
  626. LDO 80000000 PDO 00000000 HwExt 00000000
  627. SlowLock Free RemLock 10 Power D0 S0 Full Duplex
  628. Bus 08080808 Number 1 Slot 0 Dma 88888888 Interrupt 88888888
  629. AdQueue: Outstanding 200, Low 100, High 200 Busy
  630. ResourceList: Allocated 80808080 Translated 80808080
  631. MappedAddressList:
  632. Virtual Physical Size Bus
  633. 80808080 8000000000000000 1500 1
  634. 80808080 8000000000000000 1500 1
  635. 80808080 8000000000000000 1500 1
  636. 80808080 8000000000000000 1500 1
  637. 80808080 8000000000000000 1500 1
  638. 80808080 8000000000000000 1500 1
  639. */
  640. {
  641. ULONG64 AdapterPtr;
  642. ULONG64 Driver;
  643. CHAR DriverName[100];
  644. if (Verbose) {
  645. dprintf ("VERBOSE: dumping adapter %08x\n", Adapter);
  646. }
  647. AdapterPtr = GetAdapterExtension (Adapter);
  648. if (AdapterPtr == 0) {
  649. dprintf ("ERROR: %08x is not a valid adapter object\n", Adapter);
  650. return;
  651. }
  652. if (Level == 0) {
  653. Driver = ReadField (Driver);
  654. GetDriverName (Driver, DriverName);
  655. dprintf ("%8.8s %08x %08x %s\n",
  656. DriverName,
  657. (ULONG)ReadField (DeviceObject),
  658. (ULONG)Adapter,
  659. StateToString ((ULONG)ReadField (DeviceState))
  660. );
  661. } else {
  662. PSZ Adapter_SlowLock;
  663. ULONG Remlock_IoCount;
  664. dprintf ("ADAPTER %08x\n", ReadField (DeviceObject));
  665. dprintf (" Ext %08x Driver %08x Next %08x %s\n",
  666. (ULONG)AdapterPtr,
  667. (ULONG)ReadField (Driver),
  668. (ULONG)0,
  669. StateToString ((ULONG)ReadField (DeviceState)));
  670. dprintf (" LDO %08x PDO %08x\n",
  671. (ULONG)ReadField (LowerDeviceObject),
  672. (ULONG)ReadField (PhysicalDeviceObject));
  673. if (ReadField ("SlowLock") == 0) {
  674. Adapter_SlowLock = "Free";
  675. } else {
  676. Adapter_SlowLock = "Held";
  677. }
  678. Remlock_IoCount = GetEmbeddedRemlockCount (AdapterPtr,
  679. "raidport!RAID_ADAPTER_EXTENSION",
  680. "RemoveLock");
  681. dprintf (" SlowLock %s RemLock %d Power %s %s %s\n",
  682. Adapter_SlowLock,
  683. Remlock_IoCount,
  684. "S0", "D0",
  685. (ReadField (Mode) == RaidSynchronizeFullDuplex ?
  686. "Full Duplex" :
  687. "Half Duplex")
  688. );
  689. dprintf (" Bus %08x Number %d Slot %d Dma %08x Interrupt %08x\n",
  690. (ULONG)0,
  691. (ULONG)ReadField (BusNumber),
  692. (ULONG)ReadField (SlotNumber),
  693. (ULONG)ReadField (Dma.DmaAdapter),
  694. (ULONG)ReadField (Interrupt));
  695. dprintf (" ResourceList: Allocated %08x Translated %08x\n",
  696. (ULONG)ReadField (ResourceList.AllocatedResources),
  697. (ULONG)ReadField (ResourceList.TranslatedResources));
  698. dprintf (" Gateway: Outstanding %d Lower %d High %d\n",
  699. ReadField (AdapterQueue->Outstanding),
  700. ReadField (AdapterQueue->LowWaterMark),
  701. ReadField (AdapterQueue->HighWaterMark));
  702. DumpMiniport (AdapterPtr);
  703. }
  704. }
  705. VOID
  706. FixPaddedString(
  707. PSZ String
  708. )
  709. {
  710. ULONG Pos;
  711. Pos = strlen (String);
  712. if (Pos > 0) {
  713. Pos--;
  714. }
  715. while (Pos && String[Pos] == ' ') {
  716. String[Pos--] = '\000';
  717. }
  718. }
  719. VOID
  720. GetUnitProductInfo(
  721. ULONG64 Unit,
  722. PSZ VendorId,
  723. PSZ ProductId,
  724. PSZ Revision
  725. )
  726. {
  727. ULONG Offset;
  728. ULONG64 InquiryData;
  729. GetFieldOffset ("raidport!RAID_UNIT_EXTENSION",
  730. "InquiryData",
  731. &Offset);
  732. ReadPointer (Unit + Offset, &InquiryData);
  733. if (VendorId) {
  734. ZeroMemory (VendorId, 9);
  735. GetFieldData (InquiryData,
  736. "raidport!INQUIRYDATA",
  737. "VendorId",
  738. 8,
  739. VendorId);
  740. FixPaddedString (VendorId);
  741. }
  742. if (ProductId) {
  743. ZeroMemory (ProductId, 17);
  744. GetFieldData (InquiryData,
  745. "raidport!INQUIRYDATA",
  746. "ProductId",
  747. 16,
  748. ProductId);
  749. FixPaddedString (ProductId);
  750. }
  751. if (Revision) {
  752. ZeroMemory (Revision, 5);
  753. GetFieldData (InquiryData,
  754. "raidport!INQUIRYDATA",
  755. "ProductRevisionLevel",
  756. 4,
  757. Revision);
  758. FixPaddedString (Revision);
  759. }
  760. }
  761. ULONG
  762. GetUnitIoQueueRequests(
  763. IN ULONG64 UnitPtr
  764. )
  765. {
  766. ULONG Ret;
  767. ULONG64 Unit_IoQueue;
  768. ULONG64 IoQueue_DeviceQueue;
  769. ULONG Offset;
  770. ULONG Requests;
  771. Ret = GetFieldOffset ("raidport!RAID_UNIT_EXTENSION",
  772. "IoQueue",
  773. &Offset);
  774. if (Ret != STATUS_SUCCESS) {
  775. dprintf ("WARN: failed to get IoQueue offset from unit.\n");
  776. }
  777. Unit_IoQueue = UnitPtr + Offset;
  778. Ret = GetFieldOffset ("raidport!IO_QUEUE",
  779. "DeviceQueue",
  780. &Offset);
  781. if (Ret != STATUS_SUCCESS) {
  782. dprintf ("WARN: failed to get DeviceQueue offset from unit(1).\n");
  783. }
  784. IoQueue_DeviceQueue = Unit_IoQueue + Offset;
  785. GetFieldData (IoQueue_DeviceQueue,
  786. "raidport!EXTENDED_DEVICE_QUEUE",
  787. "OutstandingRequests",
  788. sizeof (Requests),
  789. &Requests);
  790. return Requests;
  791. }
  792. VOID
  793. DumpUnit(
  794. IN ULONG64 Unit,
  795. IN ULONG Level
  796. )
  797. {
  798. ULONG64 UnitPtr;
  799. CSHORT DeviceObject_Type;
  800. GetFieldValue (Unit, "raidport!DEVICE_OBJECT", "Type", DeviceObject_Type);
  801. if (DeviceObject_Type == IO_TYPE_DEVICE) {
  802. GetFieldValue (Unit, "raidport!DEVICE_OBJECT", "DeviceExtension", UnitPtr);
  803. if (!CheckRaidObject (UnitPtr, RaidUnitObject)) {
  804. dprintf ("ERROR: DeviceObject %8.8x is not a raid unit\n", UnitPtr);
  805. return;
  806. }
  807. } else if (CheckRaidObject (Unit, RaidUnitObject)) {
  808. UnitPtr = Unit;
  809. } else {
  810. dprintf ("ERROR: Pointer %8.8x is not a device object or raid unit object\n",
  811. Unit);
  812. return;
  813. }
  814. InitTypeRead (UnitPtr, raidport!RAID_UNIT_EXTENSION);
  815. if (Level == 0) {
  816. CHAR VendorId[9] = {0};
  817. CHAR ProductId[17] = {0};
  818. CHAR Product[25];
  819. GetUnitProductInfo (UnitPtr, VendorId, ProductId, NULL);
  820. sprintf (Product, "%s %s", VendorId, ProductId);
  821. dprintf ("%-15.15s %3d %3d %3d %08x %08x %-3d %-8.8s\n",
  822. Product,
  823. (ULONG)ReadField (PathId),
  824. (ULONG)ReadField (TargetId),
  825. (ULONG)ReadField (Lun),
  826. (ULONG)ReadField (DeviceObject),
  827. (ULONG)UnitPtr,
  828. GetUnitIoQueueRequests (UnitPtr),
  829. StateToString ((ULONG)ReadField (DeviceState)));
  830. } else {
  831. ULONG Ret;
  832. ULONG Remlock_IoCount;
  833. ULONG Remlock_Offset;
  834. ULONG Remlock_Common_Offset;
  835. PCHAR SlowLock;
  836. ULONG64 Unit_QueueFrozen;
  837. ULONG64 Unit_QueueLocked;
  838. ULONG64 Unit_TagList;
  839. ULONG64 Unit_IoQueue;
  840. ULONG64 IoQueue_DeviceQueue;
  841. ULONG Offset;
  842. ULONG Device_Offset;
  843. ULONG ByPass_Offset;
  844. ULONG64 Pointer;
  845. CHAR VendorId[9] = {0};
  846. CHAR ProductId[17] = {0};
  847. CHAR Revision[5] = {0};
  848. ULONG64 InquiryData;
  849. dprintf ("UNIT %08x\n", ReadField (DeviceObject));
  850. dprintf (" Ext %08x Adapter %08x Next %08x %s\n",
  851. (ULONG)UnitPtr,
  852. (ULONG)ReadField(Adapter),
  853. (ULONG) 0 /*BUGBUG: pull out NextField*/,
  854. StateToString((ULONG)ReadField(DeviceState)));
  855. GetFieldOffset ("raidport!RAID_UNIT_EXTENSION",
  856. "InquiryData",
  857. &Offset);
  858. ReadPointer (UnitPtr + Offset, &InquiryData);
  859. GetUnitProductInfo (UnitPtr, VendorId, ProductId, Revision);
  860. dprintf (" SCSI %d %d %d %s %s %s Inquiry %08x\n",
  861. (ULONG)ReadField(PathId),
  862. (ULONG)ReadField(TargetId),
  863. (ULONG)ReadField(Lun),
  864. VendorId,
  865. ProductId,
  866. Revision,
  867. (ULONG)InquiryData);
  868. Remlock_IoCount = -1;
  869. Ret = GetFieldOffset ("raidport!RAID_UNIT_EXTENSION",
  870. "RemoveLock",
  871. &Remlock_Offset);
  872. if (Ret == STATUS_SUCCESS) {
  873. Ret = GetFieldOffset ("raidport!IO_REMOVE_LOCK",
  874. "Common",
  875. &Remlock_Common_Offset);
  876. if (Ret == STATUS_SUCCESS) {
  877. GetFieldData (UnitPtr + Remlock_Offset + Remlock_Common_Offset,
  878. "raidport!IO_REMOVE_LOCK_COMMON_BLOCK",
  879. "IoCount",
  880. sizeof (Remlock_IoCount),
  881. &Remlock_IoCount);
  882. }
  883. }
  884. if (Ret != STATUS_SUCCESS) {
  885. printf ("WARN: couldn't get IO_REMOVE_LOCK status\n");
  886. }
  887. if (ReadField ("SlowLock") == 0) {
  888. SlowLock = "Free";
  889. } else {
  890. SlowLock = "Held";
  891. }
  892. dprintf (" SlowLock %s RemLock %d PageCount %d\n",
  893. SlowLock,
  894. Remlock_IoCount,
  895. (ULONG)ReadField (PagingPathCount));
  896. Pointer = ReadField (SrbExtensionRegion.VirtualBase);
  897. dprintf (" SrbExtension Size %d Start %08x End %08x\n",
  898. 0, // BUGBUG: Get srb extension size from the miniport
  899. (ULONG)Pointer,
  900. (ULONG)Pointer + (ULONG)ReadField (SrbExtensionRegion.Length));
  901. Ret = GetFieldOffset ("raidport!RAID_UNIT_EXTENSION",
  902. "TagList",
  903. &Offset);
  904. if (Ret != STATUS_SUCCESS) {
  905. dprintf ("WARN: Couldn't read TagList field\n");
  906. }
  907. Unit_QueueFrozen = ReadField (Flags.QueueFrozen);
  908. Unit_QueueLocked = ReadField (Flags.QueueLocked);
  909. Unit_TagList = UnitPtr + Offset;
  910. dprintf (" TagList %08x (%d of %d used)\n",
  911. (ULONG)(Unit_TagList),
  912. (ULONG)ReadField(TagList.OutstandingTags),
  913. (ULONG)ReadField(TagList.Count));
  914. Ret = GetFieldOffset ("raidport!RAID_UNIT_EXTENSION",
  915. "IoQueue",
  916. &Offset);
  917. if (Ret != STATUS_SUCCESS) {
  918. dprintf ("WARN: failed to get IoQueue offset from unit.\n");
  919. }
  920. Unit_IoQueue = UnitPtr + Offset;
  921. Ret = GetFieldOffset ("raidport!IO_QUEUE",
  922. "DeviceQueue",
  923. &Offset);
  924. if (Ret != STATUS_SUCCESS) {
  925. dprintf ("WARN: failed to get DeviceQueue offset from unit.\n");
  926. }
  927. IoQueue_DeviceQueue = Unit_IoQueue + Offset;
  928. InitTypeRead (IoQueue_DeviceQueue, raidport!EXTENDED_DEVICE_QUEUE);
  929. dprintf (" IoQueue %s %s; Outstanding %d Device %d ByPass %d\n",
  930. Unit_QueueFrozen ? "Frozen" : "Unfrozen",
  931. Unit_QueueLocked ? "Locked" : "Unlocked",
  932. (ULONG)ReadField(OutstandingRequests),
  933. (ULONG)ReadField(DeviceRequests),
  934. (ULONG)ReadField(ByPassRequests));
  935. Ret = GetFieldOffset ("raidport!EXTENDED_DEVICE_QUEUE",
  936. "DeviceListHead",
  937. &Device_Offset);
  938. if (Ret != STATUS_SUCCESS) {
  939. dprintf ("WARN: offset of DeviceListHead within EXTENDED_DEVICE_QUEUE failed\n");
  940. }
  941. Ret = GetFieldOffset ("raidport!EXTENDED_DEVICE_QUEUE",
  942. "ByPassListHead",
  943. &ByPass_Offset);
  944. if (Ret != STATUS_SUCCESS) {
  945. dprintf ("WARN: offset of ByPassListHead within EXTENDED_DEVICE_QUEUE failed\n");
  946. }
  947. dprintf (" Depth %d DeviceList %08x ByPassList %08x\n",
  948. (ULONG)ReadField(Depth),
  949. (ULONG)(IoQueue_DeviceQueue + Device_Offset),
  950. (ULONG)(IoQueue_DeviceQueue + ByPass_Offset));
  951. }
  952. /*
  953. UNIT 8f888888
  954. Ext 8e000000 Adapter 8100000000 Next 8e888888 Working
  955. SCSI [3, 0, 0] MYLEX DAC960 122222 InquiryData 08080808
  956. SlowLock Free RemLock 10 PageCount 20
  957. SrbExtension Size 20 VA Start 90000000 End 20000000
  958. TagList 08080808 (20 of 256 used)
  959. IoQueue Unfrozen Unlocked; Outstanding 200, Device 200, ByPass 200
  960. Depth 254 DeviceListHead 00000000 ByPassListHead 88888888
  961. Outstanding IRPs:
  962. IRP 00000000 Scsi ExecuteScsi function
  963. IRP 00000000 Scsi ExecuteScsi function
  964. IRP 00000000 Scsi ExecuteScsi function
  965. IRP 00000000 Scsi ExecuteScsi function
  966. IRP 00000000 Scsi ExecuteScsi function
  967. IRP 00000000 Scsi ExecuteScsi function
  968. IRP 00000000 Scsi ExecuteScsi function
  969. IRP 00000000 Scsi ExecuteScsi function
  970. Device IRPs:
  971. IRP 00000000 ssssssssssssssssssssssss
  972. IRP 00000000 ssssssssssssssssssssssss
  973. IRP 00000000 ssssssssssssssssssssssss
  974. IRP 00000000 ssssssssssssssssssssssss
  975. IRP 00000000 ssssssssssssssssssssssss
  976. ByPass IRPs:
  977. IRP 00000000 ssssssssssssssssssssssss
  978. IRP 00000000 ssssssssssssssssssssssss
  979. IRP 00000000 ssssssssssssssssssssssss
  980. IRP 00000000 ssssssssssssssssssssssss
  981. IRP 00000000 ssssssssssssssssssssssss
  982. */
  983. }
  984. VOID
  985. ParseArgs(
  986. IN PSZ Args,
  987. OUT PULONG64 UnitPtr,
  988. OUT PULONG Level
  989. )
  990. {
  991. LONG Unit;
  992. *UnitPtr = -1;
  993. *Level = 0;
  994. if (Args[0] != '\000') {
  995. Unit = (LONG)strtoul (Args, &Args, 16);
  996. *UnitPtr = (ULONG64)(LONG64)Unit;
  997. if (Args[0] != '\000') {
  998. strtoul (Args, &Args, 10);
  999. }
  1000. }
  1001. }
  1002. DECLARE_API ( unit )
  1003. {
  1004. ULONG Level;
  1005. ULONG64 Unit;
  1006. Unit = -1;
  1007. Level = -1;
  1008. ParseArgs ( (PSZ)args, &Unit, &Level);
  1009. if (Unit == -1) {
  1010. if (Level == -1) {
  1011. Level = 1;
  1012. }
  1013. ListAllUnits (Level);
  1014. } else {
  1015. if (Level == -1) {
  1016. Level = 2;
  1017. }
  1018. DumpUnit (Unit, 2);
  1019. }
  1020. return S_OK;
  1021. }
  1022. DECLARE_API ( adapter )
  1023. {
  1024. ULONG Level;
  1025. ULONG64 Adapter;
  1026. Adapter = -1;
  1027. Level = -1;
  1028. ParseArgs ( (PSZ)args, &Adapter, &Level);
  1029. if (Adapter == -1) {
  1030. if (Level == -1) {
  1031. Level = 1;
  1032. }
  1033. ListAllAdapters (Level);
  1034. } else {
  1035. if (Level == -1) {
  1036. Level = 2;
  1037. }
  1038. DumpAdapter (Adapter, 2);
  1039. }
  1040. return S_OK;
  1041. }
  1042. DECLARE_API ( verbose )
  1043. {
  1044. ULONG NewValue;
  1045. NewValue = strtoul (args, NULL, 16);
  1046. dprintf ("Setting Verbose from %d to %d\n", (ULONG)Verbose, (ULONG)NewValue);
  1047. Verbose = (BOOLEAN) NewValue;
  1048. return S_OK;
  1049. }
  1050. DECLARE_API ( help )
  1051. {
  1052. dprintf (" !raid.help [command] - Get help.\n");
  1053. dprintf (" !raid.adapter [adapter [detail]] - Get adapter information.\n");
  1054. dprintf (" !raid.unit [unit [detail]] - Get unit information.\n");
  1055. #if 0
  1056. if (args != NULL && (_stricmp (args, "adapter") == 00)) {
  1057. dprintf ("------------------------------------------------------------------------------\n");
  1058. dprintf ("\n");
  1059. dprintf ("NAME:\n");
  1060. dprintf ("\n");
  1061. dprintf (" !raid.adapter\n");
  1062. dprintf ("\n");
  1063. dprintf ("USAGE:\n");
  1064. dprintf ("\n");
  1065. dprintf (" adapter [ADAPTER-OBJECT [DETAIL-LEVEL]]\n");
  1066. dprintf ("\n");
  1067. dprintf ("ARGUMENTS:\n");
  1068. dprintf ("\n");
  1069. dprintf (" ADAPTER-OBJECT - Pointer to a device object representing an adapter\n");
  1070. dprintf (" or pointer to an adapter extension. If ADAPTER is 0 or the\n");
  1071. dprintf (" argument is not present, the command will dump information about\n");
  1072. dprintf (" all adapters, not just the adapter specified.\n");
  1073. dprintf ("\n");
  1074. dprintf (" DETAIL-LEVEL - Detail level for dump adapter structs.\n");
  1075. dprintf ("\n");
  1076. dprintf ("-----------------------------------------------------------------------------\n");
  1077. } else if (args != NULL && (_stricmp (args, "unit") == 00)) {
  1078. dprintf ("Unit help\n");
  1079. } else {
  1080. dprintf (" !raid.help [command] - Get help.\n");
  1081. dprintf (" !raid.adapter [adapter [detail]] - Get adapter information.\n");
  1082. dprintf (" !raid.unit [unit [detail]] - Get unit information.\n");
  1083. }
  1084. #endif
  1085. return S_OK;
  1086. }