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