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.

692 lines
27 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. debug.c
  5. Abstract:
  6. CLASSPNP debug code and data
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include "classp.h"
  13. #include "debug.h"
  14. #if DBG
  15. //
  16. // default to not breaking in for lost irps, five minutes before we even
  17. // bother checking for lost irps, using standard debug print macros, and
  18. // using a 64k debug print buffer
  19. //
  20. #ifndef CLASS_GLOBAL_BREAK_ON_LOST_IRPS
  21. #error "CLASS_GLOBAL_BREAK_ON_LOST_IRPS undefined"
  22. #define CLASS_GLOBAL_BREAK_ON_LOST_IRPS 0
  23. #endif // CLASS_GLOBAL_BREAK_ON_LOST_IRPS
  24. #ifndef CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB
  25. #error "CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB undefined"
  26. #define CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB 300
  27. #endif // CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB
  28. #ifndef CLASS_GLOBAL_USE_DELAYED_RETRY
  29. #error "CLASS_GLOBAL_USE_DELAYED_RETRY undefined"
  30. #define CLASS_GLOBAL_USE_DELAYED_RETRY 1
  31. #endif // CLASS_GLOBAL_USE_DELAYED_RETRY
  32. #ifndef CLASS_GLOBAL_BUFFERED_DEBUG_PRINT
  33. #error "CLASS_GLOBAL_BUFFERED_DEBUG_PRINT undefined"
  34. #define CLASS_GLOBAL_BUFFERED_DEBUG_PRINT 0
  35. #endif // CLASS_GLOBAL_BUFFERED_DEBUG_PRINT
  36. #ifndef CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE
  37. #error "CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE undefined"
  38. #define CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE 512
  39. #endif // CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE
  40. #ifndef CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS
  41. #error "CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS undefined"
  42. #define CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS 512
  43. #endif // CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS
  44. #pragma data_seg("NONPAGE")
  45. CLASSPNP_GLOBALS ClasspnpGlobals;
  46. //
  47. // the low sixteen bits are used to see if the debug level is high enough
  48. // the high sixteen bits are used to singly enable debug levels 1-16
  49. //
  50. LONG ClassDebug = 0x00000000;
  51. BOOLEAN DebugTrapOnWarn = FALSE;
  52. VOID ClasspInitializeDebugGlobals()
  53. {
  54. KIRQL irql;
  55. if (InterlockedCompareExchange(&ClasspnpGlobals.Initializing, 1, 0) == 0) {
  56. KeInitializeSpinLock(&ClasspnpGlobals.SpinLock);
  57. KeAcquireSpinLock(&ClasspnpGlobals.SpinLock, &irql);
  58. DebugPrint((1, "CLASSPNP.SYS => Initializing ClasspnpGlobals...\n"));
  59. ClasspnpGlobals.Buffer = NULL;
  60. ClasspnpGlobals.Index = -1;
  61. ClasspnpGlobals.BreakOnLostIrps = CLASS_GLOBAL_BREAK_ON_LOST_IRPS;
  62. ClasspnpGlobals.EachBufferSize = CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE;
  63. ClasspnpGlobals.NumberOfBuffers = CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS;
  64. ClasspnpGlobals.SecondsToWaitForIrps = CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB;
  65. //
  66. // this should be the last item set
  67. //
  68. ClasspnpGlobals.UseBufferedDebugPrint = CLASS_GLOBAL_BUFFERED_DEBUG_PRINT;
  69. KeReleaseSpinLock(&ClasspnpGlobals.SpinLock, irql);
  70. InterlockedExchange(&ClasspnpGlobals.Initialized, 1);
  71. }
  72. }
  73. /*++////////////////////////////////////////////////////////////////////////////
  74. ClassDebugPrint()
  75. Routine Description:
  76. Debug print for all class drivers, NOOP on FRE versions.
  77. Allows printing to a debug buffer (with auto fallback to kdprint) by
  78. properly setting the Globals in classpnp on CHK versions.
  79. Arguments:
  80. Debug print level, or from 0 to 3 for legacy drivers.
  81. Return Value:
  82. None
  83. --*/
  84. VOID ClassDebugPrint(CLASS_DEBUG_LEVEL DebugPrintLevel, PCCHAR DebugMessage, ...)
  85. {
  86. va_list ap;
  87. va_start(ap, DebugMessage);
  88. if ((DebugPrintLevel <= (ClassDebug & 0x0000ffff)) ||
  89. ((1 << (DebugPrintLevel + 15)) & ClassDebug)) {
  90. if (ClasspnpGlobals.UseBufferedDebugPrint &&
  91. ClasspnpGlobals.Buffer == NULL) {
  92. //
  93. // this double-check prevents always taking
  94. // a spinlock just to ensure we have a buffer
  95. //
  96. KIRQL irql;
  97. KeAcquireSpinLock(&ClasspnpGlobals.SpinLock, &irql);
  98. if (ClasspnpGlobals.Buffer == NULL) {
  99. SIZE_T bufferSize;
  100. bufferSize = ClasspnpGlobals.NumberOfBuffers *
  101. ClasspnpGlobals.EachBufferSize;
  102. DbgPrintEx(DPFLTR_CLASSPNP_ID, DPFLTR_ERROR_LEVEL,
  103. "ClassDebugPrint: Allocating %x bytes for "
  104. "classdebugprint buffer\n", bufferSize);
  105. ClasspnpGlobals.Index = -1;
  106. ClasspnpGlobals.Buffer =
  107. ExAllocatePoolWithTag(NonPagedPool, bufferSize, 'bDcS');
  108. DbgPrintEx(DPFLTR_CLASSPNP_ID, DPFLTR_ERROR_LEVEL,
  109. "ClassDebugPrint: Allocated buffer at %p\n",
  110. ClasspnpGlobals.Buffer);
  111. }
  112. KeReleaseSpinLock(&ClasspnpGlobals.SpinLock, irql);
  113. }
  114. if (ClasspnpGlobals.UseBufferedDebugPrint &&
  115. ClasspnpGlobals.Buffer != NULL) {
  116. //
  117. // we never free the buffer, so once it exists,
  118. // we can just print to it with immunity
  119. //
  120. ULONG index;
  121. PUCHAR buffer;
  122. index = InterlockedIncrement(&ClasspnpGlobals.Index);
  123. index %= ClasspnpGlobals.NumberOfBuffers;
  124. index *= (ULONG)ClasspnpGlobals.EachBufferSize;
  125. buffer = ClasspnpGlobals.Buffer;
  126. buffer += index;
  127. _vsnprintf(buffer, ClasspnpGlobals.EachBufferSize, DebugMessage, ap);
  128. } else {
  129. //
  130. // either we could not allocate a buffer for debug prints
  131. // or buffered debug prints are disabled
  132. //
  133. vDbgPrintEx(DPFLTR_CLASSPNP_ID, DPFLTR_INFO_LEVEL, DebugMessage, ap);
  134. }
  135. }
  136. va_end(ap);
  137. }
  138. char *DbgGetIoctlStr(ULONG ioctl)
  139. {
  140. char *ioctlStr = "?";
  141. switch (ioctl){
  142. #undef MAKE_CASE
  143. #define MAKE_CASE(ioctlCode) case ioctlCode: ioctlStr = #ioctlCode; break;
  144. MAKE_CASE(IOCTL_STORAGE_CHECK_VERIFY)
  145. MAKE_CASE(IOCTL_STORAGE_CHECK_VERIFY2)
  146. MAKE_CASE(IOCTL_STORAGE_MEDIA_REMOVAL)
  147. MAKE_CASE(IOCTL_STORAGE_EJECT_MEDIA)
  148. MAKE_CASE(IOCTL_STORAGE_LOAD_MEDIA)
  149. MAKE_CASE(IOCTL_STORAGE_LOAD_MEDIA2)
  150. MAKE_CASE(IOCTL_STORAGE_RESERVE)
  151. MAKE_CASE(IOCTL_STORAGE_RELEASE)
  152. MAKE_CASE(IOCTL_STORAGE_FIND_NEW_DEVICES)
  153. MAKE_CASE(IOCTL_STORAGE_EJECTION_CONTROL)
  154. MAKE_CASE(IOCTL_STORAGE_MCN_CONTROL)
  155. MAKE_CASE(IOCTL_STORAGE_GET_MEDIA_TYPES)
  156. MAKE_CASE(IOCTL_STORAGE_GET_MEDIA_TYPES_EX)
  157. MAKE_CASE(IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER)
  158. MAKE_CASE(IOCTL_STORAGE_GET_HOTPLUG_INFO)
  159. MAKE_CASE(IOCTL_STORAGE_RESET_BUS)
  160. MAKE_CASE(IOCTL_STORAGE_RESET_DEVICE)
  161. MAKE_CASE(IOCTL_STORAGE_GET_DEVICE_NUMBER)
  162. MAKE_CASE(IOCTL_STORAGE_PREDICT_FAILURE)
  163. MAKE_CASE(IOCTL_STORAGE_QUERY_PROPERTY)
  164. MAKE_CASE(OBSOLETE_IOCTL_STORAGE_RESET_BUS)
  165. MAKE_CASE(OBSOLETE_IOCTL_STORAGE_RESET_DEVICE)
  166. }
  167. return ioctlStr;
  168. }
  169. char *DbgGetScsiOpStr(PSCSI_REQUEST_BLOCK Srb)
  170. {
  171. PCDB pCdb = (PCDB)Srb->Cdb;
  172. UCHAR scsiOp = pCdb->CDB6GENERIC.OperationCode;
  173. char *scsiOpStr = "?";
  174. switch (scsiOp){
  175. #undef MAKE_CASE
  176. #define MAKE_CASE(scsiOpCode) case scsiOpCode: scsiOpStr = #scsiOpCode; break;
  177. MAKE_CASE(SCSIOP_TEST_UNIT_READY)
  178. MAKE_CASE(SCSIOP_REWIND) // aka SCSIOP_REZERO_UNIT
  179. MAKE_CASE(SCSIOP_REQUEST_BLOCK_ADDR)
  180. MAKE_CASE(SCSIOP_REQUEST_SENSE)
  181. MAKE_CASE(SCSIOP_FORMAT_UNIT)
  182. MAKE_CASE(SCSIOP_READ_BLOCK_LIMITS)
  183. MAKE_CASE(SCSIOP_INIT_ELEMENT_STATUS) // aka SCSIOP_REASSIGN_BLOCKS
  184. MAKE_CASE(SCSIOP_RECEIVE) // aka SCSIOP_READ6
  185. MAKE_CASE(SCSIOP_SEND) // aka SCSIOP_WRITE6, SCSIOP_PRINT
  186. MAKE_CASE(SCSIOP_SLEW_PRINT) // aka SCSIOP_SEEK6, SCSIOP_TRACK_SELECT
  187. MAKE_CASE(SCSIOP_SEEK_BLOCK)
  188. MAKE_CASE(SCSIOP_PARTITION)
  189. MAKE_CASE(SCSIOP_READ_REVERSE)
  190. MAKE_CASE(SCSIOP_FLUSH_BUFFER) // aka SCSIOP_WRITE_FILEMARKS
  191. MAKE_CASE(SCSIOP_SPACE)
  192. MAKE_CASE(SCSIOP_INQUIRY)
  193. MAKE_CASE(SCSIOP_VERIFY6)
  194. MAKE_CASE(SCSIOP_RECOVER_BUF_DATA)
  195. MAKE_CASE(SCSIOP_MODE_SELECT)
  196. MAKE_CASE(SCSIOP_RESERVE_UNIT)
  197. MAKE_CASE(SCSIOP_RELEASE_UNIT)
  198. MAKE_CASE(SCSIOP_COPY)
  199. MAKE_CASE(SCSIOP_ERASE)
  200. MAKE_CASE(SCSIOP_MODE_SENSE)
  201. MAKE_CASE(SCSIOP_START_STOP_UNIT) // aka SCSIOP_STOP_PRINT, SCSIOP_LOAD_UNLOAD
  202. MAKE_CASE(SCSIOP_RECEIVE_DIAGNOSTIC)
  203. MAKE_CASE(SCSIOP_SEND_DIAGNOSTIC)
  204. MAKE_CASE(SCSIOP_MEDIUM_REMOVAL)
  205. MAKE_CASE(SCSIOP_READ_FORMATTED_CAPACITY)
  206. MAKE_CASE(SCSIOP_READ_CAPACITY)
  207. MAKE_CASE(SCSIOP_READ)
  208. MAKE_CASE(SCSIOP_WRITE)
  209. MAKE_CASE(SCSIOP_SEEK) // aka SCSIOP_LOCATE, SCSIOP_POSITION_TO_ELEMENT
  210. MAKE_CASE(SCSIOP_WRITE_VERIFY)
  211. MAKE_CASE(SCSIOP_VERIFY)
  212. MAKE_CASE(SCSIOP_SEARCH_DATA_HIGH)
  213. MAKE_CASE(SCSIOP_SEARCH_DATA_EQUAL)
  214. MAKE_CASE(SCSIOP_SEARCH_DATA_LOW)
  215. MAKE_CASE(SCSIOP_SET_LIMITS)
  216. MAKE_CASE(SCSIOP_READ_POSITION)
  217. MAKE_CASE(SCSIOP_SYNCHRONIZE_CACHE)
  218. MAKE_CASE(SCSIOP_COMPARE)
  219. MAKE_CASE(SCSIOP_COPY_COMPARE)
  220. MAKE_CASE(SCSIOP_WRITE_DATA_BUFF)
  221. MAKE_CASE(SCSIOP_READ_DATA_BUFF)
  222. MAKE_CASE(SCSIOP_CHANGE_DEFINITION)
  223. MAKE_CASE(SCSIOP_READ_SUB_CHANNEL)
  224. MAKE_CASE(SCSIOP_READ_TOC)
  225. MAKE_CASE(SCSIOP_READ_HEADER)
  226. MAKE_CASE(SCSIOP_PLAY_AUDIO)
  227. MAKE_CASE(SCSIOP_GET_CONFIGURATION)
  228. MAKE_CASE(SCSIOP_PLAY_AUDIO_MSF)
  229. MAKE_CASE(SCSIOP_PLAY_TRACK_INDEX)
  230. MAKE_CASE(SCSIOP_PLAY_TRACK_RELATIVE)
  231. MAKE_CASE(SCSIOP_GET_EVENT_STATUS)
  232. MAKE_CASE(SCSIOP_PAUSE_RESUME)
  233. MAKE_CASE(SCSIOP_LOG_SELECT)
  234. MAKE_CASE(SCSIOP_LOG_SENSE)
  235. MAKE_CASE(SCSIOP_STOP_PLAY_SCAN)
  236. MAKE_CASE(SCSIOP_READ_DISK_INFORMATION)
  237. MAKE_CASE(SCSIOP_READ_TRACK_INFORMATION)
  238. MAKE_CASE(SCSIOP_RESERVE_TRACK_RZONE)
  239. MAKE_CASE(SCSIOP_SEND_OPC_INFORMATION)
  240. MAKE_CASE(SCSIOP_MODE_SELECT10)
  241. MAKE_CASE(SCSIOP_MODE_SENSE10)
  242. MAKE_CASE(SCSIOP_CLOSE_TRACK_SESSION)
  243. MAKE_CASE(SCSIOP_READ_BUFFER_CAPACITY)
  244. MAKE_CASE(SCSIOP_SEND_CUE_SHEET)
  245. MAKE_CASE(SCSIOP_PERSISTENT_RESERVE_IN)
  246. MAKE_CASE(SCSIOP_PERSISTENT_RESERVE_OUT)
  247. MAKE_CASE(SCSIOP_REPORT_LUNS)
  248. MAKE_CASE(SCSIOP_BLANK)
  249. MAKE_CASE(SCSIOP_SEND_KEY)
  250. MAKE_CASE(SCSIOP_REPORT_KEY)
  251. MAKE_CASE(SCSIOP_MOVE_MEDIUM)
  252. MAKE_CASE(SCSIOP_LOAD_UNLOAD_SLOT) // aka SCSIOP_EXCHANGE_MEDIUM
  253. MAKE_CASE(SCSIOP_SET_READ_AHEAD)
  254. MAKE_CASE(SCSIOP_READ_DVD_STRUCTURE)
  255. MAKE_CASE(SCSIOP_REQUEST_VOL_ELEMENT)
  256. MAKE_CASE(SCSIOP_SEND_VOLUME_TAG)
  257. MAKE_CASE(SCSIOP_READ_ELEMENT_STATUS)
  258. MAKE_CASE(SCSIOP_READ_CD_MSF)
  259. MAKE_CASE(SCSIOP_SCAN_CD)
  260. MAKE_CASE(SCSIOP_SET_CD_SPEED)
  261. MAKE_CASE(SCSIOP_PLAY_CD)
  262. MAKE_CASE(SCSIOP_MECHANISM_STATUS)
  263. MAKE_CASE(SCSIOP_READ_CD)
  264. MAKE_CASE(SCSIOP_SEND_DVD_STRUCTURE)
  265. MAKE_CASE(SCSIOP_INIT_ELEMENT_RANGE)
  266. }
  267. return scsiOpStr;
  268. }
  269. char *DbgGetSrbStatusStr(PSCSI_REQUEST_BLOCK Srb)
  270. {
  271. char *srbStatStr = "?";
  272. switch (Srb->SrbStatus){
  273. #undef MAKE_CASE
  274. #define MAKE_CASE(srbStat) \
  275. case srbStat: \
  276. srbStatStr = #srbStat; \
  277. break; \
  278. case srbStat|SRB_STATUS_QUEUE_FROZEN: \
  279. srbStatStr = #srbStat "|SRB_STATUS_QUEUE_FROZEN"; \
  280. break; \
  281. case srbStat|SRB_STATUS_AUTOSENSE_VALID: \
  282. srbStatStr = #srbStat "|SRB_STATUS_AUTOSENSE_VALID"; \
  283. break; \
  284. case srbStat|SRB_STATUS_QUEUE_FROZEN|SRB_STATUS_AUTOSENSE_VALID: \
  285. srbStatStr = #srbStat "|SRB_STATUS_QUEUE_FROZEN|SRB_STATUS_AUTOSENSE_VALID"; \
  286. break;
  287. MAKE_CASE(SRB_STATUS_PENDING)
  288. MAKE_CASE(SRB_STATUS_SUCCESS)
  289. MAKE_CASE(SRB_STATUS_ABORTED)
  290. MAKE_CASE(SRB_STATUS_ABORT_FAILED)
  291. MAKE_CASE(SRB_STATUS_ERROR)
  292. MAKE_CASE(SRB_STATUS_BUSY)
  293. MAKE_CASE(SRB_STATUS_INVALID_REQUEST)
  294. MAKE_CASE(SRB_STATUS_INVALID_PATH_ID)
  295. MAKE_CASE(SRB_STATUS_NO_DEVICE)
  296. MAKE_CASE(SRB_STATUS_TIMEOUT)
  297. MAKE_CASE(SRB_STATUS_SELECTION_TIMEOUT)
  298. MAKE_CASE(SRB_STATUS_COMMAND_TIMEOUT)
  299. MAKE_CASE(SRB_STATUS_MESSAGE_REJECTED)
  300. MAKE_CASE(SRB_STATUS_BUS_RESET)
  301. MAKE_CASE(SRB_STATUS_PARITY_ERROR)
  302. MAKE_CASE(SRB_STATUS_REQUEST_SENSE_FAILED)
  303. MAKE_CASE(SRB_STATUS_NO_HBA)
  304. MAKE_CASE(SRB_STATUS_DATA_OVERRUN)
  305. MAKE_CASE(SRB_STATUS_UNEXPECTED_BUS_FREE)
  306. MAKE_CASE(SRB_STATUS_PHASE_SEQUENCE_FAILURE)
  307. MAKE_CASE(SRB_STATUS_BAD_SRB_BLOCK_LENGTH)
  308. MAKE_CASE(SRB_STATUS_REQUEST_FLUSHED)
  309. MAKE_CASE(SRB_STATUS_INVALID_LUN)
  310. MAKE_CASE(SRB_STATUS_INVALID_TARGET_ID)
  311. MAKE_CASE(SRB_STATUS_BAD_FUNCTION)
  312. MAKE_CASE(SRB_STATUS_ERROR_RECOVERY)
  313. MAKE_CASE(SRB_STATUS_NOT_POWERED)
  314. MAKE_CASE(SRB_STATUS_INTERNAL_ERROR)
  315. }
  316. return srbStatStr;
  317. }
  318. char *DbgGetSenseCodeStr(PSCSI_REQUEST_BLOCK Srb)
  319. {
  320. char *senseCodeStr = "?";
  321. if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID){
  322. PSENSE_DATA senseData;
  323. UCHAR senseCode;
  324. ASSERT(Srb->SenseInfoBuffer);
  325. senseData = Srb->SenseInfoBuffer;
  326. senseCode = senseData->SenseKey & 0xf;
  327. switch (senseCode){
  328. #undef MAKE_CASE
  329. #define MAKE_CASE(snsCod) case snsCod: senseCodeStr = #snsCod; break;
  330. MAKE_CASE(SCSI_SENSE_NO_SENSE)
  331. MAKE_CASE(SCSI_SENSE_RECOVERED_ERROR)
  332. MAKE_CASE(SCSI_SENSE_NOT_READY)
  333. MAKE_CASE(SCSI_SENSE_MEDIUM_ERROR)
  334. MAKE_CASE(SCSI_SENSE_HARDWARE_ERROR)
  335. MAKE_CASE(SCSI_SENSE_ILLEGAL_REQUEST)
  336. MAKE_CASE(SCSI_SENSE_UNIT_ATTENTION)
  337. MAKE_CASE(SCSI_SENSE_DATA_PROTECT)
  338. MAKE_CASE(SCSI_SENSE_BLANK_CHECK)
  339. MAKE_CASE(SCSI_SENSE_UNIQUE)
  340. MAKE_CASE(SCSI_SENSE_COPY_ABORTED)
  341. MAKE_CASE(SCSI_SENSE_ABORTED_COMMAND)
  342. MAKE_CASE(SCSI_SENSE_EQUAL)
  343. MAKE_CASE(SCSI_SENSE_VOL_OVERFLOW)
  344. MAKE_CASE(SCSI_SENSE_MISCOMPARE)
  345. MAKE_CASE(SCSI_SENSE_RESERVED)
  346. }
  347. }
  348. return senseCodeStr;
  349. }
  350. char *DbgGetAdditionalSenseCodeStr(PSCSI_REQUEST_BLOCK Srb)
  351. {
  352. char *adSenseCodeStr = "?";
  353. if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID){
  354. PSENSE_DATA senseData;
  355. UCHAR adSenseCode;
  356. ASSERT(Srb->SenseInfoBuffer);
  357. senseData = Srb->SenseInfoBuffer;
  358. adSenseCode = senseData->AdditionalSenseCode;
  359. switch (adSenseCode){
  360. #undef MAKE_CASE
  361. #define MAKE_CASE(adSnsCod) case adSnsCod: adSenseCodeStr = #adSnsCod; break;
  362. MAKE_CASE(SCSI_ADSENSE_NO_SENSE)
  363. MAKE_CASE(SCSI_ADSENSE_LUN_NOT_READY)
  364. MAKE_CASE(SCSI_ADSENSE_TRACK_ERROR)
  365. MAKE_CASE(SCSI_ADSENSE_SEEK_ERROR)
  366. MAKE_CASE(SCSI_ADSENSE_REC_DATA_NOECC)
  367. MAKE_CASE(SCSI_ADSENSE_REC_DATA_ECC)
  368. MAKE_CASE(SCSI_ADSENSE_ILLEGAL_COMMAND)
  369. MAKE_CASE(SCSI_ADSENSE_ILLEGAL_BLOCK)
  370. MAKE_CASE(SCSI_ADSENSE_INVALID_CDB)
  371. MAKE_CASE(SCSI_ADSENSE_INVALID_LUN)
  372. MAKE_CASE(SCSI_ADSENSE_WRITE_PROTECT) // aka SCSI_ADWRITE_PROTECT
  373. MAKE_CASE(SCSI_ADSENSE_MEDIUM_CHANGED)
  374. MAKE_CASE(SCSI_ADSENSE_BUS_RESET)
  375. MAKE_CASE(SCSI_ADSENSE_INVALID_MEDIA)
  376. MAKE_CASE(SCSI_ADSENSE_NO_MEDIA_IN_DEVICE)
  377. MAKE_CASE(SCSI_ADSENSE_POSITION_ERROR)
  378. MAKE_CASE(SCSI_ADSENSE_OPERATOR_REQUEST)
  379. MAKE_CASE(SCSI_ADSENSE_FAILURE_PREDICTION_THRESHOLD_EXCEEDED)
  380. MAKE_CASE(SCSI_ADSENSE_COPY_PROTECTION_FAILURE)
  381. MAKE_CASE(SCSI_ADSENSE_VENDOR_UNIQUE)
  382. MAKE_CASE(SCSI_ADSENSE_MUSIC_AREA)
  383. MAKE_CASE(SCSI_ADSENSE_DATA_AREA)
  384. MAKE_CASE(SCSI_ADSENSE_VOLUME_OVERFLOW)
  385. }
  386. }
  387. return adSenseCodeStr;
  388. }
  389. char *DbgGetAdditionalSenseCodeQualifierStr(PSCSI_REQUEST_BLOCK Srb)
  390. {
  391. char *adSenseCodeQualStr = "?";
  392. if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID){
  393. PSENSE_DATA senseData;
  394. UCHAR adSenseCode;
  395. UCHAR adSenseCodeQual;
  396. ASSERT(Srb->SenseInfoBuffer);
  397. senseData = Srb->SenseInfoBuffer;
  398. adSenseCode = senseData->AdditionalSenseCode;
  399. adSenseCodeQual = senseData->AdditionalSenseCodeQualifier;
  400. switch (adSenseCode){
  401. #undef MAKE_CASE
  402. #define MAKE_CASE(adSnsCodQual) case adSnsCodQual: adSenseCodeQualStr = #adSnsCodQual; break;
  403. case SCSI_ADSENSE_LUN_NOT_READY:
  404. switch (adSenseCodeQual){
  405. MAKE_CASE(SCSI_SENSEQ_CAUSE_NOT_REPORTABLE)
  406. MAKE_CASE(SCSI_SENSEQ_BECOMING_READY)
  407. MAKE_CASE(SCSI_SENSEQ_INIT_COMMAND_REQUIRED)
  408. MAKE_CASE(SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED)
  409. MAKE_CASE(SCSI_SENSEQ_FORMAT_IN_PROGRESS)
  410. MAKE_CASE(SCSI_SENSEQ_REBUILD_IN_PROGRESS)
  411. MAKE_CASE(SCSI_SENSEQ_RECALCULATION_IN_PROGRESS)
  412. MAKE_CASE(SCSI_SENSEQ_OPERATION_IN_PROGRESS)
  413. MAKE_CASE(SCSI_SENSEQ_LONG_WRITE_IN_PROGRESS)
  414. }
  415. break;
  416. case SCSI_ADSENSE_NO_SENSE:
  417. switch (adSenseCodeQual){
  418. MAKE_CASE(SCSI_SENSEQ_FILEMARK_DETECTED)
  419. MAKE_CASE(SCSI_SENSEQ_END_OF_MEDIA_DETECTED)
  420. MAKE_CASE(SCSI_SENSEQ_SETMARK_DETECTED)
  421. MAKE_CASE(SCSI_SENSEQ_BEGINNING_OF_MEDIA_DETECTED)
  422. }
  423. break;
  424. case SCSI_ADSENSE_ILLEGAL_BLOCK:
  425. switch (adSenseCodeQual){
  426. MAKE_CASE(SCSI_SENSEQ_ILLEGAL_ELEMENT_ADDR)
  427. }
  428. break;
  429. case SCSI_ADSENSE_POSITION_ERROR:
  430. switch (adSenseCodeQual){
  431. MAKE_CASE(SCSI_SENSEQ_DESTINATION_FULL)
  432. MAKE_CASE(SCSI_SENSEQ_SOURCE_EMPTY)
  433. }
  434. break;
  435. case SCSI_ADSENSE_INVALID_MEDIA:
  436. switch (adSenseCodeQual){
  437. MAKE_CASE(SCSI_SENSEQ_INCOMPATIBLE_MEDIA_INSTALLED)
  438. MAKE_CASE(SCSI_SENSEQ_UNKNOWN_FORMAT)
  439. MAKE_CASE(SCSI_SENSEQ_INCOMPATIBLE_FORMAT)
  440. MAKE_CASE(SCSI_SENSEQ_CLEANING_CARTRIDGE_INSTALLED)
  441. }
  442. break;
  443. case SCSI_ADSENSE_OPERATOR_REQUEST:
  444. switch (adSenseCodeQual){
  445. MAKE_CASE(SCSI_SENSEQ_STATE_CHANGE_INPUT)
  446. MAKE_CASE(SCSI_SENSEQ_MEDIUM_REMOVAL)
  447. MAKE_CASE(SCSI_SENSEQ_WRITE_PROTECT_ENABLE)
  448. MAKE_CASE(SCSI_SENSEQ_WRITE_PROTECT_DISABLE)
  449. }
  450. break;
  451. case SCSI_ADSENSE_COPY_PROTECTION_FAILURE:
  452. switch (adSenseCodeQual){
  453. MAKE_CASE(SCSI_SENSEQ_AUTHENTICATION_FAILURE)
  454. MAKE_CASE(SCSI_SENSEQ_KEY_NOT_PRESENT)
  455. MAKE_CASE(SCSI_SENSEQ_KEY_NOT_ESTABLISHED)
  456. MAKE_CASE(SCSI_SENSEQ_READ_OF_SCRAMBLED_SECTOR_WITHOUT_AUTHENTICATION)
  457. MAKE_CASE(SCSI_SENSEQ_MEDIA_CODE_MISMATCHED_TO_LOGICAL_UNIT)
  458. MAKE_CASE(SCSI_SENSEQ_LOGICAL_UNIT_RESET_COUNT_ERROR)
  459. }
  460. break;
  461. }
  462. }
  463. return adSenseCodeQualStr;
  464. }
  465. /*
  466. * DbgCheckReturnedPkt
  467. *
  468. * Check a completed TRANSFER_PACKET for all sorts of error conditions
  469. * and warn/trap appropriately.
  470. */
  471. VOID DbgCheckReturnedPkt(TRANSFER_PACKET *Pkt)
  472. {
  473. PCDB pCdb = (PCDB)Pkt->Srb.Cdb;
  474. ASSERT(Pkt->Srb.OriginalRequest == Pkt->Irp);
  475. ASSERT(Pkt->Srb.DataBuffer == Pkt->BufPtrCopy);
  476. ASSERT(Pkt->Srb.DataTransferLength <= Pkt->BufLenCopy);
  477. ASSERT(!Pkt->Irp->CancelRoutine);
  478. if (SRB_STATUS(Pkt->Srb.SrbStatus) == SRB_STATUS_PENDING){
  479. DBGERR(("SRB completed with status PENDING in packet %ph: (op=%s srbstat=%s(%xh), irpstat=%xh)",
  480. Pkt,
  481. DBGGETSCSIOPSTR(&Pkt->Srb),
  482. DBGGETSRBSTATUSSTR(&Pkt->Srb),
  483. (ULONG)Pkt->Srb.SrbStatus,
  484. Pkt->Irp->IoStatus.Status));
  485. }
  486. else if (SRB_STATUS(Pkt->Srb.SrbStatus) == SRB_STATUS_SUCCESS){
  487. /*
  488. * Make sure SRB and IRP status match.
  489. */
  490. if (!NT_SUCCESS(Pkt->Irp->IoStatus.Status)){
  491. DBGWARN(("SRB and IRP status don't match in packet %ph: (op=%s srbstat=%s(%xh), irpstat=%xh)",
  492. Pkt,
  493. DBGGETSCSIOPSTR(&Pkt->Srb),
  494. DBGGETSRBSTATUSSTR(&Pkt->Srb),
  495. (ULONG)Pkt->Srb.SrbStatus,
  496. Pkt->Irp->IoStatus.Status));
  497. }
  498. if (Pkt->Irp->IoStatus.Information != Pkt->Srb.DataTransferLength){
  499. DBGERR(("SRB and IRP result transfer lengths don't match in succeeded packet %ph: (op=%s, SrbStatus=%s, Srb.DataTransferLength=%xh, Irp->IoStatus.Information=%xh).",
  500. Pkt,
  501. DBGGETSCSIOPSTR(&Pkt->Srb),
  502. DBGGETSRBSTATUSSTR(&Pkt->Srb),
  503. Pkt->Srb.DataTransferLength,
  504. Pkt->Irp->IoStatus.Information));
  505. }
  506. }
  507. else {
  508. if (NT_SUCCESS(Pkt->Irp->IoStatus.Status)){
  509. DBGWARN(("SRB and IRP status don't match in packet %ph: (op=%s srbstat=%s(%xh), irpstat=%xh)",
  510. Pkt,
  511. DBGGETSCSIOPSTR(&Pkt->Srb),
  512. DBGGETSRBSTATUSSTR(&Pkt->Srb),
  513. (ULONG)Pkt->Srb.SrbStatus,
  514. Pkt->Irp->IoStatus.Status));
  515. }
  516. DBGTRACE(ClassDebugWarning, ("Packet %ph failed (op=%s srbstat=%s(%xh), irpstat=%xh, sense=%s/%s/%s)",
  517. Pkt,
  518. DBGGETSCSIOPSTR(&Pkt->Srb),
  519. DBGGETSRBSTATUSSTR(&Pkt->Srb),
  520. (ULONG)Pkt->Srb.SrbStatus,
  521. Pkt->Irp->IoStatus.Status,
  522. DBGGETSENSECODESTR(&Pkt->Srb),
  523. DBGGETADSENSECODESTR(&Pkt->Srb),
  524. DBGGETADSENSEQUALIFIERSTR(&Pkt->Srb)));
  525. /*
  526. * If the SRB failed with underrun or overrun, then the actual
  527. * transferred length should be returned in both SRB and IRP.
  528. * (SRB's only have an error status for overrun, so it's overloaded).
  529. */
  530. if ((SRB_STATUS(Pkt->Srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) &&
  531. (Pkt->Irp->IoStatus.Information != Pkt->Srb.DataTransferLength)){
  532. DBGERR(("SRB and IRP result transfer lengths don't match in failed packet %ph: (op=%s, SrbStatus=%s, Srb.DataTransferLength=%xh, Irp->IoStatus.Information=%xh).",
  533. Pkt,
  534. DBGGETSCSIOPSTR(&Pkt->Srb),
  535. DBGGETSRBSTATUSSTR(&Pkt->Srb),
  536. Pkt->Srb.DataTransferLength,
  537. Pkt->Irp->IoStatus.Information));
  538. }
  539. }
  540. /*
  541. * Some miniport drivers have been caught changing the SCSI operation
  542. * code in the SRB. This is absolutely disallowed as it breaks our error handling.
  543. */
  544. switch (pCdb->CDB10.OperationCode){
  545. case SCSIOP_MEDIUM_REMOVAL:
  546. case SCSIOP_MODE_SENSE:
  547. case SCSIOP_READ_CAPACITY:
  548. case SCSIOP_READ:
  549. case SCSIOP_WRITE:
  550. case SCSIOP_START_STOP_UNIT:
  551. break;
  552. default:
  553. DBGERR(("Miniport illegally changed Srb.Cdb.OperationCode in packet %ph failed (op=%s srbstat=%s(%xh), irpstat=%xh, sense=%s/%s/%s)",
  554. Pkt,
  555. DBGGETSCSIOPSTR(&Pkt->Srb),
  556. DBGGETSRBSTATUSSTR(&Pkt->Srb),
  557. (ULONG)Pkt->Srb.SrbStatus,
  558. Pkt->Irp->IoStatus.Status,
  559. DBGGETSENSECODESTR(&Pkt->Srb),
  560. DBGGETADSENSECODESTR(&Pkt->Srb),
  561. DBGGETADSENSEQUALIFIERSTR(&Pkt->Srb)));
  562. break;
  563. }
  564. }
  565. #else
  566. // We have to keep this in the retail build for legacy.
  567. VOID ClassDebugPrint(CLASS_DEBUG_LEVEL DebugPrintLevel, PCCHAR DebugMessage, ...)
  568. {
  569. }
  570. #endif