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