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