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.

1939 lines
59 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1992 - 1999
  3. Module Name:
  4. scsikd.c
  5. Abstract:
  6. Debugger Extension Api for interpretting scsiport structures
  7. Author:
  8. Peter Wieland (peterwie) 16-Oct-1995
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. John Strange (johnstra) 17-Apr-2000 : make 64b friendly
  13. --*/
  14. #include "pch.h"
  15. #include "port.h"
  16. FLAG_NAME LuFlags[] = {
  17. FLAG_NAME(LU_QUEUE_FROZEN), // 0001
  18. FLAG_NAME(LU_LOGICAL_UNIT_IS_ACTIVE), // 0002
  19. FLAG_NAME(LU_NEED_REQUEST_SENSE), // 0004
  20. FLAG_NAME(LU_LOGICAL_UNIT_IS_BUSY), // 0008
  21. FLAG_NAME(LU_QUEUE_IS_FULL), // 0010
  22. FLAG_NAME(LU_PENDING_LU_REQUEST), // 0020
  23. FLAG_NAME(LU_QUEUE_LOCKED), // 0040
  24. FLAG_NAME(LU_QUEUE_PAUSED), // 0080
  25. {0,0}
  26. };
  27. FLAG_NAME AdapterFlags[] = {
  28. FLAG_NAME(PD_DEVICE_IS_BUSY), // 0X00001
  29. FLAG_NAME(PD_NOTIFICATION_REQUIRED), // 0X00004
  30. FLAG_NAME(PD_READY_FOR_NEXT_REQUEST), // 0X00008
  31. FLAG_NAME(PD_FLUSH_ADAPTER_BUFFERS), // 0X00010
  32. FLAG_NAME(PD_MAP_TRANSFER), // 0X00020
  33. FLAG_NAME(PD_LOG_ERROR), // 0X00040
  34. FLAG_NAME(PD_RESET_HOLD), // 0X00080
  35. FLAG_NAME(PD_HELD_REQUEST), // 0X00100
  36. FLAG_NAME(PD_RESET_REPORTED), // 0X00200
  37. FLAG_NAME(PD_PENDING_DEVICE_REQUEST), // 0X00800
  38. FLAG_NAME(PD_DISCONNECT_RUNNING), // 0X01000
  39. FLAG_NAME(PD_DISABLE_CALL_REQUEST), // 0X02000
  40. FLAG_NAME(PD_DISABLE_INTERRUPTS), // 0X04000
  41. FLAG_NAME(PD_ENABLE_CALL_REQUEST), // 0X08000
  42. FLAG_NAME(PD_TIMER_CALL_REQUEST), // 0X10000
  43. FLAG_NAME(PD_WMI_REQUEST), // 0X20000
  44. {0,0}
  45. };
  46. VOID
  47. ScsiDumpPdo(
  48. IN ULONG64 LunAddress,
  49. IN ULONG Detail,
  50. IN ULONG Depth
  51. );
  52. VOID
  53. ScsiDumpFdo(
  54. ULONG64 Address,
  55. ULONG Detail,
  56. ULONG Depth
  57. );
  58. VOID
  59. ScsiDumpSrbData(
  60. ULONG64 SrbData,
  61. ULONG Depth
  62. );
  63. VOID
  64. ScsiDumpAdapterPerfCounters(
  65. ULONG64 Adapter,
  66. ULONG Depth
  67. );
  68. VOID
  69. ScsiDumpScatterGatherList(
  70. ULONG64 List,
  71. ULONG Entries,
  72. ULONG Depth
  73. );
  74. VOID
  75. ScsiDumpActiveRequests(
  76. IN ULONG64 ListHead,
  77. IN ULONG TickCount,
  78. IN ULONG Depth
  79. );
  80. VOID
  81. ScsiDumpScsiportExtension(
  82. IN ULONG64 Address,
  83. IN ULONG Detail,
  84. IN ULONG Depth
  85. );
  86. VOID
  87. ScsiDumpInterruptData(
  88. IN ULONG64 Address,
  89. IN ULONG Detail,
  90. IN ULONG Depth
  91. );
  92. VOID
  93. ScsiDumpChildren(
  94. IN ULONG64 Adapter,
  95. IN ULONG Depth
  96. );
  97. PUCHAR
  98. SecondsToString(
  99. ULONG Count
  100. );
  101. VOID
  102. ScsiDumpLocks(
  103. ULONG64 CommonExtension,
  104. ULONG Depth
  105. );
  106. VOID
  107. ScsiDumpQueuedRequests(
  108. IN ULONG64 DeviceObject,
  109. IN ULONG TickCount,
  110. IN ULONG Depth
  111. );
  112. DECLARE_API(scsiext)
  113. /*++
  114. Routine Description:
  115. Dumps the device extension for a given device object, or dumps the
  116. given device extension
  117. Arguments:
  118. args - string containing the address of the device object or device
  119. extension
  120. Return Value:
  121. none
  122. --*/
  123. {
  124. ULONG64 address = 0;
  125. ULONG result;
  126. ULONG64 detail = 0;
  127. CSHORT Type;
  128. if (GetExpressionEx(args, &address, &args))
  129. {
  130. GetExpressionEx(args, &detail, &args);
  131. }
  132. //
  133. // The supplied address may be either the address of a device object or the
  134. // address of a device extension. To distinguish which, we treat the
  135. // address as a device object and read what would be its type field. If
  136. // the
  137. //
  138. result = GetFieldData(address,
  139. "scsiport!_DEVICE_OBJECT",
  140. "Type",
  141. sizeof(CSHORT),
  142. &Type
  143. );
  144. if (result) {
  145. SCSIKD_PRINT_ERROR(result);
  146. return E_FAIL;
  147. }
  148. //
  149. // See if the supplied address holds a device object. If it does, read the
  150. // address of the device extension. Otherwise, we assume the supplied
  151. // addres holds a device extension and we use it directly.
  152. //
  153. if (Type == IO_TYPE_DEVICE) {
  154. result = GetFieldData(address,
  155. "scsiport!_DEVICE_OBJECT",
  156. "DeviceExtension",
  157. sizeof(ULONG64),
  158. &address
  159. );
  160. if (result) {
  161. SCSIKD_PRINT_ERROR(result);
  162. return E_FAIL;
  163. }
  164. }
  165. //
  166. // Call worker routine to dump the information.
  167. //
  168. ScsiDumpScsiportExtension(address, (ULONG)detail, 0);
  169. return S_OK;
  170. }
  171. VOID
  172. ScsiDumpScsiportExtension(
  173. IN ULONG64 CommonExtension,
  174. IN ULONG Detail,
  175. IN ULONG Depth
  176. )
  177. {
  178. ULONG tmp;
  179. ULONG result;
  180. ULONG64 DeviceObject = 0;
  181. ULONG IsPdo = 0;
  182. ULONG IsInitialized = 0;
  183. ULONG WmiInitialized = 0;
  184. ULONG WmiMiniPortSupport = 0;
  185. ULONG CurrentPnpState = 0;
  186. ULONG PreviousPnpState = 0;
  187. ULONG IsRemoved = 0;
  188. ULONG64 LowerDeviceObject = 0;
  189. ULONG SrbFlags = 0;
  190. ULONG64 MajorFunction = 0;
  191. SYSTEM_POWER_STATE CurrentSystemState = 0;
  192. DEVICE_POWER_STATE CurrentDeviceState = 0;
  193. DEVICE_POWER_STATE DesiredDeviceState = 0;
  194. ULONG64 IdleTimer = 0;
  195. ULONG64 WmiScsiPortRegInfoBuf = 0;
  196. ULONG WmiScsiPortRegInfoBufSize = 0;
  197. ULONG PagingPathCount = 0;
  198. ULONG HibernatePathCount = 0;
  199. ULONG DumpPathCount = 0;
  200. FIELD_INFO deviceFields[] = {
  201. {"DeviceObject", NULL, 0, COPY, 0, (PVOID) &DeviceObject},
  202. {"IsPdo", NULL, 0, COPY, 0, (PVOID) &IsPdo},
  203. {"IsInitialized", NULL, 0, COPY, 0, (PVOID) &IsInitialized},
  204. {"WmiInitialized", NULL, 0, COPY, 0, (PVOID) &WmiInitialized},
  205. {"WmiMiniPortSupport", NULL, 0, COPY, 0, (PVOID) &WmiMiniPortSupport},
  206. {"CurrentPnpState", NULL, 0, COPY, 0, (PVOID) &CurrentPnpState},
  207. {"PreviousPnpState", NULL, 0, COPY, 0, (PVOID) &PreviousPnpState},
  208. {"IsRemoved", NULL, 0, COPY, 0, (PVOID) &IsRemoved},
  209. {"LowerDeviceObject", NULL, 0, COPY, 0, (PVOID) &LowerDeviceObject},
  210. {"SrbFlags", NULL, 0, COPY, 0, (PVOID) &SrbFlags},
  211. {"MajorFunction", NULL, 0, COPY, 0, (PVOID) &MajorFunction},
  212. {"CurrentSystemState", NULL, 0, COPY, 0, (PVOID) &CurrentSystemState},
  213. {"CurrentDeviceState", NULL, 0, COPY, 0, (PVOID) &CurrentDeviceState},
  214. {"DesiredDeviceState", NULL, 0, COPY, 0, (PVOID) &DesiredDeviceState},
  215. {"IdleTimer", NULL, 0, COPY, 0, (PVOID) &IdleTimer},
  216. {"WmiScsiPortRegInfoBuf", NULL, 0, COPY, 0, (PVOID) &WmiScsiPortRegInfoBuf},
  217. {"WmiScsiPortRegInfoBufSize", NULL, 0, COPY, 0, (PVOID) &WmiScsiPortRegInfoBufSize},
  218. {"PagingPathCount", NULL, 0, COPY, 0, (PVOID) &PagingPathCount},
  219. {"HibernatePathCount", NULL, 0, COPY, 0, (PVOID) &HibernatePathCount},
  220. {"DumpPathCount", NULL, 0, COPY, 0, (PVOID) &DumpPathCount},
  221. };
  222. SYM_DUMP_PARAM DevSym = {
  223. sizeof (SYM_DUMP_PARAM),
  224. "scsiport!_COMMON_EXTENSION",
  225. DBG_DUMP_NO_PRINT,
  226. CommonExtension,
  227. NULL, NULL, NULL,
  228. sizeof (deviceFields) / sizeof (FIELD_INFO),
  229. &deviceFields[0]
  230. };
  231. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  232. if (result) {
  233. dprintf("%08p: Could not read device object\n", CommonExtension);
  234. return;
  235. }
  236. xdprintfEx(Depth, ("Scsiport %s device extension at address %p\n",
  237. IsPdo ? "physical" : "functional", CommonExtension));
  238. xdprintfEx(Depth, ("Common Extension:\n"));
  239. Depth += 1;
  240. tmp = Depth;
  241. if(IsInitialized) {
  242. xdprintfEx(tmp, ("Initialized "));
  243. tmp = 0;
  244. }
  245. if(IsRemoved) {
  246. xdprintfEx(tmp, ("Removed " ));
  247. tmp = 0;
  248. }
  249. switch(IsRemoved) {
  250. case REMOVE_PENDING: {
  251. xdprintfEx(tmp, ("RemovePending"));
  252. tmp = 0;
  253. break;
  254. }
  255. case REMOVE_COMPLETE: {
  256. xdprintfEx(tmp, ("RemoveComplete"));
  257. tmp = 0;
  258. break;
  259. }
  260. }
  261. if(WmiMiniPortSupport) {
  262. if(WmiInitialized) {
  263. xdprintfEx(tmp, ("WmiInit"));
  264. } else {
  265. xdprintfEx(tmp, ("Wmi"));
  266. }
  267. tmp = 0;
  268. }
  269. if(tmp == 0) {
  270. dprintf("\n");
  271. }
  272. tmp = 0;
  273. xdprintfEx(Depth, ("DO 0x%08p LowerObject 0x%08p SRB Flags %#08lx\n",
  274. DeviceObject,
  275. LowerDeviceObject,
  276. SrbFlags));
  277. xdprintfEx(Depth, ("Current Power (D%d,S%d) Desired Power D%d Idle %#08lx\n",
  278. CurrentDeviceState - 1,
  279. CurrentSystemState - 1,
  280. DesiredDeviceState - 1,
  281. IdleTimer));
  282. xdprintfEx(Depth, ("Current PnP state 0x%x Previous state 0x%x\n",
  283. CurrentPnpState,
  284. PreviousPnpState));
  285. xdprintfEx(Depth, ("DispatchTable %08p UsePathCounts (P%d, H%d, C%d)\n",
  286. MajorFunction,
  287. PagingPathCount,
  288. HibernatePathCount,
  289. DumpPathCount));
  290. if(WmiMiniPortSupport) {
  291. xdprintfEx(Depth, ("DispatchTable 0x%08p WmiInfoSize %#08lx\n",
  292. WmiScsiPortRegInfoBuf,
  293. WmiScsiPortRegInfoBufSize));
  294. }
  295. if(IsPdo) {
  296. xdprintfEx(Depth - 1, ("Logical Unit Extension:\n"));
  297. ScsiDumpPdo(CommonExtension, Detail, Depth);
  298. } else {
  299. xdprintfEx(Depth - 1, ("Adapter Extension:\n"));
  300. ScsiDumpFdo(CommonExtension, Detail, Depth);
  301. }
  302. if(Detail > 1) {
  303. ScsiDumpLocks(CommonExtension, Depth - 1);
  304. }
  305. return;
  306. }
  307. VOID
  308. ScsiDumpFdo(
  309. ULONG64 Address,
  310. ULONG Detail,
  311. ULONG Depth
  312. )
  313. {
  314. ULONG tmp = Depth;
  315. ULONG result;
  316. ULONG NumOfFields;
  317. ULONG PortNumber = 0;
  318. UCHAR IsPnp = 0;
  319. UCHAR IsMiniportDetected = 0;
  320. UCHAR IsInVirtualSlot = 0;
  321. UCHAR HasInterrupt = 0;
  322. UCHAR DisablePower = 0;
  323. UCHAR DisableStop = 0;
  324. ULONG64 LowerPdo = 0;
  325. ULONG64 HwDeviceExtension = 0;
  326. LONG ActiveRequestCount = 0;
  327. ULONG NumberOfBuses = 0;
  328. ULONG MaximumTargetIds = 0;
  329. ULONG MaxLuCount = 0;
  330. ULONG Flags = 0;
  331. ULONG64 NonCachedExtension = 0;
  332. ULONG IoAddress = 0;
  333. ULONG InterruptLevel = 0;
  334. ULONG RealBusNumber = 0;
  335. ULONG RealSlotNumber = 0;
  336. LONG PortTimeoutCounter = 0;
  337. ULONG DpcFlags = 0;
  338. ULONG SequenceNumber = 0;
  339. ULONG64 SrbExtensionListHeader = 0;
  340. ULONG NumberOfRequests = 0;
  341. ULONG64 QueueTagBitMap = 0;
  342. ULONG QueueTagHint = 0;
  343. ULONG HwLogicalUnitExtensionSize = 0;
  344. ULONG SrbExtensionSize = 0;
  345. ULONG LargeScatterGatherListSize = 0;
  346. ULONG64 EmergencySrbData = 0;
  347. ULONG CommonBufferSize = 0;
  348. ULONG64 PhysicalCommonBuffer = 0;
  349. ULONG64 SrbExtensionBuffer = 0;
  350. ULONG64 InterruptObject = 0;
  351. ULONG64 InterruptObject2 = 0;
  352. ULONG64 DmaAdapterObject = 0;
  353. ULONG64 AllocatedResources = 0;
  354. ULONG64 TranslatedResources = 0;
  355. ULONG64 PortConfig = 0;
  356. ULONG64 PortDeviceMapKey = 0;
  357. ULONG64 BusDeviceMapKeys = 0;
  358. UCHAR RemoveTrackingLookasideListInitialized = 0;
  359. ULONG64 AddrOfMaxQueueTag = 0;
  360. ULONG64 SrbDataBlockedRequests = 0;
  361. ULONG64 SrbDataLookasideList = 0;
  362. ULONG64 MediumScatterGatherLookasideList = 0;
  363. ULONG64 RemoveTrackingLookasideList = 0;
  364. ULONG64 InterruptData = 0;
  365. UCHAR MaxQueueTag = 0;
  366. FIELD_INFO deviceFields[] = {
  367. {"PortNumber", NULL, 0, COPY, 0, (PVOID) &PortNumber},
  368. {"IsPnp", NULL, 0, COPY, 0, (PVOID) &IsPnp},
  369. {"IsMiniportDetected", NULL, 0, COPY, 0, (PVOID) &IsMiniportDetected},
  370. {"IsInVirtualSlot", NULL, 0, COPY, 0, (PVOID) &IsInVirtualSlot},
  371. {"HasInterrupt", NULL, 0, COPY, 0, (PVOID) &HasInterrupt},
  372. {"DisablePower", NULL, 0, COPY, 0, (PVOID) &DisablePower},
  373. {"DisableStop", NULL, 0, COPY, 0, (PVOID) &DisableStop},
  374. {"LowerPdo", NULL, 0, COPY, 0, (PVOID) &LowerPdo},
  375. {"HwDeviceExtension", NULL, 0, COPY, 0, (PVOID) &HwDeviceExtension},
  376. {"ActiveRequestCount", NULL, 0, COPY, 0, (PVOID) &ActiveRequestCount},
  377. {"NumberOfBuses", NULL, 0, COPY, 0, (PVOID) &NumberOfBuses},
  378. {"MaximumTargetIds", NULL, 0, COPY, 0, (PVOID) &MaximumTargetIds},
  379. {"MaxLuCount", NULL, 0, COPY, 0, (PVOID) &MaxLuCount},
  380. {"Flags", NULL, 0, COPY, 0, (PVOID) &Flags},
  381. {"NonCachedExtension", NULL, 0, COPY, 0, (PVOID) &NonCachedExtension},
  382. {"IoAddress", NULL, 0, COPY, 0, (PVOID) &IoAddress},
  383. {"InterruptLevel", NULL, 0, COPY, 0, (PVOID) &InterruptLevel},
  384. {"RealBusNumber", NULL, 0, COPY, 0, (PVOID) &RealBusNumber},
  385. {"RealSlotNumber", NULL, 0, COPY, 0, (PVOID) &RealSlotNumber},
  386. {"PortTimeoutCounter", NULL, 0, COPY, 0, (PVOID) &PortTimeoutCounter},
  387. {"DpcFlags", NULL, 0, COPY, 0, (PVOID) &DpcFlags},
  388. {"SequenceNumber", NULL, 0, COPY, 0, (PVOID) &SequenceNumber},
  389. {"SrbExtensionListHeader", NULL, 0, COPY, 0, (PVOID) &SrbExtensionListHeader},
  390. {"NumberOfRequests", NULL, 0, COPY, 0, (PVOID) &NumberOfRequests},
  391. {"QueueTagBitMap", NULL, 0, COPY, 0, (PVOID) &QueueTagBitMap},
  392. {"QueueTagHint", NULL, 0, COPY, 0, (PVOID) &QueueTagHint},
  393. {"HwLogicalUnitExtensionSize", NULL, 0, COPY, 0, (PVOID) &HwLogicalUnitExtensionSize},
  394. {"SrbExtensionSize", NULL, 0, COPY, 0, (PVOID) &SrbExtensionSize},
  395. {"LargeScatterGatherListSize", NULL, 0, COPY, 0, (PVOID) &LargeScatterGatherListSize},
  396. {"EmergencySrbData", NULL, 0, COPY, 0, (PVOID) &EmergencySrbData},
  397. {"CommonBufferSize", NULL, 0, COPY, 0, (PVOID) &CommonBufferSize},
  398. {"PhysicalCommonBuffer.QuadPart", NULL, 0, COPY, 0, (PVOID) &PhysicalCommonBuffer},
  399. {"SrbExtensionBuffer", NULL, 0, COPY, 0, (PVOID) &SrbExtensionBuffer},
  400. {"InterruptObject", NULL, 0, COPY, 0, (PVOID) &InterruptObject},
  401. {"InterruptObject2", NULL, 0, COPY, 0, (PVOID) &InterruptObject2},
  402. {"DmaAdapterObject", NULL, 0, COPY, 0, (PVOID) &DmaAdapterObject},
  403. {"AllocatedResources", NULL, 0, COPY, 0, (PVOID) &AllocatedResources},
  404. {"TranslatedResources", NULL, 0, COPY, 0, (PVOID) &TranslatedResources},
  405. {"PortConfig", NULL, 0, COPY, 0, (PVOID) &PortConfig},
  406. {"PortDeviceMapKey", NULL, 0, COPY, 0, (PVOID) &PortDeviceMapKey},
  407. {"BusDeviceMapKeys", NULL, 0, COPY, 0, (PVOID) &BusDeviceMapKeys},
  408. {"CommonExtension.RemoveTrackingLookasideListInitialized", NULL, 0, COPY, 0, (PVOID) &RemoveTrackingLookasideListInitialized},
  409. {"MaxQueueTag", NULL, 0, ADDROF, 0, NULL},
  410. {"SrbDataBlockedRequests", NULL, 0, ADDROF, 0, NULL},
  411. {"SrbDataLookasideList", NULL, 0, ADDROF, 0, NULL},
  412. {"MediumScatterGatherLookasideList", NULL, 0, ADDROF, 0, NULL},
  413. {"CommonExtension.RemoveTrackingLookasideList", NULL, 0, ADDROF, 0, NULL},
  414. {"InterruptData", NULL, 0, ADDROF, 0, NULL},
  415. };
  416. SYM_DUMP_PARAM DevSym = {
  417. sizeof (SYM_DUMP_PARAM),
  418. "scsiport!_ADAPTER_EXTENSION",
  419. DBG_DUMP_NO_PRINT,
  420. Address,
  421. NULL, NULL, NULL,
  422. sizeof (deviceFields) / sizeof (FIELD_INFO),
  423. &deviceFields[0]
  424. };
  425. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  426. if (result) {
  427. SCSIKD_PRINT_ERROR(result);
  428. return;
  429. }
  430. result = GetFieldData(Address,
  431. "scsiport!_ADAPTER_EXTENSION",
  432. "MaxQueueTag",
  433. sizeof(UCHAR),
  434. &MaxQueueTag
  435. );
  436. if (result) {
  437. SCSIKD_PRINT_ERROR(result);
  438. return;
  439. }
  440. NumOfFields = sizeof (deviceFields) / sizeof (FIELD_INFO);
  441. InterruptData = deviceFields[NumOfFields-1].address;
  442. RemoveTrackingLookasideList = deviceFields[NumOfFields-2].address;
  443. MediumScatterGatherLookasideList = deviceFields[NumOfFields-3].address;
  444. SrbDataLookasideList = deviceFields[NumOfFields-4].address;
  445. SrbDataBlockedRequests = deviceFields[NumOfFields-5].address;
  446. AddrOfMaxQueueTag = deviceFields[NumOfFields-6].address;
  447. xdprintfEx(Depth, ("Port %d ", PortNumber));
  448. if(IsPnp) {
  449. xdprintfEx(tmp, ("IsPnp "));
  450. tmp = 0;
  451. }
  452. if(IsMiniportDetected) {
  453. xdprintfEx(tmp, ("MpDetected "));
  454. tmp = 0;
  455. }
  456. if(IsInVirtualSlot) {
  457. xdprintfEx(tmp, ("VirtualSlot "));
  458. tmp = 0;
  459. }
  460. if(HasInterrupt) {
  461. xdprintfEx(tmp, ("HasInterrupt"));
  462. tmp = 0;
  463. }
  464. if(DisablePower) {
  465. xdprintfEx(tmp, ("NoPower"));
  466. tmp = 0;
  467. }
  468. if(DisableStop) {
  469. xdprintfEx(tmp, ("NoStop"));
  470. tmp = 0;
  471. }
  472. dprintf("\n");
  473. xdprintfEx(Depth, ("LowerPdo 0x%08p HwDevExt 0x%08p Active Requests 0x%08lx\n",
  474. LowerPdo,
  475. HwDeviceExtension,
  476. ActiveRequestCount));
  477. xdprintfEx(Depth, ("MaxBus 0x%02x MaxTarget 0x%02x MaxLun 0x%02x\n",
  478. NumberOfBuses,
  479. MaximumTargetIds,
  480. MaxLuCount));
  481. DumpFlags(Depth, "Port Flags", Flags, AdapterFlags);
  482. xdprintfEx(Depth, ("NonCacheExt 0x%08p IoBase 0x%08x Int 0x%02x\n",
  483. NonCachedExtension,
  484. IoAddress,
  485. InterruptLevel));
  486. xdprintfEx(Depth, ("RealBus# 0x%0x RealSlot# 0x%0x\n",
  487. RealBusNumber,
  488. RealSlotNumber));
  489. xdprintfEx(Depth, ("Timeout 0x%08x DpcFlags 0x%08x Sequence 0x%08x\n",
  490. PortTimeoutCounter,
  491. DpcFlags,
  492. SequenceNumber));
  493. xdprintfEx(Depth, ("Srb Ext Header 0x%08p No. Requests 0x%08lx\n",
  494. SrbExtensionListHeader, NumberOfRequests));
  495. xdprintfEx(Depth, ("QueueTag BitMap 0x%08p Hint 0x%08lx\n",
  496. QueueTagBitMap, QueueTagHint));
  497. xdprintfEx(Depth, ("MaxQueueTag 0x%2x (@0x%08p)\n",
  498. MaxQueueTag, AddrOfMaxQueueTag));
  499. xdprintfEx(Depth, ("LuExt Size 0x%08lx SrbExt Size 0x%08lx\n",
  500. HwLogicalUnitExtensionSize,
  501. SrbExtensionSize));
  502. xdprintfEx(Depth + 1, ("SG List Size - Small %d Large %d\n",
  503. SP_SMALL_PHYSICAL_BREAK_VALUE,
  504. LargeScatterGatherListSize));
  505. Depth++;
  506. xdprintfEx(Depth, ("Emergency - SrbData 0x%08p Blocked List @0x%08p\n",
  507. EmergencySrbData,
  508. SrbDataBlockedRequests));
  509. xdprintfEx(Depth, ("CommonBuff - Size: 0x%08lx PA: 0x%016I64x VA: 0x%08p\n",
  510. CommonBufferSize,
  511. PhysicalCommonBuffer,
  512. SrbExtensionBuffer));
  513. xdprintfEx(Depth, ("Ke Objects - Int1: 0x%08p Int2: 0x%08p Dma: 0x%08p\n",
  514. InterruptObject,
  515. InterruptObject2,
  516. DmaAdapterObject));
  517. xdprintfEx(Depth, ("Lookaside - SrbData @ 0x%08p SgList @0x%08p Remove: @0x%08p\n",
  518. SrbDataLookasideList,
  519. MediumScatterGatherLookasideList,
  520. (RemoveTrackingLookasideListInitialized ?
  521. RemoveTrackingLookasideList : 0)));
  522. xdprintfEx(Depth, ("Resources - Raw: 0x%08p Translated: 0x%08p\n",
  523. AllocatedResources,
  524. TranslatedResources));
  525. xdprintfEx(Depth, ("Port Config %08p\n", PortConfig));
  526. xdprintfEx(Depth, ("DeviceMap Handles: Port %p Busses %p\n",
  527. PortDeviceMapKey, BusDeviceMapKeys));
  528. Depth--;
  529. ScsiDumpInterruptData(InterruptData,
  530. Detail,
  531. Depth);
  532. ScsiDumpAdapterPerfCounters(Address, Depth);
  533. ScsiDumpChildren(Address, Depth);
  534. return;
  535. }
  536. VOID
  537. ScsiDumpChildren(
  538. IN ULONG64 AdapterExtensionAddr,
  539. IN ULONG Depth
  540. )
  541. {
  542. ULONG i;
  543. ULONG64 realLun;
  544. ULONG64 realLuns[8];
  545. ULONG64 lun;
  546. UCHAR CurrentPnpState=0, PreviousPnpState=0;
  547. ULONG CurrentDeviceState=0;
  548. ULONG DesiredDeviceState=0, CurrentSystemState=0;
  549. ULONG64 DeviceObject=0, NextLogicalUnit=0;
  550. ULONG result;
  551. UCHAR PathId=0, TargetId=0, Lun=0;
  552. UCHAR IsClaimed=0, IsMissing=0, IsEnumerated=0, IsVisible=0, IsMismatched=0;
  553. ULONG64 b6, b7, b8;
  554. InitTypeRead(AdapterExtensionAddr, scsiport!_ADAPTER_EXTENSION);
  555. realLuns[0] = ReadField(LogicalUnitList[0].List);
  556. realLuns[1] = ReadField(LogicalUnitList[1].List);
  557. realLuns[2] = ReadField(LogicalUnitList[2].List);
  558. realLuns[3] = ReadField(LogicalUnitList[3].List);
  559. realLuns[4] = ReadField(LogicalUnitList[4].List);
  560. realLuns[5] = ReadField(LogicalUnitList[5].List);
  561. realLuns[6] = ReadField(LogicalUnitList[6].List);
  562. realLuns[7] = ReadField(LogicalUnitList[7].List);
  563. Depth++;
  564. for (i = 0; i < NUMBER_LOGICAL_UNIT_BINS; i++) {
  565. realLun = realLuns[i];
  566. while ((realLun != 0) && (!CheckControlC())) {
  567. FIELD_INFO deviceFields[] = {
  568. {"PathId", NULL, 0, COPY, 0, (PVOID) &PathId},
  569. {"TargetId", NULL, 0, COPY, 0, (PVOID) &TargetId},
  570. {"IsClaimed", NULL, 0, COPY, 0, (PVOID) &IsClaimed},
  571. {"IsMissing", NULL, 0, COPY, 0, (PVOID) &IsMissing},
  572. {"IsEnumerated", NULL, 0, COPY, 0, (PVOID) &IsEnumerated},
  573. {"IsVisible", NULL, 0, COPY, 0, (PVOID) &IsVisible},
  574. {"IsMismatched", NULL, 0, COPY, 0, (PVOID) &IsMismatched},
  575. {"DeviceObject", NULL, 0, COPY, 0, (PVOID) &DeviceObject},
  576. {"NextLogicalUnit", NULL, 0, COPY, 0, (PVOID) &NextLogicalUnit},
  577. {"CommonExtension.CurrentPnpState", NULL, 0, COPY, 0, (PVOID) &CurrentPnpState},
  578. {"CommonExtension.PreviousPnpState" , NULL, 0, COPY, 0, (PVOID) &PreviousPnpState},
  579. {"CommonExtension.CurrentDeviceState", NULL, 0, COPY, 0, (PVOID) &CurrentDeviceState},
  580. {"CommonExtension.DesiredDeviceState", NULL, 0, COPY, 0, (PVOID) &DesiredDeviceState},
  581. {"CommonExtension.CurrentSystemState", NULL, 0, COPY, 0, (PVOID) &CurrentSystemState},
  582. };
  583. SYM_DUMP_PARAM DevSym = {
  584. sizeof (SYM_DUMP_PARAM),
  585. "scsiport!_LOGICAL_UNIT_EXTENSION",
  586. DBG_DUMP_NO_PRINT,
  587. realLun,
  588. NULL, NULL, NULL,
  589. sizeof (deviceFields) / sizeof (FIELD_INFO),
  590. &deviceFields[0]
  591. };
  592. xdprintfEx(Depth, ("LUN "));
  593. dprintf("%08p ", realLun);
  594. if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) {
  595. dprintf("%08lx: Could not read device object\n", realLun);
  596. return;
  597. }
  598. result = (ULONG) InitTypeRead(realLun, scsiport!_LOGICAL_UNIT_EXTENSION);
  599. if (result != 0) {
  600. dprintf("could not init read type (%x)\n", result);
  601. return;
  602. }
  603. lun = ReadField(Lun);
  604. Lun = (UCHAR) lun;
  605. #if 0
  606. PathId = ReadField(PathId);
  607. TargetId = ReadField(TargetId);
  608. IsClaimed = ReadField(IsClaimed);
  609. IsMissing = ReadField(IsMissing);
  610. IsEnumerated = ReadField(IsEnumerated);
  611. IsVisible = ReadField(IsVisible);
  612. IsMismatched = ReadField(IsMismatched);
  613. #endif
  614. dprintf("@ (%3d,%3d,%3d) %c%c%c%c%c pnp(%02x/%02x) pow(%d%c,%d) DevObj %08p\n",
  615. PathId,
  616. TargetId,
  617. Lun,
  618. (IsClaimed ? 'c' : ' '),
  619. (IsMissing ? 'm' : ' '),
  620. (IsEnumerated ? 'e' : ' '),
  621. (IsVisible ? 'v' : ' '),
  622. (IsMismatched ? 'r' : ' '),
  623. CurrentPnpState,
  624. PreviousPnpState,
  625. CurrentDeviceState - 1,
  626. ((DesiredDeviceState == PowerDeviceUnspecified) ? ' ' : '*'),
  627. CurrentSystemState - 1,
  628. DeviceObject);
  629. realLun = ReadField(NextLogicalUnit);
  630. }
  631. }
  632. return;
  633. }
  634. VOID
  635. ScsiDumpInterruptData(
  636. IN ULONG64 Address,
  637. IN ULONG Detail,
  638. IN ULONG Depth
  639. )
  640. {
  641. ULONG result;
  642. ULONG NumOfFields;
  643. //
  644. // Architecture independent fields declarations.
  645. //
  646. //
  647. ULONG InterruptFlags = 0;
  648. ULONG64 CompletedRequests;
  649. ULONG64 AddrOfCompletedRequests;
  650. ULONG64 ReadyLogicalUnit = 0;
  651. ULONG64 WmiMiniPortRequests = 0;
  652. FIELD_INFO deviceFields[] = {
  653. {"InterruptFlags", NULL, 0, COPY, 0, (PVOID) &InterruptFlags},
  654. {"ReadyLogicalUnit", NULL, 0, COPY, 0, (PVOID) &ReadyLogicalUnit},
  655. {"WmiMiniPortRequests", NULL, 0, COPY, 0, (PVOID) &WmiMiniPortRequests},
  656. {"CompletedRequests", NULL, 0, ADDROF, 0, NULL},
  657. };
  658. SYM_DUMP_PARAM DevSym = {
  659. sizeof (SYM_DUMP_PARAM),
  660. "scsiport!_INTERRUPT_DATA",
  661. DBG_DUMP_NO_PRINT,
  662. Address,
  663. NULL, NULL, NULL,
  664. sizeof (deviceFields) / sizeof (FIELD_INFO),
  665. &deviceFields[0]
  666. };
  667. //
  668. // Read in the top-level field data. Quit on failure.
  669. //
  670. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  671. if (result) {
  672. dprintf("error reading INTERRUPT_DATA @ %08p\n", Address);
  673. return;
  674. }
  675. //
  676. // Get address-of information.
  677. //
  678. NumOfFields = sizeof (deviceFields) / sizeof (FIELD_INFO);
  679. AddrOfCompletedRequests = deviceFields[NumOfFields-1].address;
  680. //
  681. // Do a separate get of the CompleteRequests field. This is necessary
  682. // because the typedump Ioctl doesn't like retreiving both the addr-of
  683. // and the data-of a field.
  684. //
  685. result = GetFieldData(Address,
  686. "scsiport!_INTERRUPT_DATA",
  687. "CompletedRequests",
  688. sizeof(ULONG64),
  689. &CompletedRequests
  690. );
  691. if (result) {
  692. dprintf("error (%08x): @ %s %d\n", result, __FILE__, __LINE__);
  693. return;
  694. }
  695. xdprintfEx(Depth, ("Interrupt Data @0x%08p:\n", Address));
  696. Depth++;
  697. DumpFlags(Depth, "Flags", InterruptFlags, AdapterFlags);
  698. xdprintfEx(Depth, ("Ready LUN 0x%08p Wmi Events 0x%08p\n",
  699. ReadyLogicalUnit,
  700. WmiMiniPortRequests));
  701. {
  702. ULONG count = 0;
  703. ULONG64 request = CompletedRequests;
  704. xdprintfEx(Depth, ("Completed Request List (@0x%08p): ",
  705. AddrOfCompletedRequests));
  706. Depth += 1;
  707. while((request != 0) && (!CheckControlC())) {
  708. ULONG64 NextCompletedRequests;
  709. if(Detail != 0) {
  710. if(count == 0) {
  711. dprintf("\n");
  712. }
  713. xdprintfEx(Depth, ("SrbData 0x%08p ", request));
  714. }
  715. count++;
  716. result = GetFieldData(request,
  717. "scsiport!_SRB_DATA",
  718. "CompletedRequests",
  719. sizeof(ULONG64),
  720. &NextCompletedRequests
  721. );
  722. if (result) {
  723. dprintf("error (%08x): @ %s %d\n", result, __FILE__, __LINE__);
  724. return;
  725. }
  726. if(Detail != 0) {
  727. ULONG64 CurrentSrb, CurrentIrp;
  728. result = GetFieldData(request,
  729. "scsiport!_SRB_DATA",
  730. "CurrentSrb",
  731. sizeof(ULONG64),
  732. &CurrentSrb
  733. );
  734. if (result) {
  735. dprintf("error (%08x): @ %s %d\n", result, __FILE__, __LINE__);
  736. return;
  737. }
  738. result = GetFieldData(request,
  739. "scsiport!_SRB_DATA",
  740. "CurrentIrp",
  741. sizeof(ULONG64),
  742. &CurrentIrp
  743. );
  744. if (result) {
  745. dprintf("error (%08x): @ %s %d\n", result, __FILE__, __LINE__);
  746. return;
  747. }
  748. dprintf("Srb 0x%08p Irp 0x%08p\n",
  749. CurrentSrb,
  750. CurrentIrp);
  751. }
  752. request = NextCompletedRequests;
  753. }
  754. Depth -= 1;
  755. if((Detail == 0) || (count == 0)) {
  756. dprintf("%d entries\n", count);
  757. } else {
  758. xdprintfEx(Depth + 1, ("%d entries\n", count));
  759. }
  760. }
  761. return;
  762. }
  763. VOID
  764. ScsiDumpPdo(
  765. IN ULONG64 LunAddress,
  766. IN ULONG Detail,
  767. IN ULONG Depth
  768. )
  769. {
  770. ULONG result;
  771. ULONG Fields;
  772. UCHAR PathId;
  773. UCHAR TargetId;
  774. UCHAR Lun;
  775. ULONG PortNumber;
  776. UCHAR IsClaimed;
  777. UCHAR IsMissing;
  778. UCHAR IsEnumerated;
  779. UCHAR IsVisible;
  780. UCHAR IsMismatched;
  781. ULONG LunLuFlags;
  782. UCHAR RetryCount;
  783. ULONG CurrentKey;
  784. ULONG QueueLockCount;
  785. ULONG QueuePauseCount;
  786. ULONG64 HwLogicalUnitExtension;
  787. ULONG64 AdapterExtension;
  788. LONG RequestTimeoutCounter;
  789. ULONG64 NextLogicalUnit;
  790. ULONG64 ReadyLogicalUnit;
  791. ULONG64 PendingRequest;
  792. ULONG64 BusyRequest;
  793. ULONG64 CurrentUntaggedRequest;
  794. ULONG64 CompletedAbort;
  795. ULONG64 AbortSrb;
  796. ULONG QueueCount;
  797. ULONG MaxQueueDepth;
  798. ULONG64 TargetDeviceMapKey;
  799. ULONG64 LunDeviceMapKey;
  800. ULONG64 ActiveFailedRequest;
  801. ULONG64 BlockedFailedRequest;
  802. ULONG64 RequestSenseIrp;
  803. ULONG64 BypassSrbDataList_Next;
  804. ULONG64 RequestList_Flink;
  805. ULONG64 CommonExtension_DeviceObject;
  806. ULONG64 AddrOf_InquiryData;
  807. ULONG64 AddrOf_RequestSenseSrb;
  808. ULONG64 AddrOf_RequestSenseMdl;
  809. ULONG64 AddrOf_BypassSrbDataBlocks;
  810. ULONG64 AddrOf_RequestList;
  811. ULONG logEntries;
  812. ULONG Adapter_TickCount;
  813. FIELD_INFO deviceFields[] = {
  814. {"PathId", NULL, 0, COPY, 0, (PVOID) &PathId},
  815. {"TargetId", NULL, 0, COPY, 0, (PVOID) &TargetId},
  816. {"Lun", NULL, 0, COPY, 0, (PVOID) &Lun},
  817. {"PortNumber", NULL, 0, COPY, 0, (PVOID) &PortNumber},
  818. {"IsClaimed", NULL, 0, COPY, 0, (PVOID) &IsClaimed},
  819. {"IsMissing", NULL, 0, COPY, 0, (PVOID) &IsMissing},
  820. {"IsEnumerated", NULL, 0, COPY, 0, (PVOID) &IsEnumerated},
  821. {"IsVisible", NULL, 0, COPY, 0, (PVOID) &IsVisible},
  822. {"IsMismatched", NULL, 0, COPY, 0, (PVOID) &IsMismatched},
  823. {"LuFlags", NULL, 0, COPY, 0, (PVOID) &LunLuFlags},
  824. {"RetryCount", NULL, 0, COPY, 0, (PVOID) &RetryCount},
  825. {"CurrentKey", NULL, 0, COPY, 0, (PVOID) &CurrentKey},
  826. {"QueueCount", NULL, 0, COPY, 0, (PVOID) &QueueCount},
  827. {"QueueLockCount", NULL, 0, COPY, 0, (PVOID) &QueueLockCount},
  828. {"QueuePauseCount", NULL, 0, COPY, 0, (PVOID) &QueuePauseCount},
  829. {"HwLogicalUnitExtension", NULL, 0, COPY, 0, (PVOID) &HwLogicalUnitExtension},
  830. {"AdapterExtension", NULL, 0, COPY, 0, (PVOID) &AdapterExtension},
  831. {"RequestTimeoutCounter", NULL, 0, COPY, 0, (PVOID) &RequestTimeoutCounter},
  832. {"NextLogicalUnit", NULL, 0, COPY, 0, (PVOID) &NextLogicalUnit},
  833. {"ReadyLogicalUnit", NULL, 0, COPY, 0, (PVOID) &ReadyLogicalUnit},
  834. {"PendingRequest", NULL, 0, COPY, 0, (PVOID) &PendingRequest},
  835. {"BusyRequest", NULL, 0, COPY, 0, (PVOID) &BusyRequest},
  836. {"CurrentUntaggedRequest", NULL, 0, COPY, 0, (PVOID) &CurrentUntaggedRequest},
  837. {"CompletedAbort", NULL, 0, COPY, 0, (PVOID) &CompletedAbort},
  838. {"AbortSrb", NULL, 0, COPY, 0, (PVOID) &AbortSrb},
  839. {"MaxQueueDepth", NULL, 0, COPY, 0, (PVOID) &MaxQueueDepth},
  840. {"TargetDeviceMapKey", NULL, 0, COPY, 0, (PVOID) &TargetDeviceMapKey},
  841. {"LunDeviceMapKey", NULL, 0, COPY, 0, (PVOID) &LunDeviceMapKey},
  842. {"ActiveFailedRequest", NULL, 0, COPY, 0, (PVOID) &ActiveFailedRequest},
  843. {"BlockedFailedRequest", NULL, 0, COPY, 0, (PVOID) &BlockedFailedRequest},
  844. {"RequestSenseIrp", NULL, 0, COPY, 0, (PVOID) &RequestSenseIrp},
  845. {"BypassSrbDataList.Next", NULL, 0, COPY, 0, (PVOID) &BypassSrbDataList_Next},
  846. {"InquiryData", NULL, 0, ADDROF, 0, NULL},
  847. {"RequestSenseSrb", NULL, 0, ADDROF, 0, NULL},
  848. {"RequestSenseMdl", NULL, 0, ADDROF, 0, NULL},
  849. {"BypassSrbDataBlocks", NULL, 0, ADDROF, 0, NULL},
  850. {"RequestList", NULL, 0, ADDROF, 0, NULL},
  851. };
  852. SYM_DUMP_PARAM DevSym = {
  853. sizeof (SYM_DUMP_PARAM),
  854. "scsiport!_LOGICAL_UNIT_EXTENSION",
  855. DBG_DUMP_NO_PRINT,
  856. LunAddress,
  857. NULL, NULL, NULL,
  858. sizeof (deviceFields) / sizeof (FIELD_INFO),
  859. &deviceFields[0]
  860. };
  861. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  862. if (result) {
  863. dprintf("%08p: Could not read _LOGICAL_UNIT_EXTENSION\n", LunAddress);
  864. return;
  865. }
  866. Fields = sizeof (deviceFields) / sizeof (FIELD_INFO);
  867. AddrOf_RequestList = deviceFields[Fields-1].address;
  868. AddrOf_BypassSrbDataBlocks = deviceFields[Fields-2].address;
  869. AddrOf_RequestSenseMdl = deviceFields[Fields-3].address;
  870. AddrOf_RequestSenseSrb = deviceFields[Fields-4].address;
  871. AddrOf_InquiryData = deviceFields[Fields-5].address;
  872. result = GetFieldData(AddrOf_RequestList,
  873. "scsiport!LIST_ENTRY",
  874. "Flink",
  875. sizeof(ULONG64),
  876. &RequestList_Flink);
  877. if (result) {
  878. dprintf("Error reading request list from adapter extension @%p\n", AdapterExtension);
  879. return;
  880. }
  881. result = GetFieldData(AdapterExtension,
  882. "scsiport!_ADAPTER_EXTENSION",
  883. "TickCount",
  884. sizeof(ULONG),
  885. &Adapter_TickCount);
  886. if (result) {
  887. dprintf("Error reading TickCount from adapter extension @%p\n", AdapterExtension);
  888. return;
  889. }
  890. InitTypeRead(LunAddress, scsiport!_LOGICAL_UNIT_EXTENSION);
  891. QueueCount = (ULONG)ReadField(QueueCount);
  892. xdprintfEx(Depth, ("Address (%d, %d, %d, %d) %s %s %s %s %s\n",
  893. PortNumber, PathId, TargetId, Lun,
  894. (IsClaimed ? "Claimed" : ""),
  895. (IsMissing ? "Missing" : ""),
  896. (IsEnumerated ? "Enumerated" : ""),
  897. (IsVisible ? "Visible" : ""),
  898. (IsMismatched ? "Mismatched" : "")));
  899. //
  900. // Print out the various LU flags
  901. //
  902. DumpFlags(Depth, "LuFlags", LunLuFlags, LuFlags);
  903. xdprintfEx(Depth, ("Retry 0x%02x Key 0x%08lx\n",
  904. RetryCount, CurrentKey));
  905. xdprintfEx(Depth, ("Lock 0x%08lx Pause 0x%08lx CurrentLock: 0x%p\n",
  906. QueueLockCount, QueuePauseCount, NULL));
  907. xdprintfEx(Depth, ("HwLuExt 0x%08p Adapter 0x%08p Timeout 0x%08x\n",
  908. HwLogicalUnitExtension, AdapterExtension,
  909. RequestTimeoutCounter));
  910. xdprintfEx(Depth, ("NextLun 0x%p ReadyLun 0x%p\n",
  911. NextLogicalUnit, ReadyLogicalUnit));
  912. xdprintfEx(Depth, ("Pending 0x%p Busy 0x%p Untagged 0x%p\n",
  913. PendingRequest,
  914. BusyRequest,
  915. CurrentUntaggedRequest));
  916. if((CompletedAbort != 0) || (AbortSrb != 0)) {
  917. xdprintfEx(Depth, ("Abort 0x%p Completed Abort 0x%p\n",
  918. AbortSrb, CompletedAbort));
  919. }
  920. xdprintfEx(Depth, ("Q Depth %03d (%03d) InquiryData 0x%p\n",
  921. QueueCount, MaxQueueDepth, AddrOf_InquiryData));
  922. xdprintfEx(Depth, ("DeviceMap Keys: Target %#08lx Lun %#08lx\n",
  923. TargetDeviceMapKey, LunDeviceMapKey));
  924. xdprintfEx(Depth, ("Bypass SRB_DATA blocks %d @ %08p List %08p\n",
  925. NUMBER_BYPASS_SRB_DATA_BLOCKS,
  926. AddrOf_BypassSrbDataBlocks,
  927. BypassSrbDataList_Next));
  928. if((ActiveFailedRequest != 0) ||
  929. (BlockedFailedRequest != 0)) {
  930. xdprintfEx(Depth, ("Failed Requests - "));
  931. if(ActiveFailedRequest != 0) {
  932. dprintf("Active %#08I ", ActiveFailedRequest);
  933. }
  934. if(BlockedFailedRequest != 0) {
  935. dprintf("Blocked %#08I ", BlockedFailedRequest);
  936. }
  937. dprintf("\n");
  938. }
  939. xdprintfEx(Depth, ("RS Irp %p Srb @ %p MDL @ %p\n",
  940. RequestSenseIrp,
  941. AddrOf_RequestSenseSrb,
  942. AddrOf_RequestSenseMdl));
  943. if((RequestList_Flink) == AddrOf_RequestList) {
  944. xdprintfEx(Depth, ("Request List @0x%p is empty\n",
  945. AddrOf_RequestList));
  946. } else {
  947. xdprintfEx(Depth, ("Request list @0x%p:\n", AddrOf_RequestList));
  948. ScsiDumpActiveRequests(AddrOf_RequestList,
  949. Adapter_TickCount,
  950. Depth + 2);
  951. }
  952. if (Detail != 0) {
  953. //
  954. // The caller wants additional detail. Dump the queued requests.
  955. // Extract the address of the device object from the common extension
  956. // and pass it to the routine that dumps queued requests.
  957. //
  958. ULONG64 DeviceObject;
  959. result = GetFieldData(LunAddress,
  960. "scsiport!_COMMON_EXTENSION",
  961. "DeviceObject",
  962. sizeof(ULONG64),
  963. &DeviceObject);
  964. if (result) {
  965. dprintf("Error reading DeviceObject @%p\n", LunAddress);
  966. return;
  967. }
  968. xdprintfEx(Depth, ("Queued requests:\n"));
  969. ScsiDumpQueuedRequests(
  970. DeviceObject,
  971. Adapter_TickCount,
  972. Depth + 2
  973. );
  974. }
  975. //
  976. // Dump the per-lun IO log.
  977. //
  978. InitTypeRead(LunAddress, scsiport!_LOGICAL_UNIT_EXTENSION);
  979. logEntries = (ULONG) ReadField(IoLogEntries);
  980. if (logEntries > 0) {
  981. ULONG index;
  982. ULONG offset;
  983. ULONG64 logAddress;
  984. SP_LUN_IO_LOG ioLog[10] = {0};
  985. ULONG bytesRead;
  986. PSP_LUN_IO_LOG entry;
  987. ULONG i;
  988. dprintf("Log:\n");
  989. if (logEntries >= 10) {
  990. //
  991. // The current index is the oldest entry in the log.
  992. //
  993. index = (ULONG) ReadField(IoLogIndex);
  994. if (index >= 10) {
  995. index = 0;
  996. }
  997. } else {
  998. //
  999. // we haven't wrapped so zero is the oldest entry in the log.
  1000. //
  1001. index = 0;
  1002. }
  1003. //
  1004. // Get the offset of the log array relative to the beginning of the
  1005. // logical unit extension.
  1006. //
  1007. result = GetFieldOffset("scsiport!_LOGICAL_UNIT_EXTENSION",
  1008. "IoLog",
  1009. &offset);
  1010. if (result != 0) {
  1011. goto NoLogEntry;
  1012. }
  1013. //
  1014. // Calculate the address of the log.
  1015. //
  1016. logAddress = LunAddress + offset;
  1017. //
  1018. // Read all of the log entries.
  1019. //
  1020. result = ReadMemory(logAddress,
  1021. (PVOID) ioLog,
  1022. sizeof(SP_LUN_IO_LOG) * 10,
  1023. &bytesRead);
  1024. xdprintfEx(Depth, ("\n"));
  1025. xdprintfEx(Depth, (" Srb Scsi \n"));
  1026. xdprintfEx(Depth, ("TickCount Cmd Status Status Sector Tag\n"));
  1027. xdprintfEx(Depth, ("--------- --- ------ ------ -------- ---\n"));
  1028. //
  1029. // Dump the log, beginning with the oldest entry.
  1030. //
  1031. for (i=0; i<logEntries; i++) {
  1032. entry = &ioLog[index];
  1033. xdprintfEx(Depth, ("%08x %02x %02x %02x %08x %02x",
  1034. entry->TickCount,
  1035. entry->Cdb[0],
  1036. entry->SrbStatus,
  1037. entry->ScsiStatus,
  1038. entry->QueueSortKey,
  1039. entry->Tag
  1040. ));
  1041. if (entry->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) {
  1042. PSENSE_DATA senseData = (PSENSE_DATA) entry->SenseData;
  1043. dprintf(" (%x, %x, %x)\n",
  1044. senseData->ErrorCode,
  1045. senseData->AdditionalSenseCode,
  1046. senseData->AdditionalSenseCodeQualifier);
  1047. } else {
  1048. dprintf("\n");
  1049. }
  1050. index++;
  1051. if (index == 10) {
  1052. index = 0;
  1053. }
  1054. }
  1055. }
  1056. NoLogEntry:
  1057. return;
  1058. }
  1059. VOID
  1060. ScsiDumpActiveRequests(
  1061. IN ULONG64 ListHead,
  1062. IN ULONG TickCount,
  1063. IN ULONG Depth
  1064. )
  1065. {
  1066. ULONG result;
  1067. ULONG64 lastEntry = 0;
  1068. ULONG64 entry = 0;
  1069. ULONG64 realEntry = 0;
  1070. ULONG64 CurrentSrb = 0;
  1071. ULONG64 CurrentIrp = 0;
  1072. ULONG64 RequestList = 0;
  1073. ULONG OffsetOfRequestList = 0;
  1074. ULONG SrbTickCount = 0;
  1075. ULONG Key = 0;
  1076. FIELD_INFO deviceFields[] = {
  1077. {"CurrentSrb", NULL, 0, COPY, 0, (PVOID) &CurrentSrb},
  1078. {"CurrentIrp", NULL, 0, COPY, 0, (PVOID) &CurrentIrp},
  1079. {"TickCount", NULL, 0, COPY, 0, (PVOID) &SrbTickCount},
  1080. {"RequestList", NULL, 0, ADDROF, 0, NULL},
  1081. };
  1082. SYM_DUMP_PARAM DevSym = {
  1083. sizeof (SYM_DUMP_PARAM),
  1084. "scsiport!_SRB_DATA",
  1085. DBG_DUMP_NO_PRINT,
  1086. 0,
  1087. NULL, NULL, NULL,
  1088. sizeof (deviceFields) / sizeof (FIELD_INFO),
  1089. &deviceFields[0]
  1090. };
  1091. result = GetFieldOffset("scsiport!_SRB_DATA",
  1092. "RequestList",
  1093. &OffsetOfRequestList);
  1094. if (result) {
  1095. dprintf("failed to get offset of request list (%08X)\n", result);
  1096. return;
  1097. }
  1098. entry = ListHead;
  1099. realEntry = entry;
  1100. InitTypeRead(ListHead, nt!_LIST_ENTRY);
  1101. lastEntry = ReadField(Blink);
  1102. xdprintfEx(Depth, ("Tick count is %d\n", TickCount));
  1103. do {
  1104. ULONG64 realSrbData;
  1105. GetFieldData(realEntry,
  1106. "scsiport!_LIST_ENTRY",
  1107. "Flink",
  1108. sizeof(ULONG64),
  1109. &entry);
  1110. //
  1111. // entry points to the list entry element of the srb data. Calculate
  1112. // the address of the start of the srb data block.
  1113. //
  1114. realSrbData = entry - OffsetOfRequestList;
  1115. xdprintfEx(Depth, ("SrbData %08p ", realSrbData));
  1116. //
  1117. // Read the SRB_DATA information we need.
  1118. //
  1119. DevSym.addr = realSrbData;
  1120. if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) {
  1121. dprintf("%08p: Could not read device object\n", realSrbData);
  1122. return;
  1123. }
  1124. RequestList = deviceFields[3].address;
  1125. InitTypeRead(CurrentSrb, scsiport!_SCSI_REQUEST_BLOCK);
  1126. Key = (ULONG)ReadField(QueueSortKey);
  1127. //
  1128. // Update realEntry.
  1129. //
  1130. realEntry = RequestList;
  1131. dprintf("Srb %08p Irp %08p Key %x %s\n",
  1132. CurrentSrb,
  1133. CurrentIrp,
  1134. Key,
  1135. SecondsToString(TickCount - SrbTickCount));
  1136. } while((entry != lastEntry) && (!CheckControlC()));
  1137. return;
  1138. }
  1139. VOID
  1140. ScsiDumpLocks(
  1141. ULONG64 CommonExtension,
  1142. ULONG Depth
  1143. )
  1144. /*++
  1145. Routine Description:
  1146. dumps the remove locks for a given device object
  1147. Arguments:
  1148. CommonExtension - a pointer to the local copy of the device object
  1149. common extension
  1150. Return Value:
  1151. None
  1152. --*/
  1153. {
  1154. ULONG result;
  1155. LONG RemoveLock;
  1156. ULONG64 RemoveTrackingSpinlock;
  1157. ULONG64 RemoveTrackingList;
  1158. InitTypeRead(CommonExtension, scsiport!_COMMON_EXTENSION);
  1159. RemoveLock = (ULONG) ReadField(RemoveLock);
  1160. RemoveTrackingSpinlock = ReadField(RemoveTrackingSpinlock);
  1161. RemoveTrackingList = ReadField(RemoveTrackingList);
  1162. xdprintfEx(Depth, ("RemoveLock count is %d", RemoveLock));
  1163. if((PVOID)RemoveTrackingSpinlock != (PVOID)-1) {
  1164. ULONG64 lockEntryAddress = RemoveTrackingList;
  1165. dprintf(":\n");
  1166. Depth++;
  1167. if(RemoveTrackingSpinlock != 0) {
  1168. xdprintfEx(Depth, ("RemoveTrackingList is in intermediate state"
  1169. "@ %p\n", RemoveTrackingList));
  1170. return;
  1171. }
  1172. while((lockEntryAddress != 0L) && !CheckControlC()) {
  1173. UCHAR buffer[512];
  1174. ULONG64 File;
  1175. ULONG64 Tag;
  1176. ULONG64 NextBlock;
  1177. ULONG Line;
  1178. InitTypeRead(lockEntryAddress, scsiport!REMOVE_TRACKING_BLOCK);
  1179. File = ReadField(File);
  1180. Tag = ReadField(Tag);
  1181. Line = (ULONG) ReadField(Line);
  1182. NextBlock = ReadField(NextBlock);
  1183. result = sizeof(buffer);
  1184. if(!GetAnsiString(File,
  1185. buffer,
  1186. &result)) {
  1187. xdprintfEx(Depth, ("Tag 0x%p File 0x%p Line %d\n",
  1188. Tag,
  1189. File,
  1190. Line));
  1191. } else {
  1192. PUCHAR name;
  1193. name = &buffer[result];
  1194. while((result > 0) &&
  1195. (*(name - 1) != '\\') &&
  1196. (*(name - 1) != '/') &&
  1197. (!CheckControlC())) {
  1198. name--;
  1199. result--;
  1200. }
  1201. xdprintfEx(Depth, ("Tag 0x%p File %s Line %d\n",
  1202. Tag,
  1203. name,
  1204. Line));
  1205. }
  1206. lockEntryAddress = NextBlock;
  1207. }
  1208. } else {
  1209. dprintf(" (not tracked on free build)\n");
  1210. }
  1211. return;
  1212. }
  1213. VOID
  1214. ScsiDumpSrbData(
  1215. ULONG64 SrbData,
  1216. ULONG Depth
  1217. )
  1218. {
  1219. ULONG result;
  1220. CSHORT Type = 0;
  1221. ULONG64 LogicalUnit = 0;
  1222. ULONG64 CurrentSrb = 0;
  1223. ULONG64 CurrentIrp = 0;
  1224. ULONG64 RequestSenseSave = 0;
  1225. ULONG QueueTag = 0;
  1226. ULONG64 CompletedRequests = 0;
  1227. ULONG ErrorLogRetryCount = 0;
  1228. ULONG SequenceNumber = 0;
  1229. ULONG Flags = 0;
  1230. ULONG64 RequestListFlink = 0;
  1231. ULONG64 RequestListBlink = 0;
  1232. ULONG64 DataOffset = 0;
  1233. ULONG64 OriginalDataBuffer = 0;
  1234. ULONG64 MapRegisterBase = 0;
  1235. ULONG NumberOfMapRegisters = 0;
  1236. ULONG64 ScatterGatherList = 0;
  1237. FIELD_INFO deviceFields[] = {
  1238. {"Type", NULL, 0, COPY, 0, (PVOID) &Type},
  1239. {"LogicalUnit", NULL, 0, COPY, 0, (PVOID) &LogicalUnit},
  1240. {"CurrentSrb", NULL, 0, COPY, 0, (PVOID) &CurrentSrb},
  1241. {"CurrentIrp", NULL, 0, COPY, 0, (PVOID) &CurrentIrp},
  1242. {"RequestSenseSave", NULL, 0, COPY, 0, (PVOID) &RequestSenseSave},
  1243. {"QueueTag", NULL, 0, COPY, 0, (PVOID) &QueueTag},
  1244. {"CompletedRequests", NULL, 0, COPY, 0, (PVOID) &CompletedRequests},
  1245. {"ErrorLogRetryCount", NULL, 0, COPY, 0, (PVOID) &ErrorLogRetryCount},
  1246. {"SequenceNumber", NULL, 0, COPY, 0, (PVOID) &SequenceNumber},
  1247. {"Flags", NULL, 0, COPY, 0, (PVOID) &Flags},
  1248. {"RequestList.Flink", NULL, 0, COPY, 0, (PVOID) &RequestListFlink},
  1249. {"RequestList.Blink", NULL, 0, COPY, 0, (PVOID) &RequestListBlink},
  1250. {"DataOffset", NULL, 0, COPY, 0, (PVOID) &DataOffset},
  1251. {"OriginalDataBuffer", NULL, 0, COPY, 0, (PVOID) &OriginalDataBuffer},
  1252. {"MapRegisterBase", NULL, 0, COPY, 0, (PVOID) &MapRegisterBase},
  1253. {"NumberOfMapRegisters", NULL, 0, COPY, 0, (PVOID) &NumberOfMapRegisters},
  1254. {"ScatterGatherList", NULL, 0, COPY, 0, (PVOID) &ScatterGatherList},
  1255. };
  1256. SYM_DUMP_PARAM DevSym = {
  1257. sizeof (SYM_DUMP_PARAM),
  1258. "scsiport!_SRB_DATA",
  1259. DBG_DUMP_NO_PRINT,
  1260. SrbData,
  1261. NULL, NULL, NULL,
  1262. sizeof (deviceFields) / sizeof (FIELD_INFO),
  1263. &deviceFields[0]
  1264. };
  1265. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  1266. if (result) {
  1267. SCSIKD_PRINT_ERROR(result);
  1268. return;
  1269. }
  1270. if(Type != SRB_DATA_TYPE) {
  1271. dprintf("Type (%#x) does not match SRB_DATA_TYPE (%#x)\n",
  1272. Type, SRB_DATA_TYPE);
  1273. }
  1274. xdprintfEx(Depth, ("Lun 0x%p Srb 0x%p Irp 0x%p\n",
  1275. LogicalUnit, CurrentSrb, CurrentIrp));
  1276. xdprintfEx(Depth, ("Sense 0x%p Tag 0x%08lx Next Completed 0x%p\n",
  1277. RequestSenseSave,
  1278. QueueTag, CompletedRequests));
  1279. xdprintfEx(Depth, ("Retry 0x%02x Seq 0x%08lx Flags 0x%08lx\n",
  1280. ErrorLogRetryCount, SequenceNumber,
  1281. Flags));
  1282. xdprintfEx(Depth, ("Request List: Next 0x%p Previous 0x%p\n",
  1283. RequestListFlink, RequestListBlink));
  1284. xdprintfEx(Depth, ("Data Offset 0x%p Original Data Buffer 0x%p\n", DataOffset, OriginalDataBuffer));
  1285. xdprintfEx(Depth, ("Map Registers 0x%p (0x%02x) SG List 0x%p\n",
  1286. MapRegisterBase,
  1287. NumberOfMapRegisters,
  1288. ScatterGatherList));
  1289. if(ScatterGatherList != 0) {
  1290. ScsiDumpScatterGatherList(ScatterGatherList,
  1291. NumberOfMapRegisters,
  1292. Depth + 1);
  1293. }
  1294. return;
  1295. }
  1296. VOID
  1297. ScsiDumpScatterGatherList(
  1298. ULONG64 List,
  1299. ULONG Entries,
  1300. ULONG Depth
  1301. )
  1302. {
  1303. ULONG result;
  1304. ULONG i;
  1305. ULONG start = TRUE;
  1306. ULONG64 PhysicalAddress;
  1307. ULONG Length;
  1308. for(i = 0; i < Entries; i++) {
  1309. InitTypeRead(List, nt!_SCATTER_GATHER_ELEMENT);
  1310. PhysicalAddress = ReadField(Address);
  1311. Length = (ULONG) ReadField(Length);
  1312. if(start) {
  1313. xdprintfEx(Depth, ("0x%016I64x (0x%08lx), ",
  1314. PhysicalAddress,
  1315. Length));
  1316. } else {
  1317. dprintf("0x%016I64x (0x%08lx),\n",
  1318. PhysicalAddress,
  1319. Length);
  1320. }
  1321. start = !start;
  1322. List += (IsPtr64() != 0) ? 0x18 : 0xc;
  1323. }
  1324. if(!start) {
  1325. dprintf("\n");
  1326. }
  1327. }
  1328. DECLARE_API(srbdata)
  1329. {
  1330. ULONG64 address;
  1331. GetExpressionEx(args, &address, &args);
  1332. dprintf("SrbData structure at %#p\n", address);
  1333. ScsiDumpSrbData(address, 1);
  1334. return S_OK;
  1335. }
  1336. VOID
  1337. ScsiDumpAdapterPerfCounters(
  1338. ULONG64 Adapter,
  1339. ULONG Depth
  1340. )
  1341. {
  1342. #if TEST_LISTS
  1343. ULONG result;
  1344. ULONG SmallAllocationCount;
  1345. ULONG LargeAllocationCount;
  1346. ULONG64 ScatterGatherAllocationCount;
  1347. ULONG64 SmallAllocationSize;
  1348. ULONG64 MediumAllocationSize;
  1349. ULONG64 LargeAllocationSize;
  1350. ULONG64 SrbDataAllocationCount;
  1351. ULONG64 SrbDataResurrectionCount;
  1352. ULONG64 SrbDataEmergencyFreeCount;
  1353. FIELD_INFO deviceFields[] = {
  1354. {"SmallAllocationCount", NULL, 0, COPY, 0, (PVOID) &SmallAllocationCount},
  1355. {"LargeAllocationCount", NULL, 0, COPY, 0, (PVOID) &LargeAllocationCount},
  1356. {"ScatterGatherAllocationCount", NULL, 0, COPY, 0, (PVOID) &ScatterGatherAllocationCount},
  1357. {"SmallAllocationSize", NULL, 0, COPY, 0, (PVOID) &SmallAllocationSize},
  1358. {"MediumAllocationSize", NULL, 0, COPY, 0, (PVOID) &MediumAllocationSize},
  1359. {"LargeAllocationSize", NULL, 0, COPY, 0, (PVOID) &LargeAllocationSize},
  1360. {"SrbDataAllocationCount", NULL, 0, COPY, 0, (PVOID) &SrbDataAllocationCount},
  1361. {"SrbDataResurrectionCount", NULL, 0, COPY, 0, (PVOID) &SrbDataResurrectionCount},
  1362. {"SrbDataEmergencyFreeCount", NULL, 0, COPY, 0, (PVOID) &SrbDataEmergencyFreeCount},
  1363. };
  1364. SYM_DUMP_PARAM DevSym = {
  1365. sizeof (SYM_DUMP_PARAM),
  1366. "scsiport!_ADAPTER_EXTENSION",
  1367. DBG_DUMP_NO_PRINT,
  1368. Adapter,
  1369. NULL, NULL, NULL,
  1370. sizeof (deviceFields) / sizeof (FIELD_INFO),
  1371. &deviceFields[0]
  1372. };
  1373. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  1374. if (result) {
  1375. SCSIKD_PRINT_ERROR(result);
  1376. return;
  1377. }
  1378. ULONG mediumAllocationCount = (ULONG)
  1379. (ScatterGatherAllocationCount -
  1380. (SmallAllocationCount +
  1381. LargeAllocationCount));
  1382. double average;
  1383. xdprintfEx(Depth, ("Performance Counters:\n"));
  1384. Depth++;
  1385. xdprintfEx(Depth, ("SGList Allocs - "));
  1386. dprintf("Small: %d, ", SmallAllocationCount);
  1387. dprintf("Med: %d, ",
  1388. (ScatterGatherAllocationCount -
  1389. SmallAllocationCount -
  1390. LargeAllocationCount));
  1391. dprintf("Large: %d, ", LargeAllocationCount);
  1392. dprintf("Total: %I64d\n",
  1393. ScatterGatherAllocationCount);
  1394. xdprintfEx(Depth, ("Average SG Entries - "));
  1395. if(SmallAllocationCount != 0) {
  1396. average = ((double) (SmallAllocationSize)) / SmallAllocationCount;
  1397. dprintf("Small: %.2f ", average);
  1398. }
  1399. if(mediumAllocationCount != 0) {
  1400. average = ((double) (MediumAllocationSize)) / mediumAllocationCount;
  1401. dprintf("Medium: %.2f ", average);
  1402. }
  1403. if(Adapter->LargeAllocationCount != 0) {
  1404. average = ((double) (Adapter->LargeAllocationSize)) / LargeAllocationCount;
  1405. dprintf("Large: %.2f", average);
  1406. }
  1407. dprintf("\n");
  1408. xdprintfEx(Depth, ("SrbData - Allocs: %I64d, ",
  1409. SrbDataAllocationCount));
  1410. dprintf("Resurrected: %I64d, ",
  1411. SrbDataResurrectionCount);
  1412. dprintf("Timer Serviced: %I64d,\n",
  1413. SrbDataServicedFromTickHandlerCount);
  1414. xdprintfEx(Depth, (" Queued: %I64d, ",
  1415. SrbDataQueueInsertionCount));
  1416. dprintf("Emergency Freed: %I64d\n",
  1417. SrbDataEmergencyFreeCount);
  1418. #endif
  1419. return;
  1420. }
  1421. PUCHAR
  1422. SecondsToString(
  1423. ULONG Count
  1424. )
  1425. {
  1426. static UCHAR string[64] = "";
  1427. UCHAR tmp[16];
  1428. ULONG seconds = 0;
  1429. ULONG minutes = 0;
  1430. ULONG hours = 0;
  1431. ULONG days = 0;
  1432. string[0] = '\0';
  1433. if(Count == 0) {
  1434. sprintf(string, "<1s");
  1435. return string;
  1436. }
  1437. seconds = Count % 60;
  1438. Count /= 60;
  1439. if(Count != 0) {
  1440. minutes = Count % 60;
  1441. Count /= 60;
  1442. }
  1443. if(Count != 0) {
  1444. hours = Count % 24;
  1445. Count /= 24;
  1446. }
  1447. if(Count != 0) {
  1448. days = Count;
  1449. }
  1450. if(days != 0) {
  1451. sprintf(tmp, "%dd", days);
  1452. strcat(string, tmp);
  1453. }
  1454. if(hours != 0) {
  1455. sprintf(tmp, "%dh", hours);
  1456. strcat(string, tmp);
  1457. }
  1458. if(minutes != 0) {
  1459. sprintf(tmp, "%dm", minutes);
  1460. strcat(string, tmp);
  1461. }
  1462. if(seconds != 0) {
  1463. sprintf(tmp, "%ds", seconds);
  1464. strcat(string, tmp);
  1465. }
  1466. return string;
  1467. }
  1468. VOID
  1469. ScsiDumpQueuedRequests(
  1470. IN ULONG64 DeviceObject,
  1471. IN ULONG TickCount,
  1472. IN ULONG Depth
  1473. )
  1474. {
  1475. ULONG result;
  1476. ULONG64 ListHeadFlink;
  1477. ULONG64 ListHeadBlink;
  1478. ULONG64 DeviceListHead;
  1479. ULONG64 realEntry;
  1480. //
  1481. // Get the address of the head of the device list in the device queue.
  1482. //
  1483. result = GetFieldData(
  1484. DeviceObject,
  1485. "scsiport!_DEVICE_OBJECT",
  1486. "DeviceQueue.DeviceListHead",
  1487. sizeof(ULONG64),
  1488. &DeviceListHead);
  1489. if (result) {
  1490. SCSIKD_PRINT_ERROR(result);
  1491. return;
  1492. }
  1493. //
  1494. // Get the forward and backward link fields from the list head. If
  1495. // the queue is empty, we're done.
  1496. //
  1497. InitTypeRead(DeviceListHead, scsiport!_LIST_ENTRY);
  1498. ListHeadFlink = ReadField(CurrentSrb);
  1499. ListHeadBlink = ReadField(CurrentIrp);
  1500. if (ListHeadFlink == ListHeadBlink) {
  1501. xdprintfEx(Depth, ("Device Queue is empty\n"));
  1502. return;
  1503. }
  1504. //
  1505. // Initialize a pointer the head of the list.
  1506. //
  1507. realEntry = DeviceListHead;
  1508. do {
  1509. ULONG64 realIrp;
  1510. ULONG64 realStack;
  1511. ULONG64 realSrb;
  1512. ULONG64 realSrbData;
  1513. ULONG64 CurrentSrb;
  1514. ULONG64 CurrentIrp;
  1515. ULONG OffsetOfDeviceListEntry;
  1516. ULONG SrbDataTickCount;
  1517. //
  1518. // Get the address of the next entry in the queue.
  1519. //
  1520. result = GetFieldData(realEntry,
  1521. "scsiport!_LIST_ENTRY",
  1522. "Flink",
  1523. sizeof(ULONG64),
  1524. &realEntry);
  1525. if (result) {
  1526. SCSIKD_PRINT_ERROR(result);
  1527. break;
  1528. }
  1529. //
  1530. // We to calculate the address of the IRP using the address of the
  1531. // list entry. Can't use static CONTAINING_RECORD; we need a runtime
  1532. // equivalent. So we use type info to get the offset of the list
  1533. // entry and calculate the address of the beginning of the IRP. This
  1534. // makes the extension work for 32b and 64b debuggees.
  1535. //
  1536. result = GetFieldOffset(
  1537. "scsiport!_IRP",
  1538. "Tail.Overlay.DeviceQueueEntry.DeviceListEntry",
  1539. &OffsetOfDeviceListEntry);
  1540. if (result) {
  1541. SCSIKD_PRINT_ERROR(result);
  1542. break;
  1543. }
  1544. realIrp = realEntry - OffsetOfDeviceListEntry;
  1545. //
  1546. // Now we need to read in the address of the current IO stack
  1547. // location.
  1548. //
  1549. result = GetFieldData(
  1550. realIrp,
  1551. "scsiport!_IRP",
  1552. "Tail.Overlay.CurrentStackLocation",
  1553. sizeof(ULONG64),
  1554. &realStack);
  1555. if (result) {
  1556. SCSIKD_PRINT_ERROR(result);
  1557. break;
  1558. }
  1559. //
  1560. // Load the SRB field of the stack location.
  1561. //
  1562. result = GetFieldData(
  1563. realStack,
  1564. "scsiport!_IO_STACK_LOCATION",
  1565. "Parameters.Scsi.Srb",
  1566. sizeof(ULONG64),
  1567. &realSrb);
  1568. if (result) {
  1569. SCSIKD_PRINT_ERROR(result);
  1570. break;
  1571. }
  1572. //
  1573. // Pick out the pointer to the srb data and read that in.
  1574. //
  1575. result = GetFieldData(
  1576. realSrb,
  1577. "scsiport!_SCSI_REQUEST_BLOCK",
  1578. "OriginalRequest",
  1579. sizeof(ULONG64),
  1580. &realSrbData);
  1581. if (result) {
  1582. SCSIKD_PRINT_ERROR(result);
  1583. break;
  1584. }
  1585. xdprintfEx(Depth, ("SrbData 0x%p ", realSrbData));
  1586. //
  1587. // Read the SRB_DATA information we need.
  1588. //
  1589. InitTypeRead(realSrb, scsiport!_SRB_DATA);
  1590. CurrentSrb = ReadField(CurrentSrb);
  1591. CurrentIrp = ReadField(CurrentIrp);
  1592. SrbDataTickCount = (ULONG)ReadField(TickCount);
  1593. dprintf("Srb 0x%p Irp 0x%p %s\n",
  1594. CurrentSrb,
  1595. CurrentIrp,
  1596. SecondsToString(TickCount - SrbDataTickCount));
  1597. } while((realEntry != ListHeadBlink) && (!CheckControlC()));
  1598. return;
  1599. }