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.

500 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. DBG.C
  5. Abstract:
  6. This module contains debug only code for USB Hub driver
  7. Author:
  8. jdunn
  9. Environment:
  10. kernel mode only
  11. Notes:
  12. Revision History:
  13. 11-5-96 : created
  14. --*/
  15. #include <wdm.h>
  16. #ifdef WMI_SUPPORT
  17. #include <wmilib.h>
  18. #endif /* WMI_SUPPORT */
  19. #include "stdarg.h"
  20. #include "stdio.h"
  21. #include "usbhub.h"
  22. #ifdef MAX_DEBUG
  23. #define DEBUG_HEAP
  24. #endif
  25. typedef struct _HEAP_TAG_BUFFER {
  26. ULONG Sig;
  27. ULONG Length;
  28. } HEAP_TAG_BUFFER, *PHEAP_TAG_BUFFER;
  29. #if DBG
  30. // this flag causes us to write a ' in the format string
  31. // so that the string goes to the NTKERN buffer
  32. // this trick causes problems with driver verifier on NT
  33. // and the trace buffer isn't in NT anyway
  34. ULONG USBH_W98_Debug_Trace =
  35. #ifdef NTKERN_TRACE
  36. 1;
  37. #else
  38. 0;
  39. #endif
  40. VOID
  41. USBH_Assert(
  42. IN PVOID FailedAssertion,
  43. IN PVOID FileName,
  44. IN ULONG LineNumber,
  45. IN PCHAR Message
  46. )
  47. /*++
  48. Routine Description:
  49. Debug Assert function.
  50. Arguments:
  51. DeviceObject - pointer to a device object
  52. Irp - pointer to an I/O Request Packet
  53. Return Value:
  54. --*/
  55. {
  56. #ifdef NTKERN
  57. // this makes the compiler generate a ret
  58. ULONG stop = 1;
  59. assert_loop:
  60. #endif
  61. // just call the NT assert function and stop
  62. // in the debugger.
  63. RtlAssert( FailedAssertion, FileName, LineNumber, Message );
  64. // loop here to prevent users from going past
  65. // are assert before we can look at it
  66. #ifdef NTKERN
  67. DBGBREAK();
  68. if (stop) {
  69. goto assert_loop;
  70. }
  71. #endif
  72. return;
  73. }
  74. ULONG
  75. _cdecl
  76. USBH_KdPrintX(
  77. ULONG l,
  78. PCH Format,
  79. ...
  80. )
  81. {
  82. va_list list;
  83. int i;
  84. int arg[6];
  85. if (USBH_Debug_Trace_Level >= l) {
  86. if (l <= 1) {
  87. if (USBH_W98_Debug_Trace) {
  88. //override trace buffer
  89. #ifdef USBHUB20
  90. DbgPrint("USBHUB20.SYS: ");
  91. #else
  92. DbgPrint("USBHUB.SYS: ");
  93. #endif
  94. *Format = ' ';
  95. } else {
  96. #ifdef USBHUB20
  97. DbgPrint("USBHUB20.SYS: ");
  98. #else
  99. DbgPrint("USBHUB.SYS: ");
  100. #endif
  101. }
  102. } else {
  103. #ifdef USBHUB20
  104. DbgPrint("USBHUB20.SYS: ");
  105. #else
  106. DbgPrint("USBHUB.SYS: ");
  107. #endif
  108. }
  109. va_start(list, Format);
  110. for (i=0; i<6; i++)
  111. arg[i] = va_arg(list, int);
  112. DbgPrint(Format, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
  113. }
  114. return 0;
  115. }
  116. VOID
  117. UsbhWarning(
  118. PDEVICE_EXTENSION_PORT DeviceExtensionPort,
  119. PUCHAR Message,
  120. BOOLEAN DebugBreak
  121. )
  122. {
  123. DbgPrint("USBHUB: Warning **************************************************************\n");
  124. if (DeviceExtensionPort) {
  125. DbgPrint("Device PID %04.4x, VID %04.4x\n",
  126. DeviceExtensionPort->DeviceDescriptor.idProduct,
  127. DeviceExtensionPort->DeviceDescriptor.idVendor);
  128. }
  129. DbgPrint("%s", Message);
  130. DbgPrint("******************************************************************************\n");
  131. if (DebugBreak) {
  132. DBGBREAK();
  133. }
  134. }
  135. VOID
  136. UsbhInfo(
  137. PDEVICE_EXTENSION_HUB DeviceExtensionHub
  138. )
  139. {
  140. PUSB_HUB_DESCRIPTOR hubDescriptor;
  141. ULONG i;
  142. hubDescriptor = DeviceExtensionHub->HubDescriptor;
  143. USBH_KdPrint((1, "'*****************************************************\n"));
  144. if (USBH_HubIsBusPowered(DeviceExtensionHub->FunctionalDeviceObject,
  145. DeviceExtensionHub->ConfigurationDescriptor)) {
  146. USBH_KdPrint((1, "'*** Hub VID %04.4x PID %04.4x is BUS POWERED \n",
  147. DeviceExtensionHub->DeviceDescriptor.idVendor,
  148. DeviceExtensionHub->DeviceDescriptor.idProduct));
  149. } else {
  150. USBH_KdPrint((1, "'*** Hub VID %04.4x PID %04.4x is SELF POWERED \n",
  151. DeviceExtensionHub->DeviceDescriptor.idVendor,
  152. DeviceExtensionHub->DeviceDescriptor.idProduct));
  153. }
  154. USBH_KdPrint((1, "'*** has %d ports\n",
  155. hubDescriptor->bNumberOfPorts));
  156. if (HUB_IS_GANG_POWER_SWITCHED(hubDescriptor->wHubCharacteristics)) {
  157. USBH_KdPrint((1,"'*** is 'gang power switched'\n"));
  158. } else if (HUB_IS_NOT_POWER_SWITCHED(hubDescriptor->wHubCharacteristics)) {
  159. USBH_KdPrint((1,"'*** is 'not power switched'\n"));
  160. } else if (HUB_IS_PORT_POWER_SWITCHED(hubDescriptor->wHubCharacteristics)) {
  161. USBH_KdPrint((1,"'*** is 'port power switched'\n"));
  162. } else {
  163. TEST_TRAP();
  164. }
  165. for (i=0; i< hubDescriptor->bNumberOfPorts; i++) {
  166. if (PORT_ALWAYS_POWER_SWITCHED(hubDescriptor, i+1)) {
  167. USBH_KdPrint((1,"'*** port (%d) is power switched\n", i+1));
  168. }
  169. if (PORT_DEVICE_NOT_REMOVABLE(hubDescriptor, i+1)) {
  170. USBH_KdPrint((1,"'*** port (%d) device is not removable\n", i+1));
  171. }
  172. }
  173. USBH_KdPrint((1, "'*****************************************************\n"));
  174. }
  175. PVOID
  176. UsbhGetHeap(
  177. IN POOL_TYPE PoolType,
  178. IN ULONG NumberOfBytes,
  179. IN ULONG Signature,
  180. IN PLONG TotalAllocatedHeapSpace
  181. )
  182. /*++
  183. Routine Description:
  184. Debug routine, used to debug heap problems. We are using this since
  185. most NT debug functions are not supported by NTKERN.
  186. Arguments:
  187. PoolType - pool type passed to ExAllocatePool
  188. NumberOfBytes - number of bytes for item
  189. Signature - four byte signature supplied by caller
  190. TotalAllocatedHeapSpace - pointer to variable where client stores
  191. the total accumulated heap space allocated.
  192. Return Value:
  193. pointer to allocated memory
  194. --*/
  195. {
  196. PUCHAR p;
  197. #ifdef DEBUG_HEAP
  198. PHEAP_TAG_BUFFER tagBuffer;
  199. // we call ExAllocatePoolWithTag but no tag will be added
  200. // when running under NTKERN
  201. p = (PUCHAR) ExAllocatePoolWithTag(PoolType,
  202. NumberOfBytes + sizeof(HEAP_TAG_BUFFER)*2,
  203. Signature);
  204. if (p) {
  205. tagBuffer = (PHEAP_TAG_BUFFER) p;
  206. tagBuffer->Sig = Signature;
  207. tagBuffer->Length = NumberOfBytes;
  208. p += sizeof(HEAP_TAG_BUFFER);
  209. *TotalAllocatedHeapSpace += NumberOfBytes;
  210. tagBuffer = (PHEAP_TAG_BUFFER) (p + NumberOfBytes);
  211. tagBuffer->Sig = Signature;
  212. tagBuffer->Length = NumberOfBytes;
  213. }
  214. // LOGENTRY(LOG_MISC, (PUCHAR) &Signature, 0, 0, 0);
  215. // LOGENTRY(LOG_MISC, "GetH", p, NumberOfBytes, stk[1] & 0x00FFFFFF);
  216. #else
  217. p = (PUCHAR) ExAllocatePoolWithTag(PoolType,
  218. NumberOfBytes,
  219. Signature);
  220. #endif /* DEBUG_HEAP */
  221. return p;
  222. }
  223. VOID
  224. UsbhRetHeap(
  225. IN PVOID P,
  226. IN ULONG Signature,
  227. IN PLONG TotalAllocatedHeapSpace
  228. )
  229. /*++
  230. Routine Description:
  231. Debug routine, used to debug heap problems. We are using this since
  232. most NT debug functions are not supported by NTKERN.
  233. Arguments:
  234. P - pointer to free
  235. Return Value:
  236. none.
  237. --*/
  238. {
  239. #ifdef DEBUG_HEAP
  240. PHEAP_TAG_BUFFER endTagBuffer;
  241. PHEAP_TAG_BUFFER beginTagBuffer;
  242. USBH_ASSERT(P != 0);
  243. beginTagBuffer = (PHEAP_TAG_BUFFER) ((PUCHAR)P - sizeof(HEAP_TAG_BUFFER));
  244. endTagBuffer = (PHEAP_TAG_BUFFER) ((PUCHAR)P + beginTagBuffer->Length);
  245. *TotalAllocatedHeapSpace -= beginTagBuffer->Length;
  246. // LOGENTRY(LOG_MISC, (PUCHAR) &Signature, 0, 0, 0);
  247. // LOGENTRY(LOG_MISC, "RetH", P, tagBuffer->Length, stk[1] & 0x00FFFFFF);
  248. USBH_ASSERT(*TotalAllocatedHeapSpace >= 0);
  249. USBH_ASSERT(beginTagBuffer->Sig == Signature);
  250. USBH_ASSERT(endTagBuffer->Sig == Signature);
  251. USBH_ASSERT(endTagBuffer->Length == beginTagBuffer->Length);
  252. // fill the buffer with bad data
  253. RtlFillMemory(P, beginTagBuffer->Length, 0xff);
  254. beginTagBuffer->Sig = USBHUB_FREE_TAG;
  255. // free the original block
  256. ExFreePool(beginTagBuffer);
  257. #else
  258. ExFreePool(P);
  259. #endif /* DEBUG_HEAP */
  260. }
  261. #endif /* DBG */
  262. #ifdef DEBUG_LOG
  263. KSPIN_LOCK LogSpinLock;
  264. struct USBH_LOG_ENTRY {
  265. CHAR le_name[4]; // Identifying string
  266. ULONG_PTR le_info1; // entry specific info
  267. ULONG_PTR le_info2; // entry specific info
  268. ULONG_PTR le_info3; // entry specific info
  269. }; /* USBD_LOG_ENTRY */
  270. struct USBH_LOG_ENTRY *HubLStart = 0; // No log yet
  271. struct USBH_LOG_ENTRY *HubLPtr;
  272. struct USBH_LOG_ENTRY *HubLEnd;
  273. #ifdef PROFILE
  274. ULONG LogMask = LOG_PROFILE;
  275. #else
  276. ULONG LogMask = 0xFFFFFFFF;
  277. #endif
  278. VOID
  279. USBH_Debug_LogEntry(
  280. IN ULONG Mask,
  281. IN CHAR *Name,
  282. IN ULONG_PTR Info1,
  283. IN ULONG_PTR Info2,
  284. IN ULONG_PTR Info3
  285. )
  286. /*++
  287. Routine Description:
  288. Adds an Entry to USBH log.
  289. Arguments:
  290. Return Value:
  291. None.
  292. --*/
  293. {
  294. KIRQL irql;
  295. if (HubLStart == 0) {
  296. return;
  297. }
  298. if ((Mask & LogMask) == 0) {
  299. return;
  300. }
  301. irql = KeGetCurrentIrql();
  302. if (irql < DISPATCH_LEVEL) {
  303. KeAcquireSpinLock(&LogSpinLock, &irql);
  304. } else {
  305. KeAcquireSpinLockAtDpcLevel(&LogSpinLock);
  306. }
  307. if (HubLPtr > HubLStart) {
  308. HubLPtr -= 1; // Decrement to next entry
  309. } else {
  310. HubLPtr = HubLEnd;
  311. }
  312. if (irql < DISPATCH_LEVEL) {
  313. KeReleaseSpinLock(&LogSpinLock, irql);
  314. } else {
  315. KeReleaseSpinLockFromDpcLevel(&LogSpinLock);
  316. }
  317. USBH_ASSERT(HubLPtr >= HubLStart);
  318. RtlCopyMemory(HubLPtr->le_name, Name, 4);
  319. // LPtr->le_ret = (stk[1] & 0x00ffffff) | (CurVMID()<<24);
  320. HubLPtr->le_info1 = Info1;
  321. HubLPtr->le_info2 = Info2;
  322. HubLPtr->le_info3 = Info3;
  323. return;
  324. }
  325. VOID
  326. USBH_LogInit(
  327. )
  328. /*++
  329. Routine Description:
  330. Init the debug log - remember interesting information in a circular buffer
  331. Arguments:
  332. Return Value:
  333. None.
  334. --*/
  335. {
  336. #ifdef MAX_DEBUG
  337. ULONG logSize = 4096*6;
  338. #else
  339. ULONG logSize = 4096*3;
  340. #endif
  341. KeInitializeSpinLock(&LogSpinLock);
  342. HubLStart = ExAllocatePoolWithTag(NonPagedPool,
  343. logSize,
  344. USBHUB_HEAP_TAG);
  345. if (HubLStart) {
  346. HubLPtr = HubLStart;
  347. // Point the end (and first entry) 1 entry from the end of the segment
  348. HubLEnd = HubLStart + (logSize / sizeof(struct USBH_LOG_ENTRY)) - 1;
  349. } else {
  350. USBH_KdBreak(("no mem for log!\n"));
  351. }
  352. return;
  353. }
  354. VOID
  355. USBH_LogFree(
  356. )
  357. /*++
  358. Routine Description:
  359. Init the debug log - remember interesting information in a circular buffer
  360. Arguments:
  361. Return Value:
  362. None.
  363. --*/
  364. {
  365. if (HubLStart) {
  366. ExFreePool(HubLStart);
  367. }
  368. }
  369. #endif /* DEBUG_LOG */