1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/scsi/generic/sense.h> 31 #include <sys/scsi/generic/status.h> 32 33 #include <stddef.h> 34 #include <stdio.h> 35 36 #include <scsi/libscsi.h> 37 #include "libscsi_impl.h" 38 39 typedef struct slist { 40 char *str; 41 int value; 42 } slist_t; 43 44 static slist_t sensekey_strings[] = { 45 { "No sense error", KEY_NO_SENSE }, 46 { "Recoverable error", KEY_RECOVERABLE_ERROR }, 47 { "Not ready error", KEY_NOT_READY }, 48 { "Medium error", KEY_MEDIUM_ERROR }, 49 { "Hardware error", KEY_HARDWARE_ERROR }, 50 { "Illegal request", KEY_ILLEGAL_REQUEST }, 51 { "Unit attention error", KEY_UNIT_ATTENTION }, 52 { "Write protect error", KEY_WRITE_PROTECT }, 53 { "Blank check error", KEY_BLANK_CHECK }, 54 { "Vendor unique error", KEY_VENDOR_UNIQUE }, 55 { "Copy aborted error", KEY_COPY_ABORTED }, 56 { "Aborted command", KEY_ABORTED_COMMAND }, 57 { "Equal error", KEY_EQUAL }, 58 { "Volume overflow", KEY_VOLUME_OVERFLOW }, 59 { "Miscompare error", KEY_MISCOMPARE }, 60 { "Reserved error", KEY_RESERVED }, 61 { NULL, 0 } 62 }; 63 64 static struct asq_key_strings { 65 uint_t asc; 66 uint_t ascq; 67 const char *message; 68 } extended_sense_list[] = { 69 { 0x00, 0x00, "no additional sense info" }, 70 { 0x00, 0x01, "filemark detected" }, 71 { 0x00, 0x02, "end of partition/medium detected" }, 72 { 0x00, 0x03, "setmark detected" }, 73 { 0x00, 0x04, "begining of partition/medium detected" }, 74 { 0x00, 0x05, "end of data detected" }, 75 { 0x00, 0x06, "i/o process terminated" }, 76 { 0x00, 0x11, "audio play operation in progress" }, 77 { 0x00, 0x12, "audio play operation paused" }, 78 { 0x00, 0x13, "audio play operation successfully completed" }, 79 { 0x00, 0x14, "audio play operation stopped due to error" }, 80 { 0x00, 0x15, "no current audio status to return" }, 81 { 0x00, 0x16, "operation in progress" }, 82 { 0x00, 0x17, "cleaning requested" }, 83 { 0x00, 0x18, "erase operation in progress" }, 84 { 0x00, 0x19, "locate operation in progress" }, 85 { 0x00, 0x1A, "rewind operation in progress" }, 86 { 0x00, 0x1B, "set capacity operation in progress" }, 87 { 0x00, 0x1C, "verify operation in progress" }, 88 { 0x01, 0x00, "no index/sector signal" }, 89 { 0x02, 0x00, "no seek complete" }, 90 { 0x03, 0x00, "peripheral device write fault" }, 91 { 0x03, 0x01, "no write current" }, 92 { 0x03, 0x02, "excessive write errors" }, 93 { 0x04, 0x00, "LUN not ready" }, 94 { 0x04, 0x01, "LUN is becoming ready" }, 95 { 0x04, 0x02, "LUN initializing command required" }, 96 { 0x04, 0x03, "LUN not ready intervention required" }, 97 { 0x04, 0x04, "LUN not ready format in progress" }, 98 { 0x04, 0x05, "LUN not ready, rebuild in progress" }, 99 { 0x04, 0x06, "LUN not ready, recalculation in progress" }, 100 { 0x04, 0x07, "LUN not ready, operation in progress" }, 101 { 0x04, 0x08, "LUN not ready, long write in progress" }, 102 { 0x04, 0x09, "LUN not ready, self-test in progress" }, 103 { 0x04, 0x0A, "LUN not accessible, asymmetric access state " 104 "transition" }, 105 { 0x04, 0x0B, "LUN not accessible, target port in standby state" }, 106 { 0x04, 0x0C, "LUN not accessible, target port in unavailable state" }, 107 { 0x04, 0x10, "LUN not ready, auxiliary memory not accessible" }, 108 { 0x05, 0x00, "LUN does not respond to selection" }, 109 { 0x06, 0x00, "reference position found" }, 110 { 0x07, 0x00, "multiple peripheral devices selected" }, 111 { 0x08, 0x00, "LUN communication failure" }, 112 { 0x08, 0x01, "LUN communication time-out" }, 113 { 0x08, 0x02, "LUN communication parity error" }, 114 { 0x08, 0x03, "LUN communication crc error (ultra-DMA/32)" }, 115 { 0x08, 0x04, "unreachable copy target" }, 116 { 0x09, 0x00, "track following error" }, 117 { 0x09, 0x01, "tracking servo failure" }, 118 { 0x09, 0x02, "focus servo failure" }, 119 { 0x09, 0x03, "spindle servo failure" }, 120 { 0x09, 0x04, "head select fault" }, 121 { 0x0a, 0x00, "error log overflow" }, 122 { 0x0b, 0x00, "warning" }, 123 { 0x0b, 0x01, "warning - specified temperature exceeded" }, 124 { 0x0b, 0x02, "warning - enclosure degraded" }, 125 { 0x0c, 0x00, "write error" }, 126 { 0x0c, 0x01, "write error - recovered with auto reallocation" }, 127 { 0x0c, 0x02, "write error - auto reallocation failed" }, 128 { 0x0c, 0x03, "write error - recommend reassignment" }, 129 { 0x0c, 0x04, "compression check miscompare error" }, 130 { 0x0c, 0x05, "data expansion occurred during compression" }, 131 { 0x0c, 0x06, "block not compressible" }, 132 { 0x0c, 0x07, "write error - recovery needed" }, 133 { 0x0c, 0x08, "write error - recovery failed" }, 134 { 0x0c, 0x09, "write error - loss of streaming" }, 135 { 0x0c, 0x0a, "write error - padding blocks added" }, 136 { 0x0c, 0x0b, "auxiliary memory write error" }, 137 { 0x0c, 0x0c, "write error - unexpected unsolicited data" }, 138 { 0x0c, 0x0d, "write error - not enough unsolicited data" }, 139 { 0x0d, 0x00, "error detected by third party temporary initiator" }, 140 { 0x0d, 0x01, "third party device failure" }, 141 { 0x0d, 0x02, "copy target device not reachable" }, 142 { 0x0d, 0x03, "incorrect copy target device type" }, 143 { 0x0d, 0x04, "copy target device data underrun" }, 144 { 0x0d, 0x05, "copy target device data overrun" }, 145 { 0x0e, 0x00, "invalid information unit" }, 146 { 0x0e, 0x01, "information unit too short" }, 147 { 0x0e, 0x02, "information unit too long" }, 148 { 0x10, 0x00, "ID CRC or ECC error" }, 149 { 0x11, 0x00, "unrecovered read error" }, 150 { 0x11, 0x01, "read retries exhausted" }, 151 { 0x11, 0x02, "error too long to correct" }, 152 { 0x11, 0x03, "multiple read errors" }, 153 { 0x11, 0x04, "unrecovered read error - auto reallocate failed" }, 154 { 0x11, 0x05, "L-EC uncorrectable error" }, 155 { 0x11, 0x06, "CIRC unrecovered error" }, 156 { 0x11, 0x07, "data re-synchronization error" }, 157 { 0x11, 0x08, "incomplete block read" }, 158 { 0x11, 0x09, "no gap found" }, 159 { 0x11, 0x0a, "miscorrected error" }, 160 { 0x11, 0x0b, "unrecovered read error - recommend reassignment" }, 161 { 0x11, 0x0c, "unrecovered read error - recommend rewrite the data" }, 162 { 0x11, 0x0d, "de-compression crc error" }, 163 { 0x11, 0x0e, "cannot decompress using declared algorithm" }, 164 { 0x11, 0x0f, "error reading UPC/EAN number" }, 165 { 0x11, 0x10, "error reading ISRC number" }, 166 { 0x11, 0x11, "read error - loss of streaming" }, 167 { 0x11, 0x12, "auxiliary memory read error" }, 168 { 0x11, 0x13, "read error - failed retransmission request" }, 169 { 0x12, 0x00, "address mark not found for ID field" }, 170 { 0x13, 0x00, "address mark not found for data field" }, 171 { 0x14, 0x00, "recorded entity not found" }, 172 { 0x14, 0x01, "record not found" }, 173 { 0x14, 0x02, "filemark or setmark not found" }, 174 { 0x14, 0x03, "end-of-data not found" }, 175 { 0x14, 0x04, "block sequence error" }, 176 { 0x14, 0x05, "record not found - recommend reassignment" }, 177 { 0x14, 0x06, "record not found - data auto-reallocated" }, 178 { 0x14, 0x07, "locate operation failure" }, 179 { 0x15, 0x00, "random positioning error" }, 180 { 0x15, 0x01, "mechanical positioning error" }, 181 { 0x15, 0x02, "positioning error detected by read of medium" }, 182 { 0x16, 0x00, "data sync mark error" }, 183 { 0x16, 0x01, "data sync error - data rewritten" }, 184 { 0x16, 0x02, "data sync error - recommend rewrite" }, 185 { 0x16, 0x03, "data sync error - data auto-reallocated" }, 186 { 0x16, 0x04, "data sync error - recommend reassignment" }, 187 { 0x17, 0x00, "recovered data with no error correction" }, 188 { 0x17, 0x01, "recovered data with retries" }, 189 { 0x17, 0x02, "recovered data with positive head offset" }, 190 { 0x17, 0x03, "recovered data with negative head offset" }, 191 { 0x17, 0x04, "recovered data with retries and/or CIRC applied" }, 192 { 0x17, 0x05, "recovered data using previous sector id" }, 193 { 0x17, 0x06, "recovered data without ECC - data auto-reallocated" }, 194 { 0x17, 0x07, "recovered data without ECC - recommend reassignment" }, 195 { 0x17, 0x08, "recovered data without ECC - recommend rewrite" }, 196 { 0x17, 0x09, "recovered data without ECC - data rewritten" }, 197 { 0x18, 0x00, "recovered data with error correction" }, 198 { 0x18, 0x01, "recovered data with error corr. & retries applied" }, 199 { 0x18, 0x02, "recovered data - data auto-reallocated" }, 200 { 0x18, 0x03, "recovered data with CIRC" }, 201 { 0x18, 0x04, "recovered data with L-EC" }, 202 { 0x18, 0x05, "recovered data - recommend reassignment" }, 203 { 0x18, 0x06, "recovered data - recommend rewrite" }, 204 { 0x18, 0x07, "recovered data with ECC - data rewritten" }, 205 { 0x18, 0x08, "recovered data with linking" }, 206 { 0x19, 0x00, "defect list error" }, 207 { 0x1a, 0x00, "parameter list length error" }, 208 { 0x1b, 0x00, "synchronous data xfer error" }, 209 { 0x1c, 0x00, "defect list not found" }, 210 { 0x1c, 0x01, "primary defect list not found" }, 211 { 0x1c, 0x02, "grown defect list not found" }, 212 { 0x1d, 0x00, "miscompare during verify" }, 213 { 0x1e, 0x00, "recovered ID with ECC" }, 214 { 0x1f, 0x00, "partial defect list transfer" }, 215 { 0x20, 0x00, "invalid command operation code" }, 216 { 0x20, 0x01, "access denied - initiator pending-enrolled" }, 217 { 0x20, 0x02, "access denied - no access rights" }, 218 { 0x20, 0x03, "access denied - invalid mgmt id key" }, 219 { 0x20, 0x04, "illegal command while in write capable state" }, 220 { 0x20, 0x06, "illegal command while in explicit address mode" }, 221 { 0x20, 0x07, "illegal command while in implicit address mode" }, 222 { 0x20, 0x08, "access denied - enrollment conflict" }, 223 { 0x20, 0x09, "access denied - invalid lu identifier" }, 224 { 0x20, 0x0a, "access denied - invalid proxy token" }, 225 { 0x20, 0x0b, "access denied - ACL LUN conflict" }, 226 { 0x21, 0x00, "logical block address out of range" }, 227 { 0x21, 0x01, "invalid element address" }, 228 { 0x21, 0x02, "invalid address for write" }, 229 { 0x22, 0x00, "illegal function" }, 230 { 0x24, 0x00, "invalid field in cdb" }, 231 { 0x24, 0x01, "cdb decryption error" }, 232 { 0x25, 0x00, "LUN not supported" }, 233 { 0x26, 0x00, "invalid field in param list" }, 234 { 0x26, 0x01, "parameter not supported" }, 235 { 0x26, 0x02, "parameter value invalid" }, 236 { 0x26, 0x03, "threshold parameters not supported" }, 237 { 0x26, 0x04, "invalid release of persistent reservation" }, 238 { 0x26, 0x05, "data decryption error" }, 239 { 0x26, 0x06, "too many target descriptors" }, 240 { 0x26, 0x07, "unsupported target descriptor type code" }, 241 { 0x26, 0x08, "too many segment descriptors" }, 242 { 0x26, 0x09, "unsupported segment descriptor type code" }, 243 { 0x26, 0x0a, "unexpected inexact segment" }, 244 { 0x26, 0x0b, "inline data length exceeded" }, 245 { 0x26, 0x0c, "invalid operation for copy source or destination" }, 246 { 0x26, 0x0d, "copy segment granularity violation" }, 247 { 0x27, 0x00, "write protected" }, 248 { 0x27, 0x01, "hardware write protected" }, 249 { 0x27, 0x02, "LUN software write protected" }, 250 { 0x27, 0x03, "associated write protect" }, 251 { 0x27, 0x04, "persistent write protect" }, 252 { 0x27, 0x05, "permanent write protect" }, 253 { 0x27, 0x06, "conditional write protect" }, 254 { 0x28, 0x00, "medium may have changed" }, 255 { 0x28, 0x01, "import or export element accessed" }, 256 { 0x29, 0x00, "power on, reset, or bus reset occurred" }, 257 { 0x29, 0x01, "power on occurred" }, 258 { 0x29, 0x02, "scsi bus reset occurred" }, 259 { 0x29, 0x03, "bus device reset message occurred" }, 260 { 0x29, 0x04, "device internal reset" }, 261 { 0x29, 0x05, "transceiver mode changed to single-ended" }, 262 { 0x29, 0x06, "transceiver mode changed to LVD" }, 263 { 0x29, 0x07, "i_t nexus loss occurred" }, 264 { 0x2a, 0x00, "parameters changed" }, 265 { 0x2a, 0x01, "mode parameters changed" }, 266 { 0x2a, 0x02, "log parameters changed" }, 267 { 0x2a, 0x03, "reservations preempted" }, 268 { 0x2a, 0x04, "reservations released" }, 269 { 0x2a, 0x05, "registrations preempted" }, 270 { 0x2a, 0x06, "asymmetric access state changed" }, 271 { 0x2a, 0x07, "implicit asymmetric access state transition failed" }, 272 { 0x2b, 0x00, "copy cannot execute since host cannot disconnect" }, 273 { 0x2c, 0x00, "command sequence error" }, 274 { 0x2c, 0x03, "current program area is not empty" }, 275 { 0x2c, 0x04, "current program area is empty" }, 276 { 0x2c, 0x06, "persistent prevent conflict" }, 277 { 0x2c, 0x07, "previous busy status" }, 278 { 0x2c, 0x08, "previous task set full status" }, 279 { 0x2c, 0x09, "previous reservation conflict status" }, 280 { 0x2d, 0x00, "overwrite error on update in place" }, 281 { 0x2e, 0x00, "insufficient time for operation" }, 282 { 0x2f, 0x00, "commands cleared by another initiator" }, 283 { 0x30, 0x00, "incompatible medium installed" }, 284 { 0x30, 0x01, "cannot read medium - unknown format" }, 285 { 0x30, 0x02, "cannot read medium - incompatible format" }, 286 { 0x30, 0x03, "cleaning cartridge installed" }, 287 { 0x30, 0x04, "cannot write medium - unknown format" }, 288 { 0x30, 0x05, "cannot write medium - incompatible format" }, 289 { 0x30, 0x06, "cannot format medium - incompatible medium" }, 290 { 0x30, 0x07, "cleaning failure" }, 291 { 0x30, 0x08, "cannot write - application code mismatch" }, 292 { 0x30, 0x09, "current session not fixated for append" }, 293 { 0x30, 0x10, "medium not formatted" }, 294 { 0x31, 0x00, "medium format corrupted" }, 295 { 0x31, 0x01, "format command failed" }, 296 { 0x31, 0x02, "zoned formatting failed due to spare linking" }, 297 { 0x32, 0x00, "no defect spare location available" }, 298 { 0x32, 0x01, "defect list update failure" }, 299 { 0x33, 0x00, "tape length error" }, 300 { 0x34, 0x00, "enclosure failure" }, 301 { 0x35, 0x00, "enclosure services failure" }, 302 { 0x35, 0x01, "unsupported enclosure function" }, 303 { 0x35, 0x02, "enclosure services unavailable" }, 304 { 0x35, 0x03, "enclosure services transfer failure" }, 305 { 0x35, 0x04, "enclosure services transfer refused" }, 306 { 0x36, 0x00, "ribbon, ink, or toner failure" }, 307 { 0x37, 0x00, "rounded parameter" }, 308 { 0x39, 0x00, "saving parameters not supported" }, 309 { 0x3a, 0x00, "medium not present" }, 310 { 0x3a, 0x01, "medium not present - tray closed" }, 311 { 0x3a, 0x02, "medium not present - tray open" }, 312 { 0x3a, 0x03, "medium not present - loadable" }, 313 { 0x3a, 0x04, "medium not present - medium auxiliary memory " 314 "accessible" }, 315 { 0x3b, 0x00, "sequential positioning error" }, 316 { 0x3b, 0x01, "tape position error at beginning-of-medium" }, 317 { 0x3b, 0x02, "tape position error at end-of-medium" }, 318 { 0x3b, 0x08, "reposition error" }, 319 { 0x3b, 0x0c, "position past beginning of medium" }, 320 { 0x3b, 0x0d, "medium destination element full" }, 321 { 0x3b, 0x0e, "medium source element empty" }, 322 { 0x3b, 0x0f, "end of medium reached" }, 323 { 0x3b, 0x11, "medium magazine not accessible" }, 324 { 0x3b, 0x12, "medium magazine removed" }, 325 { 0x3b, 0x13, "medium magazine inserted" }, 326 { 0x3b, 0x14, "medium magazine locked" }, 327 { 0x3b, 0x15, "medium magazine unlocked" }, 328 { 0x3b, 0x16, "mechanical positioning or changer error" }, 329 { 0x3d, 0x00, "invalid bits in indentify message" }, 330 { 0x3e, 0x00, "LUN has not self-configured yet" }, 331 { 0x3e, 0x01, "LUN failure" }, 332 { 0x3e, 0x02, "timeout on LUN" }, 333 { 0x3e, 0x03, "LUN failed self-test" }, 334 { 0x3e, 0x04, "LUN unable to update self-test log" }, 335 { 0x3f, 0x00, "target operating conditions have changed" }, 336 { 0x3f, 0x01, "microcode has been changed" }, 337 { 0x3f, 0x02, "changed operating definition" }, 338 { 0x3f, 0x03, "inquiry data has changed" }, 339 { 0x3f, 0x04, "component device attached" }, 340 { 0x3f, 0x05, "device identifier changed" }, 341 { 0x3f, 0x06, "redundancy group created or modified" }, 342 { 0x3f, 0x07, "redundancy group deleted" }, 343 { 0x3f, 0x08, "spare created or modified" }, 344 { 0x3f, 0x09, "spare deleted" }, 345 { 0x3f, 0x0a, "volume set created or modified" }, 346 { 0x3f, 0x0b, "volume set deleted" }, 347 { 0x3f, 0x0c, "volume set deassigned" }, 348 { 0x3f, 0x0d, "volume set reassigned" }, 349 { 0x3f, 0x0e, "reported LUNs data has changed" }, 350 { 0x3f, 0x0f, "echo buffer overwritten" }, 351 { 0x3f, 0x10, "medium loadable" }, 352 { 0x3f, 0x11, "medium auxiliary memory accessible" }, 353 { 0x40, 0x00, "ram failure" }, 354 { 0x41, 0x00, "data path failure" }, 355 { 0x42, 0x00, "power-on or self-test failure" }, 356 { 0x43, 0x00, "message error" }, 357 { 0x44, 0x00, "internal target failure" }, 358 { 0x45, 0x00, "select or reselect failure" }, 359 { 0x46, 0x00, "unsuccessful soft reset" }, 360 { 0x47, 0x00, "scsi parity error" }, 361 { 0x47, 0x01, "data phase crc error detected" }, 362 { 0x47, 0x02, "scsi parity error detected during st data phase" }, 363 { 0x47, 0x03, "information unit iucrc error detected" }, 364 { 0x47, 0x04, "asynchronous information protection error detected" }, 365 { 0x47, 0x05, "protocol service crc error" }, 366 { 0x47, 0x7f, "some commands cleared by iscsi protocol event" }, 367 { 0x48, 0x00, "initiator detected error message received" }, 368 { 0x49, 0x00, "invalid message error" }, 369 { 0x4a, 0x00, "command phase error" }, 370 { 0x4b, 0x00, "data phase error" }, 371 { 0x4b, 0x01, "invalid target port transfer tag received" }, 372 { 0x4b, 0x02, "too much write data" }, 373 { 0x4b, 0x03, "ack/nak timeout" }, 374 { 0x4b, 0x04, "nak received" }, 375 { 0x4b, 0x05, "data offset error" }, 376 { 0x4c, 0x00, "logical unit failed self-configuration" }, 377 { 0x4d, 0x00, "tagged overlapped commands (ASCQ = queue tag)" }, 378 { 0x4e, 0x00, "overlapped commands attempted" }, 379 { 0x50, 0x00, "write append error" }, 380 { 0x51, 0x00, "erase failure" }, 381 { 0x52, 0x00, "cartridge fault" }, 382 { 0x53, 0x00, "media load or eject failed" }, 383 { 0x53, 0x01, "unload tape failure" }, 384 { 0x53, 0x02, "medium removal prevented" }, 385 { 0x54, 0x00, "scsi to host system interface failure" }, 386 { 0x55, 0x00, "system resource failure" }, 387 { 0x55, 0x01, "system buffer full" }, 388 { 0x55, 0x02, "insufficient reservation resources" }, 389 { 0x55, 0x03, "insufficient resources" }, 390 { 0x55, 0x04, "insufficient registration resources" }, 391 { 0x55, 0x05, "insufficient access control resources" }, 392 { 0x55, 0x06, "auxiliary memory out of space" }, 393 { 0x57, 0x00, "unable to recover TOC" }, 394 { 0x58, 0x00, "generation does not exist" }, 395 { 0x59, 0x00, "updated block read" }, 396 { 0x5a, 0x00, "operator request or state change input" }, 397 { 0x5a, 0x01, "operator medium removal request" }, 398 { 0x5a, 0x02, "operator selected write protect" }, 399 { 0x5a, 0x03, "operator selected write permit" }, 400 { 0x5b, 0x00, "log exception" }, 401 { 0x5b, 0x01, "threshold condition met" }, 402 { 0x5b, 0x02, "log counter at maximum" }, 403 { 0x5b, 0x03, "log list codes exhausted" }, 404 { 0x5c, 0x00, "RPL status change" }, 405 { 0x5c, 0x01, "spindles synchronized" }, 406 { 0x5c, 0x02, "spindles not synchronized" }, 407 { 0x5d, 0x00, "drive operation marginal, service immediately" 408 " (failure prediction threshold exceeded)" }, 409 { 0x5d, 0x01, "media failure prediction threshold exceeded" }, 410 { 0x5d, 0x02, "LUN failure prediction threshold exceeded" }, 411 { 0x5d, 0x03, "spare area exhaustion prediction threshold exceeded" }, 412 { 0x5d, 0x10, "hardware impending failure general hard drive failure" }, 413 { 0x5d, 0x11, "hardware impending failure drive error rate too high" }, 414 { 0x5d, 0x12, "hardware impending failure data error rate too high" }, 415 { 0x5d, 0x13, "hardware impending failure seek error rate too high" }, 416 { 0x5d, 0x14, "hardware impending failure too many block reassigns" }, 417 { 0x5d, 0x15, "hardware impending failure access times too high" }, 418 { 0x5d, 0x16, "hardware impending failure start unit times too high" }, 419 { 0x5d, 0x17, "hardware impending failure channel parametrics" }, 420 { 0x5d, 0x18, "hardware impending failure controller detected" }, 421 { 0x5d, 0x19, "hardware impending failure throughput performance" }, 422 { 0x5d, 0x1a, "hardware impending failure seek time performance" }, 423 { 0x5d, 0x1b, "hardware impending failure spin-up retry count" }, 424 { 0x5d, 0x1c, "hardware impending failure drive calibration retry " 425 "count" }, 426 { 0x5d, 0x20, "controller impending failure general hard drive " 427 "failure" }, 428 { 0x5d, 0x21, "controller impending failure drive error rate too " 429 "high" }, 430 { 0x5d, 0x22, "controller impending failure data error rate too high" }, 431 { 0x5d, 0x23, "controller impending failure seek error rate too high" }, 432 { 0x5d, 0x24, "controller impending failure too many block reassigns" }, 433 { 0x5d, 0x25, "controller impending failure access times too high" }, 434 { 0x5d, 0x26, "controller impending failure start unit times too " 435 "high" }, 436 { 0x5d, 0x27, "controller impending failure channel parametrics" }, 437 { 0x5d, 0x28, "controller impending failure controller detected" }, 438 { 0x5d, 0x29, "controller impending failure throughput performance" }, 439 { 0x5d, 0x2a, "controller impending failure seek time performance" }, 440 { 0x5d, 0x2b, "controller impending failure spin-up retry count" }, 441 { 0x5d, 0x2c, "controller impending failure drive calibration retry " 442 "cnt" }, 443 { 0x5d, 0x30, "data channel impending failure general hard drive " 444 "failure" }, 445 { 0x5d, 0x31, "data channel impending failure drive error rate too " 446 "high" }, 447 { 0x5d, 0x32, "data channel impending failure data error rate too " 448 "high" }, 449 { 0x5d, 0x33, "data channel impending failure seek error rate too " 450 "high" }, 451 { 0x5d, 0x34, "data channel impending failure too many block " 452 "reassigns" }, 453 { 0x5d, 0x35, "data channel impending failure access times too high" }, 454 { 0x5d, 0x36, "data channel impending failure start unit times too " 455 "high" }, 456 { 0x5d, 0x37, "data channel impending failure channel parametrics" }, 457 { 0x5d, 0x38, "data channel impending failure controller detected" }, 458 { 0x5d, 0x39, "data channel impending failure throughput performance" }, 459 { 0x5d, 0x3a, "data channel impending failure seek time performance" }, 460 { 0x5d, 0x3b, "data channel impending failure spin-up retry count" }, 461 { 0x5d, 0x3c, "data channel impending failure drive calibrate retry " 462 "cnt" }, 463 { 0x5d, 0x40, "servo impending failure general hard drive failure" }, 464 { 0x5d, 0x41, "servo impending failure drive error rate too high" }, 465 { 0x5d, 0x42, "servo impending failure data error rate too high" }, 466 { 0x5d, 0x43, "servo impending failure seek error rate too high" }, 467 { 0x5d, 0x44, "servo impending failure too many block reassigns" }, 468 { 0x5d, 0x45, "servo impending failure access times too high" }, 469 { 0x5d, 0x46, "servo impending failure start unit times too high" }, 470 { 0x5d, 0x47, "servo impending failure channel parametrics" }, 471 { 0x5d, 0x48, "servo impending failure controller detected" }, 472 { 0x5d, 0x49, "servo impending failure throughput performance" }, 473 { 0x5d, 0x4a, "servo impending failure seek time performance" }, 474 { 0x5d, 0x4b, "servo impending failure spin-up retry count" }, 475 { 0x5d, 0x4c, "servo impending failure drive calibration retry count" }, 476 { 0x5d, 0x50, "spindle impending failure general hard drive failure" }, 477 { 0x5d, 0x51, "spindle impending failure drive error rate too high" }, 478 { 0x5d, 0x52, "spindle impending failure data error rate too high" }, 479 { 0x5d, 0x53, "spindle impending failure seek error rate too high" }, 480 { 0x5d, 0x54, "spindle impending failure too many block reassigns" }, 481 { 0x5d, 0x55, "spindle impending failure access times too high" }, 482 { 0x5d, 0x56, "spindle impending failure start unit times too high" }, 483 { 0x5d, 0x57, "spindle impending failure channel parametrics" }, 484 { 0x5d, 0x58, "spindle impending failure controller detected" }, 485 { 0x5d, 0x59, "spindle impending failure throughput performance" }, 486 { 0x5d, 0x5a, "spindle impending failure seek time performance" }, 487 { 0x5d, 0x5b, "spindle impending failure spin-up retry count" }, 488 { 0x5d, 0x5c, "spindle impending failure drive calibration retry " 489 "count" }, 490 { 0x5d, 0x60, "firmware impending failure general hard drive failure" }, 491 { 0x5d, 0x61, "firmware impending failure drive error rate too high" }, 492 { 0x5d, 0x62, "firmware impending failure data error rate too high" }, 493 { 0x5d, 0x63, "firmware impending failure seek error rate too high" }, 494 { 0x5d, 0x64, "firmware impending failure too many block reassigns" }, 495 { 0x5d, 0x65, "firmware impending failure access times too high" }, 496 { 0x5d, 0x66, "firmware impending failure start unit times too high" }, 497 { 0x5d, 0x67, "firmware impending failure channel parametrics" }, 498 { 0x5d, 0x68, "firmware impending failure controller detected" }, 499 { 0x5d, 0x69, "firmware impending failure throughput performance" }, 500 { 0x5d, 0x6a, "firmware impending failure seek time performance" }, 501 { 0x5d, 0x6b, "firmware impending failure spin-up retry count" }, 502 { 0x5d, 0x6c, "firmware impending failure drive calibration retry " 503 "count" }, 504 { 0x5d, 0xff, "failure prediction threshold exceeded (false)" }, 505 { 0x5e, 0x00, "low power condition active" }, 506 { 0x5e, 0x01, "idle condition activated by timer" }, 507 { 0x5e, 0x02, "standby condition activated by timer" }, 508 { 0x5e, 0x03, "idle condition activated by command" }, 509 { 0x5e, 0x04, "standby condition activated by command" }, 510 { 0x60, 0x00, "lamp failure" }, 511 { 0x61, 0x00, "video aquisition error" }, 512 { 0x62, 0x00, "scan head positioning error" }, 513 { 0x63, 0x00, "end of user area encountered on this track" }, 514 { 0x63, 0x01, "packet does not fit in available space" }, 515 { 0x64, 0x00, "illegal mode for this track" }, 516 { 0x64, 0x01, "invalid packet size" }, 517 { 0x65, 0x00, "voltage fault" }, 518 { 0x66, 0x00, "automatic document feeder cover up" }, 519 { 0x67, 0x00, "configuration failure" }, 520 { 0x67, 0x01, "configuration of incapable LUNs failed" }, 521 { 0x67, 0x02, "add LUN failed" }, 522 { 0x67, 0x03, "modification of LUN failed" }, 523 { 0x67, 0x04, "exchange of LUN failed" }, 524 { 0x67, 0x05, "remove of LUN failed" }, 525 { 0x67, 0x06, "attachment of LUN failed" }, 526 { 0x67, 0x07, "creation of LUN failed" }, 527 { 0x67, 0x08, "assign failure occurred" }, 528 { 0x67, 0x09, "multiply assigned LUN" }, 529 { 0x67, 0x0a, "set target port groups command failed" }, 530 { 0x68, 0x00, "logical unit not configured" }, 531 { 0x69, 0x00, "data loss on logical unit" }, 532 { 0x69, 0x01, "multiple LUN failures" }, 533 { 0x69, 0x02, "parity/data mismatch" }, 534 { 0x6a, 0x00, "informational, refer to log" }, 535 { 0x6b, 0x00, "state change has occured" }, 536 { 0x6b, 0x01, "redundancy level got better" }, 537 { 0x6b, 0x02, "redundancy level got worse" }, 538 { 0x6c, 0x00, "rebuild failure occured" }, 539 { 0x6d, 0x00, "recalculate failure occured" }, 540 { 0x6e, 0x00, "command to logical unit failed" }, 541 { 0x6f, 0x00, "copy protect key exchange failure authentication " 542 "failure" }, 543 { 0x6f, 0x01, "copy protect key exchange failure key not present" }, 544 { 0x6f, 0x02, "copy protect key exchange failure key not established" }, 545 { 0x6f, 0x03, "read of scrambled sector without authentication" }, 546 { 0x6f, 0x04, "media region code is mismatched to LUN region" }, 547 { 0x6f, 0x05, "drive region must be permanent/region reset count " 548 "error" }, 549 { 0x70, 0xffff, "decompression exception short algorithm id of ASCQ" }, 550 { 0x71, 0x00, "decompression exception long algorithm id" }, 551 { 0x72, 0x00, "session fixation error" }, 552 { 0x72, 0x01, "session fixation error writing lead-in" }, 553 { 0x72, 0x02, "session fixation error writing lead-out" }, 554 { 0x72, 0x03, "session fixation error - incomplete track in session" }, 555 { 0x72, 0x04, "empty or partially written reserved track" }, 556 { 0x72, 0x05, "no more track reservations allowed" }, 557 { 0x73, 0x00, "cd control error" }, 558 { 0x73, 0x01, "power calibration area almost full" }, 559 { 0x73, 0x02, "power calibration area is full" }, 560 { 0x73, 0x03, "power calibration area error" }, 561 { 0x73, 0x04, "program memory area update failure" }, 562 { 0x73, 0x05, "program memory area is full" }, 563 { 0x73, 0x06, "rma/pma is almost full" }, 564 { 0xffff, 0xffff, NULL } 565 }; 566 567 static const char * 568 find_string(slist_t *slist, int match_value) 569 { 570 for (; slist->str != NULL; slist++) { 571 if (slist->value == match_value) { 572 return (slist->str); 573 } 574 } 575 576 return (NULL); 577 } 578 579 const char * 580 libscsi_sense_key_name(uint64_t key) 581 { 582 return (find_string(sensekey_strings, (int)key)); 583 } 584 585 /* 586 * Given an asc (Additional Sense Code) and ascq (Additional Sense Code 587 * Qualifier), return a string describing the error information. 588 */ 589 const char * 590 libscsi_sense_code_name(uint64_t asc, uint64_t ascq) 591 { 592 int i = 0; 593 594 while (extended_sense_list[i].asc != 0xffff) { 595 if ((asc == extended_sense_list[i].asc) && 596 ((ascq == extended_sense_list[i].ascq) || 597 (extended_sense_list[i].ascq == 0xffff))) { 598 return ((char *)extended_sense_list[i].message); 599 } 600 i++; 601 } 602 603 return (NULL); 604 } 605 606 /* 607 * Retrieve "information" field from descriptor format sense data. Iterates 608 * through each sense descriptor looking for the information descriptor and 609 * returns the information field from that descriptor. 610 */ 611 static diskaddr_t 612 scsi_extract_sense_info_descr(struct scsi_descr_sense_hdr *sdsp, size_t len) 613 { 614 diskaddr_t result; 615 uint8_t *descr_offset; 616 size_t valid_sense_length; 617 struct scsi_information_sense_descr *isd; 618 619 /* 620 * Initialize result to -1 indicating there is no information 621 * descriptor 622 */ 623 result = (diskaddr_t)-1; 624 625 /* 626 * The first descriptor will immediately follow the header 627 */ 628 descr_offset = (uint8_t *)(sdsp+1); 629 630 /* 631 * Calculate the amount of valid sense data 632 */ 633 valid_sense_length = 634 MIN((sizeof (struct scsi_descr_sense_hdr) + 635 sdsp->ds_addl_sense_length), len); 636 637 /* 638 * Iterate through the list of descriptors, stopping when we run out of 639 * sense data 640 */ 641 while ((descr_offset + sizeof (struct scsi_information_sense_descr)) <= 642 (uint8_t *)sdsp + valid_sense_length) { 643 /* 644 * Check if this is an information descriptor. We can use the 645 * scsi_information_sense_descr structure as a template since 646 * the first two fields are always the same 647 */ 648 isd = (struct scsi_information_sense_descr *)descr_offset; 649 if (isd->isd_descr_type == DESCR_INFORMATION) { 650 /* 651 * Found an information descriptor. Copy the 652 * information field. There will only be one 653 * information descriptor so we can stop looking. 654 */ 655 result = 656 (((diskaddr_t)isd->isd_information[0] << 56) | 657 ((diskaddr_t)isd->isd_information[1] << 48) | 658 ((diskaddr_t)isd->isd_information[2] << 40) | 659 ((diskaddr_t)isd->isd_information[3] << 32) | 660 ((diskaddr_t)isd->isd_information[4] << 24) | 661 ((diskaddr_t)isd->isd_information[5] << 16) | 662 ((diskaddr_t)isd->isd_information[6] << 8) | 663 ((diskaddr_t)isd->isd_information[7])); 664 break; 665 } 666 667 /* 668 * Get pointer to the next descriptor. The "additional length" 669 * field holds the length of the descriptor except for the 670 * "type" and "additional length" fields, so we need to add 2 to 671 * get the total length. 672 */ 673 descr_offset += (isd->isd_addl_length + 2); 674 } 675 676 return (result); 677 } 678 679 int 680 libscsi_action_parse_sense(const libscsi_action_t *ap, uint64_t *keyp, 681 uint64_t *ascp, uint64_t *ascqp, diskaddr_t *blkp) 682 { 683 struct scsi_extended_sense *xsp; 684 struct scsi_descr_sense_hdr *sdsp; 685 size_t len; 686 687 if (libscsi_action_get_sense(ap, (uint8_t **)&xsp, NULL, &len) != 0) 688 return (-1); 689 690 sdsp = (struct scsi_descr_sense_hdr *)xsp; 691 692 if (keyp != NULL) 693 *keyp = (uint64_t)xsp->es_key; 694 695 switch (xsp->es_code) { 696 case CODE_FMT_DESCR_CURRENT: 697 case CODE_FMT_DESCR_DEFERRED: 698 if (blkp != NULL) 699 *blkp = (diskaddr_t) 700 scsi_extract_sense_info_descr(sdsp, len); 701 if (ascp != NULL) 702 *ascp = (uint64_t)sdsp->ds_add_code; 703 if (ascqp != NULL) 704 *ascqp = (uint64_t)sdsp->ds_qual_code; 705 break; 706 case CODE_FMT_FIXED_CURRENT: 707 case CODE_FMT_FIXED_DEFERRED: 708 default: 709 if (xsp->es_valid && blkp != NULL) 710 *blkp = (diskaddr_t) 711 ((xsp->es_info_1 << 24) | (xsp->es_info_2 << 16) | 712 (xsp->es_info_3 << 8) | xsp->es_info_4); 713 if (xsp->es_add_len >= 6) { 714 if (ascp != NULL) 715 *ascp = (uint64_t)xsp->es_add_code; 716 if (ascqp != NULL) 717 *ascqp = (uint64_t)xsp->es_qual_code; 718 } 719 break; 720 } 721 722 return (0); 723 } 724