Sync with trunk r63192.
[reactos.git] / drivers / storage / classpnp / debug.c
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