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.

678 lines
25 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1992 - 1999
  3. Module Name:
  4. atapikd.c
  5. Abstract:
  6. Debugger Extension Api for interpretting atapi structures
  7. Author:
  8. Environment:
  9. User Mode.
  10. Revision History:
  11. --*/
  12. #include "pch.h"
  13. #include "math.h"
  14. #include "ideport.h"
  15. VOID
  16. AtapiDumpPdoExtension(
  17. IN ULONG64 PdoExtAddr,
  18. IN ULONG Detail,
  19. IN ULONG Depth
  20. );
  21. VOID
  22. AtapiDumpFdoExtension(
  23. IN ULONG64 FdoExtAddr,
  24. IN ULONG Detail,
  25. IN ULONG Depth
  26. );
  27. VOID
  28. DumpPdoState(
  29. IN ULONG Depth,
  30. IN ULONG State
  31. );
  32. VOID
  33. DumpFdoState(
  34. IN ULONG Depth,
  35. IN ULONG State
  36. );
  37. #ifdef ENABLE_COMMAND_LOG
  38. VOID
  39. DumpCommandLog(
  40. IN ULONG Depth,
  41. IN ULONG64 SrbDataAddr
  42. );
  43. #else
  44. #define DumpCommandLog(a, b)
  45. #endif
  46. VOID
  47. DumpIdentifyData(
  48. IN ULONG Depth,
  49. IN PIDENTIFY_DATA IdData
  50. );
  51. PUCHAR DMR_Reason[] = {
  52. "",
  53. "Enum Failed",
  54. "Reported Missing",
  55. "Too Many Timeout",
  56. "Killed PDO",
  57. "Replaced By User"
  58. };
  59. PUCHAR DeviceType[] = {
  60. "DIRECT_ACCESS_DEVICE",
  61. "SEQUENTIAL_ACCESS_DEVICE",
  62. "PRINTER_DEVICE",
  63. "PROCESSOR_DEVICE",
  64. "WRITE_ONCE_READ_MULTIPLE_DEVICE",
  65. "READ_ONLY_DIRECT_ACCESS_DEVICE",
  66. "SCANNER_DEVICE",
  67. "OPTICAL_DEVICE",
  68. "MEDIUM_CHANGER",
  69. "COMMUNICATION_DEVICE"
  70. };
  71. PUCHAR PdoState[] = {
  72. "PDOS_DEVICE_CLAIMED",
  73. "PDOS_LEGACY_ATTACHER",
  74. "PDOS_STARTED",
  75. "PDOS_STOPPED",
  76. "PDOS_SURPRISE_REMOVED",
  77. "PDOS_REMOVED",
  78. "PDOS_DEADMEAT",
  79. "PDOS_NO_POWER_DOWN",
  80. "PDOS_QUEUE_FROZEN_BY_POWER_DOWN",
  81. "PDOS_QUEUE_FROZEN_BY_SLEEPING_SYSTEM",
  82. "PDOS_QUEUE_FROZEN_BY_STOP_DEVICE",
  83. "PDOS_QUEUE_FROZEN_BY_PARENT",
  84. "PDOS_QUEUE_FROZEN_BY_START",
  85. "PDOS_DISABLED_BY_USER",
  86. "PDOS_NEED_RESCAN",
  87. "PDOS_REPORTED_TO_PNP",
  88. "PDOS_INITIALIZED"
  89. };
  90. PUCHAR FdoState[] = {
  91. "FDOS_DEADMEAT",
  92. "FDOS_STARTED",
  93. "FDOS_STOPPED"
  94. };
  95. #define MAX_PDO_STATES 16
  96. #define MAX_FDO_STATES 3
  97. DECLARE_API(pdoext)
  98. /*++
  99. Routine Description:
  100. Dumps the pdo extension for a given device object, or dumps the
  101. given pdo extension
  102. Arguments:
  103. args - string containing the address of the device object or device
  104. extension
  105. Return Value:
  106. none
  107. --*/
  108. {
  109. ULONG64 devObjAddr = 0;
  110. ULONG detail = 0;
  111. GetAddressAndDetailLevel64(args, &devObjAddr, &detail);
  112. if (devObjAddr){
  113. CSHORT objType = GetUSHORTField(devObjAddr, "nt!_DEVICE_OBJECT", "Type");
  114. if (objType == IO_TYPE_DEVICE){
  115. ULONG64 pdoExtAddr;
  116. pdoExtAddr = GetULONGField(devObjAddr, "nt!_DEVICE_OBJECT", "DeviceExtension");
  117. if (pdoExtAddr != BAD_VALUE){
  118. AtapiDumpPdoExtension(pdoExtAddr, detail, 0);
  119. }
  120. }
  121. else {
  122. dprintf("Error: 0x%08p is not a device object\n", devObjAddr);
  123. }
  124. }
  125. else {
  126. dprintf("\n usage: !atapikd.pdoext <atapi pdo> \n\n");
  127. }
  128. return S_OK;
  129. }
  130. VOID
  131. AtapiDumpPdoExtension(
  132. IN ULONG64 PdoExtAddr,
  133. IN ULONG Detail,
  134. IN ULONG Depth
  135. )
  136. {
  137. UCHAR scsiDeviceType;
  138. ULONG pdoState;
  139. ULONG luFlags;
  140. ULONG64 attacheePdo;
  141. ULONG64 idleCounterAddr;
  142. ULONG64 srbDataAddr;
  143. ULONG devicePowerState, systemPowerState;
  144. xdprintf(Depth, ""), dprintf("\nATAPI physical device extension at address 0x%08p\n\n", PdoExtAddr);
  145. Depth++;
  146. scsiDeviceType = GetUCHARField(PdoExtAddr, "atapi!_PDO_EXTENSION", "ScsiDeviceType");
  147. pdoState = (ULONG)GetULONGField(PdoExtAddr, "atapi!_PDO_EXTENSION", "PdoState");
  148. luFlags = (ULONG)GetULONGField(PdoExtAddr, "atapi!_PDO_EXTENSION", "LuFlags");
  149. attacheePdo = GetULONGField(PdoExtAddr, "atapi!_PDO_EXTENSION", "AttacheePdo");
  150. idleCounterAddr = GetULONGField(PdoExtAddr, "atapi!_PDO_EXTENSION", "IdleCounter");
  151. srbDataAddr = GetFieldAddr(PdoExtAddr, "atapi!_PDO_EXTENSION", "SrbData");
  152. devicePowerState = (ULONG)GetULONGField(PdoExtAddr, "atapi!_PDO_EXTENSION", "DevicePowerState");
  153. systemPowerState = (ULONG)GetULONGField(PdoExtAddr, "atapi!_PDO_EXTENSION", "SystemPowerState");
  154. if ((scsiDeviceType != BAD_VALUE) && (pdoState != BAD_VALUE) && (luFlags != BAD_VALUE) &&
  155. (attacheePdo != BAD_VALUE) && (idleCounterAddr != BAD_VALUE) && (srbDataAddr != BAD_VALUE) &&
  156. (devicePowerState != BAD_VALUE) && (systemPowerState != BAD_VALUE)){
  157. ULONG idlecount;
  158. if ((scsiDeviceType >= 0) && (scsiDeviceType <= 9)) {
  159. xdprintf(Depth, ""), dprintf("SCSI Device Type : %s\n", DeviceType[scsiDeviceType]);
  160. }
  161. else {
  162. xdprintf(Depth, ""), dprintf("Connected to Unknown Device\n");
  163. }
  164. DumpPdoState(Depth, pdoState);
  165. dprintf("\n");
  166. DumpFlags(Depth, "LU Flags", luFlags, LuFlags);
  167. xdprintf(Depth, ""), dprintf("PowerState (D%d, S%d)\n", devicePowerState-1, systemPowerState-1);
  168. if (idleCounterAddr){
  169. ULONG resultLen = 0;
  170. ReadMemory(idleCounterAddr, &idlecount, sizeof(ULONG), &resultLen);
  171. if (resultLen != sizeof(ULONG)){
  172. idlecount = 0;
  173. }
  174. }
  175. else {
  176. idlecount = 0;
  177. }
  178. xdprintf(Depth, ""), dprintf("IdleCounter 0x%08x\n", idlecount);
  179. xdprintf(Depth, ""), dprintf("SrbData: (use ' dt atapi!_SRB_DATA %08p ')\n", srbDataAddr);
  180. dprintf("\n");
  181. xdprintf(Depth, ""), dprintf("(for more info, use ' dt atapi!_PDO_EXTENSION %08p ')\n", PdoExtAddr);
  182. #ifdef LOG_DEADMEAT_EVENT
  183. {
  184. ULONG deadmeatReason;
  185. deadmeatReason = (ULONG)GetULONGField(PdoExtAddr, "atapi!_PDO_EXTENSION", "DeadmeatRecord.Reason");
  186. if ((deadmeatReason != BAD_VALUE) && (deadmeatReason > 0)){
  187. dprintf("\n");
  188. xdprintf(Depth, "Deadmeat Record: \n");
  189. xdprintf(Depth+1, "Reason : %s\n", DMR_Reason[deadmeatReason]);
  190. xdprintf(Depth+1, ""), dprintf("(for more info, use ' dt -r atapi!_PDO_EXTENSION %08p ')\n", PdoExtAddr);
  191. }
  192. }
  193. #endif
  194. #ifdef ENABLE_COMMAND_LOG
  195. DumpCommandLog(Depth, srbDataAddr);
  196. #endif
  197. }
  198. dprintf("\n");
  199. }
  200. VOID DumpPdoState(IN ULONG Depth, IN ULONG State)
  201. {
  202. int inx, statebit, count;
  203. count = 0;
  204. xdprintf(Depth, ""), dprintf("PDO State (0x%08x): \n", State);
  205. if (State & 0x80000000) {
  206. xdprintf(Depth+1, "Initialized ");
  207. count++;
  208. }
  209. for (inx = 0; inx < MAX_PDO_STATES; inx++) {
  210. statebit = (1 << inx);
  211. if (State & statebit) {
  212. xdprintf(Depth+1, "%s ", PdoState[inx]);
  213. count++;
  214. if ((count % 2) == 0) {
  215. dprintf("\n");
  216. }
  217. }
  218. }
  219. dprintf("\n");
  220. }
  221. DECLARE_API(fdoext)
  222. /*++
  223. Routine Description:
  224. Dumps the fdo extension for a given device object, or dumps the
  225. given fdo extension
  226. Arguments:
  227. args - string containing the address of the device object or device
  228. extension
  229. Return Value:
  230. none
  231. --*/
  232. {
  233. ULONG64 devObjAddr;
  234. ULONG detail = 0;
  235. GetAddressAndDetailLevel64(args, &devObjAddr, &detail);
  236. if (devObjAddr){
  237. CSHORT objType = GetUSHORTField(devObjAddr, "nt!_DEVICE_OBJECT", "Type");
  238. if (objType == IO_TYPE_DEVICE){
  239. ULONG64 fdoExtAddr;
  240. fdoExtAddr = GetULONGField(devObjAddr, "nt!_DEVICE_OBJECT", "DeviceExtension");
  241. if (fdoExtAddr != BAD_VALUE){
  242. AtapiDumpFdoExtension(fdoExtAddr, detail, 0);
  243. }
  244. }
  245. else {
  246. dprintf("Error: 0x%08p is not a device object\n", devObjAddr);
  247. }
  248. }
  249. else {
  250. dprintf("\n usage: !atapikd.pdoext <atapi pdo> \n\n");
  251. }
  252. return S_OK;
  253. }
  254. DECLARE_API(miniext)
  255. /*++
  256. Routine Description:
  257. Dumps the Miniport device extension at the given address
  258. Arguments:
  259. args - string containing the address of the miniport extension
  260. Return Value:
  261. none
  262. --*/
  263. {
  264. ULONG64 hwDevExtAddr;
  265. ULONG Depth = 1;
  266. ULONG detail;
  267. GetAddressAndDetailLevel64(args, &hwDevExtAddr, &detail);
  268. if (hwDevExtAddr){
  269. ULONG64 deviceFlagsArrayAddr;
  270. ULONG64 lastLunArrayAddr;
  271. ULONG64 timeoutCountArrayAddr;
  272. ULONG64 numberOfCylindersArrayAddr;
  273. ULONG64 numberOHeadsArrayAddr;
  274. ULONG64 sectorsPerTrackArrayAddr;
  275. ULONG64 maxBlockTransferArrayAddr;
  276. ULONG64 identifyDataArrayAddr;
  277. deviceFlagsArrayAddr = GetFieldAddr(hwDevExtAddr, "atapi!_HW_DEVICE_EXTENSION", "DeviceFlags");
  278. lastLunArrayAddr = GetFieldAddr(hwDevExtAddr, "atapi!_HW_DEVICE_EXTENSION", "LastLun");
  279. timeoutCountArrayAddr = GetFieldAddr(hwDevExtAddr, "atapi!_HW_DEVICE_EXTENSION", "TimeoutCount");
  280. numberOfCylindersArrayAddr = GetFieldAddr(hwDevExtAddr, "atapi!_HW_DEVICE_EXTENSION", "NumberOfCylinders");
  281. numberOHeadsArrayAddr = GetFieldAddr(hwDevExtAddr, "atapi!_HW_DEVICE_EXTENSION", "NumberOfHeads");
  282. sectorsPerTrackArrayAddr = GetFieldAddr(hwDevExtAddr, "atapi!_HW_DEVICE_EXTENSION", "SectorsPerTrack");
  283. maxBlockTransferArrayAddr = GetFieldAddr(hwDevExtAddr, "atapi!_HW_DEVICE_EXTENSION", "MaximumBlockXfer");
  284. identifyDataArrayAddr = GetFieldAddr(hwDevExtAddr, "atapi!_HW_DEVICE_EXTENSION", "IdentifyData");
  285. if ((deviceFlagsArrayAddr != BAD_VALUE) && (lastLunArrayAddr != BAD_VALUE) &&
  286. (timeoutCountArrayAddr != BAD_VALUE) && (numberOfCylindersArrayAddr != BAD_VALUE) &&
  287. (numberOHeadsArrayAddr != BAD_VALUE) && (sectorsPerTrackArrayAddr != BAD_VALUE) &&
  288. (maxBlockTransferArrayAddr != BAD_VALUE) && (identifyDataArrayAddr != BAD_VALUE)){
  289. ULONG deviceFlagsArray[MAX_IDE_DEVICE * MAX_IDE_LINE];
  290. ULONG lastLunArray[MAX_IDE_DEVICE * MAX_IDE_LINE];
  291. ULONG timeoutCountArray[MAX_IDE_DEVICE * MAX_IDE_LINE];
  292. ULONG numberOfCylindersArray[MAX_IDE_DEVICE * MAX_IDE_LINE];
  293. ULONG numberOfHeadsArray[MAX_IDE_DEVICE * MAX_IDE_LINE];
  294. ULONG sectorsPerTrackArray[MAX_IDE_DEVICE * MAX_IDE_LINE];
  295. UCHAR maxBlockTransferArray[MAX_IDE_DEVICE * MAX_IDE_LINE];
  296. IDENTIFY_DATA identifyDataArray[MAX_IDE_DEVICE * MAX_IDE_LINE];
  297. ULONG resultLen;
  298. BOOLEAN ok;
  299. xdprintf(Depth, ""), dprintf("\nATAPI Miniport Device Extension at address 0x%08p\n\n", hwDevExtAddr);
  300. /*
  301. * Read in arrays of info for child LUNs
  302. */
  303. ok = TRUE;
  304. if (ok) ok = (BOOLEAN)ReadMemory(deviceFlagsArrayAddr, (PVOID)deviceFlagsArray, sizeof(deviceFlagsArray), &resultLen);
  305. if (ok) ok = (BOOLEAN)ReadMemory(lastLunArrayAddr, (PVOID)lastLunArray, sizeof(lastLunArray), &resultLen);
  306. if (ok) ok = (BOOLEAN)ReadMemory(timeoutCountArrayAddr, (PVOID)timeoutCountArray, sizeof(timeoutCountArray), &resultLen);
  307. if (ok) ok = (BOOLEAN)ReadMemory(numberOfCylindersArrayAddr, (PVOID)numberOfCylindersArray, sizeof(numberOfCylindersArray), &resultLen);
  308. if (ok) ok = (BOOLEAN)ReadMemory(numberOHeadsArrayAddr, (PVOID)numberOfHeadsArray, sizeof(numberOfHeadsArray), &resultLen);
  309. if (ok) ok = (BOOLEAN)ReadMemory(sectorsPerTrackArrayAddr, (PVOID)sectorsPerTrackArray, sizeof(sectorsPerTrackArray), &resultLen);
  310. if (ok) ok = (BOOLEAN)ReadMemory(maxBlockTransferArrayAddr, (PVOID)maxBlockTransferArray, sizeof(maxBlockTransferArray), &resultLen);
  311. if (ok) ok = (BOOLEAN)ReadMemory(identifyDataArrayAddr, (PVOID)identifyDataArray, sizeof(identifyDataArray), &resultLen);
  312. if (ok){
  313. ULONG i;
  314. /*
  315. * Display details for each device
  316. */
  317. dprintf("\n");
  318. for (i = 0; i < (MAX_IDE_DEVICE * MAX_IDE_LINE); i++) {
  319. if (deviceFlagsArray[i] & DFLAGS_DEVICE_PRESENT){
  320. xdprintf(Depth, "Device %d Details:\n", i);
  321. DumpFlags(Depth+1, "Device Flags", deviceFlagsArray[i], DevFlags);
  322. xdprintf(Depth+1, "TimeoutCount %u, LastLun %u, MaxBlockXfer 0x%02x\n",
  323. timeoutCountArray[i], lastLunArray[i], maxBlockTransferArray[i]);
  324. xdprintf(Depth+1, "NumCylinders 0x%08x, NumHeads 0x%08x, SectorsPerTrack 0x%08x\n",
  325. numberOfCylindersArray[i], numberOfHeadsArray[i], sectorsPerTrackArray[i]);
  326. /*
  327. * Display DeviceParameters info
  328. */
  329. dprintf("\n");
  330. if (IsPtr64()){
  331. xdprintf(Depth+1, "(cannot display DeviceParameters[] info for 64-bit)\n");
  332. }
  333. else {
  334. /*
  335. * DeviceParameters[] is an array of embedded structs.
  336. * Reading this in an architecture-agnostic way would be tricky,
  337. * so we punt and only do it for 32-bit target and 32-bit debug extension.
  338. */
  339. #ifdef _X86_
  340. HW_DEVICE_EXTENSION hwDevExt;
  341. ok = (BOOLEAN)ReadMemory(hwDevExtAddr, (PVOID)&hwDevExt, sizeof(hwDevExt), &resultLen);
  342. if (ok){
  343. #define IsInitXferMode(a) ((a == 0x7fffffff) ? -1 : a)
  344. xdprintf(Depth+1, "Device Parameters Summary :\n");
  345. xdprintf(Depth+2, "PioReadCommand 0x%02x, PioWriteCommand 0x%02x\n",
  346. hwDevExt.DeviceParameters[i].IdePioReadCommand,
  347. hwDevExt.DeviceParameters[i].IdePioWriteCommand);
  348. xdprintf(Depth+2, "IdeFlushCommand 0x%02x, MaxBytePerPioInterrupt %u\n",
  349. hwDevExt.DeviceParameters[i].IdeFlushCommand,
  350. hwDevExt.DeviceParameters[i].MaxBytePerPioInterrupt);
  351. xdprintf(Depth+2, "BestPioMode %d, BestSwDMAMode %d\n",
  352. IsInitXferMode(hwDevExt.DeviceParameters[i].BestPioMode),
  353. IsInitXferMode(hwDevExt.DeviceParameters[i].BestSwDmaMode));
  354. xdprintf(Depth+2, "BestMwDMAMode %d, BestUDMAMode %d\n",
  355. IsInitXferMode(hwDevExt.DeviceParameters[i].BestMwDmaMode),
  356. IsInitXferMode(hwDevExt.DeviceParameters[i].BestUDmaMode));
  357. xdprintf(Depth+2, "TMSupported 0x%08x, TMCurrent 0x%08x\n",
  358. hwDevExt.DeviceParameters[i].TransferModeSupported,
  359. hwDevExt.DeviceParameters[i].TransferModeCurrent);
  360. xdprintf(Depth+2, "TMMask 0x%08x, TMSelected 0x%08x\n",
  361. hwDevExt.DeviceParameters[i].TransferModeMask,
  362. hwDevExt.DeviceParameters[i].TransferModeSelected);
  363. }
  364. else {
  365. dprintf("\n failed to read HW_DEVICE_EXTENSION at 0x%08p\n", hwDevExtAddr);
  366. }
  367. #else
  368. xdprintf(Depth+1, "(64-bit debug extension cannot display DeviceParameters[] info)\n");
  369. #endif
  370. }
  371. /*
  372. * Display Identify Data
  373. */
  374. dprintf("\n");
  375. xdprintf(Depth+1, ""), dprintf("Identify Data Summary :\n");
  376. xdprintf(Depth+2, ""), dprintf("Word 1,3,6 (C-0x%04x, H-0x%04x, S-0x%04x) \n",
  377. identifyDataArray[i].NumCylinders,
  378. identifyDataArray[i].NumHeads,
  379. identifyDataArray[i].NumSectorsPerTrack);
  380. xdprintf(Depth+2, ""), dprintf("Word 54,55,56 (C-0x%04x, H-0x%04x, S-0x%04x) \n",
  381. identifyDataArray[i].NumberOfCurrentCylinders,
  382. identifyDataArray[i].NumberOfCurrentHeads,
  383. identifyDataArray[i].CurrentSectorsPerTrack);
  384. xdprintf(Depth+2, ""), dprintf("CurrentSectorCapacity 0x%08x, UserAddressableSectors 0x%08x\n",
  385. identifyDataArray[i].CurrentSectorCapacity,
  386. identifyDataArray[i].UserAddressableSectors);
  387. xdprintf(Depth+2, ""), dprintf("Capabilities(word 49) 0x%04x, UDMASup 0x%02x, UDMAActive 0x%02x\n",
  388. identifyDataArray[i].Capabilities,
  389. identifyDataArray[i].UltraDMASupport,
  390. identifyDataArray[i].UltraDMAActive);
  391. dprintf("\n");
  392. }
  393. else {
  394. xdprintf(Depth, "Device %d not present\n", i);
  395. }
  396. }
  397. }
  398. else {
  399. dprintf("\n ReadMemory failed to read one of the arrays from HW_DEVICE_EXTENSION @ 0x%08p\n", hwDevExtAddr);
  400. }
  401. }
  402. dprintf("\n");
  403. xdprintf(Depth+1, ""), dprintf("(for more info, use ' dt atapi!_HW_DEVICE_EXTENSION %08p ')\n", hwDevExtAddr);
  404. }
  405. else {
  406. dprintf("\n usage: !atapikd.miniext <PHW_DEVICE_EXTENSION> \n\n");
  407. }
  408. dprintf("\n");
  409. return S_OK;
  410. }
  411. VOID AtapiDumpFdoExtension(IN ULONG64 FdoExtAddr, IN ULONG Detail, IN ULONG Depth)
  412. {
  413. ULONG devicePowerState, systemPowerState;
  414. ULONG flags, srbFlags, fdoState;
  415. ULONG64 interruptDataAddr;
  416. ULONG64 ideResourceAddr;
  417. xdprintf(Depth, ""), dprintf("\nATAPI Functional Device Extension @ 0x%08p\n\n", FdoExtAddr);
  418. devicePowerState = (ULONG)GetULONGField(FdoExtAddr, "atapi!_FDO_EXTENSION", "DevicePowerState");
  419. systemPowerState = (ULONG)GetULONGField(FdoExtAddr, "atapi!_FDO_EXTENSION", "SystemPowerState");
  420. flags = (ULONG)GetULONGField(FdoExtAddr, "atapi!_FDO_EXTENSION", "Flags");
  421. srbFlags = (ULONG)GetULONGField(FdoExtAddr, "atapi!_FDO_EXTENSION", "SrbFlags");
  422. fdoState = (ULONG)GetULONGField(FdoExtAddr, "atapi!_FDO_EXTENSION", "FdoState");
  423. interruptDataAddr = GetFieldAddr(FdoExtAddr, "atapi!_FDO_EXTENSION", "InterruptData");
  424. ideResourceAddr = GetFieldAddr(FdoExtAddr, "atapi!_FDO_EXTENSION", "IdeResource");
  425. if ((devicePowerState != BAD_VALUE) && (systemPowerState != BAD_VALUE) &&
  426. (flags != BAD_VALUE) && (srbFlags != BAD_VALUE) && (fdoState != BAD_VALUE) &&
  427. (interruptDataAddr != BAD_VALUE) && (ideResourceAddr != BAD_VALUE)){
  428. ULONG interruptFlags, interruptMode, interruptLevel;
  429. BOOLEAN primaryDiskClaimed, secondaryDiskClaimed;
  430. xdprintf(Depth+1, "Power State (D%d, S%d)\n", devicePowerState-1, systemPowerState-1);
  431. DumpFlags(Depth+1, "Port Flags", flags, PortFlags);
  432. DumpFlags(Depth+1, "SRB Flags", srbFlags, SrbFlags);
  433. DumpFdoState(Depth+1, fdoState);
  434. /*
  435. * Display interrupt data
  436. */
  437. dprintf("\n");
  438. xdprintf(Depth+1, "Interrupt Data: \n");
  439. interruptFlags = (ULONG)GetULONGField(interruptDataAddr, "atapi!_INTERRUPT_DATA", "InterruptFlags");
  440. if (interruptFlags != BAD_VALUE){
  441. DumpFlags(Depth+2, "Port Flags", interruptFlags, PortFlags);
  442. }
  443. xdprintf(Depth+2, ""), dprintf("(for more info, use ' dt atapi!_INTERRUPT_DATA %08p ')\n", interruptDataAddr);
  444. /*
  445. * Display IDE_RESOURCE info
  446. */
  447. dprintf("\n");
  448. xdprintf(Depth+1, " IDE Resources: \n");
  449. interruptMode = (ULONG)GetULONGField(ideResourceAddr, "atapi!_IDE_RESOURCE", "InterruptMode");
  450. interruptLevel = (ULONG)GetULONGField(ideResourceAddr, "atapi!_IDE_RESOURCE", "InterruptLevel");
  451. primaryDiskClaimed = (BOOLEAN)GetUCHARField(ideResourceAddr, "atapi!_IDE_RESOURCE", "AtdiskPrimaryClaimed");
  452. secondaryDiskClaimed = (BOOLEAN)GetUCHARField(ideResourceAddr, "atapi!_IDE_RESOURCE", "AtdiskSecondaryClaimed");
  453. if ((interruptMode != BAD_VALUE) && (interruptLevel != BAD_VALUE) &&
  454. (primaryDiskClaimed != BAD_VALUE) && (secondaryDiskClaimed != BAD_VALUE)){
  455. xdprintf(Depth+2, "Interrupt Mode : %s \n", interruptMode ? "Latched" : "Level Sensitive");
  456. xdprintf(Depth+2, "Interrupt Level 0x%x\n", interruptLevel);
  457. xdprintf(Depth+2, "Primary Disk %s.\n", primaryDiskClaimed ? "Claimed" : "Not Claimed");
  458. xdprintf(Depth+2, "Secondary Disk %s.\n", secondaryDiskClaimed ? "Claimed" : "Not Claimed");
  459. }
  460. xdprintf(Depth+2, ""), dprintf("(for more info use ' dt atapi!_IDE_RESOURCE %08p ')\n", ideResourceAddr);
  461. }
  462. dprintf("\n");
  463. xdprintf(Depth+1, ""), dprintf("(for more info, use ' dt atapi!_FDO_EXTENSION %08p ')\n", FdoExtAddr);
  464. dprintf("\n");
  465. }
  466. VOID DumpFdoState(IN ULONG Depth, IN ULONG State)
  467. {
  468. int inx, count;
  469. count = 0;
  470. xdprintf(Depth, ""), dprintf("FDO State (0x%08x): \n", State);
  471. for (inx = 0; inx < MAX_FDO_STATES; inx++) {
  472. if (State & (1<<inx)) {
  473. xdprintf(Depth+1, "%s ", FdoState[inx]);
  474. }
  475. }
  476. dprintf("\n");
  477. }
  478. #ifdef ENABLE_COMMAND_LOG
  479. VOID ShowCommandLog(ULONG Depth, PCOMMAND_LOG CmdLogEntry, ULONG LogNumber)
  480. {
  481. if ((CmdLogEntry->FinalTaskFile.bCommandReg & IDE_STATUS_ERROR) || (CmdLogEntry->Cdb[0] == SCSIOP_REQUEST_SENSE)){
  482. xdprintf(Depth, "Log[%03d]: Cmd(%02x), Sts(%02x), BmStat(%02x), Sense(%02x/%02x/%02x)",
  483. LogNumber, CmdLogEntry->Cdb[0], CmdLogEntry->FinalTaskFile.bCommandReg, CmdLogEntry->BmStatus,
  484. CmdLogEntry->SenseData[0], CmdLogEntry->SenseData[1], CmdLogEntry->SenseData[2]);
  485. }
  486. else {
  487. xdprintf(Depth, "Log[%03d]: Cmd(%02x), Sts(%02x), BmStat(%02x)",
  488. LogNumber, CmdLogEntry->Cdb[0], CmdLogEntry->FinalTaskFile.bCommandReg, CmdLogEntry->BmStatus);
  489. }
  490. // BUGBUG - what's this ?
  491. if (CmdLogEntry->Cdb[0] == 0xc8){
  492. xdprintf(Depth, "CmdR(%02x)", CmdLogEntry->Cdb[7]);
  493. }
  494. dprintf("\n");
  495. }
  496. VOID DumpCommandLog(IN ULONG Depth, IN ULONG64 SrbDataAddr)
  497. {
  498. ULONG64 cmdLogAddr;
  499. ULONG cmdLogIndex;
  500. dprintf("\n");
  501. cmdLogAddr = GetULONGField(SrbDataAddr, "atapi!_SRB_DATA", "IdeCommandLog");
  502. cmdLogIndex = (ULONG)GetULONGField(SrbDataAddr, "atapi!_SRB_DATA", "IdeCommandLogIndex");
  503. if ((cmdLogAddr != BAD_VALUE) && (cmdLogIndex != BAD_VALUE)){
  504. UCHAR cmdLogBlock[MAX_COMMAND_LOG_ENTRIES*sizeof(COMMAND_LOG)];
  505. ULONG resultLen;
  506. BOOLEAN ok;
  507. xdprintf(Depth, ""), dprintf("Command Log Summary at 0x%08p:\n", cmdLogAddr);
  508. ok = (BOOLEAN)ReadMemory(cmdLogAddr, (PVOID)cmdLogBlock, sizeof(cmdLogBlock), &resultLen);
  509. if (ok){
  510. PCOMMAND_LOG cmdLog = (PCOMMAND_LOG)cmdLogBlock;
  511. ULONG logIndex, logNumber;
  512. /*
  513. * Print the log in temporal order, starting at the correct point in the circular log buffer.
  514. */
  515. logNumber = 0;
  516. for (logIndex=cmdLogIndex+1; logIndex< MAX_COMMAND_LOG_ENTRIES; logIndex++, logNumber++) {
  517. ShowCommandLog(Depth+1, &cmdLog[logIndex], logNumber);
  518. }
  519. for (logIndex=0; logIndex <= cmdLogIndex; logIndex++, logNumber++) {
  520. ShowCommandLog(Depth+1, &cmdLog[logIndex], logNumber);
  521. }
  522. }
  523. else {
  524. dprintf("\n Error reading command log at address 0x%08p\n", cmdLogAddr);
  525. }
  526. }
  527. }
  528. #endif