1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include "sg_include.h" 5 #include "sg_err.h" 6 7 /* This file is a huge cut, paste and hack from linux/drivers/scsi/constant.c 8 * which I guess was written by: 9 * Copyright (C) 1993, 1994, 1995 Eric Youngdale 10 11 * The rest of this is: 12 * Copyright (C) 1999 - 2003 D. Gilbert 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2, or (at your option) 17 * any later version. 18 * 19 * ASCII values for a number of symbolic constants, printing functions, etc. 20 * 21 * Some of the tables have been updated for SCSI 2. 22 * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) 23 * 24 * Version 0.89 (20030313) 25 * sense key specific field (bytes 15-17) decoding [Trent Piepho] 26 */ 27 28 #define OUTP stderr 29 30 static const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 31 16, 12, 10, 10 32 }; 33 34 #define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] 35 36 static const char unknown[] = "UNKNOWN"; 37 38 static const char *group_0_commands[] = { 39 /* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense", 40 /* 04-07 */ "Format Unit", "Read Block Limits", unknown, 41 "Reasssign Blocks", 42 /* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, 43 unknown, 44 /* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", 45 "Inquiry", 46 /* 13-16 */ "Verify", "Recover Buffered Data", "Mode Select", "Reserve", 47 /* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit", 48 /* 1c-1d */ "Receive Diagnostic", "Send Diagnostic", 49 /* 1e-1f */ "Prevent/Allow Medium Removal", unknown, 50 }; 51 52 static const char *group_1_commands[] = { 53 /* 20-23 */ unknown, unknown, unknown, "Read Format capacities", 54 /* 24-28 */ "Set window", "Read Capacity", 55 unknown, unknown, "Read (10)", 56 /* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase", 57 "Read updated block", 58 /* 2e-31 */ "Write Verify", "Verify", "Search High", "Search Equal", 59 /* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position", 60 /* 35-37 */ "Synchronize Cache", "Lock/Unlock Cache", 61 "Read Defect Data", 62 /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", 63 "Read Buffer", 64 /* 3d-3f */ "Update Block", "Read Long", "Write Long", 65 }; 66 67 static const char *group_2_commands[] = { 68 /* 40-41 */ "Change Definition", "Write Same", 69 /* 42-48 */ "Read sub-channel", "Read TOC", "Read header", 70 "Play audio (10)", "Get configuration", "Play audio msf", 71 "Play audio track/index", 72 /* 49-4f */ "Play track relative (10)", "Get event status notification", 73 "Pause/resume", "Log Select", "Log Sense", "Stop play/scan", 74 unknown, 75 /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", 76 "Xdread, Read track info", 77 "Reserve track", "Send OPC onfo", "Mode Select (10)", 78 /* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", 79 "Read master cue", 80 "Mode Sense (10)", "Close track/session", 81 /* 5c-5f */ "Read buffer capacity", "Send cue sheet", 82 "Persistent reserve in", 83 "Persistent reserve out", 84 }; 85 86 /* The following are 16 byte commands in group 4 */ 87 static const char *group_4_commands[] = { 88 /* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", 89 "Extended copy", 90 "Receive copy results", 91 /* 85-89 */ "Memory Export In (16)", "Access control in", 92 "Access control out", 93 "Read (16)", "Memory Export Out (16)", 94 /* 8a-8f */ "Write (16)", unknown, "Read attributes", 95 "Write attributes", 96 "Write and verify (16)", "Verify (16)", 97 /* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)", 98 "Lock/unlock cache (16)", "Write same (16)", unknown, 99 /* 95-99 */ unknown, unknown, unknown, unknown, unknown, 100 /* 9a-9f */ unknown, unknown, unknown, unknown, "Service action in", 101 "Service action out", 102 }; 103 104 /* The following are 12 byte commands in group 5 */ 105 static const char *group_5_commands[] = { 106 /* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance (in)", 107 "Maintenance (out)", "Move medium/play audio(12)", 108 /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)", 109 "Play track relative(12)", 110 /* aa-ae */ "Write(12)", unknown, "Erase(12), Get Performance", 111 "Read DVD structure", "Write and verify(12)", 112 /* af-b1 */ "Verify(12)", "Search data high(12)", 113 "Search data equal(12)", 114 /* b2-b4 */ "Search data low(12)", "Set limits(12)", 115 "Read element status attached", 116 /* b5-b6 */ "Request volume element address", 117 "Send volume tag, set streaming", 118 /* b7-b9 */ "Read defect data(12)", "Read element status", 119 "Read CD msf", 120 /* ba-bc */ "Redundancy group (in), Scan", 121 "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd", 122 /* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd", 123 "Volume set (out), Send DVD structure", 124 }; 125 126 #define group(opcode) (((opcode) >> 5) & 7) 127 128 #define RESERVED_GROUP 0 129 #define VENDOR_GROUP 1 130 131 static const char **commands[] = { 132 group_0_commands, group_1_commands, group_2_commands, 133 (const char **)RESERVED_GROUP, group_4_commands, 134 group_5_commands, (const char **)VENDOR_GROUP, 135 (const char **)VENDOR_GROUP 136 }; 137 138 static const char reserved[] = "RESERVED"; 139 static const char vendor[] = "VENDOR SPECIFIC"; 140 141 static void print_opcode(int opcode) 142 { 143 const char **table = commands[group(opcode)]; 144 145 switch ((unsigned long)table) { 146 case RESERVED_GROUP: 147 fprintf(OUTP, "%s(0x%02x)", reserved, opcode); 148 break; 149 case VENDOR_GROUP: 150 fprintf(OUTP, "%s(0x%02x)", vendor, opcode); 151 break; 152 default: 153 fprintf(OUTP, "%s", table[opcode & 0x1f]); 154 break; 155 } 156 } 157 158 void sg_print_command(const unsigned char *command) 159 { 160 int k, s; 161 print_opcode(command[0]); 162 fprintf(OUTP, " ["); 163 for (k = 0, s = COMMAND_SIZE(command[0]); k < s; ++k) 164 fprintf(OUTP, "%02x ", command[k]); 165 fprintf(OUTP, "]\n"); 166 } 167 168 void sg_print_status(int masked_status) 169 { 170 int scsi_status = (masked_status << 1) & 0x7e; 171 172 sg_print_scsi_status(scsi_status); 173 } 174 175 void sg_print_scsi_status(int scsi_status) 176 { 177 const char *ccp; 178 179 scsi_status &= 0x7e; /* sanitize as much as possible */ 180 switch (scsi_status) { 181 case 0: 182 ccp = "Good"; 183 break; 184 case 0x2: 185 ccp = "Check Condition"; 186 break; 187 case 0x4: 188 ccp = "Condition Met"; 189 break; 190 case 0x8: 191 ccp = "Busy"; 192 break; 193 case 0x10: 194 ccp = "Intermediate"; 195 break; 196 case 0x14: 197 ccp = "Intermediate-Condition Met"; 198 break; 199 case 0x18: 200 ccp = "Reservation Conflict"; 201 break; 202 case 0x22: 203 ccp = "Command Terminated (obsolete)"; 204 break; 205 case 0x28: 206 ccp = "Task set Full"; 207 break; 208 case 0x30: 209 ccp = "ACA Active"; 210 break; 211 case 0x40: 212 ccp = "Task Aborted"; 213 break; 214 default: 215 ccp = "Unknown status"; 216 break; 217 } 218 fprintf(OUTP, "%s ", ccp); 219 } 220 221 /* In brackets is the related SCSI document (see www.t10.org) with the */ 222 /* peripheral device type after the colon */ 223 /* No programmatic use is made of these flags currently */ 224 #define D 0x0001 /* DIRECT ACCESS DEVICE (disk) [SBC-2: 0] */ 225 #define T 0x0002 /* SEQUENTIAL ACCESS DEVICE (tape) [SSC: 1] */ 226 #define L 0x0004 /* PRINTER DEVICE [SSC: 2] */ 227 #define P 0x0008 /* PROCESSOR DEVICE [SPC-2: 3] */ 228 #define W 0x0010 /* WRITE ONCE READ MULTIPLE DEVICE [SBC-2: 4] */ 229 #define R 0x0020 /* CD/DVD DEVICE [MMC-2: 5] */ 230 #define S 0x0040 /* SCANNER DEVICE [SCSI-2 (obsolete): 6] */ 231 #define O 0x0080 /* OPTICAL MEMORY DEVICE [SBC-2: 7] */ 232 #define M 0x0100 /* MEDIA CHANGER DEVICE [SMC-2: 8] */ 233 #define C 0x0200 /* COMMUNICATION DEVICE [SCSI-2 (obsolete): 9] */ 234 #define A 0x0400 /* ARRAY STORAGE [SCC-2: 12] */ 235 #define E 0x0800 /* ENCLOSURE SERVICES DEVICE [SES: 13] */ 236 #define B 0x1000 /* SIMPLIFIED DIRECT ACCESS DEVICE [RBC: 14] */ 237 #define K 0x2000 /* OPTICAL CARD READER/WRITER DEVICE [OCRW: 15] */ 238 239 #define SC_ALL_DEVS ( D|T|L|P|W|R|S|O|M|C|A|E|B|K ) 240 241 /* oft used strings are encoded using ASCII codes 0x1 to 0x1f . */ 242 /* This is to save space. This encoding should be UTF-8 and */ 243 /* UTF-16 friendly. */ 244 #define SC_AUDIO_PLAY_OPERATION "\x1" 245 #define SC_LOGICAL_UNIT "\x2" 246 #define SC_NOT_READY "\x3" 247 #define SC_OPERATION "\x4" 248 #define SC_IN_PROGRESS "\x5" 249 #define SC_HARDWARE_IF "\x6" 250 #define SC_CONTROLLER_IF "\x7" 251 #define SC_DATA_CHANNEL_IF "\x8" 252 #define SC_SERVO_IF "\x9" 253 #define SC_SPINDLE_IF "\xa" 254 #define SC_FIRMWARE_IF "\xb" 255 #define SC_RECOVERED_DATA "\xc" 256 #define SC_ERROR_RATE_TOO_HIGH "\xd" 257 #define SC_TIMES_TOO_HIGH "\xe" 258 259 struct error_info { 260 unsigned char code1, code2; 261 unsigned short int devices; 262 const char *text; 263 }; 264 265 struct error_info2 { 266 unsigned char code1, code2_min, code2_max; 267 unsigned short int devices; 268 const char *text; 269 }; 270 271 static struct error_info2 additional2[] = { 272 {0x40, 0x00, 0x7f, D, "Ram failure (%x)"}, 273 {0x40, 0x80, 0xff, D | T | L | P | W | R | S | O | M | C, 274 "Diagnostic failure on component (%x)"}, 275 {0x41, 0x00, 0xff, D, "Data path failure (%x)"}, 276 {0x42, 0x00, 0xff, D, "Power-on or self-test failure (%x)"}, 277 {0, 0, 0, 0, NULL} 278 }; 279 280 static struct error_info additional[] = { 281 {0x00, 0x00, SC_ALL_DEVS, "No additional sense information"}, 282 {0x00, 0x01, T, "Filemark detected"}, 283 {0x00, 0x02, T | S, "End-of-partition/medium detected"}, 284 {0x00, 0x03, T, "Setmark detected"}, 285 {0x00, 0x04, T | S, "Beginning-of-partition/medium detected"}, 286 {0x00, 0x05, T | L | S, "End-of-data detected"}, 287 {0x00, 0x06, SC_ALL_DEVS, "I/O process terminated"}, 288 {0x00, 0x11, R, SC_AUDIO_PLAY_OPERATION SC_IN_PROGRESS}, 289 {0x00, 0x12, R, SC_AUDIO_PLAY_OPERATION "paused"}, 290 {0x00, 0x13, R, SC_AUDIO_PLAY_OPERATION "successfully completed"}, 291 {0x00, 0x14, R, SC_AUDIO_PLAY_OPERATION "stopped due to error"}, 292 {0x00, 0x15, R, "No current audio status to return"}, 293 {0x00, 0x16, SC_ALL_DEVS, SC_OPERATION SC_IN_PROGRESS}, 294 {0x00, 0x17, D | T | L | W | R | S | O | M | A | E | B | K, 295 "Cleaning requested"}, 296 {0x00, 0x18, T, "Erase" SC_OPERATION SC_IN_PROGRESS}, 297 {0x00, 0x19, T, "Locate" SC_OPERATION SC_IN_PROGRESS}, 298 {0x00, 0x1a, T, "Rewind" SC_OPERATION SC_IN_PROGRESS}, 299 {0x00, 0x1b, T, "Set capacity" SC_OPERATION SC_IN_PROGRESS}, 300 {0x00, 0x1c, T, "Verify" SC_OPERATION SC_IN_PROGRESS}, 301 {0x01, 0x00, D | W | O | B | K, "No index/sector signal"}, 302 {0x02, 0x00, D | W | R | O | M | B | K, "No seek complete"}, 303 {0x03, 0x00, D | T | L | W | S | O | B | K, 304 "Peripheral device write fault"}, 305 {0x03, 0x01, T, "No write current"}, 306 {0x03, 0x02, T, "Excessive write errors"}, 307 {0x04, 0x00, SC_ALL_DEVS, 308 SC_LOGICAL_UNIT SC_NOT_READY "cause not reportable"}, 309 {0x04, 0x01, SC_ALL_DEVS, 310 SC_LOGICAL_UNIT "is" SC_IN_PROGRESS "of becoming ready"}, 311 {0x04, 0x02, SC_ALL_DEVS, 312 SC_LOGICAL_UNIT SC_NOT_READY "initializing cmd. required"}, 313 {0x04, 0x03, SC_ALL_DEVS, 314 SC_LOGICAL_UNIT SC_NOT_READY "manual intervention required"}, 315 {0x04, 0x04, D | T | L | R | O | B, 316 SC_LOGICAL_UNIT SC_NOT_READY "format" SC_IN_PROGRESS}, 317 {0x04, 0x05, D | T | W | O | M | C | A | B | K, 318 SC_LOGICAL_UNIT SC_NOT_READY "rebuild" SC_IN_PROGRESS}, 319 {0x04, 0x06, D | T | W | O | M | C | A | B | K, 320 SC_LOGICAL_UNIT SC_NOT_READY "recalculation" SC_IN_PROGRESS}, 321 {0x04, 0x07, SC_ALL_DEVS, 322 SC_LOGICAL_UNIT SC_NOT_READY SC_OPERATION SC_IN_PROGRESS}, 323 {0x04, 0x08, R, 324 SC_LOGICAL_UNIT SC_NOT_READY "long write" SC_IN_PROGRESS}, 325 {0x04, 0x09, SC_ALL_DEVS, 326 SC_LOGICAL_UNIT SC_NOT_READY "self-test" SC_IN_PROGRESS}, 327 {0x04, 0x0a, SC_ALL_DEVS, 328 SC_LOGICAL_UNIT "not accessible, asymmetric access state transition"}, 329 {0x04, 0x0b, SC_ALL_DEVS, 330 SC_LOGICAL_UNIT "not accessible, target port in standby state"}, 331 {0x04, 0x0c, SC_ALL_DEVS, 332 SC_LOGICAL_UNIT "not accessible, target port in unavailable state"}, 333 {0x04, 0x10, SC_ALL_DEVS, 334 SC_LOGICAL_UNIT SC_NOT_READY "auxiliary memory not accessible"}, 335 {0x05, 0x00, D | T | L | W | R | S | O | M | C | A | E | B | K, 336 SC_LOGICAL_UNIT "does not respond to selection"}, 337 {0x06, 0x00, D | W | R | O | M | B | K, "No reference position found"}, 338 {0x07, 0x00, D | T | L | W | R | S | O | M | B | K, 339 "Multiple peripheral devices selected"}, 340 {0x08, 0x00, D | T | L | W | R | S | O | M | C | A | E | B | K, 341 SC_LOGICAL_UNIT "communication failure"}, 342 {0x08, 0x01, D | T | L | W | R | S | O | M | C | A | E | B | K, 343 SC_LOGICAL_UNIT "communication time-out"}, 344 {0x08, 0x02, D | T | L | W | R | S | O | M | C | A | E | B | K, 345 SC_LOGICAL_UNIT "communication parity error"}, 346 {0x08, 0x03, D | T | R | O | M | B | K, 347 SC_LOGICAL_UNIT "communication CRC error (Ultra-DMA/32)"}, 348 {0x08, 0x04, D | T | L | P | W | R | S | O | C | K, 349 "Unreachable copy target"}, 350 {0x09, 0x00, D | T | W | R | O | B, "Track following error"}, 351 {0x09, 0x01, W | R | O | K, "Tracking servo failure"}, 352 {0x09, 0x02, W | R | O | K, "Focus servo failure"}, 353 {0x09, 0x03, W | R | O, "Spindle servo failure"}, 354 {0x09, 0x04, D | T | W | R | O | B, "Head select fault"}, 355 {0x0A, 0x00, SC_ALL_DEVS, "Error log overflow"}, 356 {0x0B, 0x00, SC_ALL_DEVS, "Warning"}, 357 {0x0B, 0x01, SC_ALL_DEVS, "Warning - specified temperature exceeded"}, 358 {0x0B, 0x02, SC_ALL_DEVS, "Warning - enclosure degraded"}, 359 {0x0C, 0x00, T | R | S, "Write error"}, 360 {0x0C, 0x01, K, "Write error - recovered with auto reallocation"}, 361 {0x0C, 0x02, D | W | O | B | K, 362 "Write error - auto reallocation failed"}, 363 {0x0C, 0x03, D | W | O | B | K, "Write error - recommend reassignment"}, 364 {0x0C, 0x04, D | T | W | O | B, "Compression check miscompare error"}, 365 {0x0C, 0x05, D | T | W | O | B, 366 "Data expansion occurred during compression"}, 367 {0x0C, 0x06, D | T | W | O | B, "Block not compressible"}, 368 {0x0C, 0x07, R, "Write error - recovery needed"}, 369 {0x0C, 0x08, R, "Write error - recovery failed"}, 370 {0x0C, 0x09, R, "Write error - loss of streaming"}, 371 {0x0C, 0x0A, R, "Write error - padding blocks added"}, 372 {0x0C, 0x0B, D | T | W | R | O | M | B, "Auxiliary memory write error"}, 373 {0x0C, 0x0C, SC_ALL_DEVS, "Write error - unexpected unsolicited data"}, 374 {0x0C, 0x0D, SC_ALL_DEVS, "Write error - not enough unsolicited data"}, 375 {0x0D, 0x00, D | T | L | P | W | R | S | O | C | A | K, 376 "Error detected by third party temporary initiator"}, 377 {0x0D, 0x01, D | T | L | P | W | R | S | O | C | A | K, 378 "Third party device failure"}, 379 {0x0D, 0x02, D | T | L | P | W | R | S | O | C | A | K, 380 "Copy target device not reachable"}, 381 {0x0D, 0x03, D | T | L | P | W | R | S | O | C | A | K, 382 "Incorrect copy target device"}, 383 {0x0D, 0x04, D | T | L | P | W | R | S | O | C | A | K, 384 "Copy target device underrun"}, 385 {0x0D, 0x05, D | T | L | P | W | R | S | O | C | A | K, 386 "Copy target device overrun"}, 387 {0x10, 0x00, D | W | O | B | K, "Id CRC or ECC error"}, 388 {0x11, 0x00, D | T | W | R | S | O | B | K, "Unrecovered read error"}, 389 {0x11, 0x01, D | T | W | R | S | O | B | K, "Read retries exhausted"}, 390 {0x11, 0x02, D | T | W | R | S | O | B | K, 391 "Error too long to correct"}, 392 {0x11, 0x03, D | T | W | S | O | B | K, "Multiple read errors"}, 393 {0x11, 0x04, D | W | O | B | K, 394 "Unrecovered read error - auto reallocate failed"}, 395 {0x11, 0x05, W | R | O | B, "L-EC uncorrectable error"}, 396 {0x11, 0x06, W | R | O | B, "CIRC unrecovered error"}, 397 {0x11, 0x07, W | O | B, "Data re-synchronization error"}, 398 {0x11, 0x08, T, "Incomplete block read"}, 399 {0x11, 0x09, T, "No gap found"}, 400 {0x11, 0x0A, D | T | O | B | K, "Miscorrected error"}, 401 {0x11, 0x0B, D | W | O | B | K, 402 "Unrecovered read error - recommend reassignment"}, 403 {0x11, 0x0C, D | W | O | B | K, 404 "Unrecovered read error - recommend rewrite the data"}, 405 {0x11, 0x0D, D | T | W | R | O | B, "De-compression CRC error"}, 406 {0x11, 0x0E, D | T | W | R | O | B, 407 "Cannot decompress using declared algorithm"}, 408 {0x11, 0x0F, R, "Error reading UPC/EAN number"}, 409 {0x11, 0x10, R, "Error reading ISRC number"}, 410 {0x11, 0x11, R, "Read error - loss of streaming"}, 411 {0x11, 0x12, D | T | W | R | O | M | B, "Auxiliary memory read error"}, 412 {0x11, 0x13, SC_ALL_DEVS, "Read error - failed retransmission request"}, 413 {0x12, 0x00, D | W | O | B | K, "Address mark not found for id field"}, 414 {0x13, 0x00, D | W | O | B | K, 415 "Address mark not found for data field"}, 416 {0x14, 0x00, D | T | L | W | R | S | O | B | K, 417 "Recorded entity not found"}, 418 {0x14, 0x01, D | T | W | R | O | B | K, "Record not found"}, 419 {0x14, 0x02, T, "Filemark or setmark not found"}, 420 {0x14, 0x03, T, "End-of-data not found"}, 421 {0x14, 0x04, T, "Block sequence error"}, 422 {0x14, 0x05, D | T | W | O | B | K, 423 "Record not found - recommend reassignment"}, 424 {0x14, 0x06, D | T | W | O | B | K, 425 "Record not found - data auto-reallocated"}, 426 {0x14, 0x07, T, "Locate" SC_OPERATION " failure"}, 427 {0x15, 0x00, D | T | L | W | R | S | O | M | B | K, 428 "Random positioning error"}, 429 {0x15, 0x01, D | T | L | W | R | S | O | M | B | K, 430 "Mechanical positioning error"}, 431 {0x15, 0x02, D | T | W | R | O | B | K, 432 "Positioning error detected by read of medium"}, 433 {0x16, 0x00, D | W | O | B | K, "Data synchronization mark error"}, 434 {0x16, 0x01, D | W | O | B | K, "Data sync error - data rewritten"}, 435 {0x16, 0x02, D | W | O | B | K, "Data sync error - recommend rewrite"}, 436 {0x16, 0x03, D | W | O | B | K, 437 "Data sync error - data auto-reallocated"}, 438 {0x16, 0x04, D | W | O | B | K, 439 "Data sync error - recommend reassignment"}, 440 {0x17, 0x00, D | T | W | R | S | O | B | K, 441 SC_RECOVERED_DATA "with no error correction applied"}, 442 {0x17, 0x01, D | T | W | R | S | O | B | K, 443 SC_RECOVERED_DATA "with retries"}, 444 {0x17, 0x02, D | T | W | R | O | B | K, 445 SC_RECOVERED_DATA "with positive head offset"}, 446 {0x17, 0x03, D | T | W | R | O | B | K, 447 SC_RECOVERED_DATA "with negative head offset"}, 448 {0x17, 0x04, W | R | O | B, 449 SC_RECOVERED_DATA "with retries and/or circ applied"}, 450 {0x17, 0x05, D | W | R | O | B | K, 451 SC_RECOVERED_DATA "using previous sector id"}, 452 {0x17, 0x06, D | W | O | B | K, 453 SC_RECOVERED_DATA "without ecc - data auto-reallocated"}, 454 {0x17, 0x07, D | W | R | O | B | K, 455 SC_RECOVERED_DATA "without ecc - recommend reassignment"}, 456 {0x17, 0x08, D | W | R | O | B | K, 457 SC_RECOVERED_DATA "without ecc - recommend rewrite"}, 458 {0x17, 0x09, D | W | R | O | B | K, 459 SC_RECOVERED_DATA "without ecc - data rewritten"}, 460 {0x18, 0x00, D | T | W | R | O | B | K, 461 SC_RECOVERED_DATA "with error correction applied"}, 462 {0x18, 0x01, D | W | R | O | B | K, 463 SC_RECOVERED_DATA "with error corr. & retries applied"}, 464 {0x18, 0x02, D | W | R | O | B | K, 465 SC_RECOVERED_DATA "- data auto-reallocated"}, 466 {0x18, 0x03, R, SC_RECOVERED_DATA "with CIRC"}, 467 {0x18, 0x04, R, SC_RECOVERED_DATA "with L-EC"}, 468 {0x18, 0x05, D | W | R | O | B | K, 469 SC_RECOVERED_DATA "- recommend reassignment"}, 470 {0x18, 0x06, D | W | R | O | B | K, 471 SC_RECOVERED_DATA "- recommend rewrite"}, 472 {0x18, 0x07, D | W | O | B | K, 473 SC_RECOVERED_DATA "with ecc - data rewritten"}, 474 {0x18, 0x08, R, SC_RECOVERED_DATA "with linking"}, 475 {0x19, 0x00, D | O | K, "Defect list error"}, 476 {0x19, 0x01, D | O | K, "Defect list not available"}, 477 {0x19, 0x02, D | O | K, "Defect list error in primary list"}, 478 {0x19, 0x03, D | O | K, "Defect list error in grown list"}, 479 {0x1A, 0x00, SC_ALL_DEVS, "Parameter list length error"}, 480 {0x1B, 0x00, SC_ALL_DEVS, "Synchronous data transfer error"}, 481 {0x1C, 0x00, D | O | B | K, "Defect list not found"}, 482 {0x1C, 0x01, D | O | B | K, "Primary defect list not found"}, 483 {0x1C, 0x02, D | O | B | K, "Grown defect list not found"}, 484 {0x1D, 0x00, D | T | W | R | O | B | K, 485 "Miscompare during verify" SC_OPERATION}, 486 {0x1E, 0x00, D | W | O | B | K, "Recovered id with ecc correction"}, 487 {0x1F, 0x00, D | O | K, "Partial defect list transfer"}, 488 {0x20, 0x00, SC_ALL_DEVS, "Invalid command" SC_OPERATION " code"}, 489 {0x20, 0x01, D | T | P | W | R | O | M | A | E | B | K, 490 "Access denied - initiator pending-enrolled"}, 491 {0x20, 0x02, D | T | P | W | R | O | M | A | E | B | K, 492 "Access denied - no access rights"}, 493 {0x20, 0x03, D | T | P | W | R | O | M | A | E | B | K, 494 "Access denied - no mgmt id key"}, 495 {0x20, 0x04, T, "Illegal command while in write capable state"}, 496 {0x20, 0x05, T, "Obsolete"}, 497 {0x20, 0x06, T, "Illegal command while in explicit address mode"}, 498 {0x20, 0x07, T, "Illegal command while in implicit address mode"}, 499 {0x20, 0x08, D | T | P | W | R | O | M | A | E | B | K, 500 "Access denied - enrollment conflict"}, 501 {0x20, 0x09, D | T | P | W | R | O | M | A | E | B | K, 502 "Access denied - invalid LU identifier"}, 503 {0x20, 0x0A, D | T | P | W | R | O | M | A | E | B | K, 504 "Access denied - invalid proxy token"}, 505 {0x20, 0x0B, D | T | P | W | R | O | M | A | E | B | K, 506 "Access denied - ACL LUN conflict"}, 507 {0x21, 0x00, D | T | W | R | O | M | B | K, 508 "Logical block address out of range"}, 509 {0x21, 0x01, D | T | W | R | O | M | B | K, "Invalid element address"}, 510 {0x21, 0x02, R, "Invalid address for write"}, 511 {0x22, 0x00, D, "Illegal function (use 20 00,24 00,or 26 00)"}, 512 {0x24, 0x00, SC_ALL_DEVS, "Invalid field in cdb"}, 513 {0x24, 0x01, SC_ALL_DEVS, "CDB decryption error"}, 514 {0x25, 0x00, SC_ALL_DEVS, SC_LOGICAL_UNIT "not supported"}, 515 {0x26, 0x00, SC_ALL_DEVS, "Invalid field in parameter list"}, 516 {0x26, 0x01, SC_ALL_DEVS, "Parameter not supported"}, 517 {0x26, 0x02, SC_ALL_DEVS, "Parameter value invalid"}, 518 {0x26, 0x03, D | T | L | P | W | R | S | O | M | C | A | E | K, 519 "Threshold parameters not supported"}, 520 {0x26, 0x04, SC_ALL_DEVS, "Invalid release of persistent reservation"}, 521 {0x26, 0x05, D | T | L | P | W | R | S | O | M | C | A | B | K, 522 "Data decryption error"}, 523 {0x26, 0x06, D | T | L | P | W | R | S | O | C | K, 524 "Too many target descriptors"}, 525 {0x26, 0x07, D | T | L | P | W | R | S | O | C | K, 526 "Unsupported target descriptor type code"}, 527 {0x26, 0x08, D | T | L | P | W | R | S | O | C | K, 528 "Too many segment descriptors"}, 529 {0x26, 0x09, D | T | L | P | W | R | S | O | C | K, 530 "Unsupported segment descriptor type code"}, 531 {0x26, 0x0A, D | T | L | P | W | R | S | O | C | K, 532 "Unexpected inexact segment"}, 533 {0x26, 0x0B, D | T | L | P | W | R | S | O | C | K, 534 "Inline data length exceeded"}, 535 {0x26, 0x0C, D | T | L | P | W | R | S | O | C | K, 536 "Invalid" SC_OPERATION " for copy source or destination"}, 537 {0x26, 0x0D, D | T | L | P | W | R | S | O | C | K, 538 "Copy segment granularity violation"}, 539 {0x27, 0x00, D | T | W | R | O | B | K, "Write protected"}, 540 {0x27, 0x01, D | T | W | R | O | B | K, "Hardware write protected"}, 541 {0x27, 0x02, D | T | W | R | O | B | K, 542 SC_LOGICAL_UNIT "software write protected"}, 543 {0x27, 0x03, T | R, "Associated write protect"}, 544 {0x27, 0x04, T | R, "Persistent write protect"}, 545 {0x27, 0x05, T | R, "Permanent write protect"}, 546 {0x27, 0x06, R, "Conditional write protect"}, 547 {0x28, 0x00, SC_ALL_DEVS, 548 "Not ready to ready change, medium may have changed"}, 549 {0x28, 0x01, D | T | W | R | O | M | B, 550 "Import or export element accessed"}, 551 {0x29, 0x00, SC_ALL_DEVS, 552 "Power on,reset,or bus device reset occurred"}, 553 {0x29, 0x01, SC_ALL_DEVS, "Power on occurred"}, 554 {0x29, 0x02, SC_ALL_DEVS, "Scsi bus reset occurred"}, 555 {0x29, 0x03, SC_ALL_DEVS, "Bus device reset function occurred"}, 556 {0x29, 0x04, SC_ALL_DEVS, "Device internal reset"}, 557 {0x29, 0x05, SC_ALL_DEVS, "Transceiver mode changed to single-ended"}, 558 {0x29, 0x06, SC_ALL_DEVS, "Transceiver mode changed to lvd"}, 559 {0x29, 0x07, SC_ALL_DEVS, "I_T nexus loss occurred"}, 560 {0x2A, 0x00, D | T | L | W | R | S | O | M | C | A | E | B | K, 561 "Parameters changed"}, 562 {0x2A, 0x01, D | T | L | W | R | S | O | M | C | A | E | B | K, 563 "Mode parameters changed"}, 564 {0x2A, 0x02, D | T | L | W | R | S | O | M | C | A | E | K, 565 "Log parameters changed"}, 566 {0x2A, 0x03, D | T | L | P | W | R | S | O | M | C | A | E | K, 567 "Reservations preempted"}, 568 {0x2A, 0x04, D | T | L | P | W | R | S | O | M | C | A | E, 569 "Reservations released"}, 570 {0x2A, 0x05, D | T | L | P | W | R | S | O | M | C | A | E, 571 "Registrations preempted"}, 572 {0x2A, 0x06, SC_ALL_DEVS, "Asymmetric access state changed"}, 573 {0x2A, 0x07, SC_ALL_DEVS, 574 "Implicit asymmetric access state transition failed"}, 575 {0x2B, 0x00, D | T | L | P | W | R | S | O | C | K, 576 "Copy cannot execute since host cannot disconnect"}, 577 {0x2C, 0x00, SC_ALL_DEVS, "Command sequence error"}, 578 {0x2C, 0x01, S, "Too many windows specified"}, 579 {0x2C, 0x02, S, "Invalid combination of windows specified"}, 580 {0x2C, 0x03, R, "Current program area is not empty"}, 581 {0x2C, 0x04, R, "Current program area is empty"}, 582 {0x2C, 0x05, B, "Illegal power condition request"}, 583 {0x2C, 0x06, R, "Persistent prevent conflict"}, 584 {0x2C, 0x07, SC_ALL_DEVS, "Previous busy status"}, 585 {0x2C, 0x08, SC_ALL_DEVS, "Previous task set full status"}, 586 {0x2C, 0x09, D | T | L | P | W | R | S | O | M | E | B | K, 587 "Previous reservation conflict status"}, 588 {0x2D, 0x00, T, "Overwrite error on update in place"}, 589 {0x2F, 0x00, SC_ALL_DEVS, "Commands cleared by another initiator"}, 590 {0x30, 0x00, D | T | W | R | O | M | B | K, 591 "Incompatible medium installed"}, 592 {0x30, 0x01, D | T | W | R | O | B | K, 593 "Cannot read medium - unknown format"}, 594 {0x30, 0x02, D | T | W | R | O | B | K, 595 "Cannot read medium - incompatible format"}, 596 {0x30, 0x03, D | T | R | K, "Cleaning cartridge installed"}, 597 {0x30, 0x04, D | T | W | R | O | B | K, 598 "Cannot write medium - unknown format"}, 599 {0x30, 0x05, D | T | W | R | O | B | K, 600 "Cannot write medium - incompatible format"}, 601 {0x30, 0x06, D | T | W | R | O | B, 602 "Cannot format medium - incompatible medium"}, 603 {0x30, 0x07, D | T | L | W | R | S | O | M | A | E | B | K, 604 "Cleaning failure"}, 605 {0x30, 0x08, R, "Cannot write - application code mismatch"}, 606 {0x30, 0x09, R, "Current session not fixated for append"}, 607 {0x30, 0x10, R, "Medium not formatted"}, /* should ascq be 0xa ?? */ 608 {0x31, 0x00, D | T | W | R | O | B | K, "Medium format corrupted"}, 609 {0x31, 0x01, D | L | R | O | B, "Format command failed"}, 610 {0x31, 0x02, R, "Zoned formatting failed due to spare linking"}, 611 {0x32, 0x00, D | W | O | B | K, "No defect spare location available"}, 612 {0x32, 0x01, D | W | O | B | K, "Defect list update failure"}, 613 {0x33, 0x00, T, "Tape length error"}, 614 {0x34, 0x00, SC_ALL_DEVS, "Enclosure failure"}, 615 {0x35, 0x00, SC_ALL_DEVS, "Enclosure services failure"}, 616 {0x35, 0x01, SC_ALL_DEVS, "Unsupported enclosure function"}, 617 {0x35, 0x02, SC_ALL_DEVS, "Enclosure services unavailable"}, 618 {0x35, 0x03, SC_ALL_DEVS, "Enclosure services transfer failure"}, 619 {0x35, 0x04, SC_ALL_DEVS, "Enclosure services transfer refused"}, 620 {0x36, 0x00, L, "Ribbon,ink,or toner failure"}, 621 {0x37, 0x00, D | T | L | W | R | S | O | M | C | A | E | B | K, 622 "Rounded parameter"}, 623 {0x38, 0x00, B, "Event status notification"}, 624 {0x38, 0x02, B, "Esn - power management class event"}, 625 {0x38, 0x04, B, "Esn - media class event"}, 626 {0x38, 0x06, B, "Esn - device busy class event"}, 627 {0x39, 0x00, D | T | L | W | R | S | O | M | C | A | E | K, 628 "Saving parameters not supported"}, 629 {0x3A, 0x00, D | T | L | W | R | S | O | M | B | K, 630 "Medium not present"}, 631 {0x3A, 0x01, D | T | W | R | O | M | B | K, 632 "Medium not present - tray closed"}, 633 {0x3A, 0x02, D | T | W | R | O | M | B | K, 634 "Medium not present - tray open"}, 635 {0x3A, 0x03, D | T | W | R | O | M | B, 636 "Medium not present - loadable"}, 637 {0x3A, 0x04, D | T | W | R | O | M | B, 638 "Medium not present - medium auxiliary memory accessible"}, 639 {0x3B, 0x00, T | L, "Sequential positioning error"}, 640 {0x3B, 0x01, T, "Tape position error at beginning-of-medium"}, 641 {0x3B, 0x02, T, "Tape position error at end-of-medium"}, 642 {0x3B, 0x03, L, "Tape or electronic vertical forms unit " SC_NOT_READY}, 643 {0x3B, 0x04, L, "Slew failure"}, 644 {0x3B, 0x05, L, "Paper jam"}, 645 {0x3B, 0x06, L, "Failed to sense top-of-form"}, 646 {0x3B, 0x07, L, "Failed to sense bottom-of-form"}, 647 {0x3B, 0x08, T, "Reposition error"}, 648 {0x3B, 0x09, S, "Read past end of medium"}, 649 {0x3B, 0x0A, S, "Read past beginning of medium"}, 650 {0x3B, 0x0B, S, "Position past end of medium"}, 651 {0x3B, 0x0C, T | S, "Position past beginning of medium"}, 652 {0x3B, 0x0D, D | T | W | R | O | M | B | K, 653 "Medium destination element full"}, 654 {0x3B, 0x0E, D | T | W | R | O | M | B | K, 655 "Medium source element empty"}, 656 {0x3B, 0x0F, R, "End of medium reached"}, 657 {0x3B, 0x11, D | T | W | R | O | M | B | K, 658 "Medium magazine not accessible"}, 659 {0x3B, 0x12, D | T | W | R | O | M | B | K, "Medium magazine removed"}, 660 {0x3B, 0x13, D | T | W | R | O | M | B | K, "Medium magazine inserted"}, 661 {0x3B, 0x14, D | T | W | R | O | M | B | K, "Medium magazine locked"}, 662 {0x3B, 0x15, D | T | W | R | O | M | B | K, "Medium magazine unlocked"}, 663 {0x3B, 0x16, R, "Mechanical positioning or changer error"}, 664 {0x3D, 0x00, D | T | L | P | W | R | S | O | M | C | A | E | K, 665 "Invalid bits in identify message"}, 666 {0x3E, 0x00, SC_ALL_DEVS, 667 SC_LOGICAL_UNIT "has not self-configured yet"}, 668 {0x3E, 0x01, SC_ALL_DEVS, SC_LOGICAL_UNIT "failure"}, 669 {0x3E, 0x02, SC_ALL_DEVS, "Timeout on logical unit"}, 670 {0x3E, 0x03, SC_ALL_DEVS, SC_LOGICAL_UNIT "failed self-test"}, 671 {0x3E, 0x04, SC_ALL_DEVS, 672 SC_LOGICAL_UNIT "unable to update self-test log"}, 673 {0x3F, 0x00, SC_ALL_DEVS, "Target operating conditions have changed"}, 674 {0x3F, 0x01, SC_ALL_DEVS, "Microcode has been changed"}, 675 {0x3F, 0x02, D | T | L | P | W | R | S | O | M | C | B | K, 676 "Changed operating definition"}, 677 {0x3F, 0x03, SC_ALL_DEVS, "Inquiry data has changed"}, 678 {0x3F, 0x04, D | T | W | R | O | M | C | A | E | B | K, 679 "Component device attached"}, 680 {0x3F, 0x05, D | T | W | R | O | M | C | A | E | B | K, 681 "Device identifier changed"}, 682 {0x3F, 0x06, D | T | W | R | O | M | C | A | E | B, 683 "Redundancy group created or modified"}, 684 {0x3F, 0x07, D | T | W | R | O | M | C | A | E | B, 685 "Redundancy group deleted"}, 686 {0x3F, 0x08, D | T | W | R | O | M | C | A | E | B, 687 "Spare created or modified"}, 688 {0x3F, 0x09, D | T | W | R | O | M | C | A | E | B, "Spare deleted"}, 689 {0x3F, 0x0A, D | T | W | R | O | M | C | A | E | B | K, 690 "Volume set created or modified"}, 691 {0x3F, 0x0B, D | T | W | R | O | M | C | A | E | B | K, 692 "Volume set deleted"}, 693 {0x3F, 0x0C, D | T | W | R | O | M | C | A | E | B | K, 694 "Volume set deassigned"}, 695 {0x3F, 0x0D, D | T | W | R | O | M | C | A | E | B | K, 696 "Volume set reassigned"}, 697 {0x3F, 0x0E, D | T | L | P | W | R | S | O | M | C | A | E, 698 "Reported luns data has changed"}, 699 {0x3F, 0x10, D | T | W | R | O | M | B, "Medium loadable"}, 700 {0x3F, 0x11, D | T | W | R | O | M | B, 701 "Medium auxiliary memory accessible"}, 702 {0x40, 0x00, D, "Ram failure (should use 40 nn)"}, 703 /* 704 * FIXME(eric) - need a way to represent wildcards here. 705 */ 706 {0x40, 0x00, SC_ALL_DEVS, 707 "Diagnostic failure on component nn (80h-ffh)"}, 708 {0x41, 0x00, D, "Data path failure (should use 40 nn)"}, 709 {0x42, 0x00, D, "Power-on or self-test failure (should use 40 nn)"}, 710 {0x43, 0x00, SC_ALL_DEVS, "Message error"}, 711 {0x44, 0x00, SC_ALL_DEVS, "Internal target failure"}, 712 {0x45, 0x00, SC_ALL_DEVS, "Select or reselect failure"}, 713 {0x46, 0x00, D | T | L | P | W | R | S | O | M | C | B | K, 714 "Unsuccessful soft reset"}, 715 {0x47, 0x00, SC_ALL_DEVS, "Scsi parity error"}, 716 {0x47, 0x01, SC_ALL_DEVS, "Data phase CRC error detected"}, 717 {0x47, 0x02, SC_ALL_DEVS, 718 "Scsi parity error detected during st data phase"}, 719 {0x47, 0x03, SC_ALL_DEVS, "Information unit CRC error detected"}, 720 {0x47, 0x04, SC_ALL_DEVS, 721 "Asynchronous information protection error detected"}, 722 {0x47, 0x05, SC_ALL_DEVS, "Protocol service CRC error"}, 723 {0x48, 0x00, SC_ALL_DEVS, "Initiator detected error message received"}, 724 {0x49, 0x00, SC_ALL_DEVS, "Invalid message error"}, 725 {0x4A, 0x00, SC_ALL_DEVS, "Command phase error"}, 726 {0x4B, 0x00, SC_ALL_DEVS, "Data phase error"}, 727 {0x4C, 0x00, SC_ALL_DEVS, SC_LOGICAL_UNIT "failed self-configuration"}, 728 /* 729 * FIXME(eric) - need a way to represent wildcards here. 730 */ 731 {0x4D, 0x00, SC_ALL_DEVS, 732 "Tagged overlapped commands (nn = queue tag)"}, 733 {0x4E, 0x00, SC_ALL_DEVS, "Overlapped commands attempted"}, 734 {0x50, 0x00, T, "Write append error"}, 735 {0x50, 0x01, T, "Write append position error"}, 736 {0x50, 0x02, T, "Position error related to timing"}, 737 {0x51, 0x00, T | R | O, "Erase failure"}, 738 {0x52, 0x00, T, "Cartridge fault"}, 739 {0x53, 0x00, D | T | L | W | R | S | O | M | B | K, 740 "Media load or eject failed"}, 741 {0x53, 0x01, T, "Unload tape failure"}, 742 {0x53, 0x02, D | T | W | R | O | M | B | K, "Medium removal prevented"}, 743 {0x54, 0x00, P, "Scsi to host system interface failure"}, 744 {0x55, 0x00, P, "System resource failure"}, 745 {0x55, 0x01, D | O | B | K, "System buffer full"}, 746 {0x55, 0x02, D | T | L | P | W | R | S | O | M | A | E | K, 747 "Insufficient reservation resources"}, 748 {0x55, 0x03, D | T | L | P | W | R | S | O | M | C | A | E, 749 "Insufficient resources"}, 750 {0x55, 0x04, D | T | L | P | W | R | S | O | M | A | E, 751 "Insufficient registration resources"}, 752 {0x55, 0x05, D | T | P | W | R | O | M | A | E | B | K, 753 "Insufficient access control resources"}, 754 {0x55, 0x06, D | T | W | R | O | M | B, 755 "Auxiliary memory out of space"}, 756 {0x57, 0x00, R, "Unable to recover table-of-contents"}, 757 {0x58, 0x00, O, "Generation does not exist"}, 758 {0x59, 0x00, O, "Updated block read"}, 759 {0x5A, 0x00, D | T | L | P | W | R | S | O | M | B | K, 760 "Operator request or state change input"}, 761 {0x5A, 0x01, D | T | W | R | O | M | B | K, 762 "Operator medium removal request"}, 763 {0x5A, 0x02, D | T | W | R | O | A | B | K, 764 "Operator selected write protect"}, 765 {0x5A, 0x03, D | T | W | R | O | A | B | K, 766 "Operator selected write permit"}, 767 {0x5B, 0x00, D | T | L | P | W | R | S | O | M | K, "Log exception"}, 768 {0x5B, 0x01, D | T | L | P | W | R | S | O | M | K, 769 "Threshold condition met"}, 770 {0x5B, 0x02, D | T | L | P | W | R | S | O | M | K, 771 "Log counter at maximum"}, 772 {0x5B, 0x03, D | T | L | P | W | R | S | O | M | K, 773 "Log list codes exhausted"}, 774 {0x5C, 0x00, D | O, "Rpl status change"}, 775 {0x5C, 0x01, D | O, "Spindles synchronized"}, 776 {0x5C, 0x02, D | O, "Spindles not synchronized"}, 777 {0x5D, 0x00, SC_ALL_DEVS, "Failure prediction threshold exceeded"}, 778 {0x5D, 0x01, R | B, "Media failure prediction threshold exceeded"}, 779 {0x5D, 0x02, R, 780 SC_LOGICAL_UNIT "failure prediction threshold exceeded"}, 781 {0x5D, 0x03, R, "spare area exhaustion prediction threshold exceeded"}, 782 /* large series of "impending failure" messages */ 783 {0x5D, 0x10, D | B, SC_HARDWARE_IF "general hard drive failure"}, 784 {0x5D, 0x11, D | B, SC_HARDWARE_IF "drive" SC_ERROR_RATE_TOO_HIGH}, 785 {0x5D, 0x12, D | B, SC_HARDWARE_IF "data" SC_ERROR_RATE_TOO_HIGH}, 786 {0x5D, 0x13, D | B, SC_HARDWARE_IF "seek" SC_ERROR_RATE_TOO_HIGH}, 787 {0x5D, 0x14, D | B, SC_HARDWARE_IF "too many block reassigns"}, 788 {0x5D, 0x15, D | B, SC_HARDWARE_IF "access" SC_TIMES_TOO_HIGH}, 789 {0x5D, 0x16, D | B, SC_HARDWARE_IF "start unit" SC_TIMES_TOO_HIGH}, 790 {0x5D, 0x17, D | B, SC_HARDWARE_IF "channel parametrics"}, 791 {0x5D, 0x18, D | B, SC_HARDWARE_IF "controller detected"}, 792 {0x5D, 0x19, D | B, SC_HARDWARE_IF "throughput performance"}, 793 {0x5D, 0x1A, D | B, SC_HARDWARE_IF "seek time performance"}, 794 {0x5D, 0x1B, D | B, SC_HARDWARE_IF "spin-up retry count"}, 795 {0x5D, 0x1C, D | B, SC_HARDWARE_IF "drive calibration retry count"}, 796 {0x5D, 0x20, D | B, SC_CONTROLLER_IF "general hard drive failure"}, 797 {0x5D, 0x21, D | B, SC_CONTROLLER_IF "drive" SC_ERROR_RATE_TOO_HIGH}, 798 {0x5D, 0x22, D | B, SC_CONTROLLER_IF "data" SC_ERROR_RATE_TOO_HIGH}, 799 {0x5D, 0x23, D | B, SC_CONTROLLER_IF "seek" SC_ERROR_RATE_TOO_HIGH}, 800 {0x5D, 0x24, D | B, SC_CONTROLLER_IF "too many block reassigns"}, 801 {0x5D, 0x25, D | B, SC_CONTROLLER_IF "access" SC_TIMES_TOO_HIGH}, 802 {0x5D, 0x26, D | B, SC_CONTROLLER_IF "start unit" SC_TIMES_TOO_HIGH}, 803 {0x5D, 0x27, D | B, SC_CONTROLLER_IF "channel parametrics"}, 804 {0x5D, 0x28, D | B, SC_CONTROLLER_IF "controller detected"}, 805 {0x5D, 0x29, D | B, SC_CONTROLLER_IF "throughput performance"}, 806 {0x5D, 0x2A, D | B, SC_CONTROLLER_IF "seek time performance"}, 807 {0x5D, 0x2B, D | B, SC_CONTROLLER_IF "spin-up retry count"}, 808 {0x5D, 0x2C, D | B, SC_CONTROLLER_IF "drive calibration retry count"}, 809 {0x5D, 0x30, D | B, SC_DATA_CHANNEL_IF "general hard drive failure"}, 810 {0x5D, 0x31, D | B, SC_DATA_CHANNEL_IF "drive" SC_ERROR_RATE_TOO_HIGH}, 811 {0x5D, 0x32, D | B, SC_DATA_CHANNEL_IF "data" SC_ERROR_RATE_TOO_HIGH}, 812 {0x5D, 0x33, D | B, SC_DATA_CHANNEL_IF "seek" SC_ERROR_RATE_TOO_HIGH}, 813 {0x5D, 0x34, D | B, SC_DATA_CHANNEL_IF "too many block reassigns"}, 814 {0x5D, 0x35, D | B, SC_DATA_CHANNEL_IF "access" SC_TIMES_TOO_HIGH}, 815 {0x5D, 0x36, D | B, SC_DATA_CHANNEL_IF "start unit" SC_TIMES_TOO_HIGH}, 816 {0x5D, 0x37, D | B, SC_DATA_CHANNEL_IF "channel parametrics"}, 817 {0x5D, 0x38, D | B, SC_DATA_CHANNEL_IF "controller detected"}, 818 {0x5D, 0x39, D | B, SC_DATA_CHANNEL_IF "throughput performance"}, 819 {0x5D, 0x3A, D | B, SC_DATA_CHANNEL_IF "seek time performance"}, 820 {0x5D, 0x3B, D | B, SC_DATA_CHANNEL_IF "spin-up retry count"}, 821 {0x5D, 0x3C, D | B, SC_DATA_CHANNEL_IF "drive calibration retry count"}, 822 {0x5D, 0x40, D | B, SC_SERVO_IF "general hard drive failure"}, 823 {0x5D, 0x41, D | B, SC_SERVO_IF "drive" SC_ERROR_RATE_TOO_HIGH}, 824 {0x5D, 0x42, D | B, SC_SERVO_IF "data" SC_ERROR_RATE_TOO_HIGH}, 825 {0x5D, 0x43, D | B, SC_SERVO_IF "seek" SC_ERROR_RATE_TOO_HIGH}, 826 {0x5D, 0x44, D | B, SC_SERVO_IF "too many block reassigns"}, 827 {0x5D, 0x45, D | B, SC_SERVO_IF "access" SC_TIMES_TOO_HIGH}, 828 {0x5D, 0x46, D | B, SC_SERVO_IF "start unit" SC_TIMES_TOO_HIGH}, 829 {0x5D, 0x47, D | B, SC_SERVO_IF "channel parametrics"}, 830 {0x5D, 0x48, D | B, SC_SERVO_IF "controller detected"}, 831 {0x5D, 0x49, D | B, SC_SERVO_IF "throughput performance"}, 832 {0x5D, 0x4A, D | B, SC_SERVO_IF "seek time performance"}, 833 {0x5D, 0x4B, D | B, SC_SERVO_IF "spin-up retry count"}, 834 {0x5D, 0x4C, D | B, SC_SERVO_IF "drive calibration retry count"}, 835 {0x5D, 0x50, D | B, SC_SPINDLE_IF "general hard drive failure"}, 836 {0x5D, 0x51, D | B, SC_SPINDLE_IF "drive" SC_ERROR_RATE_TOO_HIGH}, 837 {0x5D, 0x52, D | B, SC_SPINDLE_IF "data" SC_ERROR_RATE_TOO_HIGH}, 838 {0x5D, 0x53, D | B, SC_SPINDLE_IF "seek" SC_ERROR_RATE_TOO_HIGH}, 839 {0x5D, 0x54, D | B, SC_SPINDLE_IF "too many block reassigns"}, 840 {0x5D, 0x55, D | B, SC_SPINDLE_IF "access" SC_TIMES_TOO_HIGH}, 841 {0x5D, 0x56, D | B, SC_SPINDLE_IF "start unit" SC_TIMES_TOO_HIGH}, 842 {0x5D, 0x57, D | B, SC_SPINDLE_IF "channel parametrics"}, 843 {0x5D, 0x58, D | B, SC_SPINDLE_IF "controller detected"}, 844 {0x5D, 0x59, D | B, SC_SPINDLE_IF "throughput performance"}, 845 {0x5D, 0x5A, D | B, SC_SPINDLE_IF "seek time performance"}, 846 {0x5D, 0x5B, D | B, SC_SPINDLE_IF "spin-up retry count"}, 847 {0x5D, 0x5C, D | B, SC_SPINDLE_IF "drive calibration retry count"}, 848 {0x5D, 0x60, D | B, SC_FIRMWARE_IF "general hard drive failure"}, 849 {0x5D, 0x61, D | B, SC_FIRMWARE_IF "drive" SC_ERROR_RATE_TOO_HIGH}, 850 {0x5D, 0x62, D | B, SC_FIRMWARE_IF "data" SC_ERROR_RATE_TOO_HIGH}, 851 {0x5D, 0x63, D | B, SC_FIRMWARE_IF "seek" SC_ERROR_RATE_TOO_HIGH}, 852 {0x5D, 0x64, D | B, SC_FIRMWARE_IF "too many block reassigns"}, 853 {0x5D, 0x65, D | B, SC_FIRMWARE_IF "access" SC_TIMES_TOO_HIGH}, 854 {0x5D, 0x66, D | B, SC_FIRMWARE_IF "start unit" SC_TIMES_TOO_HIGH}, 855 {0x5D, 0x67, D | B, SC_FIRMWARE_IF "channel parametrics"}, 856 {0x5D, 0x68, D | B, SC_FIRMWARE_IF "controller detected"}, 857 {0x5D, 0x69, D | B, SC_FIRMWARE_IF "throughput performance"}, 858 {0x5D, 0x6A, D | B, SC_FIRMWARE_IF "seek time performance"}, 859 {0x5D, 0x6B, D | B, SC_FIRMWARE_IF "spin-up retry count"}, 860 {0x5D, 0x6C, D | B, SC_FIRMWARE_IF "drive calibration retry count"}, 861 {0x5D, 0xFF, SC_ALL_DEVS, 862 "Failure prediction threshold exceeded (false)"}, 863 {0x5E, 0x00, D | T | L | P | W | R | S | O | C | A | K, 864 "Low power condition on"}, 865 {0x5E, 0x01, D | T | L | P | W | R | S | O | C | A | K, 866 "Idle condition activated by timer"}, 867 {0x5E, 0x02, D | T | L | P | W | R | S | O | C | A | K, 868 "Standby condition activated by timer"}, 869 {0x5E, 0x03, D | T | L | P | W | R | S | O | C | A | K, 870 "Idle condition activated by command"}, 871 {0x5E, 0x04, D | T | L | P | W | R | S | O | C | A | K, 872 "Standby condition activated by command"}, 873 {0x5E, 0x41, B, "Power state change to active"}, 874 {0x5E, 0x42, B, "Power state change to idle"}, 875 {0x5E, 0x43, B, "Power state change to standby"}, 876 {0x5E, 0x45, B, "Power state change to sleep"}, 877 {0x5E, 0x47, B | K, "Power state change to device control"}, 878 {0x60, 0x00, S, "Lamp failure"}, 879 {0x61, 0x00, S, "Video acquisition error"}, 880 {0x61, 0x01, S, "Unable to acquire video"}, 881 {0x61, 0x02, S, "Out of focus"}, 882 {0x62, 0x00, S, "Scan head positioning error"}, 883 {0x63, 0x00, R, "End of user area encountered on this track"}, 884 {0x63, 0x01, R, "Packet does not fit in available space"}, 885 {0x64, 0x00, R, "Illegal mode for this track"}, 886 {0x64, 0x01, R, "Invalid packet size"}, 887 {0x65, 0x00, SC_ALL_DEVS, "Voltage fault"}, 888 {0x66, 0x00, S, "Automatic document feeder cover up"}, 889 {0x66, 0x01, S, "Automatic document feeder lift up"}, 890 {0x66, 0x02, S, "Document jam in automatic document feeder"}, 891 {0x66, 0x03, S, "Document miss feed automatic in document feeder"}, 892 {0x67, 0x00, A, "Configuration failure"}, 893 {0x67, 0x01, A, "Configuration of incapable logical units failed"}, 894 {0x67, 0x02, A, "Add logical unit failed"}, 895 {0x67, 0x03, A, "Modification of logical unit failed"}, 896 {0x67, 0x04, A, "Exchange of logical unit failed"}, 897 {0x67, 0x05, A, "Remove of logical unit failed"}, 898 {0x67, 0x06, A, "Attachment of logical unit failed"}, 899 {0x67, 0x07, A, "Creation of logical unit failed"}, 900 {0x67, 0x08, A, "Assign failure occurred"}, 901 {0x67, 0x09, A, "Multiply assigned logical unit"}, 902 {0x67, 0x0A, SC_ALL_DEVS, "Set target port groups command failed"}, 903 {0x68, 0x00, A, SC_LOGICAL_UNIT "not configured"}, 904 {0x69, 0x00, A, "Data loss on logical unit"}, 905 {0x69, 0x01, A, "Multiple logical unit failures"}, 906 {0x69, 0x02, A, "Parity/data mismatch"}, 907 {0x6A, 0x00, A, "Informational,refer to log"}, 908 {0x6B, 0x00, A, "State change has occurred"}, 909 {0x6B, 0x01, A, "Redundancy level got better"}, 910 {0x6B, 0x02, A, "Redundancy level got worse"}, 911 {0x6C, 0x00, A, "Rebuild failure occurred"}, 912 {0x6D, 0x00, A, "Recalculate failure occurred"}, 913 {0x6E, 0x00, A, "Command to logical unit failed"}, 914 {0x6F, 0x00, R, 915 "Copy protection key exchange failure - authentication failure"}, 916 {0x6F, 0x01, R, 917 "Copy protection key exchange failure - key not present"}, 918 {0x6F, 0x02, R, 919 "Copy protection key exchange failure - key not established"}, 920 {0x6F, 0x03, R, "Read of scrambled sector without authentication"}, 921 {0x6F, 0x04, R, 922 "Media region code is mismatched to logical unit region"}, 923 {0x6F, 0x05, R, 924 "Drive region must be permanent/region reset count error"}, 925 /* 926 * FIXME(eric) - need a way to represent wildcards here. 927 */ 928 {0x70, 0x00, T, "Decompression exception short algorithm id of nn"}, 929 {0x71, 0x00, T, "Decompression exception long algorithm id"}, 930 {0x72, 0x00, R, "Session fixation error"}, 931 {0x72, 0x01, R, "Session fixation error writing lead-in"}, 932 {0x72, 0x02, R, "Session fixation error writing lead-out"}, 933 {0x72, 0x03, R, "Session fixation error - incomplete track in session"}, 934 {0x72, 0x04, R, "Empty or partially written reserved track"}, 935 {0x72, 0x05, R, "No more track reservations allowed"}, 936 {0x73, 0x00, R, "Cd control error"}, 937 {0x73, 0x01, R, "Power calibration area almost full"}, 938 {0x73, 0x02, R, "Power calibration area is full"}, 939 {0x73, 0x03, R, "Power calibration area error"}, 940 {0x73, 0x04, R, "Program memory area update failure"}, 941 {0x73, 0x05, R, "Program memory area is full"}, 942 {0x73, 0x06, R, "RMA/PMA is full"}, 943 {0, 0, 0, NULL} 944 }; 945 946 static const char *sc_oft_used[0x1f] = { 947 "umulig", /* index 0x0 should be impossible */ 948 "Audio play operation ", 949 "Logical unit ", 950 "not ready, ", 951 " operation", 952 " in progress ", 953 "Hardware impending failure ", 954 "Controller impending failure ", 955 "Data channel impending failure ", /* index 0x8 */ 956 "Servo impending failure ", 957 "Spindle impending failure ", 958 "Firmware impending failure ", 959 "Recovered data ", 960 " error rate too high", 961 " times too high", 962 }; 963 964 static const char *snstext[] = { 965 "No Sense", /* There is no sense information */ 966 "Recovered Error", /* The last command completed successfully 967 but used error correction */ 968 "Not Ready", /* The addressed target is not ready */ 969 "Medium Error", /* Data error detected on the medium */ 970 "Hardware Error", /* Controller or device failure */ 971 "Illegal Request", 972 "Unit Attention", /* Removable medium was changed, or 973 the target has been reset */ 974 "Data Protect", /* Access to the data is blocked */ 975 "Blank Check", /* Reached unexpected written or unwritten 976 region of the medium */ 977 "Key=9", /* Vendor specific */ 978 "Copy Aborted", /* COPY or COMPARE was aborted */ 979 "Aborted Command", /* The target aborted the command */ 980 "Equal", /* SEARCH DATA found data equal (obsolete) */ 981 "Volume Overflow", /* Medium full with still data to be written */ 982 "Miscompare", /* Source data and data on the medium 983 do not agree */ 984 "Key=15" /* Reserved */ 985 }; 986 987 static 988 void sg_print_asc_ascq(unsigned char asc, unsigned char ascq) 989 { 990 int k, j; 991 char obuff[256]; 992 const char *ccp; 993 const char *oup; 994 char c; 995 int found = 0; 996 997 for (k = 0; additional[k].text; k++) { 998 if (additional[k].code1 == asc && additional[k].code2 == ascq) { 999 found = 1; 1000 ccp = additional[k].text; 1001 for (j = 0; *ccp && (j < sizeof(obuff)); ++ccp) { 1002 c = *ccp; 1003 if ((c < 0x20) && (c > 0)) { 1004 oup = sc_oft_used[(int)c]; 1005 if (oup) { 1006 strcpy(obuff + j, oup); 1007 j += strlen(oup); 1008 } else { 1009 strcpy(obuff + j, "???"); 1010 j += 3; 1011 } 1012 } else 1013 obuff[j++] = c; 1014 } 1015 if (j < sizeof(obuff)) 1016 obuff[j] = '\0'; 1017 else 1018 obuff[sizeof(obuff) - 1] = '\0'; 1019 fprintf(OUTP, "Additional sense: %s\n", obuff); 1020 } 1021 } 1022 if (found) 1023 return; 1024 1025 for (k = 0; additional2[k].text; k++) { 1026 if ((additional2[k].code1 == asc) && 1027 (ascq >= additional2[k].code2_min) && 1028 (ascq <= additional2[k].code2_max)) { 1029 found = 1; 1030 fprintf(OUTP, "Additional sense: "); 1031 fprintf(OUTP, additional2[k].text, ascq); 1032 fprintf(OUTP, "\n"); 1033 } 1034 } 1035 if (!found) 1036 fprintf(OUTP, "ASC=%2x ASCQ=%2x\n", asc, ascq); 1037 } 1038 1039 /* Print sense information */ 1040 void sg_print_sense(const char *leadin, const unsigned char *sense_buffer, 1041 int sb_len) 1042 { 1043 int k, s; 1044 int sense_key, sense_class, valid, code; 1045 int descriptor_format = 0; 1046 const char *error = NULL; 1047 1048 if (sb_len < 1) { 1049 fprintf(OUTP, "sense buffer empty\n"); 1050 return; 1051 } 1052 sense_class = (sense_buffer[0] >> 4) & 0x07; 1053 code = sense_buffer[0] & 0xf; 1054 valid = sense_buffer[0] & 0x80; 1055 if (leadin) 1056 fprintf(OUTP, "%s: ", leadin); 1057 1058 if (sense_class == 7) { /* extended sense data */ 1059 s = sense_buffer[7] + 8; 1060 if (s > sb_len) { 1061 fprintf(OUTP, 1062 "Sense buffer too small (at %d bytes), %d bytes " 1063 "truncated\n", sb_len, s - sb_len); 1064 s = sb_len; 1065 } 1066 1067 switch (code) { 1068 case 0x0: 1069 error = "Current"; /* error concerns current command */ 1070 break; 1071 case 0x1: 1072 error = "Deferred"; /* error concerns some earlier command */ 1073 /* e.g., an earlier write to disk cache succeeded, but 1074 now the disk discovers that it cannot write the data */ 1075 break; 1076 case 0x2: 1077 descriptor_format = 1; 1078 error = "Descriptor current"; 1079 /* new descriptor sense format */ 1080 break; 1081 case 0x3: 1082 descriptor_format = 1; 1083 error = "Descriptor deferred"; 1084 /* new descriptor sense format (deferred report) */ 1085 break; 1086 default: 1087 error = "Invalid"; 1088 } 1089 sense_key = sense_buffer[descriptor_format ? 1 : 2] & 0xf; 1090 fprintf(OUTP, "%s, Sense key: %s\n", error, snstext[sense_key]); 1091 1092 if (descriptor_format) 1093 sg_print_asc_ascq(sense_buffer[2], sense_buffer[3]); 1094 else { 1095 if (!valid) 1096 fprintf(OUTP, "[valid=0] "); 1097 fprintf(OUTP, "Info fld=0x%x, ", 1098 (int)((sense_buffer[3] << 24) | 1099 (sense_buffer[4] << 16) | (sense_buffer[5] 1100 << 8) | 1101 sense_buffer[6])); 1102 1103 if (sense_buffer[2] & 0x80) 1104 fprintf(OUTP, "FMK "); /* current command has read a filemark */ 1105 if (sense_buffer[2] & 0x40) 1106 fprintf(OUTP, "EOM "); /* end-of-medium condition exists */ 1107 if (sense_buffer[2] & 0x20) 1108 fprintf(OUTP, "ILI "); /* incorrect block length requested */ 1109 1110 if (s > 13) { 1111 if (sense_buffer[12] || sense_buffer[13]) 1112 sg_print_asc_ascq(sense_buffer[12], 1113 sense_buffer[13]); 1114 } 1115 if (sense_key == 5 && s >= 18 1116 && (sense_buffer[15] & 0x80)) { 1117 fprintf(OUTP, 1118 "Sense Key Specific: Error in %s byte %d", 1119 (sense_buffer[15] & 0x40) ? "Command" : 1120 "Data", 1121 (sense_buffer[16] << 8) | 1122 sense_buffer[17]); 1123 if (sense_buffer[15] & 0x08) { 1124 fprintf(OUTP, " bit %d\n", 1125 sense_buffer[15] & 0x07); 1126 } else { 1127 fprintf(OUTP, "\n"); 1128 } 1129 } 1130 } 1131 1132 } else { /* non-extended sense data */ 1133 1134 /* 1135 * Standard says: 1136 * sense_buffer[0] & 0200 : address valid 1137 * sense_buffer[0] & 0177 : vendor-specific error code 1138 * sense_buffer[1] & 0340 : vendor-specific 1139 * sense_buffer[1..3] : 21-bit logical block address 1140 */ 1141 1142 if (sb_len < 4) { 1143 fprintf(OUTP, 1144 "sense buffer too short (4 byte minimum)\n"); 1145 return; 1146 } 1147 if (leadin) 1148 fprintf(OUTP, "%s: ", leadin); 1149 if (sense_buffer[0] < 15) 1150 fprintf(OUTP, 1151 "old sense: key %s\n", 1152 snstext[sense_buffer[0] & 0x0f]); 1153 else 1154 fprintf(OUTP, "sns = %2x %2x\n", sense_buffer[0], 1155 sense_buffer[2]); 1156 1157 fprintf(OUTP, "Non-extended sense class %d code 0x%0x ", 1158 sense_class, code); 1159 s = 4; 1160 } 1161 1162 fprintf(OUTP, "Raw sense data (in hex):\n "); 1163 for (k = 0; k < s; ++k) { 1164 if ((k > 0) && (0 == (k % 24))) 1165 fprintf(OUTP, "\n "); 1166 fprintf(OUTP, "%02x ", sense_buffer[k]); 1167 } 1168 fprintf(OUTP, "\n"); 1169 } 1170 1171 static const char *hostbyte_table[] = { 1172 "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", 1173 "DID_BAD_TARGET", 1174 "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", 1175 "DID_PASSTHROUGH", "DID_SOFT_ERROR", NULL 1176 }; 1177 1178 void sg_print_host_status(int host_status) 1179 { 1180 static int maxcode = 0; 1181 int i; 1182 1183 if (!maxcode) { 1184 for (i = 0; hostbyte_table[i]; i++) ; 1185 maxcode = i - 1; 1186 } 1187 fprintf(OUTP, "Host_status=0x%02x", host_status); 1188 if (host_status > maxcode) { 1189 fprintf(OUTP, "is invalid "); 1190 return; 1191 } 1192 fprintf(OUTP, "(%s) ", hostbyte_table[host_status]); 1193 } 1194 1195 static const char *driverbyte_table[] = { 1196 "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", 1197 "DRIVER_ERROR", 1198 "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE", NULL 1199 }; 1200 1201 static const char *driversuggest_table[] = { "SUGGEST_OK", 1202 "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", 1203 unknown, unknown, unknown, "SUGGEST_SENSE", NULL 1204 }; 1205 1206 void sg_print_driver_status(int driver_status) 1207 { 1208 static int driver_max = 0, suggest_max = 0; 1209 int i; 1210 int dr = driver_status & SG_ERR_DRIVER_MASK; 1211 int su = (driver_status & SG_ERR_SUGGEST_MASK) >> 4; 1212 1213 if (!driver_max) { 1214 for (i = 0; driverbyte_table[i]; i++) ; 1215 driver_max = i; 1216 for (i = 0; driversuggest_table[i]; i++) ; 1217 suggest_max = i; 1218 } 1219 fprintf(OUTP, "Driver_status=0x%02x", driver_status); 1220 fprintf(OUTP, " (%s,%s) ", 1221 dr < driver_max ? driverbyte_table[dr] : "invalid", 1222 su < suggest_max ? driversuggest_table[su] : "invalid"); 1223 } 1224 1225 static int sg_sense_print(const char *leadin, int scsi_status, 1226 int host_status, int driver_status, 1227 const unsigned char *sense_buffer, int sb_len) 1228 { 1229 int done_leadin = 0; 1230 int done_sense = 0; 1231 1232 scsi_status &= 0x7e; /*sanity */ 1233 if ((0 == scsi_status) && (0 == host_status) && (0 == driver_status)) 1234 return 1; /* No problems */ 1235 if (0 != scsi_status) { 1236 if (leadin) 1237 fprintf(OUTP, "%s: ", leadin); 1238 done_leadin = 1; 1239 fprintf(OUTP, "scsi status: "); 1240 sg_print_scsi_status(scsi_status); 1241 fprintf(OUTP, "\n"); 1242 if (sense_buffer && ((scsi_status == SCSI_CHECK_CONDITION) || 1243 (scsi_status == 1244 SCSI_COMMAND_TERMINATED))) { 1245 sg_print_sense(0, sense_buffer, sb_len); 1246 done_sense = 1; 1247 } 1248 } 1249 if (0 != host_status) { 1250 if (leadin && (!done_leadin)) 1251 fprintf(OUTP, "%s: ", leadin); 1252 if (done_leadin) 1253 fprintf(OUTP, "plus...: "); 1254 else 1255 done_leadin = 1; 1256 sg_print_host_status(host_status); 1257 fprintf(OUTP, "\n"); 1258 } 1259 if (0 != driver_status) { 1260 if (leadin && (!done_leadin)) 1261 fprintf(OUTP, "%s: ", leadin); 1262 if (done_leadin) 1263 fprintf(OUTP, "plus...: "); 1264 else 1265 done_leadin = 1; 1266 sg_print_driver_status(driver_status); 1267 fprintf(OUTP, "\n"); 1268 if (sense_buffer && (!done_sense) && 1269 (SG_ERR_DRIVER_SENSE == (0xf & driver_status))) 1270 sg_print_sense(0, sense_buffer, sb_len); 1271 } 1272 return 0; 1273 } 1274 1275 #ifdef SG_IO 1276 int sg_chk_n_print3(const char *leadin, struct sg_io_hdr *hp) 1277 { 1278 return sg_sense_print(leadin, hp->status, hp->host_status, 1279 hp->driver_status, hp->sbp, hp->sb_len_wr); 1280 } 1281 #endif 1282 1283 int sg_chk_n_print(const char *leadin, int masked_status, 1284 int host_status, int driver_status, 1285 const unsigned char *sense_buffer, int sb_len) 1286 { 1287 int scsi_status = (masked_status << 1) & 0x7e; 1288 1289 return sg_sense_print(leadin, scsi_status, host_status, driver_status, 1290 sense_buffer, sb_len); 1291 } 1292 1293 #ifdef SG_IO 1294 int sg_err_category3(struct sg_io_hdr *hp) 1295 { 1296 return sg_err_category_new(hp->status, hp->host_status, 1297 hp->driver_status, hp->sbp, hp->sb_len_wr); 1298 } 1299 #endif 1300 1301 int sg_err_category(int masked_status, int host_status, 1302 int driver_status, const unsigned char *sense_buffer, 1303 int sb_len) 1304 { 1305 int scsi_status = (masked_status << 1) & 0x7e; 1306 1307 return sg_err_category_new(scsi_status, host_status, driver_status, 1308 sense_buffer, sb_len); 1309 } 1310 1311 int sg_err_category_new(int scsi_status, int host_status, int driver_status, 1312 const unsigned char *sense_buffer, int sb_len) 1313 { 1314 scsi_status &= 0x7e; 1315 if ((0 == scsi_status) && (0 == host_status) && (0 == driver_status)) 1316 return SG_ERR_CAT_CLEAN; 1317 if ((SCSI_CHECK_CONDITION == scsi_status) || 1318 (SCSI_COMMAND_TERMINATED == scsi_status) || 1319 (SG_ERR_DRIVER_SENSE == (0xf & driver_status))) { 1320 if (sense_buffer && (sb_len > 2)) { 1321 int sense_key; 1322 unsigned char asc; 1323 1324 if (sense_buffer[0] & 0x2) { 1325 sense_key = sense_buffer[1] & 0xf; 1326 asc = sense_buffer[2]; 1327 } else { 1328 sense_key = sense_buffer[2] & 0xf; 1329 asc = (sb_len > 12) ? sense_buffer[12] : 0; 1330 } 1331 1332 if (RECOVERED_ERROR == sense_key) 1333 return SG_ERR_CAT_RECOVERED; 1334 else if (UNIT_ATTENTION == sense_key) { 1335 if (0x28 == asc) 1336 return SG_ERR_CAT_MEDIA_CHANGED; 1337 if (0x29 == asc) 1338 return SG_ERR_CAT_RESET; 1339 } 1340 } 1341 return SG_ERR_CAT_SENSE; 1342 } 1343 if (0 != host_status) { 1344 if ((SG_ERR_DID_NO_CONNECT == host_status) || 1345 (SG_ERR_DID_BUS_BUSY == host_status) || 1346 (SG_ERR_DID_TIME_OUT == host_status)) 1347 return SG_ERR_CAT_TIMEOUT; 1348 } 1349 if (0 != driver_status) { 1350 if (SG_ERR_DRIVER_TIMEOUT == driver_status) 1351 return SG_ERR_CAT_TIMEOUT; 1352 } 1353 return SG_ERR_CAT_OTHER; 1354 } 1355 1356 int sg_get_command_size(unsigned char opcode) 1357 { 1358 return COMMAND_SIZE(opcode); 1359 } 1360 1361 void sg_get_command_name(unsigned char opcode, int buff_len, char *buff) 1362 { 1363 const char **table = commands[group(opcode)]; 1364 1365 if ((NULL == buff) || (buff_len < 1)) 1366 return; 1367 1368 switch ((unsigned long)table) { 1369 case RESERVED_GROUP: 1370 strncpy(buff, reserved, buff_len); 1371 break; 1372 case VENDOR_GROUP: 1373 strncpy(buff, vendor, buff_len); 1374 break; 1375 default: 1376 strncpy(buff, table[opcode & 0x1f], buff_len); 1377 break; 1378 } 1379 } 1380