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.

1846 lines
55 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;
  125. ULONG result;
  126. ULONG detail = 0;
  127. CSHORT Type;
  128. //
  129. // Parse the argument string for the address to dump and for any additional
  130. // details the caller wishes to have dumped.
  131. //
  132. GetAddressAndDetailLevel64(args, &address, &detail);
  133. //
  134. // The supplied address may be either the address of a device object or the
  135. // address of a device extension. To distinguish which, we treat the
  136. // address as a device object and read what would be its type field. If
  137. // the
  138. //
  139. result = GetFieldData(address,
  140. "scsiport!_DEVICE_OBJECT",
  141. "Type",
  142. sizeof(CSHORT),
  143. &Type
  144. );
  145. if (result) {
  146. SCSIKD_PRINT_ERROR(result);
  147. return E_FAIL;
  148. }
  149. //
  150. // See if the supplied address holds a device object. If it does, read the
  151. // address of the device extension. Otherwise, we assume the supplied
  152. // addres holds a device extension and we use it directly.
  153. //
  154. if (Type == IO_TYPE_DEVICE) {
  155. result = GetFieldData(address,
  156. "scsiport!_DEVICE_OBJECT",
  157. "DeviceExtension",
  158. sizeof(ULONG64),
  159. &address
  160. );
  161. if (result) {
  162. SCSIKD_PRINT_ERROR(result);
  163. return E_FAIL;
  164. }
  165. }
  166. //
  167. // Call worker routine to dump the information.
  168. //
  169. ScsiDumpScsiportExtension(address, detail, 0);
  170. return S_OK;
  171. }
  172. VOID
  173. ScsiDumpScsiportExtension(
  174. IN ULONG64 CommonExtension,
  175. IN ULONG Detail,
  176. IN ULONG Depth
  177. )
  178. {
  179. ULONG tmp;
  180. ULONG result;
  181. ULONG64 DeviceObject = 0;
  182. ULONG IsPdo = 0;
  183. ULONG IsInitialized = 0;
  184. ULONG WmiInitialized = 0;
  185. ULONG WmiMiniPortSupport = 0;
  186. ULONG CurrentPnpState = 0;
  187. ULONG PreviousPnpState = 0;
  188. ULONG IsRemoved = 0;
  189. ULONG64 LowerDeviceObject = 0;
  190. ULONG SrbFlags = 0;
  191. ULONG64 MajorFunction = 0;
  192. SYSTEM_POWER_STATE CurrentSystemState = 0;
  193. DEVICE_POWER_STATE CurrentDeviceState = 0;
  194. DEVICE_POWER_STATE DesiredDeviceState = 0;
  195. ULONG64 IdleTimer = 0;
  196. ULONG64 WmiScsiPortRegInfoBuf = 0;
  197. ULONG WmiScsiPortRegInfoBufSize = 0;
  198. ULONG PagingPathCount = 0;
  199. ULONG HibernatePathCount = 0;
  200. ULONG DumpPathCount = 0;
  201. FIELD_INFO deviceFields[] = {
  202. {"DeviceObject", NULL, 0, COPY, 0, (PVOID) &DeviceObject},
  203. {"IsPdo", NULL, 0, COPY, 0, (PVOID) &IsPdo},
  204. {"IsInitialized", NULL, 0, COPY, 0, (PVOID) &IsInitialized},
  205. {"WmiInitialized", NULL, 0, COPY, 0, (PVOID) &WmiInitialized},
  206. {"WmiMiniPortSupport", NULL, 0, COPY, 0, (PVOID) &WmiMiniPortSupport},
  207. {"CurrentPnpState", NULL, 0, COPY, 0, (PVOID) &CurrentPnpState},
  208. {"PreviousPnpState", NULL, 0, COPY, 0, (PVOID) &PreviousPnpState},
  209. {"IsRemoved", NULL, 0, COPY, 0, (PVOID) &IsRemoved},
  210. {"LowerDeviceObject", NULL, 0, COPY, 0, (PVOID) &LowerDeviceObject},
  211. {"SrbFlags", NULL, 0, COPY, 0, (PVOID) &SrbFlags},
  212. {"MajorFunction", NULL, 0, COPY, 0, (PVOID) &MajorFunction},
  213. {"CurrentSystemState", NULL, 0, COPY, 0, (PVOID) &CurrentSystemState},
  214. {"CurrentDeviceState", NULL, 0, COPY, 0, (PVOID) &CurrentDeviceState},
  215. {"DesiredDeviceState", NULL, 0, COPY, 0, (PVOID) &DesiredDeviceState},
  216. {"IdleTimer", NULL, 0, COPY, 0, (PVOID) &IdleTimer},
  217. {"WmiScsiPortRegInfoBuf", NULL, 0, COPY, 0, (PVOID) &WmiScsiPortRegInfoBuf},
  218. {"WmiScsiPortRegInfoBufSize", NULL, 0, COPY, 0, (PVOID) &WmiScsiPortRegInfoBufSize},
  219. {"PagingPathCount", NULL, 0, COPY, 0, (PVOID) &PagingPathCount},
  220. {"HibernatePathCount", NULL, 0, COPY, 0, (PVOID) &HibernatePathCount},
  221. {"DumpPathCount", NULL, 0, COPY, 0, (PVOID) &DumpPathCount},
  222. };
  223. SYM_DUMP_PARAM DevSym = {
  224. sizeof (SYM_DUMP_PARAM),
  225. "scsiport!_COMMON_EXTENSION",
  226. DBG_DUMP_NO_PRINT,
  227. CommonExtension,
  228. NULL, NULL, NULL,
  229. sizeof (deviceFields) / sizeof (FIELD_INFO),
  230. &deviceFields[0]
  231. };
  232. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  233. if (result) {
  234. dprintf("%08p: Could not read device object\n", CommonExtension);
  235. return;
  236. }
  237. xdprintfEx(Depth, ("Scsiport %s device extension at address %p\n",
  238. IsPdo ? "physical" : "functional", CommonExtension));
  239. xdprintfEx(Depth, ("Common Extension:\n"));
  240. Depth += 1;
  241. tmp = Depth;
  242. if(IsInitialized) {
  243. xdprintfEx(tmp, ("Initialized "));
  244. tmp = 0;
  245. }
  246. if(IsRemoved) {
  247. xdprintfEx(tmp, ("Removed " ));
  248. tmp = 0;
  249. }
  250. switch(IsRemoved) {
  251. case REMOVE_PENDING: {
  252. xdprintfEx(tmp, ("RemovePending"));
  253. tmp = 0;
  254. break;
  255. }
  256. case REMOVE_COMPLETE: {
  257. xdprintfEx(tmp, ("RemoveComplete"));
  258. tmp = 0;
  259. break;
  260. }
  261. }
  262. if(WmiMiniPortSupport) {
  263. if(WmiInitialized) {
  264. xdprintfEx(tmp, ("WmiInit"));
  265. } else {
  266. xdprintfEx(tmp, ("Wmi"));
  267. }
  268. tmp = 0;
  269. }
  270. if(tmp == 0) {
  271. dprintf("\n");
  272. }
  273. tmp = 0;
  274. xdprintfEx(Depth, ("DO 0x%08p LowerObject 0x%08p SRB Flags %#08lx\n",
  275. DeviceObject,
  276. LowerDeviceObject,
  277. SrbFlags));
  278. xdprintfEx(Depth, ("Current Power (D%d,S%d) Desired Power D%d Idle %#08lx\n",
  279. CurrentDeviceState - 1,
  280. CurrentSystemState - 1,
  281. DesiredDeviceState - 1,
  282. IdleTimer));
  283. xdprintfEx(Depth, ("Current PnP state 0x%x Previous state 0x%x\n",
  284. CurrentPnpState,
  285. PreviousPnpState));
  286. xdprintfEx(Depth, ("DispatchTable %08p UsePathCounts (P%d, H%d, C%d)\n",
  287. MajorFunction,
  288. PagingPathCount,
  289. HibernatePathCount,
  290. DumpPathCount));
  291. if(WmiMiniPortSupport) {
  292. xdprintfEx(Depth, ("DispatchTable 0x%08p WmiInfoSize %#08lx\n",
  293. WmiScsiPortRegInfoBuf,
  294. WmiScsiPortRegInfoBufSize));
  295. }
  296. if(IsPdo) {
  297. xdprintfEx(Depth - 1, ("Logical Unit Extension:\n"));
  298. ScsiDumpPdo(CommonExtension, Detail, Depth);
  299. } else {
  300. xdprintfEx(Depth - 1, ("Adapter Extension:\n"));
  301. ScsiDumpFdo(CommonExtension, Detail, Depth);
  302. }
  303. if(Detail > 1) {
  304. ScsiDumpLocks(CommonExtension, Depth - 1);
  305. }
  306. return;
  307. }
  308. VOID
  309. ScsiDumpFdo(
  310. ULONG64 Address,
  311. ULONG Detail,
  312. ULONG Depth
  313. )
  314. {
  315. ULONG tmp = Depth;
  316. ULONG result;
  317. ULONG NumOfFields;
  318. ULONG PortNumber = 0;
  319. UCHAR IsPnp = 0;
  320. UCHAR IsMiniportDetected = 0;
  321. UCHAR IsInVirtualSlot = 0;
  322. UCHAR HasInterrupt = 0;
  323. UCHAR DisablePower = 0;
  324. UCHAR DisableStop = 0;
  325. ULONG64 LowerPdo = 0;
  326. ULONG64 HwDeviceExtension = 0;
  327. LONG ActiveRequestCount = 0;
  328. ULONG NumberOfBuses = 0;
  329. ULONG MaximumTargetIds = 0;
  330. ULONG MaxLuCount = 0;
  331. ULONG Flags = 0;
  332. ULONG64 NonCachedExtension = 0;
  333. ULONG IoAddress = 0;
  334. ULONG InterruptLevel = 0;
  335. ULONG RealBusNumber = 0;
  336. ULONG RealSlotNumber = 0;
  337. LONG PortTimeoutCounter = 0;
  338. ULONG DpcFlags = 0;
  339. ULONG SequenceNumber = 0;
  340. ULONG64 SrbExtensionListHeader = 0;
  341. ULONG NumberOfRequests = 0;
  342. ULONG64 QueueTagBitMap = 0;
  343. ULONG QueueTagHint = 0;
  344. ULONG HwLogicalUnitExtensionSize = 0;
  345. ULONG SrbExtensionSize = 0;
  346. ULONG LargeScatterGatherListSize = 0;
  347. ULONG64 EmergencySrbData = 0;
  348. ULONG CommonBufferSize = 0;
  349. ULONG64 PhysicalCommonBuffer = 0;
  350. ULONG64 SrbExtensionBuffer = 0;
  351. ULONG64 InterruptObject = 0;
  352. ULONG64 InterruptObject2 = 0;
  353. ULONG64 DmaAdapterObject = 0;
  354. ULONG64 AllocatedResources = 0;
  355. ULONG64 TranslatedResources = 0;
  356. ULONG64 PortConfig = 0;
  357. ULONG64 PortDeviceMapKey = 0;
  358. ULONG64 BusDeviceMapKeys = 0;
  359. UCHAR RemoveTrackingLookasideListInitialized = 0;
  360. ULONG64 AddrOfMaxQueueTag = 0;
  361. ULONG64 SrbDataBlockedRequests = 0;
  362. ULONG64 SrbDataLookasideList = 0;
  363. ULONG64 MediumScatterGatherLookasideList = 0;
  364. ULONG64 RemoveTrackingLookasideList = 0;
  365. ULONG64 InterruptData = 0;
  366. UCHAR MaxQueueTag = 0;
  367. FIELD_INFO deviceFields[] = {
  368. {"PortNumber", NULL, 0, COPY, 0, (PVOID) &PortNumber},
  369. {"IsPnp", NULL, 0, COPY, 0, (PVOID) &IsPnp},
  370. {"IsMiniportDetected", NULL, 0, COPY, 0, (PVOID) &IsMiniportDetected},
  371. {"IsInVirtualSlot", NULL, 0, COPY, 0, (PVOID) &IsInVirtualSlot},
  372. {"HasInterrupt", NULL, 0, COPY, 0, (PVOID) &HasInterrupt},
  373. {"DisablePower", NULL, 0, COPY, 0, (PVOID) &DisablePower},
  374. {"DisableStop", NULL, 0, COPY, 0, (PVOID) &DisableStop},
  375. {"LowerPdo", NULL, 0, COPY, 0, (PVOID) &LowerPdo},
  376. {"HwDeviceExtension", NULL, 0, COPY, 0, (PVOID) &HwDeviceExtension},
  377. {"ActiveRequestCount", NULL, 0, COPY, 0, (PVOID) &ActiveRequestCount},
  378. {"NumberOfBuses", NULL, 0, COPY, 0, (PVOID) &NumberOfBuses},
  379. {"MaximumTargetIds", NULL, 0, COPY, 0, (PVOID) &MaximumTargetIds},
  380. {"MaxLuCount", NULL, 0, COPY, 0, (PVOID) &MaxLuCount},
  381. {"Flags", NULL, 0, COPY, 0, (PVOID) &Flags},
  382. {"NonCachedExtension", NULL, 0, COPY, 0, (PVOID) &NonCachedExtension},
  383. {"IoAddress", NULL, 0, COPY, 0, (PVOID) &IoAddress},
  384. {"InterruptLevel", NULL, 0, COPY, 0, (PVOID) &InterruptLevel},
  385. {"RealBusNumber", NULL, 0, COPY, 0, (PVOID) &RealBusNumber},
  386. {"RealSlotNumber", NULL, 0, COPY, 0, (PVOID) &RealSlotNumber},
  387. {"PortTimeoutCounter", NULL, 0, COPY, 0, (PVOID) &PortTimeoutCounter},
  388. {"DpcFlags", NULL, 0, COPY, 0, (PVOID) &DpcFlags},
  389. {"SequenceNumber", NULL, 0, COPY, 0, (PVOID) &SequenceNumber},
  390. {"SrbExtensionListHeader", NULL, 0, COPY, 0, (PVOID) &SrbExtensionListHeader},
  391. {"NumberOfRequests", NULL, 0, COPY, 0, (PVOID) &NumberOfRequests},
  392. {"QueueTagBitMap", NULL, 0, COPY, 0, (PVOID) &QueueTagBitMap},
  393. {"QueueTagHint", NULL, 0, COPY, 0, (PVOID) &QueueTagHint},
  394. {"HwLogicalUnitExtensionSize", NULL, 0, COPY, 0, (PVOID) &HwLogicalUnitExtensionSize},
  395. {"SrbExtensionSize", NULL, 0, COPY, 0, (PVOID) &SrbExtensionSize},
  396. {"LargeScatterGatherListSize", NULL, 0, COPY, 0, (PVOID) &LargeScatterGatherListSize},
  397. {"EmergencySrbData", NULL, 0, COPY, 0, (PVOID) &EmergencySrbData},
  398. {"CommonBufferSize", NULL, 0, COPY, 0, (PVOID) &CommonBufferSize},
  399. {"PhysicalCommonBuffer.QuadPart", NULL, 0, COPY, 0, (PVOID) &PhysicalCommonBuffer},
  400. {"SrbExtensionBuffer", NULL, 0, COPY, 0, (PVOID) &SrbExtensionBuffer},
  401. {"InterruptObject", NULL, 0, COPY, 0, (PVOID) &InterruptObject},
  402. {"InterruptObject2", NULL, 0, COPY, 0, (PVOID) &InterruptObject2},
  403. {"DmaAdapterObject", NULL, 0, COPY, 0, (PVOID) &DmaAdapterObject},
  404. {"AllocatedResources", NULL, 0, COPY, 0, (PVOID) &AllocatedResources},
  405. {"TranslatedResources", NULL, 0, COPY, 0, (PVOID) &TranslatedResources},
  406. {"PortConfig", NULL, 0, COPY, 0, (PVOID) &PortConfig},
  407. {"PortDeviceMapKey", NULL, 0, COPY, 0, (PVOID) &PortDeviceMapKey},
  408. {"BusDeviceMapKeys", NULL, 0, COPY, 0, (PVOID) &BusDeviceMapKeys},
  409. {"CommonExtension.RemoveTrackingLookasideListInitialized", NULL, 0, COPY, 0, (PVOID) &RemoveTrackingLookasideListInitialized},
  410. {"MaxQueueTag", NULL, 0, ADDROF, 0, NULL},
  411. {"SrbDataBlockedRequests", NULL, 0, ADDROF, 0, NULL},
  412. {"SrbDataLookasideList", NULL, 0, ADDROF, 0, NULL},
  413. {"MediumScatterGatherLookasideList", NULL, 0, ADDROF, 0, NULL},
  414. {"CommonExtension.RemoveTrackingLookasideList", NULL, 0, ADDROF, 0, NULL},
  415. {"InterruptData", NULL, 0, ADDROF, 0, NULL},
  416. };
  417. SYM_DUMP_PARAM DevSym = {
  418. sizeof (SYM_DUMP_PARAM),
  419. "scsiport!_ADAPTER_EXTENSION",
  420. DBG_DUMP_NO_PRINT,
  421. Address,
  422. NULL, NULL, NULL,
  423. sizeof (deviceFields) / sizeof (FIELD_INFO),
  424. &deviceFields[0]
  425. };
  426. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  427. if (result) {
  428. SCSIKD_PRINT_ERROR(result);
  429. return;
  430. }
  431. result = GetFieldData(Address,
  432. "scsiport!_ADAPTER_EXTENSION",
  433. "MaxQueueTag",
  434. sizeof(UCHAR),
  435. &MaxQueueTag
  436. );
  437. if (result) {
  438. SCSIKD_PRINT_ERROR(result);
  439. return;
  440. }
  441. NumOfFields = sizeof (deviceFields) / sizeof (FIELD_INFO);
  442. InterruptData = deviceFields[NumOfFields-1].address;
  443. RemoveTrackingLookasideList = deviceFields[NumOfFields-2].address;
  444. MediumScatterGatherLookasideList = deviceFields[NumOfFields-3].address;
  445. SrbDataLookasideList = deviceFields[NumOfFields-4].address;
  446. SrbDataBlockedRequests = deviceFields[NumOfFields-5].address;
  447. AddrOfMaxQueueTag = deviceFields[NumOfFields-6].address;
  448. xdprintfEx(Depth, ("Port %d ", PortNumber));
  449. if(IsPnp) {
  450. xdprintfEx(tmp, ("IsPnp "));
  451. tmp = 0;
  452. }
  453. if(IsMiniportDetected) {
  454. xdprintfEx(tmp, ("MpDetected "));
  455. tmp = 0;
  456. }
  457. if(IsInVirtualSlot) {
  458. xdprintfEx(tmp, ("VirtualSlot "));
  459. tmp = 0;
  460. }
  461. if(HasInterrupt) {
  462. xdprintfEx(tmp, ("HasInterrupt"));
  463. tmp = 0;
  464. }
  465. if(DisablePower) {
  466. xdprintfEx(tmp, ("NoPower"));
  467. tmp = 0;
  468. }
  469. if(DisableStop) {
  470. xdprintfEx(tmp, ("NoStop"));
  471. tmp = 0;
  472. }
  473. dprintf("\n");
  474. xdprintfEx(Depth, ("LowerPdo 0x%08p HwDevExt 0x%08p Active Requests 0x%08lx\n",
  475. LowerPdo,
  476. HwDeviceExtension,
  477. ActiveRequestCount));
  478. xdprintfEx(Depth, ("MaxBus 0x%02x MaxTarget 0x%02x MaxLun 0x%02x\n",
  479. NumberOfBuses,
  480. MaximumTargetIds,
  481. MaxLuCount));
  482. DumpFlags(Depth, "Port Flags", Flags, AdapterFlags);
  483. xdprintfEx(Depth, ("NonCacheExt 0x%08p IoBase 0x%08x Int 0x%02x\n",
  484. NonCachedExtension,
  485. IoAddress,
  486. InterruptLevel));
  487. xdprintfEx(Depth, ("RealBus# 0x%0x RealSlot# 0x%0x\n",
  488. RealBusNumber,
  489. RealSlotNumber));
  490. xdprintfEx(Depth, ("Timeout 0x%08x DpcFlags 0x%08x Sequence 0x%08x\n",
  491. PortTimeoutCounter,
  492. DpcFlags,
  493. SequenceNumber));
  494. xdprintfEx(Depth, ("Srb Ext Header 0x%08p No. Requests 0x%08lx\n",
  495. SrbExtensionListHeader, NumberOfRequests));
  496. xdprintfEx(Depth, ("QueueTag BitMap 0x%08p Hint 0x%08lx\n",
  497. QueueTagBitMap, QueueTagHint));
  498. xdprintfEx(Depth, ("MaxQueueTag 0x%2x (@0x%08p)\n",
  499. MaxQueueTag, AddrOfMaxQueueTag));
  500. xdprintfEx(Depth, ("LuExt Size 0x%08lx SrbExt Size 0x%08lx\n",
  501. HwLogicalUnitExtensionSize,
  502. SrbExtensionSize));
  503. xdprintfEx(Depth + 1, ("SG List Size - Small %d Large %d\n",
  504. SP_SMALL_PHYSICAL_BREAK_VALUE,
  505. LargeScatterGatherListSize));
  506. Depth++;
  507. xdprintfEx(Depth, ("Emergency - SrbData 0x%08p Blocked List @0x%08p\n",
  508. EmergencySrbData,
  509. SrbDataBlockedRequests));
  510. xdprintfEx(Depth, ("CommonBuff - Size: 0x%08lx PA: 0x%016I64x VA: 0x%08p\n",
  511. CommonBufferSize,
  512. PhysicalCommonBuffer,
  513. SrbExtensionBuffer));
  514. xdprintfEx(Depth, ("Ke Objects - Int1: 0x%08p Int2: 0x%08p Dma: 0x%08p\n",
  515. InterruptObject,
  516. InterruptObject2,
  517. DmaAdapterObject));
  518. xdprintfEx(Depth, ("Lookaside - SrbData @ 0x%08p SgList @0x%08p Remove: @0x%08p\n",
  519. SrbDataLookasideList,
  520. MediumScatterGatherLookasideList,
  521. (RemoveTrackingLookasideListInitialized ?
  522. RemoveTrackingLookasideList : 0)));
  523. xdprintfEx(Depth, ("Resources - Raw: 0x%08p Translated: 0x%08p\n",
  524. AllocatedResources,
  525. TranslatedResources));
  526. xdprintfEx(Depth, ("Port Config %08p\n", PortConfig));
  527. xdprintfEx(Depth, ("DeviceMap Handles: Port %p Busses %p\n",
  528. PortDeviceMapKey, BusDeviceMapKeys));
  529. Depth--;
  530. ScsiDumpInterruptData(InterruptData,
  531. Detail,
  532. Depth);
  533. ScsiDumpAdapterPerfCounters(Address, Depth);
  534. ScsiDumpChildren(Address, Depth);
  535. return;
  536. }
  537. VOID
  538. ScsiDumpChildren(
  539. IN ULONG64 AdapterExtensionAddr,
  540. IN ULONG Depth
  541. )
  542. {
  543. ULONG i;
  544. ULONG64 realLun;
  545. ULONG64 realLuns[8];
  546. ULONG64 lun;
  547. UCHAR CurrentPnpState=0, PreviousPnpState=0;
  548. ULONG CurrentDeviceState=0;
  549. ULONG DesiredDeviceState=0, CurrentSystemState=0;
  550. ULONG64 DeviceObject=0, NextLogicalUnit=0;
  551. ULONG result;
  552. UCHAR PathId=0, TargetId=0, Lun=0;
  553. UCHAR IsClaimed=0, IsMissing=0, IsEnumerated=0, IsVisible=0, IsMismatched=0;
  554. ULONG64 b6, b7, b8;
  555. InitTypeRead(AdapterExtensionAddr, scsiport!_ADAPTER_EXTENSION);
  556. realLuns[0] = ReadField(LogicalUnitList[0].List);
  557. realLuns[1] = ReadField(LogicalUnitList[1].List);
  558. realLuns[2] = ReadField(LogicalUnitList[2].List);
  559. realLuns[3] = ReadField(LogicalUnitList[3].List);
  560. realLuns[4] = ReadField(LogicalUnitList[4].List);
  561. realLuns[5] = ReadField(LogicalUnitList[5].List);
  562. realLuns[6] = ReadField(LogicalUnitList[6].List);
  563. realLuns[7] = ReadField(LogicalUnitList[7].List);
  564. Depth++;
  565. for (i = 0; i < NUMBER_LOGICAL_UNIT_BINS; i++) {
  566. realLun = realLuns[i];
  567. while ((realLun != 0) && (!CheckControlC())) {
  568. FIELD_INFO deviceFields[] = {
  569. {"PathId", NULL, 0, COPY, 0, (PVOID) &PathId},
  570. {"TargetId", NULL, 0, COPY, 0, (PVOID) &TargetId},
  571. {"IsClaimed", NULL, 0, COPY, 0, (PVOID) &IsClaimed},
  572. {"IsMissing", NULL, 0, COPY, 0, (PVOID) &IsMissing},
  573. {"IsEnumerated", NULL, 0, COPY, 0, (PVOID) &IsEnumerated},
  574. {"IsVisible", NULL, 0, COPY, 0, (PVOID) &IsVisible},
  575. {"IsMismatched", NULL, 0, COPY, 0, (PVOID) &IsMismatched},
  576. {"DeviceObject", NULL, 0, COPY, 0, (PVOID) &DeviceObject},
  577. {"NextLogicalUnit", NULL, 0, COPY, 0, (PVOID) &NextLogicalUnit},
  578. {"CommonExtension.CurrentPnpState", NULL, 0, COPY, 0, (PVOID) &CurrentPnpState},
  579. {"CommonExtension.PreviousPnpState" , NULL, 0, COPY, 0, (PVOID) &PreviousPnpState},
  580. {"CommonExtension.CurrentDeviceState", NULL, 0, COPY, 0, (PVOID) &CurrentDeviceState},
  581. {"CommonExtension.DesiredDeviceState", NULL, 0, COPY, 0, (PVOID) &DesiredDeviceState},
  582. {"CommonExtension.CurrentSystemState", NULL, 0, COPY, 0, (PVOID) &CurrentSystemState},
  583. };
  584. SYM_DUMP_PARAM DevSym = {
  585. sizeof (SYM_DUMP_PARAM),
  586. "scsiport!_LOGICAL_UNIT_EXTENSION",
  587. DBG_DUMP_NO_PRINT,
  588. realLun,
  589. NULL, NULL, NULL,
  590. sizeof (deviceFields) / sizeof (FIELD_INFO),
  591. &deviceFields[0]
  592. };
  593. xdprintfEx(Depth, ("LUN "));
  594. dprintf("%08p ", realLun);
  595. if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) {
  596. dprintf("%08lx: Could not read device object\n", realLun);
  597. return;
  598. }
  599. result = (ULONG) InitTypeRead(realLun, scsiport!_LOGICAL_UNIT_EXTENSION);
  600. if (result != 0) {
  601. dprintf("could not init read type (%x)\n", result);
  602. return;
  603. }
  604. lun = ReadField(Lun);
  605. Lun = (UCHAR) lun;
  606. #if 0
  607. PathId = ReadField(PathId);
  608. TargetId = ReadField(TargetId);
  609. IsClaimed = ReadField(IsClaimed);
  610. IsMissing = ReadField(IsMissing);
  611. IsEnumerated = ReadField(IsEnumerated);
  612. IsVisible = ReadField(IsVisible);
  613. IsMismatched = ReadField(IsMismatched);
  614. #endif
  615. dprintf("@ (%3d,%3d,%3d) %c%c%c%c%c pnp(%02x/%02x) pow(%d%c,%d) DevObj %08p\n",
  616. PathId,
  617. TargetId,
  618. Lun,
  619. (IsClaimed ? 'c' : ' '),
  620. (IsMissing ? 'm' : ' '),
  621. (IsEnumerated ? 'e' : ' '),
  622. (IsVisible ? 'v' : ' '),
  623. (IsMismatched ? 'r' : ' '),
  624. CurrentPnpState,
  625. PreviousPnpState,
  626. CurrentDeviceState - 1,
  627. ((DesiredDeviceState == PowerDeviceUnspecified) ? ' ' : '*'),
  628. CurrentSystemState - 1,
  629. DeviceObject);
  630. realLun = ReadField(NextLogicalUnit);
  631. }
  632. }
  633. return;
  634. }
  635. VOID
  636. ScsiDumpInterruptData(
  637. IN ULONG64 Address,
  638. IN ULONG Detail,
  639. IN ULONG Depth
  640. )
  641. {
  642. ULONG result;
  643. ULONG NumOfFields;
  644. //
  645. // Architecture independent fields declarations.
  646. //
  647. //
  648. ULONG InterruptFlags;
  649. ULONG64 CompletedRequests;
  650. ULONG64 AddrOfCompletedRequests;
  651. ULONG64 ReadyLogicalUnit;
  652. ULONG64 WmiMiniPortRequests;
  653. FIELD_INFO deviceFields[] = {
  654. {"InterruptFlags", NULL, 0, COPY, 0, (PVOID) &InterruptFlags},
  655. {"ReadyLogicalUnit", NULL, 0, COPY, 0, (PVOID) &ReadyLogicalUnit},
  656. {"WmiMiniPortRequests", NULL, 0, COPY, 0, (PVOID) &WmiMiniPortRequests},
  657. {"CompletedRequests", NULL, 0, ADDROF, 0, NULL},
  658. };
  659. SYM_DUMP_PARAM DevSym = {
  660. sizeof (SYM_DUMP_PARAM),
  661. "scsiport!_INTERRUPT_DATA",
  662. DBG_DUMP_NO_PRINT,
  663. Address,
  664. NULL, NULL, NULL,
  665. sizeof (deviceFields) / sizeof (FIELD_INFO),
  666. &deviceFields[0]
  667. };
  668. //
  669. // Read in the top-level field data. Quit on failure.
  670. //
  671. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  672. if (result) {
  673. dprintf("error reading INTERRUPT_DATA @ %08p\n", Address);
  674. return;
  675. }
  676. //
  677. // Get address-of information.
  678. //
  679. NumOfFields = sizeof (deviceFields) / sizeof (FIELD_INFO);
  680. AddrOfCompletedRequests = deviceFields[NumOfFields-1].address;
  681. //
  682. // Do a separate get of the CompleteRequests field. This is necessary
  683. // because the typedump Ioctl doesn't like retreiving both the addr-of
  684. // and the data-of a field.
  685. //
  686. result = GetFieldData(Address,
  687. "scsiport!_INTERRUPT_DATA",
  688. "CompletedRequests",
  689. sizeof(ULONG64),
  690. &CompletedRequests
  691. );
  692. if (result) {
  693. dprintf("error (%08x): @ %s %d\n", result, __FILE__, __LINE__);
  694. return;
  695. }
  696. xdprintfEx(Depth, ("Interrupt Data @0x%08p:\n", Address));
  697. Depth++;
  698. DumpFlags(Depth, "Flags", InterruptFlags, AdapterFlags);
  699. xdprintfEx(Depth, ("Ready LUN 0x%08p Wmi Events 0x%08p\n",
  700. ReadyLogicalUnit,
  701. WmiMiniPortRequests));
  702. {
  703. ULONG count = 0;
  704. ULONG64 request = CompletedRequests;
  705. xdprintfEx(Depth, ("Completed Request List (@0x%08p): ",
  706. AddrOfCompletedRequests));
  707. Depth += 1;
  708. while((request != 0) && (!CheckControlC())) {
  709. ULONG64 CompletedRequests;
  710. if(Detail != 0) {
  711. if(count == 0) {
  712. dprintf("\n");
  713. }
  714. xdprintfEx(Depth, ("SrbData 0x%08p ", request));
  715. }
  716. count++;
  717. result = GetFieldData(request,
  718. "scsiport!_SRB_DATA",
  719. "CompletedRequests",
  720. sizeof(ULONG64),
  721. &CompletedRequests
  722. );
  723. if (result) {
  724. dprintf("error (%08x): @ %s %d\n", result, __FILE__, __LINE__);
  725. return;
  726. }
  727. if(Detail != 0) {
  728. ULONG64 CurrentSrb, CurrentIrp;
  729. result = GetFieldData(request,
  730. "scsiport!_SRB_DATA",
  731. "CurrentSrb",
  732. sizeof(ULONG64),
  733. &CurrentSrb
  734. );
  735. if (result) {
  736. dprintf("error (%08x): @ %s %d\n", result, __FILE__, __LINE__);
  737. return;
  738. }
  739. result = GetFieldData(request,
  740. "scsiport!_SRB_DATA",
  741. "CurrentIrp",
  742. sizeof(ULONG64),
  743. &CurrentIrp
  744. );
  745. if (result) {
  746. dprintf("error (%08x): @ %s %d\n", result, __FILE__, __LINE__);
  747. return;
  748. }
  749. dprintf("Srb 0x%08p Irp 0x%08p\n",
  750. CurrentSrb,
  751. CurrentIrp);
  752. }
  753. request = CompletedRequests;
  754. }
  755. Depth -= 1;
  756. if((Detail == 0) || (count == 0)) {
  757. dprintf("%d entries\n", count);
  758. } else {
  759. xdprintfEx(Depth + 1, ("%d entries\n", count));
  760. }
  761. }
  762. return;
  763. }
  764. VOID
  765. ScsiDumpPdo(
  766. IN ULONG64 LunAddress,
  767. IN ULONG Detail,
  768. IN ULONG Depth
  769. )
  770. {
  771. ULONG result;
  772. ULONG Fields;
  773. UCHAR PathId;
  774. UCHAR TargetId;
  775. UCHAR Lun;
  776. ULONG PortNumber;
  777. UCHAR IsClaimed;
  778. UCHAR IsMissing;
  779. UCHAR IsEnumerated;
  780. UCHAR IsVisible;
  781. UCHAR IsMismatched;
  782. ULONG LunLuFlags;
  783. UCHAR RetryCount;
  784. ULONG CurrentKey;
  785. ULONG QueueLockCount;
  786. ULONG QueuePauseCount;
  787. ULONG64 HwLogicalUnitExtension;
  788. ULONG64 AdapterExtension;
  789. LONG RequestTimeoutCounter;
  790. ULONG64 NextLogicalUnit;
  791. ULONG64 ReadyLogicalUnit;
  792. ULONG64 PendingRequest;
  793. ULONG64 BusyRequest;
  794. ULONG64 CurrentUntaggedRequest;
  795. ULONG64 CompletedAbort;
  796. ULONG64 AbortSrb;
  797. ULONG QueueCount;
  798. ULONG MaxQueueDepth;
  799. ULONG64 TargetDeviceMapKey;
  800. ULONG64 LunDeviceMapKey;
  801. ULONG64 ActiveFailedRequest;
  802. ULONG64 BlockedFailedRequest;
  803. ULONG64 RequestSenseIrp;
  804. ULONG64 BypassSrbDataList_Next;
  805. ULONG64 RequestList_Flink;
  806. ULONG64 CommonExtension_DeviceObject;
  807. ULONG64 AddrOf_InquiryData;
  808. ULONG64 AddrOf_RequestSenseSrb;
  809. ULONG64 AddrOf_RequestSenseMdl;
  810. ULONG64 AddrOf_BypassSrbDataBlocks;
  811. ULONG64 AddrOf_RequestList;
  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. return;
  976. }
  977. VOID
  978. ScsiDumpActiveRequests(
  979. IN ULONG64 ListHead,
  980. IN ULONG TickCount,
  981. IN ULONG Depth
  982. )
  983. {
  984. ULONG result;
  985. ULONG64 lastEntry = 0;
  986. ULONG64 entry = 0;
  987. ULONG64 realEntry = 0;
  988. ULONG64 CurrentSrb = 0;
  989. ULONG64 CurrentIrp = 0;
  990. ULONG64 RequestList = 0;
  991. ULONG OffsetOfRequestList = 0;
  992. ULONG SrbTickCount = 0;
  993. ULONG Key = 0;
  994. FIELD_INFO deviceFields[] = {
  995. {"CurrentSrb", NULL, 0, COPY, 0, (PVOID) &CurrentSrb},
  996. {"CurrentIrp", NULL, 0, COPY, 0, (PVOID) &CurrentIrp},
  997. {"TickCount", NULL, 0, COPY, 0, (PVOID) &SrbTickCount},
  998. {"RequestList", NULL, 0, ADDROF, 0, NULL},
  999. };
  1000. SYM_DUMP_PARAM DevSym = {
  1001. sizeof (SYM_DUMP_PARAM),
  1002. "scsiport!_SRB_DATA",
  1003. DBG_DUMP_NO_PRINT,
  1004. 0,
  1005. NULL, NULL, NULL,
  1006. sizeof (deviceFields) / sizeof (FIELD_INFO),
  1007. &deviceFields[0]
  1008. };
  1009. result = GetFieldOffset("scsiport!_SRB_DATA",
  1010. "RequestList",
  1011. &OffsetOfRequestList);
  1012. if (result) {
  1013. dprintf("failed to get offset of request list (%08X)\n", result);
  1014. return;
  1015. }
  1016. entry = ListHead;
  1017. realEntry = entry;
  1018. InitTypeRead(ListHead, nt!_LIST_ENTRY);
  1019. lastEntry = ReadField(Blink);
  1020. xdprintfEx(Depth, ("Tick count is %d\n", TickCount));
  1021. do {
  1022. ULONG64 realSrbData;
  1023. ULONG result;
  1024. GetFieldData(realEntry,
  1025. "scsiport!_LIST_ENTRY",
  1026. "Flink",
  1027. sizeof(ULONG64),
  1028. &entry);
  1029. //
  1030. // entry points to the list entry element of the srb data. Calculate
  1031. // the address of the start of the srb data block.
  1032. //
  1033. realSrbData = entry - OffsetOfRequestList;
  1034. xdprintfEx(Depth, ("SrbData %08p ", realSrbData));
  1035. //
  1036. // Read the SRB_DATA information we need.
  1037. //
  1038. DevSym.addr = realSrbData;
  1039. if ((Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size))) {
  1040. dprintf("%08p: Could not read device object\n", realSrbData);
  1041. return;
  1042. }
  1043. RequestList = deviceFields[3].address;
  1044. InitTypeRead(CurrentSrb, scsiport!_SCSI_REQUEST_BLOCK);
  1045. Key = (ULONG)ReadField(QueueSortKey);
  1046. //
  1047. // Update realEntry.
  1048. //
  1049. realEntry = RequestList;
  1050. dprintf("Srb %08p Irp %08p Key %x %s\n",
  1051. CurrentSrb,
  1052. CurrentIrp,
  1053. Key,
  1054. SecondsToString(TickCount - SrbTickCount));
  1055. } while((entry != lastEntry) && (!CheckControlC()));
  1056. return;
  1057. }
  1058. VOID
  1059. ScsiDumpLocks(
  1060. ULONG64 CommonExtension,
  1061. ULONG Depth
  1062. )
  1063. /*++
  1064. Routine Description:
  1065. dumps the remove locks for a given device object
  1066. Arguments:
  1067. CommonExtension - a pointer to the local copy of the device object
  1068. common extension
  1069. Return Value:
  1070. None
  1071. --*/
  1072. {
  1073. ULONG result;
  1074. LONG RemoveLock;
  1075. ULONG64 RemoveTrackingSpinlock;
  1076. ULONG64 RemoveTrackingList;
  1077. InitTypeRead(CommonExtension, scsiport!_COMMON_EXTENSION);
  1078. RemoveLock = (ULONG) ReadField(RemoveLock);
  1079. RemoveTrackingSpinlock = ReadField(RemoveTrackingSpinlock);
  1080. RemoveTrackingList = ReadField(RemoveTrackingList);
  1081. xdprintfEx(Depth, ("RemoveLock count is %d", RemoveLock));
  1082. if((PVOID)RemoveTrackingSpinlock != (PVOID)-1) {
  1083. ULONG64 lockEntryAddress = RemoveTrackingList;
  1084. dprintf(":\n");
  1085. Depth++;
  1086. if(RemoveTrackingSpinlock != 0) {
  1087. xdprintfEx(Depth, ("RemoveTrackingList is in intermediate state"
  1088. "@ %p\n", RemoveTrackingList));
  1089. return;
  1090. }
  1091. while((lockEntryAddress != 0L) && !CheckControlC()) {
  1092. UCHAR buffer[512];
  1093. ULONG64 File;
  1094. ULONG64 Tag;
  1095. ULONG64 NextBlock;
  1096. ULONG Line;
  1097. InitTypeRead(lockEntryAddress, scsiport!REMOVE_TRACKING_BLOCK);
  1098. File = ReadField(File);
  1099. Tag = ReadField(Tag);
  1100. Line = (ULONG) ReadField(Line);
  1101. NextBlock = ReadField(NextBlock);
  1102. result = sizeof(buffer);
  1103. if(!GetAnsiString(File,
  1104. buffer,
  1105. &result)) {
  1106. xdprintfEx(Depth, ("Tag 0x%p File 0x%p Line %d\n",
  1107. Tag,
  1108. File,
  1109. Line));
  1110. } else {
  1111. PUCHAR name;
  1112. name = &buffer[result];
  1113. while((result > 0) &&
  1114. (*(name - 1) != '\\') &&
  1115. (*(name - 1) != '/') &&
  1116. (!CheckControlC())) {
  1117. name--;
  1118. result--;
  1119. }
  1120. xdprintfEx(Depth, ("Tag 0x%p File %s Line %d\n",
  1121. Tag,
  1122. name,
  1123. Line));
  1124. }
  1125. lockEntryAddress = NextBlock;
  1126. }
  1127. } else {
  1128. dprintf(" (not tracked on free build)\n");
  1129. }
  1130. return;
  1131. }
  1132. VOID
  1133. ScsiDumpSrbData(
  1134. ULONG64 SrbData,
  1135. ULONG Depth
  1136. )
  1137. {
  1138. ULONG result;
  1139. CSHORT Type;
  1140. ULONG64 LogicalUnit;
  1141. ULONG64 CurrentSrb;
  1142. ULONG64 CurrentIrp;
  1143. ULONG64 RequestSenseSave;
  1144. ULONG QueueTag;
  1145. ULONG64 CompletedRequests;
  1146. ULONG ErrorLogRetryCount;
  1147. ULONG SequenceNumber;
  1148. ULONG Flags;
  1149. ULONG64 RequestListFlink;
  1150. ULONG64 RequestListBlink;
  1151. ULONG64 DataOffset;
  1152. ULONG64 OriginalDataBuffer;
  1153. ULONG64 MapRegisterBase;
  1154. ULONG NumberOfMapRegisters;
  1155. ULONG64 ScatterGatherList;
  1156. FIELD_INFO deviceFields[] = {
  1157. {"Type", NULL, 0, COPY, 0, (PVOID) &Type},
  1158. {"LogicalUnit", NULL, 0, COPY, 0, (PVOID) &LogicalUnit},
  1159. {"CurrentSrb", NULL, 0, COPY, 0, (PVOID) &CurrentSrb},
  1160. {"CurrentIrp", NULL, 0, COPY, 0, (PVOID) &CurrentIrp},
  1161. {"RequestSenseSave", NULL, 0, COPY, 0, (PVOID) &RequestSenseSave},
  1162. {"QueueTag", NULL, 0, COPY, 0, (PVOID) &QueueTag},
  1163. {"CompletedRequests", NULL, 0, COPY, 0, (PVOID) &CompletedRequests},
  1164. {"ErrorLogRetryCount", NULL, 0, COPY, 0, (PVOID) &ErrorLogRetryCount},
  1165. {"SequenceNumber", NULL, 0, COPY, 0, (PVOID) &SequenceNumber},
  1166. {"Flags", NULL, 0, COPY, 0, (PVOID) &Flags},
  1167. {"RequestList.Flink", NULL, 0, COPY, 0, (PVOID) &RequestListFlink},
  1168. {"RequestList.Blink", NULL, 0, COPY, 0, (PVOID) &RequestListBlink},
  1169. {"DataOffset", NULL, 0, COPY, 0, (PVOID) &DataOffset},
  1170. {"OriginalDataBuffer", NULL, 0, COPY, 0, (PVOID) &OriginalDataBuffer},
  1171. {"MapRegisterBase", NULL, 0, COPY, 0, (PVOID) &MapRegisterBase},
  1172. {"NumberOfMapRegisters", NULL, 0, COPY, 0, (PVOID) &NumberOfMapRegisters},
  1173. {"ScatterGatherList", NULL, 0, COPY, 0, (PVOID) &ScatterGatherList},
  1174. };
  1175. SYM_DUMP_PARAM DevSym = {
  1176. sizeof (SYM_DUMP_PARAM),
  1177. "scsiport!_SRB_DATA",
  1178. DBG_DUMP_NO_PRINT,
  1179. SrbData,
  1180. NULL, NULL, NULL,
  1181. sizeof (deviceFields) / sizeof (FIELD_INFO),
  1182. &deviceFields[0]
  1183. };
  1184. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  1185. if (result) {
  1186. SCSIKD_PRINT_ERROR(result);
  1187. return;
  1188. }
  1189. if(Type != SRB_DATA_TYPE) {
  1190. dprintf("Type (%#x) does not match SRB_DATA_TYPE (%#x)\n",
  1191. Type, SRB_DATA_TYPE);
  1192. }
  1193. xdprintfEx(Depth, ("Lun 0x%p Srb 0x%p Irp 0x%p\n",
  1194. LogicalUnit, CurrentSrb, CurrentIrp));
  1195. xdprintfEx(Depth, ("Sense 0x%p Tag 0x%08lx Next Completed 0x%p\n",
  1196. RequestSenseSave,
  1197. QueueTag, CompletedRequests));
  1198. xdprintfEx(Depth, ("Retry 0x%02x Seq 0x%08lx Flags 0x%08lx\n",
  1199. ErrorLogRetryCount, SequenceNumber,
  1200. Flags));
  1201. xdprintfEx(Depth, ("Request List: Next 0x%p Previous 0x%p\n",
  1202. RequestListFlink, RequestListBlink));
  1203. xdprintfEx(Depth, ("Data Offset 0x%p Original Data Buffer 0x%p\n", DataOffset, OriginalDataBuffer));
  1204. xdprintfEx(Depth, ("Map Registers 0x%p (0x%02x) SG List 0x%p\n",
  1205. MapRegisterBase,
  1206. NumberOfMapRegisters,
  1207. ScatterGatherList));
  1208. if(ScatterGatherList != 0) {
  1209. ScsiDumpScatterGatherList(ScatterGatherList,
  1210. NumberOfMapRegisters,
  1211. Depth + 1);
  1212. }
  1213. return;
  1214. }
  1215. VOID
  1216. ScsiDumpScatterGatherList(
  1217. ULONG64 List,
  1218. ULONG Entries,
  1219. ULONG Depth
  1220. )
  1221. {
  1222. ULONG result;
  1223. ULONG i;
  1224. ULONG start = TRUE;
  1225. ULONG64 PhysicalAddress;
  1226. ULONG Length;
  1227. for(i = 0; i < Entries; i++) {
  1228. InitTypeRead(List, nt!_SCATTER_GATHER_ELEMENT);
  1229. PhysicalAddress = ReadField(Address);
  1230. Length = (ULONG) ReadField(Length);
  1231. if(start) {
  1232. xdprintfEx(Depth, ("0x%016I64x (0x%08lx), ",
  1233. PhysicalAddress,
  1234. Length));
  1235. } else {
  1236. dprintf("0x%016I64x (0x%08lx),\n",
  1237. PhysicalAddress,
  1238. Length);
  1239. }
  1240. start = !start;
  1241. List += (IsPtr64() != 0) ? 0x18 : 0xc;
  1242. }
  1243. if(!start) {
  1244. dprintf("\n");
  1245. }
  1246. }
  1247. DECLARE_API(srbdata)
  1248. {
  1249. ULONG64 address;
  1250. GetAddress(args, &address);
  1251. dprintf("SrbData structure at %#p\n", address);
  1252. ScsiDumpSrbData(address, 1);
  1253. return S_OK;
  1254. }
  1255. VOID
  1256. ScsiDumpAdapterPerfCounters(
  1257. ULONG64 Adapter,
  1258. ULONG Depth
  1259. )
  1260. {
  1261. #if TEST_LISTS
  1262. ULONG result;
  1263. ULONG SmallAllocationCount;
  1264. ULONG LargeAllocationCount;
  1265. ULONG64 ScatterGatherAllocationCount;
  1266. ULONG64 SmallAllocationSize;
  1267. ULONG64 MediumAllocationSize;
  1268. ULONG64 LargeAllocationSize;
  1269. ULONG64 SrbDataAllocationCount;
  1270. ULONG64 SrbDataResurrectionCount;
  1271. ULONG64 SrbDataEmergencyFreeCount;
  1272. FIELD_INFO deviceFields[] = {
  1273. {"SmallAllocationCount", NULL, 0, COPY, 0, (PVOID) &SmallAllocationCount},
  1274. {"LargeAllocationCount", NULL, 0, COPY, 0, (PVOID) &LargeAllocationCount},
  1275. {"ScatterGatherAllocationCount", NULL, 0, COPY, 0, (PVOID) &ScatterGatherAllocationCount},
  1276. {"SmallAllocationSize", NULL, 0, COPY, 0, (PVOID) &SmallAllocationSize},
  1277. {"MediumAllocationSize", NULL, 0, COPY, 0, (PVOID) &MediumAllocationSize},
  1278. {"LargeAllocationSize", NULL, 0, COPY, 0, (PVOID) &LargeAllocationSize},
  1279. {"SrbDataAllocationCount", NULL, 0, COPY, 0, (PVOID) &SrbDataAllocationCount},
  1280. {"SrbDataResurrectionCount", NULL, 0, COPY, 0, (PVOID) &SrbDataResurrectionCount},
  1281. {"SrbDataEmergencyFreeCount", NULL, 0, COPY, 0, (PVOID) &SrbDataEmergencyFreeCount},
  1282. };
  1283. SYM_DUMP_PARAM DevSym = {
  1284. sizeof (SYM_DUMP_PARAM),
  1285. "scsiport!_ADAPTER_EXTENSION",
  1286. DBG_DUMP_NO_PRINT,
  1287. Adapter,
  1288. NULL, NULL, NULL,
  1289. sizeof (deviceFields) / sizeof (FIELD_INFO),
  1290. &deviceFields[0]
  1291. };
  1292. result = Ioctl(IG_DUMP_SYMBOL_INFO, &DevSym, DevSym.size);
  1293. if (result) {
  1294. SCSIKD_PRINT_ERROR(result);
  1295. return;
  1296. }
  1297. ULONG mediumAllocationCount = (ULONG)
  1298. (ScatterGatherAllocationCount -
  1299. (SmallAllocationCount +
  1300. LargeAllocationCount));
  1301. double average;
  1302. xdprintfEx(Depth, ("Performance Counters:\n"));
  1303. Depth++;
  1304. xdprintfEx(Depth, ("SGList Allocs - "));
  1305. dprintf("Small: %d, ", SmallAllocationCount);
  1306. dprintf("Med: %d, ",
  1307. (ScatterGatherAllocationCount -
  1308. SmallAllocationCount -
  1309. LargeAllocationCount));
  1310. dprintf("Large: %d, ", LargeAllocationCount);
  1311. dprintf("Total: %I64d\n",
  1312. ScatterGatherAllocationCount);
  1313. xdprintfEx(Depth, ("Average SG Entries - "));
  1314. if(SmallAllocationCount != 0) {
  1315. average = ((double) (SmallAllocationSize)) / SmallAllocationCount;
  1316. dprintf("Small: %.2f ", average);
  1317. }
  1318. if(mediumAllocationCount != 0) {
  1319. average = ((double) (MediumAllocationSize)) / mediumAllocationCount;
  1320. dprintf("Medium: %.2f ", average);
  1321. }
  1322. if(Adapter->LargeAllocationCount != 0) {
  1323. average = ((double) (Adapter->LargeAllocationSize)) / LargeAllocationCount;
  1324. dprintf("Large: %.2f", average);
  1325. }
  1326. dprintf("\n");
  1327. xdprintfEx(Depth, ("SrbData - Allocs: %I64d, ",
  1328. SrbDataAllocationCount));
  1329. dprintf("Resurrected: %I64d, ",
  1330. SrbDataResurrectionCount);
  1331. dprintf("Timer Serviced: %I64d,\n",
  1332. SrbDataServicedFromTickHandlerCount);
  1333. xdprintfEx(Depth, (" Queued: %I64d, ",
  1334. SrbDataQueueInsertionCount));
  1335. dprintf("Emergency Freed: %I64d\n",
  1336. SrbDataEmergencyFreeCount);
  1337. #endif
  1338. return;
  1339. }
  1340. PUCHAR
  1341. SecondsToString(
  1342. ULONG Count
  1343. )
  1344. {
  1345. static UCHAR string[64] = "";
  1346. UCHAR tmp[16];
  1347. ULONG seconds = 0;
  1348. ULONG minutes = 0;
  1349. ULONG hours = 0;
  1350. ULONG days = 0;
  1351. string[0] = '\0';
  1352. if(Count == 0) {
  1353. sprintf(string, "<1s");
  1354. return string;
  1355. }
  1356. seconds = Count % 60;
  1357. Count /= 60;
  1358. if(Count != 0) {
  1359. minutes = Count % 60;
  1360. Count /= 60;
  1361. }
  1362. if(Count != 0) {
  1363. hours = Count % 24;
  1364. Count /= 24;
  1365. }
  1366. if(Count != 0) {
  1367. days = Count;
  1368. }
  1369. if(days != 0) {
  1370. sprintf(tmp, "%dd", days);
  1371. strcat(string, tmp);
  1372. }
  1373. if(hours != 0) {
  1374. sprintf(tmp, "%dh", hours);
  1375. strcat(string, tmp);
  1376. }
  1377. if(minutes != 0) {
  1378. sprintf(tmp, "%dm", minutes);
  1379. strcat(string, tmp);
  1380. }
  1381. if(seconds != 0) {
  1382. sprintf(tmp, "%ds", seconds);
  1383. strcat(string, tmp);
  1384. }
  1385. return string;
  1386. }
  1387. VOID
  1388. ScsiDumpQueuedRequests(
  1389. IN ULONG64 DeviceObject,
  1390. IN ULONG TickCount,
  1391. IN ULONG Depth
  1392. )
  1393. {
  1394. ULONG result;
  1395. ULONG64 ListHeadFlink;
  1396. ULONG64 ListHeadBlink;
  1397. ULONG64 DeviceListHead;
  1398. ULONG64 realEntry;
  1399. //
  1400. // Get the address of the head of the device list in the device queue.
  1401. //
  1402. result = GetFieldData(
  1403. DeviceObject,
  1404. "scsiport!_DEVICE_OBJECT",
  1405. "DeviceQueue.DeviceListHead",
  1406. sizeof(ULONG64),
  1407. &DeviceListHead);
  1408. if (result) {
  1409. SCSIKD_PRINT_ERROR(result);
  1410. return;
  1411. }
  1412. //
  1413. // Get the forward and backward link fields from the list head. If
  1414. // the queue is empty, we're done.
  1415. //
  1416. InitTypeRead(DeviceListHead, scsiport!_LIST_ENTRY);
  1417. ListHeadFlink = ReadField(CurrentSrb);
  1418. ListHeadBlink = ReadField(CurrentIrp);
  1419. if (ListHeadFlink == ListHeadBlink) {
  1420. xdprintfEx(Depth, ("Device Queue is empty\n"));
  1421. return;
  1422. }
  1423. //
  1424. // Initialize a pointer the head of the list.
  1425. //
  1426. realEntry = DeviceListHead;
  1427. do {
  1428. ULONG result;
  1429. ULONG64 realIrp;
  1430. ULONG64 realStack;
  1431. ULONG64 realSrb;
  1432. ULONG64 realSrbData;
  1433. ULONG64 CurrentSrb;
  1434. ULONG64 CurrentIrp;
  1435. ULONG OffsetOfDeviceListEntry;
  1436. ULONG SrbDataTickCount;
  1437. //
  1438. // Get the address of the next entry in the queue.
  1439. //
  1440. result = GetFieldData(realEntry,
  1441. "scsiport!_LIST_ENTRY",
  1442. "Flink",
  1443. sizeof(ULONG64),
  1444. &realEntry);
  1445. if (result) {
  1446. SCSIKD_PRINT_ERROR(result);
  1447. break;
  1448. }
  1449. //
  1450. // We to calculate the address of the IRP using the address of the
  1451. // list entry. Can't use static CONTAINING_RECORD; we need a runtime
  1452. // equivalent. So we use type info to get the offset of the list
  1453. // entry and calculate the address of the beginning of the IRP. This
  1454. // makes the extension work for 32b and 64b debuggees.
  1455. //
  1456. result = GetFieldOffset(
  1457. "scsiport!_IRP",
  1458. "Tail.Overlay.DeviceQueueEntry.DeviceListEntry",
  1459. &OffsetOfDeviceListEntry);
  1460. if (result) {
  1461. SCSIKD_PRINT_ERROR(result);
  1462. break;
  1463. }
  1464. realIrp = realEntry - OffsetOfDeviceListEntry;
  1465. //
  1466. // Now we need to read in the address of the current IO stack
  1467. // location.
  1468. //
  1469. result = GetFieldData(
  1470. realIrp,
  1471. "scsiport!_IRP",
  1472. "Tail.Overlay.CurrentStackLocation",
  1473. sizeof(ULONG64),
  1474. &realStack);
  1475. if (result) {
  1476. SCSIKD_PRINT_ERROR(result);
  1477. break;
  1478. }
  1479. //
  1480. // Load the SRB field of the stack location.
  1481. //
  1482. result = GetFieldData(
  1483. realStack,
  1484. "scsiport!_IO_STACK_LOCATION",
  1485. "Parameters.Scsi.Srb",
  1486. sizeof(ULONG64),
  1487. &realSrb);
  1488. if (result) {
  1489. SCSIKD_PRINT_ERROR(result);
  1490. break;
  1491. }
  1492. //
  1493. // Pick out the pointer to the srb data and read that in.
  1494. //
  1495. result = GetFieldData(
  1496. realSrb,
  1497. "scsiport!_SCSI_REQUEST_BLOCK",
  1498. "OriginalRequest",
  1499. sizeof(ULONG64),
  1500. &realSrbData);
  1501. if (result) {
  1502. SCSIKD_PRINT_ERROR(result);
  1503. break;
  1504. }
  1505. xdprintfEx(Depth, ("SrbData 0x%p ", realSrbData));
  1506. //
  1507. // Read the SRB_DATA information we need.
  1508. //
  1509. InitTypeRead(realSrb, scsiport!_SRB_DATA);
  1510. CurrentSrb = ReadField(CurrentSrb);
  1511. CurrentIrp = ReadField(CurrentIrp);
  1512. SrbDataTickCount = (ULONG)ReadField(TickCount);
  1513. dprintf("Srb 0x%p Irp 0x%p %s\n",
  1514. CurrentSrb,
  1515. CurrentIrp,
  1516. SecondsToString(TickCount - SrbDataTickCount));
  1517. } while((realEntry != ListHeadBlink) && (!CheckControlC()));
  1518. return;
  1519. }