1 /*- 2 * Implementation of Utility functions for all SCSI device types. 3 * 4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. 5 * Copyright (c) 1997, 1998, 2003 Kenneth D. Merry. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 14 * 2. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/types.h> 35 #include <sys/stdint.h> 36 37 #ifdef _KERNEL 38 #include <opt_scsi.h> 39 40 #include <sys/systm.h> 41 #include <sys/libkern.h> 42 #include <sys/kernel.h> 43 #include <sys/lock.h> 44 #include <sys/malloc.h> 45 #include <sys/mutex.h> 46 #include <sys/sysctl.h> 47 #else 48 #include <errno.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 #endif 53 54 #include <cam/cam.h> 55 #include <cam/cam_ccb.h> 56 #include <cam/cam_queue.h> 57 #include <cam/cam_xpt.h> 58 #include <cam/scsi/scsi_all.h> 59 #include <sys/ata.h> 60 #include <sys/sbuf.h> 61 62 #ifdef _KERNEL 63 #include <cam/cam_periph.h> 64 #include <cam/cam_xpt_sim.h> 65 #include <cam/cam_xpt_periph.h> 66 #include <cam/cam_xpt_internal.h> 67 #else 68 #include <camlib.h> 69 #include <stddef.h> 70 71 #ifndef FALSE 72 #define FALSE 0 73 #endif /* FALSE */ 74 #ifndef TRUE 75 #define TRUE 1 76 #endif /* TRUE */ 77 #define ERESTART -1 /* restart syscall */ 78 #define EJUSTRETURN -2 /* don't modify regs, just return */ 79 #endif /* !_KERNEL */ 80 81 /* 82 * This is the default number of milliseconds we wait for devices to settle 83 * after a SCSI bus reset. 84 */ 85 #ifndef SCSI_DELAY 86 #define SCSI_DELAY 2000 87 #endif 88 /* 89 * All devices need _some_ sort of bus settle delay, so we'll set it to 90 * a minimum value of 100ms. Note that this is pertinent only for SPI- 91 * not transport like Fibre Channel or iSCSI where 'delay' is completely 92 * meaningless. 93 */ 94 #ifndef SCSI_MIN_DELAY 95 #define SCSI_MIN_DELAY 100 96 #endif 97 /* 98 * Make sure the user isn't using seconds instead of milliseconds. 99 */ 100 #if (SCSI_DELAY < SCSI_MIN_DELAY && SCSI_DELAY != 0) 101 #error "SCSI_DELAY is in milliseconds, not seconds! Please use a larger value" 102 #endif 103 104 int scsi_delay; 105 106 static int ascentrycomp(const void *key, const void *member); 107 static int senseentrycomp(const void *key, const void *member); 108 static void fetchtableentries(int sense_key, int asc, int ascq, 109 struct scsi_inquiry_data *, 110 const struct sense_key_table_entry **, 111 const struct asc_table_entry **); 112 #ifdef _KERNEL 113 static void init_scsi_delay(void); 114 static int sysctl_scsi_delay(SYSCTL_HANDLER_ARGS); 115 static int set_scsi_delay(int delay); 116 #endif 117 118 #if !defined(SCSI_NO_OP_STRINGS) 119 120 #define D (1 << T_DIRECT) 121 #define T (1 << T_SEQUENTIAL) 122 #define L (1 << T_PRINTER) 123 #define P (1 << T_PROCESSOR) 124 #define W (1 << T_WORM) 125 #define R (1 << T_CDROM) 126 #define O (1 << T_OPTICAL) 127 #define M (1 << T_CHANGER) 128 #define A (1 << T_STORARRAY) 129 #define E (1 << T_ENCLOSURE) 130 #define B (1 << T_RBC) 131 #define K (1 << T_OCRW) 132 #define V (1 << T_ADC) 133 #define F (1 << T_OSD) 134 #define S (1 << T_SCANNER) 135 #define C (1 << T_COMM) 136 137 #define ALL (D | T | L | P | W | R | O | M | A | E | B | K | V | F | S | C) 138 139 static struct op_table_entry plextor_cd_ops[] = { 140 { 0xD8, R, "CD-DA READ" } 141 }; 142 143 static struct scsi_op_quirk_entry scsi_op_quirk_table[] = { 144 { 145 /* 146 * I believe that 0xD8 is the Plextor proprietary command 147 * to read CD-DA data. I'm not sure which Plextor CDROM 148 * models support the command, though. I know for sure 149 * that the 4X, 8X, and 12X models do, and presumably the 150 * 12-20X does. I don't know about any earlier models, 151 * though. If anyone has any more complete information, 152 * feel free to change this quirk entry. 153 */ 154 {T_CDROM, SIP_MEDIA_REMOVABLE, "PLEXTOR", "CD-ROM PX*", "*"}, 155 sizeof(plextor_cd_ops)/sizeof(struct op_table_entry), 156 plextor_cd_ops 157 } 158 }; 159 160 static struct op_table_entry scsi_op_codes[] = { 161 /* 162 * From: http://www.t10.org/lists/op-num.txt 163 * Modifications by Kenneth Merry (ken@FreeBSD.ORG) 164 * and Jung-uk Kim (jkim@FreeBSD.org) 165 * 166 * Note: order is important in this table, scsi_op_desc() currently 167 * depends on the opcodes in the table being in order to save 168 * search time. 169 * Note: scanner and comm. devices are carried over from the previous 170 * version because they were removed in the latest spec. 171 */ 172 /* File: OP-NUM.TXT 173 * 174 * SCSI Operation Codes 175 * Numeric Sorted Listing 176 * as of 3/11/08 177 * 178 * D - DIRECT ACCESS DEVICE (SBC-2) device column key 179 * .T - SEQUENTIAL ACCESS DEVICE (SSC-2) ----------------- 180 * . L - PRINTER DEVICE (SSC) M = Mandatory 181 * . P - PROCESSOR DEVICE (SPC) O = Optional 182 * . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC-2) V = Vendor spec. 183 * . . R - CD/DVE DEVICE (MMC-3) Z = Obsolete 184 * . . O - OPTICAL MEMORY DEVICE (SBC-2) 185 * . . .M - MEDIA CHANGER DEVICE (SMC-2) 186 * . . . A - STORAGE ARRAY DEVICE (SCC-2) 187 * . . . .E - ENCLOSURE SERVICES DEVICE (SES) 188 * . . . .B - SIMPLIFIED DIRECT-ACCESS DEVICE (RBC) 189 * . . . . K - OPTICAL CARD READER/WRITER DEVICE (OCRW) 190 * . . . . V - AUTOMATION/DRIVE INTERFACE (ADC) 191 * . . . . .F - OBJECT-BASED STORAGE (OSD) 192 * OP DTLPWROMAEBKVF Description 193 * -- -------------- ---------------------------------------------- */ 194 /* 00 MMMMMMMMMMMMMM TEST UNIT READY */ 195 { 0x00, ALL, "TEST UNIT READY" }, 196 /* 01 M REWIND */ 197 { 0x01, T, "REWIND" }, 198 /* 01 Z V ZZZZ REZERO UNIT */ 199 { 0x01, D | W | R | O | M, "REZERO UNIT" }, 200 /* 02 VVVVVV V */ 201 /* 03 MMMMMMMMMMOMMM REQUEST SENSE */ 202 { 0x03, ALL, "REQUEST SENSE" }, 203 /* 04 M OO FORMAT UNIT */ 204 { 0x04, D | R | O, "FORMAT UNIT" }, 205 /* 04 O FORMAT MEDIUM */ 206 { 0x04, T, "FORMAT MEDIUM" }, 207 /* 04 O FORMAT */ 208 { 0x04, L, "FORMAT" }, 209 /* 05 VMVVVV V READ BLOCK LIMITS */ 210 { 0x05, T, "READ BLOCK LIMITS" }, 211 /* 06 VVVVVV V */ 212 /* 07 OVV O OV REASSIGN BLOCKS */ 213 { 0x07, D | W | O, "REASSIGN BLOCKS" }, 214 /* 07 O INITIALIZE ELEMENT STATUS */ 215 { 0x07, M, "INITIALIZE ELEMENT STATUS" }, 216 /* 08 MOV O OV READ(6) */ 217 { 0x08, D | T | W | O, "READ(6)" }, 218 /* 08 O RECEIVE */ 219 { 0x08, P, "RECEIVE" }, 220 /* 08 GET MESSAGE(6) */ 221 { 0x08, C, "GET MESSAGE(6)" }, 222 /* 09 VVVVVV V */ 223 /* 0A OO O OV WRITE(6) */ 224 { 0x0A, D | T | W | O, "WRITE(6)" }, 225 /* 0A M SEND(6) */ 226 { 0x0A, P, "SEND(6)" }, 227 /* 0A SEND MESSAGE(6) */ 228 { 0x0A, C, "SEND MESSAGE(6)" }, 229 /* 0A M PRINT */ 230 { 0x0A, L, "PRINT" }, 231 /* 0B Z ZOZV SEEK(6) */ 232 { 0x0B, D | W | R | O, "SEEK(6)" }, 233 /* 0B O SET CAPACITY */ 234 { 0x0B, T, "SET CAPACITY" }, 235 /* 0B O SLEW AND PRINT */ 236 { 0x0B, L, "SLEW AND PRINT" }, 237 /* 0C VVVVVV V */ 238 /* 0D VVVVVV V */ 239 /* 0E VVVVVV V */ 240 /* 0F VOVVVV V READ REVERSE(6) */ 241 { 0x0F, T, "READ REVERSE(6)" }, 242 /* 10 VM VVV WRITE FILEMARKS(6) */ 243 { 0x10, T, "WRITE FILEMARKS(6)" }, 244 /* 10 O SYNCHRONIZE BUFFER */ 245 { 0x10, L, "SYNCHRONIZE BUFFER" }, 246 /* 11 VMVVVV SPACE(6) */ 247 { 0x11, T, "SPACE(6)" }, 248 /* 12 MMMMMMMMMMMMMM INQUIRY */ 249 { 0x12, ALL, "INQUIRY" }, 250 /* 13 V VVVV */ 251 /* 13 O VERIFY(6) */ 252 { 0x13, T, "VERIFY(6)" }, 253 /* 14 VOOVVV RECOVER BUFFERED DATA */ 254 { 0x14, T | L, "RECOVER BUFFERED DATA" }, 255 /* 15 OMO O OOOO OO MODE SELECT(6) */ 256 { 0x15, ALL & ~(P | R | B | F), "MODE SELECT(6)" }, 257 /* 16 ZZMZO OOOZ O RESERVE(6) */ 258 { 0x16, ALL & ~(R | B | V | F | C), "RESERVE(6)" }, 259 /* 16 Z RESERVE ELEMENT(6) */ 260 { 0x16, M, "RESERVE ELEMENT(6)" }, 261 /* 17 ZZMZO OOOZ O RELEASE(6) */ 262 { 0x17, ALL & ~(R | B | V | F | C), "RELEASE(6)" }, 263 /* 17 Z RELEASE ELEMENT(6) */ 264 { 0x17, M, "RELEASE ELEMENT(6)" }, 265 /* 18 ZZZZOZO Z COPY */ 266 { 0x18, D | T | L | P | W | R | O | K | S, "COPY" }, 267 /* 19 VMVVVV ERASE(6) */ 268 { 0x19, T, "ERASE(6)" }, 269 /* 1A OMO O OOOO OO MODE SENSE(6) */ 270 { 0x1A, ALL & ~(P | R | B | F), "MODE SENSE(6)" }, 271 /* 1B O OOO O MO O START STOP UNIT */ 272 { 0x1B, D | W | R | O | A | B | K | F, "START STOP UNIT" }, 273 /* 1B O M LOAD UNLOAD */ 274 { 0x1B, T | V, "LOAD UNLOAD" }, 275 /* 1B SCAN */ 276 { 0x1B, S, "SCAN" }, 277 /* 1B O STOP PRINT */ 278 { 0x1B, L, "STOP PRINT" }, 279 /* 1B O OPEN/CLOSE IMPORT/EXPORT ELEMENT */ 280 { 0x1B, M, "OPEN/CLOSE IMPORT/EXPORT ELEMENT" }, 281 /* 1C OOOOO OOOM OOO RECEIVE DIAGNOSTIC RESULTS */ 282 { 0x1C, ALL & ~(R | B), "RECEIVE DIAGNOSTIC RESULTS" }, 283 /* 1D MMMMM MMOM MMM SEND DIAGNOSTIC */ 284 { 0x1D, ALL & ~(R | B), "SEND DIAGNOSTIC" }, 285 /* 1E OO OOOO O O PREVENT ALLOW MEDIUM REMOVAL */ 286 { 0x1E, D | T | W | R | O | M | K | F, "PREVENT ALLOW MEDIUM REMOVAL" }, 287 /* 1F */ 288 /* 20 V VVV V */ 289 /* 21 V VVV V */ 290 /* 22 V VVV V */ 291 /* 23 V V V V */ 292 /* 23 O READ FORMAT CAPACITIES */ 293 { 0x23, R, "READ FORMAT CAPACITIES" }, 294 /* 24 V VV SET WINDOW */ 295 { 0x24, S, "SET WINDOW" }, 296 /* 25 M M M M READ CAPACITY(10) */ 297 { 0x25, D | W | O | B, "READ CAPACITY(10)" }, 298 /* 25 O READ CAPACITY */ 299 { 0x25, R, "READ CAPACITY" }, 300 /* 25 M READ CARD CAPACITY */ 301 { 0x25, K, "READ CARD CAPACITY" }, 302 /* 25 GET WINDOW */ 303 { 0x25, S, "GET WINDOW" }, 304 /* 26 V VV */ 305 /* 27 V VV */ 306 /* 28 M MOM MM READ(10) */ 307 { 0x28, D | W | R | O | B | K | S, "READ(10)" }, 308 /* 28 GET MESSAGE(10) */ 309 { 0x28, C, "GET MESSAGE(10)" }, 310 /* 29 V VVO READ GENERATION */ 311 { 0x29, O, "READ GENERATION" }, 312 /* 2A O MOM MO WRITE(10) */ 313 { 0x2A, D | W | R | O | B | K, "WRITE(10)" }, 314 /* 2A SEND(10) */ 315 { 0x2A, S, "SEND(10)" }, 316 /* 2A SEND MESSAGE(10) */ 317 { 0x2A, C, "SEND MESSAGE(10)" }, 318 /* 2B Z OOO O SEEK(10) */ 319 { 0x2B, D | W | R | O | K, "SEEK(10)" }, 320 /* 2B O LOCATE(10) */ 321 { 0x2B, T, "LOCATE(10)" }, 322 /* 2B O POSITION TO ELEMENT */ 323 { 0x2B, M, "POSITION TO ELEMENT" }, 324 /* 2C V OO ERASE(10) */ 325 { 0x2C, R | O, "ERASE(10)" }, 326 /* 2D O READ UPDATED BLOCK */ 327 { 0x2D, O, "READ UPDATED BLOCK" }, 328 /* 2D V */ 329 /* 2E O OOO MO WRITE AND VERIFY(10) */ 330 { 0x2E, D | W | R | O | B | K, "WRITE AND VERIFY(10)" }, 331 /* 2F O OOO VERIFY(10) */ 332 { 0x2F, D | W | R | O, "VERIFY(10)" }, 333 /* 30 Z ZZZ SEARCH DATA HIGH(10) */ 334 { 0x30, D | W | R | O, "SEARCH DATA HIGH(10)" }, 335 /* 31 Z ZZZ SEARCH DATA EQUAL(10) */ 336 { 0x31, D | W | R | O, "SEARCH DATA EQUAL(10)" }, 337 /* 31 OBJECT POSITION */ 338 { 0x31, S, "OBJECT POSITION" }, 339 /* 32 Z ZZZ SEARCH DATA LOW(10) */ 340 { 0x32, D | W | R | O, "SEARCH DATA LOW(10)" }, 341 /* 33 Z OZO SET LIMITS(10) */ 342 { 0x33, D | W | R | O, "SET LIMITS(10)" }, 343 /* 34 O O O O PRE-FETCH(10) */ 344 { 0x34, D | W | O | K, "PRE-FETCH(10)" }, 345 /* 34 M READ POSITION */ 346 { 0x34, T, "READ POSITION" }, 347 /* 34 GET DATA BUFFER STATUS */ 348 { 0x34, S, "GET DATA BUFFER STATUS" }, 349 /* 35 O OOO MO SYNCHRONIZE CACHE(10) */ 350 { 0x35, D | W | R | O | B | K, "SYNCHRONIZE CACHE(10)" }, 351 /* 36 Z O O O LOCK UNLOCK CACHE(10) */ 352 { 0x36, D | W | O | K, "LOCK UNLOCK CACHE(10)" }, 353 /* 37 O O READ DEFECT DATA(10) */ 354 { 0x37, D | O, "READ DEFECT DATA(10)" }, 355 /* 37 O INITIALIZE ELEMENT STATUS WITH RANGE */ 356 { 0x37, M, "INITIALIZE ELEMENT STATUS WITH RANGE" }, 357 /* 38 O O O MEDIUM SCAN */ 358 { 0x38, W | O | K, "MEDIUM SCAN" }, 359 /* 39 ZZZZOZO Z COMPARE */ 360 { 0x39, D | T | L | P | W | R | O | K | S, "COMPARE" }, 361 /* 3A ZZZZOZO Z COPY AND VERIFY */ 362 { 0x3A, D | T | L | P | W | R | O | K | S, "COPY AND VERIFY" }, 363 /* 3B OOOOOOOOOOMOOO WRITE BUFFER */ 364 { 0x3B, ALL, "WRITE BUFFER" }, 365 /* 3C OOOOOOOOOO OOO READ BUFFER */ 366 { 0x3C, ALL & ~(B), "READ BUFFER" }, 367 /* 3D O UPDATE BLOCK */ 368 { 0x3D, O, "UPDATE BLOCK" }, 369 /* 3E O O O READ LONG(10) */ 370 { 0x3E, D | W | O, "READ LONG(10)" }, 371 /* 3F O O O WRITE LONG(10) */ 372 { 0x3F, D | W | O, "WRITE LONG(10)" }, 373 /* 40 ZZZZOZOZ CHANGE DEFINITION */ 374 { 0x40, D | T | L | P | W | R | O | M | S | C, "CHANGE DEFINITION" }, 375 /* 41 O WRITE SAME(10) */ 376 { 0x41, D, "WRITE SAME(10)" }, 377 /* 42 O UNMAP */ 378 { 0x42, D, "UNMAP" }, 379 /* 42 O READ SUB-CHANNEL */ 380 { 0x42, R, "READ SUB-CHANNEL" }, 381 /* 43 O READ TOC/PMA/ATIP */ 382 { 0x43, R, "READ TOC/PMA/ATIP" }, 383 /* 44 M M REPORT DENSITY SUPPORT */ 384 { 0x44, T | V, "REPORT DENSITY SUPPORT" }, 385 /* 44 READ HEADER */ 386 /* 45 O PLAY AUDIO(10) */ 387 { 0x45, R, "PLAY AUDIO(10)" }, 388 /* 46 M GET CONFIGURATION */ 389 { 0x46, R, "GET CONFIGURATION" }, 390 /* 47 O PLAY AUDIO MSF */ 391 { 0x47, R, "PLAY AUDIO MSF" }, 392 /* 48 */ 393 /* 49 */ 394 /* 4A M GET EVENT STATUS NOTIFICATION */ 395 { 0x4A, R, "GET EVENT STATUS NOTIFICATION" }, 396 /* 4B O PAUSE/RESUME */ 397 { 0x4B, R, "PAUSE/RESUME" }, 398 /* 4C OOOOO OOOO OOO LOG SELECT */ 399 { 0x4C, ALL & ~(R | B), "LOG SELECT" }, 400 /* 4D OOOOO OOOO OMO LOG SENSE */ 401 { 0x4D, ALL & ~(R | B), "LOG SENSE" }, 402 /* 4E O STOP PLAY/SCAN */ 403 { 0x4E, R, "STOP PLAY/SCAN" }, 404 /* 4F */ 405 /* 50 O XDWRITE(10) */ 406 { 0x50, D, "XDWRITE(10)" }, 407 /* 51 O XPWRITE(10) */ 408 { 0x51, D, "XPWRITE(10)" }, 409 /* 51 O READ DISC INFORMATION */ 410 { 0x51, R, "READ DISC INFORMATION" }, 411 /* 52 O XDREAD(10) */ 412 { 0x52, D, "XDREAD(10)" }, 413 /* 52 O READ TRACK INFORMATION */ 414 { 0x52, R, "READ TRACK INFORMATION" }, 415 /* 53 O RESERVE TRACK */ 416 { 0x53, R, "RESERVE TRACK" }, 417 /* 54 O SEND OPC INFORMATION */ 418 { 0x54, R, "SEND OPC INFORMATION" }, 419 /* 55 OOO OMOOOOMOMO MODE SELECT(10) */ 420 { 0x55, ALL & ~(P), "MODE SELECT(10)" }, 421 /* 56 ZZMZO OOOZ RESERVE(10) */ 422 { 0x56, ALL & ~(R | B | K | V | F | C), "RESERVE(10)" }, 423 /* 56 Z RESERVE ELEMENT(10) */ 424 { 0x56, M, "RESERVE ELEMENT(10)" }, 425 /* 57 ZZMZO OOOZ RELEASE(10) */ 426 { 0x57, ALL & ~(R | B | K | V | F | C), "RELEASE(10)" }, 427 /* 57 Z RELEASE ELEMENT(10) */ 428 { 0x57, M, "RELEASE ELEMENT(10)" }, 429 /* 58 O REPAIR TRACK */ 430 { 0x58, R, "REPAIR TRACK" }, 431 /* 59 */ 432 /* 5A OOO OMOOOOMOMO MODE SENSE(10) */ 433 { 0x5A, ALL & ~(P), "MODE SENSE(10)" }, 434 /* 5B O CLOSE TRACK/SESSION */ 435 { 0x5B, R, "CLOSE TRACK/SESSION" }, 436 /* 5C O READ BUFFER CAPACITY */ 437 { 0x5C, R, "READ BUFFER CAPACITY" }, 438 /* 5D O SEND CUE SHEET */ 439 { 0x5D, R, "SEND CUE SHEET" }, 440 /* 5E OOOOO OOOO M PERSISTENT RESERVE IN */ 441 { 0x5E, ALL & ~(R | B | K | V | C), "PERSISTENT RESERVE IN" }, 442 /* 5F OOOOO OOOO M PERSISTENT RESERVE OUT */ 443 { 0x5F, ALL & ~(R | B | K | V | C), "PERSISTENT RESERVE OUT" }, 444 /* 7E OO O OOOO O extended CDB */ 445 { 0x7E, D | T | R | M | A | E | B | V, "extended CDB" }, 446 /* 7F O M variable length CDB (more than 16 bytes) */ 447 { 0x7F, D | F, "variable length CDB (more than 16 bytes)" }, 448 /* 80 Z XDWRITE EXTENDED(16) */ 449 { 0x80, D, "XDWRITE EXTENDED(16)" }, 450 /* 80 M WRITE FILEMARKS(16) */ 451 { 0x80, T, "WRITE FILEMARKS(16)" }, 452 /* 81 Z REBUILD(16) */ 453 { 0x81, D, "REBUILD(16)" }, 454 /* 81 O READ REVERSE(16) */ 455 { 0x81, T, "READ REVERSE(16)" }, 456 /* 82 Z REGENERATE(16) */ 457 { 0x82, D, "REGENERATE(16)" }, 458 /* 83 OOOOO O OO EXTENDED COPY */ 459 { 0x83, D | T | L | P | W | O | K | V, "EXTENDED COPY" }, 460 /* 84 OOOOO O OO RECEIVE COPY RESULTS */ 461 { 0x84, D | T | L | P | W | O | K | V, "RECEIVE COPY RESULTS" }, 462 /* 85 O O O ATA COMMAND PASS THROUGH(16) */ 463 { 0x85, D | R | B, "ATA COMMAND PASS THROUGH(16)" }, 464 /* 86 OO OO OOOOOOO ACCESS CONTROL IN */ 465 { 0x86, ALL & ~(L | R | F), "ACCESS CONTROL IN" }, 466 /* 87 OO OO OOOOOOO ACCESS CONTROL OUT */ 467 { 0x87, ALL & ~(L | R | F), "ACCESS CONTROL OUT" }, 468 /* 469 * XXX READ(16)/WRITE(16) were not listed for CD/DVE in op-num.txt 470 * but we had it since r1.40. Do we really want them? 471 */ 472 /* 88 MM O O O READ(16) */ 473 { 0x88, D | T | W | O | B, "READ(16)" }, 474 /* 89 */ 475 /* 8A OM O O O WRITE(16) */ 476 { 0x8A, D | T | W | O | B, "WRITE(16)" }, 477 /* 8B O ORWRITE */ 478 { 0x8B, D, "ORWRITE" }, 479 /* 8C OO O OO O M READ ATTRIBUTE */ 480 { 0x8C, D | T | W | O | M | B | V, "READ ATTRIBUTE" }, 481 /* 8D OO O OO O O WRITE ATTRIBUTE */ 482 { 0x8D, D | T | W | O | M | B | V, "WRITE ATTRIBUTE" }, 483 /* 8E O O O O WRITE AND VERIFY(16) */ 484 { 0x8E, D | W | O | B, "WRITE AND VERIFY(16)" }, 485 /* 8F OO O O O VERIFY(16) */ 486 { 0x8F, D | T | W | O | B, "VERIFY(16)" }, 487 /* 90 O O O O PRE-FETCH(16) */ 488 { 0x90, D | W | O | B, "PRE-FETCH(16)" }, 489 /* 91 O O O O SYNCHRONIZE CACHE(16) */ 490 { 0x91, D | W | O | B, "SYNCHRONIZE CACHE(16)" }, 491 /* 91 O SPACE(16) */ 492 { 0x91, T, "SPACE(16)" }, 493 /* 92 Z O O LOCK UNLOCK CACHE(16) */ 494 { 0x92, D | W | O, "LOCK UNLOCK CACHE(16)" }, 495 /* 92 O LOCATE(16) */ 496 { 0x92, T, "LOCATE(16)" }, 497 /* 93 O WRITE SAME(16) */ 498 { 0x93, D, "WRITE SAME(16)" }, 499 /* 93 M ERASE(16) */ 500 { 0x93, T, "ERASE(16)" }, 501 /* 94 [usage proposed by SCSI Socket Services project] */ 502 /* 95 [usage proposed by SCSI Socket Services project] */ 503 /* 96 [usage proposed by SCSI Socket Services project] */ 504 /* 97 [usage proposed by SCSI Socket Services project] */ 505 /* 98 */ 506 /* 99 */ 507 /* 9A */ 508 /* 9B */ 509 /* 9C */ 510 /* 9D */ 511 /* XXX KDM ALL for this? op-num.txt defines it for none.. */ 512 /* 9E SERVICE ACTION IN(16) */ 513 { 0x9E, ALL, "SERVICE ACTION IN(16)" }, 514 /* XXX KDM ALL for this? op-num.txt defines it for ADC.. */ 515 /* 9F M SERVICE ACTION OUT(16) */ 516 { 0x9F, ALL, "SERVICE ACTION OUT(16)" }, 517 /* A0 MMOOO OMMM OMO REPORT LUNS */ 518 { 0xA0, ALL & ~(R | B), "REPORT LUNS" }, 519 /* A1 O BLANK */ 520 { 0xA1, R, "BLANK" }, 521 /* A1 O O ATA COMMAND PASS THROUGH(12) */ 522 { 0xA1, D | B, "ATA COMMAND PASS THROUGH(12)" }, 523 /* A2 OO O O SECURITY PROTOCOL IN */ 524 { 0xA2, D | T | R | V, "SECURITY PROTOCOL IN" }, 525 /* A3 OOO O OOMOOOM MAINTENANCE (IN) */ 526 { 0xA3, ALL & ~(P | R | F), "MAINTENANCE (IN)" }, 527 /* A3 O SEND KEY */ 528 { 0xA3, R, "SEND KEY" }, 529 /* A4 OOO O OOOOOOO MAINTENANCE (OUT) */ 530 { 0xA4, ALL & ~(P | R | F), "MAINTENANCE (OUT)" }, 531 /* A4 O REPORT KEY */ 532 { 0xA4, R, "REPORT KEY" }, 533 /* A5 O O OM MOVE MEDIUM */ 534 { 0xA5, T | W | O | M, "MOVE MEDIUM" }, 535 /* A5 O PLAY AUDIO(12) */ 536 { 0xA5, R, "PLAY AUDIO(12)" }, 537 /* A6 O EXCHANGE MEDIUM */ 538 { 0xA6, M, "EXCHANGE MEDIUM" }, 539 /* A6 O LOAD/UNLOAD C/DVD */ 540 { 0xA6, R, "LOAD/UNLOAD C/DVD" }, 541 /* A7 ZZ O O MOVE MEDIUM ATTACHED */ 542 { 0xA7, D | T | W | O, "MOVE MEDIUM ATTACHED" }, 543 /* A7 O SET READ AHEAD */ 544 { 0xA7, R, "SET READ AHEAD" }, 545 /* A8 O OOO READ(12) */ 546 { 0xA8, D | W | R | O, "READ(12)" }, 547 /* A8 GET MESSAGE(12) */ 548 { 0xA8, C, "GET MESSAGE(12)" }, 549 /* A9 O SERVICE ACTION OUT(12) */ 550 { 0xA9, V, "SERVICE ACTION OUT(12)" }, 551 /* AA O OOO WRITE(12) */ 552 { 0xAA, D | W | R | O, "WRITE(12)" }, 553 /* AA SEND MESSAGE(12) */ 554 { 0xAA, C, "SEND MESSAGE(12)" }, 555 /* AB O O SERVICE ACTION IN(12) */ 556 { 0xAB, R | V, "SERVICE ACTION IN(12)" }, 557 /* AC O ERASE(12) */ 558 { 0xAC, O, "ERASE(12)" }, 559 /* AC O GET PERFORMANCE */ 560 { 0xAC, R, "GET PERFORMANCE" }, 561 /* AD O READ DVD STRUCTURE */ 562 { 0xAD, R, "READ DVD STRUCTURE" }, 563 /* AE O O O WRITE AND VERIFY(12) */ 564 { 0xAE, D | W | O, "WRITE AND VERIFY(12)" }, 565 /* AF O OZO VERIFY(12) */ 566 { 0xAF, D | W | R | O, "VERIFY(12)" }, 567 /* B0 ZZZ SEARCH DATA HIGH(12) */ 568 { 0xB0, W | R | O, "SEARCH DATA HIGH(12)" }, 569 /* B1 ZZZ SEARCH DATA EQUAL(12) */ 570 { 0xB1, W | R | O, "SEARCH DATA EQUAL(12)" }, 571 /* B2 ZZZ SEARCH DATA LOW(12) */ 572 { 0xB2, W | R | O, "SEARCH DATA LOW(12)" }, 573 /* B3 Z OZO SET LIMITS(12) */ 574 { 0xB3, D | W | R | O, "SET LIMITS(12)" }, 575 /* B4 ZZ OZO READ ELEMENT STATUS ATTACHED */ 576 { 0xB4, D | T | W | R | O, "READ ELEMENT STATUS ATTACHED" }, 577 /* B5 OO O O SECURITY PROTOCOL OUT */ 578 { 0xB5, D | T | R | V, "SECURITY PROTOCOL OUT" }, 579 /* B5 O REQUEST VOLUME ELEMENT ADDRESS */ 580 { 0xB5, M, "REQUEST VOLUME ELEMENT ADDRESS" }, 581 /* B6 O SEND VOLUME TAG */ 582 { 0xB6, M, "SEND VOLUME TAG" }, 583 /* B6 O SET STREAMING */ 584 { 0xB6, R, "SET STREAMING" }, 585 /* B7 O O READ DEFECT DATA(12) */ 586 { 0xB7, D | O, "READ DEFECT DATA(12)" }, 587 /* B8 O OZOM READ ELEMENT STATUS */ 588 { 0xB8, T | W | R | O | M, "READ ELEMENT STATUS" }, 589 /* B9 O READ CD MSF */ 590 { 0xB9, R, "READ CD MSF" }, 591 /* BA O O OOMO REDUNDANCY GROUP (IN) */ 592 { 0xBA, D | W | O | M | A | E, "REDUNDANCY GROUP (IN)" }, 593 /* BA O SCAN */ 594 { 0xBA, R, "SCAN" }, 595 /* BB O O OOOO REDUNDANCY GROUP (OUT) */ 596 { 0xBB, D | W | O | M | A | E, "REDUNDANCY GROUP (OUT)" }, 597 /* BB O SET CD SPEED */ 598 { 0xBB, R, "SET CD SPEED" }, 599 /* BC O O OOMO SPARE (IN) */ 600 { 0xBC, D | W | O | M | A | E, "SPARE (IN)" }, 601 /* BD O O OOOO SPARE (OUT) */ 602 { 0xBD, D | W | O | M | A | E, "SPARE (OUT)" }, 603 /* BD O MECHANISM STATUS */ 604 { 0xBD, R, "MECHANISM STATUS" }, 605 /* BE O O OOMO VOLUME SET (IN) */ 606 { 0xBE, D | W | O | M | A | E, "VOLUME SET (IN)" }, 607 /* BE O READ CD */ 608 { 0xBE, R, "READ CD" }, 609 /* BF O O OOOO VOLUME SET (OUT) */ 610 { 0xBF, D | W | O | M | A | E, "VOLUME SET (OUT)" }, 611 /* BF O SEND DVD STRUCTURE */ 612 { 0xBF, R, "SEND DVD STRUCTURE" } 613 }; 614 615 const char * 616 scsi_op_desc(u_int16_t opcode, struct scsi_inquiry_data *inq_data) 617 { 618 caddr_t match; 619 int i, j; 620 u_int32_t opmask; 621 u_int16_t pd_type; 622 int num_ops[2]; 623 struct op_table_entry *table[2]; 624 int num_tables; 625 626 /* 627 * If we've got inquiry data, use it to determine what type of 628 * device we're dealing with here. Otherwise, assume direct 629 * access. 630 */ 631 if (inq_data == NULL) { 632 pd_type = T_DIRECT; 633 match = NULL; 634 } else { 635 pd_type = SID_TYPE(inq_data); 636 637 match = cam_quirkmatch((caddr_t)inq_data, 638 (caddr_t)scsi_op_quirk_table, 639 sizeof(scsi_op_quirk_table)/ 640 sizeof(*scsi_op_quirk_table), 641 sizeof(*scsi_op_quirk_table), 642 scsi_inquiry_match); 643 } 644 645 if (match != NULL) { 646 table[0] = ((struct scsi_op_quirk_entry *)match)->op_table; 647 num_ops[0] = ((struct scsi_op_quirk_entry *)match)->num_ops; 648 table[1] = scsi_op_codes; 649 num_ops[1] = sizeof(scsi_op_codes)/sizeof(scsi_op_codes[0]); 650 num_tables = 2; 651 } else { 652 /* 653 * If this is true, we have a vendor specific opcode that 654 * wasn't covered in the quirk table. 655 */ 656 if ((opcode > 0xBF) || ((opcode > 0x5F) && (opcode < 0x80))) 657 return("Vendor Specific Command"); 658 659 table[0] = scsi_op_codes; 660 num_ops[0] = sizeof(scsi_op_codes)/sizeof(scsi_op_codes[0]); 661 num_tables = 1; 662 } 663 664 /* RBC is 'Simplified' Direct Access Device */ 665 if (pd_type == T_RBC) 666 pd_type = T_DIRECT; 667 668 /* Map NODEVICE to Direct Access Device to handle REPORT LUNS, etc. */ 669 if (pd_type == T_NODEVICE) 670 pd_type = T_DIRECT; 671 672 opmask = 1 << pd_type; 673 674 for (j = 0; j < num_tables; j++) { 675 for (i = 0;i < num_ops[j] && table[j][i].opcode <= opcode; i++){ 676 if ((table[j][i].opcode == opcode) 677 && ((table[j][i].opmask & opmask) != 0)) 678 return(table[j][i].desc); 679 } 680 } 681 682 /* 683 * If we can't find a match for the command in the table, we just 684 * assume it's a vendor specifc command. 685 */ 686 return("Vendor Specific Command"); 687 688 } 689 690 #else /* SCSI_NO_OP_STRINGS */ 691 692 const char * 693 scsi_op_desc(u_int16_t opcode, struct scsi_inquiry_data *inq_data) 694 { 695 return(""); 696 } 697 698 #endif 699 700 701 #if !defined(SCSI_NO_SENSE_STRINGS) 702 #define SST(asc, ascq, action, desc) \ 703 asc, ascq, action, desc 704 #else 705 const char empty_string[] = ""; 706 707 #define SST(asc, ascq, action, desc) \ 708 asc, ascq, action, empty_string 709 #endif 710 711 const struct sense_key_table_entry sense_key_table[] = 712 { 713 { SSD_KEY_NO_SENSE, SS_NOP, "NO SENSE" }, 714 { SSD_KEY_RECOVERED_ERROR, SS_NOP|SSQ_PRINT_SENSE, "RECOVERED ERROR" }, 715 { SSD_KEY_NOT_READY, SS_RDEF, "NOT READY" }, 716 { SSD_KEY_MEDIUM_ERROR, SS_RDEF, "MEDIUM ERROR" }, 717 { SSD_KEY_HARDWARE_ERROR, SS_RDEF, "HARDWARE FAILURE" }, 718 { SSD_KEY_ILLEGAL_REQUEST, SS_FATAL|EINVAL, "ILLEGAL REQUEST" }, 719 { SSD_KEY_UNIT_ATTENTION, SS_FATAL|ENXIO, "UNIT ATTENTION" }, 720 { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" }, 721 { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" }, 722 { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" }, 723 { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" }, 724 { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" }, 725 { SSD_KEY_EQUAL, SS_NOP, "EQUAL" }, 726 { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" }, 727 { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" }, 728 { SSD_KEY_COMPLETED, SS_NOP, "COMPLETED" } 729 }; 730 731 const int sense_key_table_size = 732 sizeof(sense_key_table)/sizeof(sense_key_table[0]); 733 734 static struct asc_table_entry quantum_fireball_entries[] = { 735 { SST(0x04, 0x0b, SS_START | SSQ_DECREMENT_COUNT | ENXIO, 736 "Logical unit not ready, initializing cmd. required") } 737 }; 738 739 static struct asc_table_entry sony_mo_entries[] = { 740 { SST(0x04, 0x00, SS_START | SSQ_DECREMENT_COUNT | ENXIO, 741 "Logical unit not ready, cause not reportable") } 742 }; 743 744 static struct asc_table_entry hgst_entries[] = { 745 { SST(0x04, 0xF0, SS_RDEF, 746 "Vendor Unique - Logical Unit Not Ready") }, 747 { SST(0x0A, 0x01, SS_RDEF, 748 "Unrecovered Super Certification Log Write Error") }, 749 { SST(0x0A, 0x02, SS_RDEF, 750 "Unrecovered Super Certification Log Read Error") }, 751 { SST(0x15, 0x03, SS_RDEF, 752 "Unrecovered Sector Error") }, 753 { SST(0x3E, 0x04, SS_RDEF, 754 "Unrecovered Self-Test Hard-Cache Test Fail") }, 755 { SST(0x3E, 0x05, SS_RDEF, 756 "Unrecovered Self-Test OTF-Cache Fail") }, 757 { SST(0x40, 0x00, SS_RDEF, 758 "Unrecovered SAT No Buffer Overflow Error") }, 759 { SST(0x40, 0x01, SS_RDEF, 760 "Unrecovered SAT Buffer Overflow Error") }, 761 { SST(0x40, 0x02, SS_RDEF, 762 "Unrecovered SAT No Buffer Overflow With ECS Fault") }, 763 { SST(0x40, 0x03, SS_RDEF, 764 "Unrecovered SAT Buffer Overflow With ECS Fault") }, 765 { SST(0x40, 0x81, SS_RDEF, 766 "DRAM Failure") }, 767 { SST(0x44, 0x0B, SS_RDEF, 768 "Vendor Unique - Internal Target Failure") }, 769 { SST(0x44, 0xF2, SS_RDEF, 770 "Vendor Unique - Internal Target Failure") }, 771 { SST(0x44, 0xF6, SS_RDEF, 772 "Vendor Unique - Internal Target Failure") }, 773 { SST(0x44, 0xF9, SS_RDEF, 774 "Vendor Unique - Internal Target Failure") }, 775 { SST(0x44, 0xFA, SS_RDEF, 776 "Vendor Unique - Internal Target Failure") }, 777 { SST(0x5D, 0x22, SS_RDEF, 778 "Extreme Over-Temperature Warning") }, 779 { SST(0x5D, 0x50, SS_RDEF, 780 "Load/Unload cycle Count Warning") }, 781 { SST(0x81, 0x00, SS_RDEF, 782 "Vendor Unique - Internal Logic Error") }, 783 { SST(0x85, 0x00, SS_RDEF, 784 "Vendor Unique - Internal Key Seed Error") }, 785 }; 786 787 static struct asc_table_entry seagate_entries[] = { 788 { SST(0x04, 0xF0, SS_RDEF, 789 "Logical Unit Not Ready, super certify in Progress") }, 790 { SST(0x08, 0x86, SS_RDEF, 791 "Write Fault Data Corruption") }, 792 { SST(0x09, 0x0D, SS_RDEF, 793 "Tracking Failure") }, 794 { SST(0x09, 0x0E, SS_RDEF, 795 "ETF Failure") }, 796 { SST(0x0B, 0x5D, SS_RDEF, 797 "Pre-SMART Warning") }, 798 { SST(0x0B, 0x85, SS_RDEF, 799 "5V Voltage Warning") }, 800 { SST(0x0B, 0x8C, SS_RDEF, 801 "12V Voltage Warning") }, 802 { SST(0x0C, 0xFF, SS_RDEF, 803 "Write Error - Too many error recovery revs") }, 804 { SST(0x11, 0xFF, SS_RDEF, 805 "Unrecovered Read Error - Too many error recovery revs") }, 806 { SST(0x19, 0x0E, SS_RDEF, 807 "Fewer than 1/2 defect list copies") }, 808 { SST(0x20, 0xF3, SS_RDEF, 809 "Illegal CDB linked to skip mask cmd") }, 810 { SST(0x24, 0xF0, SS_RDEF, 811 "Illegal byte in CDB, LBA not matching") }, 812 { SST(0x24, 0xF1, SS_RDEF, 813 "Illegal byte in CDB, LEN not matching") }, 814 { SST(0x24, 0xF2, SS_RDEF, 815 "Mask not matching transfer length") }, 816 { SST(0x24, 0xF3, SS_RDEF, 817 "Drive formatted without plist") }, 818 { SST(0x26, 0x95, SS_RDEF, 819 "Invalid Field Parameter - CAP File") }, 820 { SST(0x26, 0x96, SS_RDEF, 821 "Invalid Field Parameter - RAP File") }, 822 { SST(0x26, 0x97, SS_RDEF, 823 "Invalid Field Parameter - TMS Firmware Tag") }, 824 { SST(0x26, 0x98, SS_RDEF, 825 "Invalid Field Parameter - Check Sum") }, 826 { SST(0x26, 0x99, SS_RDEF, 827 "Invalid Field Parameter - Firmware Tag") }, 828 { SST(0x29, 0x08, SS_RDEF, 829 "Write Log Dump data") }, 830 { SST(0x29, 0x09, SS_RDEF, 831 "Write Log Dump data") }, 832 { SST(0x29, 0x0A, SS_RDEF, 833 "Reserved disk space") }, 834 { SST(0x29, 0x0B, SS_RDEF, 835 "SDBP") }, 836 { SST(0x29, 0x0C, SS_RDEF, 837 "SDBP") }, 838 { SST(0x31, 0x91, SS_RDEF, 839 "Format Corrupted World Wide Name (WWN) is Invalid") }, 840 { SST(0x32, 0x03, SS_RDEF, 841 "Defect List - Length exceeds Command Allocated Length") }, 842 { SST(0x33, 0x00, SS_RDEF, 843 "Flash not ready for access") }, 844 { SST(0x3F, 0x70, SS_RDEF, 845 "Invalid RAP block") }, 846 { SST(0x3F, 0x71, SS_RDEF, 847 "RAP/ETF mismatch") }, 848 { SST(0x3F, 0x90, SS_RDEF, 849 "Invalid CAP block") }, 850 { SST(0x3F, 0x91, SS_RDEF, 851 "World Wide Name (WWN) Mismatch") }, 852 { SST(0x40, 0x01, SS_RDEF, 853 "DRAM Parity Error") }, 854 { SST(0x40, 0x02, SS_RDEF, 855 "DRAM Parity Error") }, 856 { SST(0x42, 0x0A, SS_RDEF, 857 "Loopback Test") }, 858 { SST(0x42, 0x0B, SS_RDEF, 859 "Loopback Test") }, 860 { SST(0x44, 0xF2, SS_RDEF, 861 "Compare error during data integrity check") }, 862 { SST(0x44, 0xF6, SS_RDEF, 863 "Unrecoverable error during data integrity check") }, 864 { SST(0x47, 0x80, SS_RDEF, 865 "Fibre Channel Sequence Error") }, 866 { SST(0x4E, 0x01, SS_RDEF, 867 "Information Unit Too Short") }, 868 { SST(0x80, 0x00, SS_RDEF, 869 "General Firmware Error / Command Timeout") }, 870 { SST(0x80, 0x01, SS_RDEF, 871 "Command Timeout") }, 872 { SST(0x80, 0x02, SS_RDEF, 873 "Command Timeout") }, 874 { SST(0x80, 0x80, SS_RDEF, 875 "FC FIFO Error During Read Transfer") }, 876 { SST(0x80, 0x81, SS_RDEF, 877 "FC FIFO Error During Write Transfer") }, 878 { SST(0x80, 0x82, SS_RDEF, 879 "DISC FIFO Error During Read Transfer") }, 880 { SST(0x80, 0x83, SS_RDEF, 881 "DISC FIFO Error During Write Transfer") }, 882 { SST(0x80, 0x84, SS_RDEF, 883 "LBA Seeded LRC Error on Read") }, 884 { SST(0x80, 0x85, SS_RDEF, 885 "LBA Seeded LRC Error on Write") }, 886 { SST(0x80, 0x86, SS_RDEF, 887 "IOEDC Error on Read") }, 888 { SST(0x80, 0x87, SS_RDEF, 889 "IOEDC Error on Write") }, 890 { SST(0x80, 0x88, SS_RDEF, 891 "Host Parity Check Failed") }, 892 { SST(0x80, 0x89, SS_RDEF, 893 "IOEDC error on read detected by formatter") }, 894 { SST(0x80, 0x8A, SS_RDEF, 895 "Host Parity Errors / Host FIFO Initialization Failed") }, 896 { SST(0x80, 0x8B, SS_RDEF, 897 "Host Parity Errors") }, 898 { SST(0x80, 0x8C, SS_RDEF, 899 "Host Parity Errors") }, 900 { SST(0x80, 0x8D, SS_RDEF, 901 "Host Parity Errors") }, 902 { SST(0x81, 0x00, SS_RDEF, 903 "LA Check Failed") }, 904 { SST(0x82, 0x00, SS_RDEF, 905 "Internal client detected insufficient buffer") }, 906 { SST(0x84, 0x00, SS_RDEF, 907 "Scheduled Diagnostic And Repair") }, 908 }; 909 910 static struct scsi_sense_quirk_entry sense_quirk_table[] = { 911 { 912 /* 913 * XXX The Quantum Fireball ST and SE like to return 0x04 0x0b 914 * when they really should return 0x04 0x02. 915 */ 916 {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"}, 917 /*num_sense_keys*/0, 918 sizeof(quantum_fireball_entries)/sizeof(struct asc_table_entry), 919 /*sense key entries*/NULL, 920 quantum_fireball_entries 921 }, 922 { 923 /* 924 * This Sony MO drive likes to return 0x04, 0x00 when it 925 * isn't spun up. 926 */ 927 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"}, 928 /*num_sense_keys*/0, 929 sizeof(sony_mo_entries)/sizeof(struct asc_table_entry), 930 /*sense key entries*/NULL, 931 sony_mo_entries 932 }, 933 { 934 /* 935 * HGST vendor-specific error codes 936 */ 937 {T_DIRECT, SIP_MEDIA_FIXED, "HGST", "*", "*"}, 938 /*num_sense_keys*/0, 939 sizeof(hgst_entries)/sizeof(struct asc_table_entry), 940 /*sense key entries*/NULL, 941 hgst_entries 942 }, 943 { 944 /* 945 * SEAGATE vendor-specific error codes 946 */ 947 {T_DIRECT, SIP_MEDIA_FIXED, "SEAGATE", "*", "*"}, 948 /*num_sense_keys*/0, 949 sizeof(seagate_entries)/sizeof(struct asc_table_entry), 950 /*sense key entries*/NULL, 951 seagate_entries 952 } 953 }; 954 955 const int sense_quirk_table_size = 956 sizeof(sense_quirk_table)/sizeof(sense_quirk_table[0]); 957 958 static struct asc_table_entry asc_table[] = { 959 /* 960 * From: http://www.t10.org/lists/asc-num.txt 961 * Modifications by Jung-uk Kim (jkim@FreeBSD.org) 962 */ 963 /* 964 * File: ASC-NUM.TXT 965 * 966 * SCSI ASC/ASCQ Assignments 967 * Numeric Sorted Listing 968 * as of 5/20/12 969 * 970 * D - DIRECT ACCESS DEVICE (SBC-2) device column key 971 * .T - SEQUENTIAL ACCESS DEVICE (SSC) ------------------- 972 * . L - PRINTER DEVICE (SSC) blank = reserved 973 * . P - PROCESSOR DEVICE (SPC) not blank = allowed 974 * . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC-2) 975 * . . R - CD DEVICE (MMC) 976 * . . O - OPTICAL MEMORY DEVICE (SBC-2) 977 * . . .M - MEDIA CHANGER DEVICE (SMC) 978 * . . . A - STORAGE ARRAY DEVICE (SCC) 979 * . . . E - ENCLOSURE SERVICES DEVICE (SES) 980 * . . . .B - SIMPLIFIED DIRECT-ACCESS DEVICE (RBC) 981 * . . . . K - OPTICAL CARD READER/WRITER DEVICE (OCRW) 982 * . . . . V - AUTOMATION/DRIVE INTERFACE (ADC) 983 * . . . . .F - OBJECT-BASED STORAGE (OSD) 984 * DTLPWROMAEBKVF 985 * ASC ASCQ Action 986 * Description 987 */ 988 /* DTLPWROMAEBKVF */ 989 { SST(0x00, 0x00, SS_NOP, 990 "No additional sense information") }, 991 /* T */ 992 { SST(0x00, 0x01, SS_RDEF, 993 "Filemark detected") }, 994 /* T */ 995 { SST(0x00, 0x02, SS_RDEF, 996 "End-of-partition/medium detected") }, 997 /* T */ 998 { SST(0x00, 0x03, SS_RDEF, 999 "Setmark detected") }, 1000 /* T */ 1001 { SST(0x00, 0x04, SS_RDEF, 1002 "Beginning-of-partition/medium detected") }, 1003 /* TL */ 1004 { SST(0x00, 0x05, SS_RDEF, 1005 "End-of-data detected") }, 1006 /* DTLPWROMAEBKVF */ 1007 { SST(0x00, 0x06, SS_RDEF, 1008 "I/O process terminated") }, 1009 /* T */ 1010 { SST(0x00, 0x07, SS_RDEF, /* XXX TBD */ 1011 "Programmable early warning detected") }, 1012 /* R */ 1013 { SST(0x00, 0x11, SS_FATAL | EBUSY, 1014 "Audio play operation in progress") }, 1015 /* R */ 1016 { SST(0x00, 0x12, SS_NOP, 1017 "Audio play operation paused") }, 1018 /* R */ 1019 { SST(0x00, 0x13, SS_NOP, 1020 "Audio play operation successfully completed") }, 1021 /* R */ 1022 { SST(0x00, 0x14, SS_RDEF, 1023 "Audio play operation stopped due to error") }, 1024 /* R */ 1025 { SST(0x00, 0x15, SS_NOP, 1026 "No current audio status to return") }, 1027 /* DTLPWROMAEBKVF */ 1028 { SST(0x00, 0x16, SS_FATAL | EBUSY, 1029 "Operation in progress") }, 1030 /* DTL WROMAEBKVF */ 1031 { SST(0x00, 0x17, SS_RDEF, 1032 "Cleaning requested") }, 1033 /* T */ 1034 { SST(0x00, 0x18, SS_RDEF, /* XXX TBD */ 1035 "Erase operation in progress") }, 1036 /* T */ 1037 { SST(0x00, 0x19, SS_RDEF, /* XXX TBD */ 1038 "Locate operation in progress") }, 1039 /* T */ 1040 { SST(0x00, 0x1A, SS_RDEF, /* XXX TBD */ 1041 "Rewind operation in progress") }, 1042 /* T */ 1043 { SST(0x00, 0x1B, SS_RDEF, /* XXX TBD */ 1044 "Set capacity operation in progress") }, 1045 /* T */ 1046 { SST(0x00, 0x1C, SS_RDEF, /* XXX TBD */ 1047 "Verify operation in progress") }, 1048 /* DT B */ 1049 { SST(0x00, 0x1D, SS_RDEF, /* XXX TBD */ 1050 "ATA pass through information available") }, 1051 /* DT R MAEBKV */ 1052 { SST(0x00, 0x1E, SS_RDEF, /* XXX TBD */ 1053 "Conflicting SA creation request") }, 1054 /* DT B */ 1055 { SST(0x00, 0x1F, SS_RDEF, /* XXX TBD */ 1056 "Logical unit transitioning to another power condition") }, 1057 /* DT P B */ 1058 { SST(0x00, 0x20, SS_RDEF, /* XXX TBD */ 1059 "Extended copy information available") }, 1060 /* D W O BK */ 1061 { SST(0x01, 0x00, SS_RDEF, 1062 "No index/sector signal") }, 1063 /* D WRO BK */ 1064 { SST(0x02, 0x00, SS_RDEF, 1065 "No seek complete") }, 1066 /* DTL W O BK */ 1067 { SST(0x03, 0x00, SS_RDEF, 1068 "Peripheral device write fault") }, 1069 /* T */ 1070 { SST(0x03, 0x01, SS_RDEF, 1071 "No write current") }, 1072 /* T */ 1073 { SST(0x03, 0x02, SS_RDEF, 1074 "Excessive write errors") }, 1075 /* DTLPWROMAEBKVF */ 1076 { SST(0x04, 0x00, SS_RDEF, 1077 "Logical unit not ready, cause not reportable") }, 1078 /* DTLPWROMAEBKVF */ 1079 { SST(0x04, 0x01, SS_TUR | SSQ_MANY | SSQ_DECREMENT_COUNT | EBUSY, 1080 "Logical unit is in process of becoming ready") }, 1081 /* DTLPWROMAEBKVF */ 1082 { SST(0x04, 0x02, SS_START | SSQ_DECREMENT_COUNT | ENXIO, 1083 "Logical unit not ready, initializing command required") }, 1084 /* DTLPWROMAEBKVF */ 1085 { SST(0x04, 0x03, SS_FATAL | ENXIO, 1086 "Logical unit not ready, manual intervention required") }, 1087 /* DTL RO B */ 1088 { SST(0x04, 0x04, SS_FATAL | EBUSY, 1089 "Logical unit not ready, format in progress") }, 1090 /* DT W O A BK F */ 1091 { SST(0x04, 0x05, SS_FATAL | EBUSY, 1092 "Logical unit not ready, rebuild in progress") }, 1093 /* DT W O A BK */ 1094 { SST(0x04, 0x06, SS_FATAL | EBUSY, 1095 "Logical unit not ready, recalculation in progress") }, 1096 /* DTLPWROMAEBKVF */ 1097 { SST(0x04, 0x07, SS_FATAL | EBUSY, 1098 "Logical unit not ready, operation in progress") }, 1099 /* R */ 1100 { SST(0x04, 0x08, SS_FATAL | EBUSY, 1101 "Logical unit not ready, long write in progress") }, 1102 /* DTLPWROMAEBKVF */ 1103 { SST(0x04, 0x09, SS_RDEF, /* XXX TBD */ 1104 "Logical unit not ready, self-test in progress") }, 1105 /* DTLPWROMAEBKVF */ 1106 { SST(0x04, 0x0A, SS_RDEF, /* XXX TBD */ 1107 "Logical unit not accessible, asymmetric access state transition")}, 1108 /* DTLPWROMAEBKVF */ 1109 { SST(0x04, 0x0B, SS_RDEF, /* XXX TBD */ 1110 "Logical unit not accessible, target port in standby state") }, 1111 /* DTLPWROMAEBKVF */ 1112 { SST(0x04, 0x0C, SS_RDEF, /* XXX TBD */ 1113 "Logical unit not accessible, target port in unavailable state") }, 1114 /* F */ 1115 { SST(0x04, 0x0D, SS_RDEF, /* XXX TBD */ 1116 "Logical unit not ready, structure check required") }, 1117 /* DT WROM B */ 1118 { SST(0x04, 0x10, SS_RDEF, /* XXX TBD */ 1119 "Logical unit not ready, auxiliary memory not accessible") }, 1120 /* DT WRO AEB VF */ 1121 { SST(0x04, 0x11, SS_RDEF, /* XXX TBD */ 1122 "Logical unit not ready, notify (enable spinup) required") }, 1123 /* M V */ 1124 { SST(0x04, 0x12, SS_RDEF, /* XXX TBD */ 1125 "Logical unit not ready, offline") }, 1126 /* DT R MAEBKV */ 1127 { SST(0x04, 0x13, SS_RDEF, /* XXX TBD */ 1128 "Logical unit not ready, SA creation in progress") }, 1129 /* D B */ 1130 { SST(0x04, 0x14, SS_RDEF, /* XXX TBD */ 1131 "Logical unit not ready, space allocation in progress") }, 1132 /* M */ 1133 { SST(0x04, 0x15, SS_RDEF, /* XXX TBD */ 1134 "Logical unit not ready, robotics disabled") }, 1135 /* M */ 1136 { SST(0x04, 0x16, SS_RDEF, /* XXX TBD */ 1137 "Logical unit not ready, configuration required") }, 1138 /* M */ 1139 { SST(0x04, 0x17, SS_RDEF, /* XXX TBD */ 1140 "Logical unit not ready, calibration required") }, 1141 /* M */ 1142 { SST(0x04, 0x18, SS_RDEF, /* XXX TBD */ 1143 "Logical unit not ready, a door is open") }, 1144 /* M */ 1145 { SST(0x04, 0x19, SS_RDEF, /* XXX TBD */ 1146 "Logical unit not ready, operating in sequential mode") }, 1147 /* DT B */ 1148 { SST(0x04, 0x1A, SS_RDEF, /* XXX TBD */ 1149 "Logical unit not ready, START/STOP UNIT command in progress") }, 1150 /* D B */ 1151 { SST(0x04, 0x1B, SS_RDEF, /* XXX TBD */ 1152 "Logical unit not ready, sanitize in progress") }, 1153 /* DT MAEB */ 1154 { SST(0x04, 0x1C, SS_RDEF, /* XXX TBD */ 1155 "Logical unit not ready, additional power use not yet granted") }, 1156 /* DTL WROMAEBKVF */ 1157 { SST(0x05, 0x00, SS_RDEF, 1158 "Logical unit does not respond to selection") }, 1159 /* D WROM BK */ 1160 { SST(0x06, 0x00, SS_RDEF, 1161 "No reference position found") }, 1162 /* DTL WROM BK */ 1163 { SST(0x07, 0x00, SS_RDEF, 1164 "Multiple peripheral devices selected") }, 1165 /* DTL WROMAEBKVF */ 1166 { SST(0x08, 0x00, SS_RDEF, 1167 "Logical unit communication failure") }, 1168 /* DTL WROMAEBKVF */ 1169 { SST(0x08, 0x01, SS_RDEF, 1170 "Logical unit communication time-out") }, 1171 /* DTL WROMAEBKVF */ 1172 { SST(0x08, 0x02, SS_RDEF, 1173 "Logical unit communication parity error") }, 1174 /* DT ROM BK */ 1175 { SST(0x08, 0x03, SS_RDEF, 1176 "Logical unit communication CRC error (Ultra-DMA/32)") }, 1177 /* DTLPWRO K */ 1178 { SST(0x08, 0x04, SS_RDEF, /* XXX TBD */ 1179 "Unreachable copy target") }, 1180 /* DT WRO B */ 1181 { SST(0x09, 0x00, SS_RDEF, 1182 "Track following error") }, 1183 /* WRO K */ 1184 { SST(0x09, 0x01, SS_RDEF, 1185 "Tracking servo failure") }, 1186 /* WRO K */ 1187 { SST(0x09, 0x02, SS_RDEF, 1188 "Focus servo failure") }, 1189 /* WRO */ 1190 { SST(0x09, 0x03, SS_RDEF, 1191 "Spindle servo failure") }, 1192 /* DT WRO B */ 1193 { SST(0x09, 0x04, SS_RDEF, 1194 "Head select fault") }, 1195 /* DTLPWROMAEBKVF */ 1196 { SST(0x0A, 0x00, SS_FATAL | ENOSPC, 1197 "Error log overflow") }, 1198 /* DTLPWROMAEBKVF */ 1199 { SST(0x0B, 0x00, SS_RDEF, 1200 "Warning") }, 1201 /* DTLPWROMAEBKVF */ 1202 { SST(0x0B, 0x01, SS_RDEF, 1203 "Warning - specified temperature exceeded") }, 1204 /* DTLPWROMAEBKVF */ 1205 { SST(0x0B, 0x02, SS_RDEF, 1206 "Warning - enclosure degraded") }, 1207 /* DTLPWROMAEBKVF */ 1208 { SST(0x0B, 0x03, SS_RDEF, /* XXX TBD */ 1209 "Warning - background self-test failed") }, 1210 /* DTLPWRO AEBKVF */ 1211 { SST(0x0B, 0x04, SS_RDEF, /* XXX TBD */ 1212 "Warning - background pre-scan detected medium error") }, 1213 /* DTLPWRO AEBKVF */ 1214 { SST(0x0B, 0x05, SS_RDEF, /* XXX TBD */ 1215 "Warning - background medium scan detected medium error") }, 1216 /* DTLPWROMAEBKVF */ 1217 { SST(0x0B, 0x06, SS_RDEF, /* XXX TBD */ 1218 "Warning - non-volatile cache now volatile") }, 1219 /* DTLPWROMAEBKVF */ 1220 { SST(0x0B, 0x07, SS_RDEF, /* XXX TBD */ 1221 "Warning - degraded power to non-volatile cache") }, 1222 /* DTLPWROMAEBKVF */ 1223 { SST(0x0B, 0x08, SS_RDEF, /* XXX TBD */ 1224 "Warning - power loss expected") }, 1225 /* D */ 1226 { SST(0x0B, 0x09, SS_RDEF, /* XXX TBD */ 1227 "Warning - device statistics notification available") }, 1228 /* T R */ 1229 { SST(0x0C, 0x00, SS_RDEF, 1230 "Write error") }, 1231 /* K */ 1232 { SST(0x0C, 0x01, SS_NOP | SSQ_PRINT_SENSE, 1233 "Write error - recovered with auto reallocation") }, 1234 /* D W O BK */ 1235 { SST(0x0C, 0x02, SS_RDEF, 1236 "Write error - auto reallocation failed") }, 1237 /* D W O BK */ 1238 { SST(0x0C, 0x03, SS_RDEF, 1239 "Write error - recommend reassignment") }, 1240 /* DT W O B */ 1241 { SST(0x0C, 0x04, SS_RDEF, 1242 "Compression check miscompare error") }, 1243 /* DT W O B */ 1244 { SST(0x0C, 0x05, SS_RDEF, 1245 "Data expansion occurred during compression") }, 1246 /* DT W O B */ 1247 { SST(0x0C, 0x06, SS_RDEF, 1248 "Block not compressible") }, 1249 /* R */ 1250 { SST(0x0C, 0x07, SS_RDEF, 1251 "Write error - recovery needed") }, 1252 /* R */ 1253 { SST(0x0C, 0x08, SS_RDEF, 1254 "Write error - recovery failed") }, 1255 /* R */ 1256 { SST(0x0C, 0x09, SS_RDEF, 1257 "Write error - loss of streaming") }, 1258 /* R */ 1259 { SST(0x0C, 0x0A, SS_RDEF, 1260 "Write error - padding blocks added") }, 1261 /* DT WROM B */ 1262 { SST(0x0C, 0x0B, SS_RDEF, /* XXX TBD */ 1263 "Auxiliary memory write error") }, 1264 /* DTLPWRO AEBKVF */ 1265 { SST(0x0C, 0x0C, SS_RDEF, /* XXX TBD */ 1266 "Write error - unexpected unsolicited data") }, 1267 /* DTLPWRO AEBKVF */ 1268 { SST(0x0C, 0x0D, SS_RDEF, /* XXX TBD */ 1269 "Write error - not enough unsolicited data") }, 1270 /* DT W O BK */ 1271 { SST(0x0C, 0x0E, SS_RDEF, /* XXX TBD */ 1272 "Multiple write errors") }, 1273 /* R */ 1274 { SST(0x0C, 0x0F, SS_RDEF, /* XXX TBD */ 1275 "Defects in error window") }, 1276 /* DTLPWRO A K */ 1277 { SST(0x0D, 0x00, SS_RDEF, /* XXX TBD */ 1278 "Error detected by third party temporary initiator") }, 1279 /* DTLPWRO A K */ 1280 { SST(0x0D, 0x01, SS_RDEF, /* XXX TBD */ 1281 "Third party device failure") }, 1282 /* DTLPWRO A K */ 1283 { SST(0x0D, 0x02, SS_RDEF, /* XXX TBD */ 1284 "Copy target device not reachable") }, 1285 /* DTLPWRO A K */ 1286 { SST(0x0D, 0x03, SS_RDEF, /* XXX TBD */ 1287 "Incorrect copy target device type") }, 1288 /* DTLPWRO A K */ 1289 { SST(0x0D, 0x04, SS_RDEF, /* XXX TBD */ 1290 "Copy target device data underrun") }, 1291 /* DTLPWRO A K */ 1292 { SST(0x0D, 0x05, SS_RDEF, /* XXX TBD */ 1293 "Copy target device data overrun") }, 1294 /* DT PWROMAEBK F */ 1295 { SST(0x0E, 0x00, SS_RDEF, /* XXX TBD */ 1296 "Invalid information unit") }, 1297 /* DT PWROMAEBK F */ 1298 { SST(0x0E, 0x01, SS_RDEF, /* XXX TBD */ 1299 "Information unit too short") }, 1300 /* DT PWROMAEBK F */ 1301 { SST(0x0E, 0x02, SS_RDEF, /* XXX TBD */ 1302 "Information unit too long") }, 1303 /* DT P R MAEBK F */ 1304 { SST(0x0E, 0x03, SS_RDEF, /* XXX TBD */ 1305 "Invalid field in command information unit") }, 1306 /* D W O BK */ 1307 { SST(0x10, 0x00, SS_RDEF, 1308 "ID CRC or ECC error") }, 1309 /* DT W O */ 1310 { SST(0x10, 0x01, SS_RDEF, /* XXX TBD */ 1311 "Logical block guard check failed") }, 1312 /* DT W O */ 1313 { SST(0x10, 0x02, SS_RDEF, /* XXX TBD */ 1314 "Logical block application tag check failed") }, 1315 /* DT W O */ 1316 { SST(0x10, 0x03, SS_RDEF, /* XXX TBD */ 1317 "Logical block reference tag check failed") }, 1318 /* T */ 1319 { SST(0x10, 0x04, SS_RDEF, /* XXX TBD */ 1320 "Logical block protection error on recovered buffer data") }, 1321 /* T */ 1322 { SST(0x10, 0x05, SS_RDEF, /* XXX TBD */ 1323 "Logical block protection method error") }, 1324 /* DT WRO BK */ 1325 { SST(0x11, 0x00, SS_FATAL|EIO, 1326 "Unrecovered read error") }, 1327 /* DT WRO BK */ 1328 { SST(0x11, 0x01, SS_FATAL|EIO, 1329 "Read retries exhausted") }, 1330 /* DT WRO BK */ 1331 { SST(0x11, 0x02, SS_FATAL|EIO, 1332 "Error too long to correct") }, 1333 /* DT W O BK */ 1334 { SST(0x11, 0x03, SS_FATAL|EIO, 1335 "Multiple read errors") }, 1336 /* D W O BK */ 1337 { SST(0x11, 0x04, SS_FATAL|EIO, 1338 "Unrecovered read error - auto reallocate failed") }, 1339 /* WRO B */ 1340 { SST(0x11, 0x05, SS_FATAL|EIO, 1341 "L-EC uncorrectable error") }, 1342 /* WRO B */ 1343 { SST(0x11, 0x06, SS_FATAL|EIO, 1344 "CIRC unrecovered error") }, 1345 /* W O B */ 1346 { SST(0x11, 0x07, SS_RDEF, 1347 "Data re-synchronization error") }, 1348 /* T */ 1349 { SST(0x11, 0x08, SS_RDEF, 1350 "Incomplete block read") }, 1351 /* T */ 1352 { SST(0x11, 0x09, SS_RDEF, 1353 "No gap found") }, 1354 /* DT O BK */ 1355 { SST(0x11, 0x0A, SS_RDEF, 1356 "Miscorrected error") }, 1357 /* D W O BK */ 1358 { SST(0x11, 0x0B, SS_FATAL|EIO, 1359 "Unrecovered read error - recommend reassignment") }, 1360 /* D W O BK */ 1361 { SST(0x11, 0x0C, SS_FATAL|EIO, 1362 "Unrecovered read error - recommend rewrite the data") }, 1363 /* DT WRO B */ 1364 { SST(0x11, 0x0D, SS_RDEF, 1365 "De-compression CRC error") }, 1366 /* DT WRO B */ 1367 { SST(0x11, 0x0E, SS_RDEF, 1368 "Cannot decompress using declared algorithm") }, 1369 /* R */ 1370 { SST(0x11, 0x0F, SS_RDEF, 1371 "Error reading UPC/EAN number") }, 1372 /* R */ 1373 { SST(0x11, 0x10, SS_RDEF, 1374 "Error reading ISRC number") }, 1375 /* R */ 1376 { SST(0x11, 0x11, SS_RDEF, 1377 "Read error - loss of streaming") }, 1378 /* DT WROM B */ 1379 { SST(0x11, 0x12, SS_RDEF, /* XXX TBD */ 1380 "Auxiliary memory read error") }, 1381 /* DTLPWRO AEBKVF */ 1382 { SST(0x11, 0x13, SS_RDEF, /* XXX TBD */ 1383 "Read error - failed retransmission request") }, 1384 /* D */ 1385 { SST(0x11, 0x14, SS_RDEF, /* XXX TBD */ 1386 "Read error - LBA marked bad by application client") }, 1387 /* D W O BK */ 1388 { SST(0x12, 0x00, SS_RDEF, 1389 "Address mark not found for ID field") }, 1390 /* D W O BK */ 1391 { SST(0x13, 0x00, SS_RDEF, 1392 "Address mark not found for data field") }, 1393 /* DTL WRO BK */ 1394 { SST(0x14, 0x00, SS_RDEF, 1395 "Recorded entity not found") }, 1396 /* DT WRO BK */ 1397 { SST(0x14, 0x01, SS_RDEF, 1398 "Record not found") }, 1399 /* T */ 1400 { SST(0x14, 0x02, SS_RDEF, 1401 "Filemark or setmark not found") }, 1402 /* T */ 1403 { SST(0x14, 0x03, SS_RDEF, 1404 "End-of-data not found") }, 1405 /* T */ 1406 { SST(0x14, 0x04, SS_RDEF, 1407 "Block sequence error") }, 1408 /* DT W O BK */ 1409 { SST(0x14, 0x05, SS_RDEF, 1410 "Record not found - recommend reassignment") }, 1411 /* DT W O BK */ 1412 { SST(0x14, 0x06, SS_RDEF, 1413 "Record not found - data auto-reallocated") }, 1414 /* T */ 1415 { SST(0x14, 0x07, SS_RDEF, /* XXX TBD */ 1416 "Locate operation failure") }, 1417 /* DTL WROM BK */ 1418 { SST(0x15, 0x00, SS_RDEF, 1419 "Random positioning error") }, 1420 /* DTL WROM BK */ 1421 { SST(0x15, 0x01, SS_RDEF, 1422 "Mechanical positioning error") }, 1423 /* DT WRO BK */ 1424 { SST(0x15, 0x02, SS_RDEF, 1425 "Positioning error detected by read of medium") }, 1426 /* D W O BK */ 1427 { SST(0x16, 0x00, SS_RDEF, 1428 "Data synchronization mark error") }, 1429 /* D W O BK */ 1430 { SST(0x16, 0x01, SS_RDEF, 1431 "Data sync error - data rewritten") }, 1432 /* D W O BK */ 1433 { SST(0x16, 0x02, SS_RDEF, 1434 "Data sync error - recommend rewrite") }, 1435 /* D W O BK */ 1436 { SST(0x16, 0x03, SS_NOP | SSQ_PRINT_SENSE, 1437 "Data sync error - data auto-reallocated") }, 1438 /* D W O BK */ 1439 { SST(0x16, 0x04, SS_RDEF, 1440 "Data sync error - recommend reassignment") }, 1441 /* DT WRO BK */ 1442 { SST(0x17, 0x00, SS_NOP | SSQ_PRINT_SENSE, 1443 "Recovered data with no error correction applied") }, 1444 /* DT WRO BK */ 1445 { SST(0x17, 0x01, SS_NOP | SSQ_PRINT_SENSE, 1446 "Recovered data with retries") }, 1447 /* DT WRO BK */ 1448 { SST(0x17, 0x02, SS_NOP | SSQ_PRINT_SENSE, 1449 "Recovered data with positive head offset") }, 1450 /* DT WRO BK */ 1451 { SST(0x17, 0x03, SS_NOP | SSQ_PRINT_SENSE, 1452 "Recovered data with negative head offset") }, 1453 /* WRO B */ 1454 { SST(0x17, 0x04, SS_NOP | SSQ_PRINT_SENSE, 1455 "Recovered data with retries and/or CIRC applied") }, 1456 /* D WRO BK */ 1457 { SST(0x17, 0x05, SS_NOP | SSQ_PRINT_SENSE, 1458 "Recovered data using previous sector ID") }, 1459 /* D W O BK */ 1460 { SST(0x17, 0x06, SS_NOP | SSQ_PRINT_SENSE, 1461 "Recovered data without ECC - data auto-reallocated") }, 1462 /* D WRO BK */ 1463 { SST(0x17, 0x07, SS_NOP | SSQ_PRINT_SENSE, 1464 "Recovered data without ECC - recommend reassignment") }, 1465 /* D WRO BK */ 1466 { SST(0x17, 0x08, SS_NOP | SSQ_PRINT_SENSE, 1467 "Recovered data without ECC - recommend rewrite") }, 1468 /* D WRO BK */ 1469 { SST(0x17, 0x09, SS_NOP | SSQ_PRINT_SENSE, 1470 "Recovered data without ECC - data rewritten") }, 1471 /* DT WRO BK */ 1472 { SST(0x18, 0x00, SS_NOP | SSQ_PRINT_SENSE, 1473 "Recovered data with error correction applied") }, 1474 /* D WRO BK */ 1475 { SST(0x18, 0x01, SS_NOP | SSQ_PRINT_SENSE, 1476 "Recovered data with error corr. & retries applied") }, 1477 /* D WRO BK */ 1478 { SST(0x18, 0x02, SS_NOP | SSQ_PRINT_SENSE, 1479 "Recovered data - data auto-reallocated") }, 1480 /* R */ 1481 { SST(0x18, 0x03, SS_NOP | SSQ_PRINT_SENSE, 1482 "Recovered data with CIRC") }, 1483 /* R */ 1484 { SST(0x18, 0x04, SS_NOP | SSQ_PRINT_SENSE, 1485 "Recovered data with L-EC") }, 1486 /* D WRO BK */ 1487 { SST(0x18, 0x05, SS_NOP | SSQ_PRINT_SENSE, 1488 "Recovered data - recommend reassignment") }, 1489 /* D WRO BK */ 1490 { SST(0x18, 0x06, SS_NOP | SSQ_PRINT_SENSE, 1491 "Recovered data - recommend rewrite") }, 1492 /* D W O BK */ 1493 { SST(0x18, 0x07, SS_NOP | SSQ_PRINT_SENSE, 1494 "Recovered data with ECC - data rewritten") }, 1495 /* R */ 1496 { SST(0x18, 0x08, SS_RDEF, /* XXX TBD */ 1497 "Recovered data with linking") }, 1498 /* D O K */ 1499 { SST(0x19, 0x00, SS_RDEF, 1500 "Defect list error") }, 1501 /* D O K */ 1502 { SST(0x19, 0x01, SS_RDEF, 1503 "Defect list not available") }, 1504 /* D O K */ 1505 { SST(0x19, 0x02, SS_RDEF, 1506 "Defect list error in primary list") }, 1507 /* D O K */ 1508 { SST(0x19, 0x03, SS_RDEF, 1509 "Defect list error in grown list") }, 1510 /* DTLPWROMAEBKVF */ 1511 { SST(0x1A, 0x00, SS_RDEF, 1512 "Parameter list length error") }, 1513 /* DTLPWROMAEBKVF */ 1514 { SST(0x1B, 0x00, SS_RDEF, 1515 "Synchronous data transfer error") }, 1516 /* D O BK */ 1517 { SST(0x1C, 0x00, SS_RDEF, 1518 "Defect list not found") }, 1519 /* D O BK */ 1520 { SST(0x1C, 0x01, SS_RDEF, 1521 "Primary defect list not found") }, 1522 /* D O BK */ 1523 { SST(0x1C, 0x02, SS_RDEF, 1524 "Grown defect list not found") }, 1525 /* DT WRO BK */ 1526 { SST(0x1D, 0x00, SS_FATAL, 1527 "Miscompare during verify operation") }, 1528 /* D B */ 1529 { SST(0x1D, 0x01, SS_RDEF, /* XXX TBD */ 1530 "Miscomparable verify of unmapped LBA") }, 1531 /* D W O BK */ 1532 { SST(0x1E, 0x00, SS_NOP | SSQ_PRINT_SENSE, 1533 "Recovered ID with ECC correction") }, 1534 /* D O K */ 1535 { SST(0x1F, 0x00, SS_RDEF, 1536 "Partial defect list transfer") }, 1537 /* DTLPWROMAEBKVF */ 1538 { SST(0x20, 0x00, SS_FATAL | EINVAL, 1539 "Invalid command operation code") }, 1540 /* DT PWROMAEBK */ 1541 { SST(0x20, 0x01, SS_RDEF, /* XXX TBD */ 1542 "Access denied - initiator pending-enrolled") }, 1543 /* DT PWROMAEBK */ 1544 { SST(0x20, 0x02, SS_RDEF, /* XXX TBD */ 1545 "Access denied - no access rights") }, 1546 /* DT PWROMAEBK */ 1547 { SST(0x20, 0x03, SS_RDEF, /* XXX TBD */ 1548 "Access denied - invalid mgmt ID key") }, 1549 /* T */ 1550 { SST(0x20, 0x04, SS_RDEF, /* XXX TBD */ 1551 "Illegal command while in write capable state") }, 1552 /* T */ 1553 { SST(0x20, 0x05, SS_RDEF, /* XXX TBD */ 1554 "Obsolete") }, 1555 /* T */ 1556 { SST(0x20, 0x06, SS_RDEF, /* XXX TBD */ 1557 "Illegal command while in explicit address mode") }, 1558 /* T */ 1559 { SST(0x20, 0x07, SS_RDEF, /* XXX TBD */ 1560 "Illegal command while in implicit address mode") }, 1561 /* DT PWROMAEBK */ 1562 { SST(0x20, 0x08, SS_RDEF, /* XXX TBD */ 1563 "Access denied - enrollment conflict") }, 1564 /* DT PWROMAEBK */ 1565 { SST(0x20, 0x09, SS_RDEF, /* XXX TBD */ 1566 "Access denied - invalid LU identifier") }, 1567 /* DT PWROMAEBK */ 1568 { SST(0x20, 0x0A, SS_RDEF, /* XXX TBD */ 1569 "Access denied - invalid proxy token") }, 1570 /* DT PWROMAEBK */ 1571 { SST(0x20, 0x0B, SS_RDEF, /* XXX TBD */ 1572 "Access denied - ACL LUN conflict") }, 1573 /* T */ 1574 { SST(0x20, 0x0C, SS_FATAL | EINVAL, 1575 "Illegal command when not in append-only mode") }, 1576 /* DT WRO BK */ 1577 { SST(0x21, 0x00, SS_FATAL | EINVAL, 1578 "Logical block address out of range") }, 1579 /* DT WROM BK */ 1580 { SST(0x21, 0x01, SS_FATAL | EINVAL, 1581 "Invalid element address") }, 1582 /* R */ 1583 { SST(0x21, 0x02, SS_RDEF, /* XXX TBD */ 1584 "Invalid address for write") }, 1585 /* R */ 1586 { SST(0x21, 0x03, SS_RDEF, /* XXX TBD */ 1587 "Invalid write crossing layer jump") }, 1588 /* D */ 1589 { SST(0x22, 0x00, SS_FATAL | EINVAL, 1590 "Illegal function (use 20 00, 24 00, or 26 00)") }, 1591 /* DT P B */ 1592 { SST(0x23, 0x00, SS_RDEF, /* XXX TBD */ 1593 "Invalid token operation, cause not reportable") }, 1594 /* DT P B */ 1595 { SST(0x23, 0x01, SS_RDEF, /* XXX TBD */ 1596 "Invalid token operation, unsupported token type") }, 1597 /* DT P B */ 1598 { SST(0x23, 0x02, SS_RDEF, /* XXX TBD */ 1599 "Invalid token operation, remote token usage not supported") }, 1600 /* DT P B */ 1601 { SST(0x23, 0x03, SS_RDEF, /* XXX TBD */ 1602 "Invalid token operation, remote ROD token creation not supported") }, 1603 /* DT P B */ 1604 { SST(0x23, 0x04, SS_RDEF, /* XXX TBD */ 1605 "Invalid token operation, token unknown") }, 1606 /* DT P B */ 1607 { SST(0x23, 0x05, SS_RDEF, /* XXX TBD */ 1608 "Invalid token operation, token corrupt") }, 1609 /* DT P B */ 1610 { SST(0x23, 0x06, SS_RDEF, /* XXX TBD */ 1611 "Invalid token operation, token revoked") }, 1612 /* DT P B */ 1613 { SST(0x23, 0x07, SS_RDEF, /* XXX TBD */ 1614 "Invalid token operation, token expired") }, 1615 /* DT P B */ 1616 { SST(0x23, 0x08, SS_RDEF, /* XXX TBD */ 1617 "Invalid token operation, token cancelled") }, 1618 /* DT P B */ 1619 { SST(0x23, 0x09, SS_RDEF, /* XXX TBD */ 1620 "Invalid token operation, token deleted") }, 1621 /* DT P B */ 1622 { SST(0x23, 0x0A, SS_RDEF, /* XXX TBD */ 1623 "Invalid token operation, invalid token length") }, 1624 /* DTLPWROMAEBKVF */ 1625 { SST(0x24, 0x00, SS_FATAL | EINVAL, 1626 "Invalid field in CDB") }, 1627 /* DTLPWRO AEBKVF */ 1628 { SST(0x24, 0x01, SS_RDEF, /* XXX TBD */ 1629 "CDB decryption error") }, 1630 /* T */ 1631 { SST(0x24, 0x02, SS_RDEF, /* XXX TBD */ 1632 "Obsolete") }, 1633 /* T */ 1634 { SST(0x24, 0x03, SS_RDEF, /* XXX TBD */ 1635 "Obsolete") }, 1636 /* F */ 1637 { SST(0x24, 0x04, SS_RDEF, /* XXX TBD */ 1638 "Security audit value frozen") }, 1639 /* F */ 1640 { SST(0x24, 0x05, SS_RDEF, /* XXX TBD */ 1641 "Security working key frozen") }, 1642 /* F */ 1643 { SST(0x24, 0x06, SS_RDEF, /* XXX TBD */ 1644 "NONCE not unique") }, 1645 /* F */ 1646 { SST(0x24, 0x07, SS_RDEF, /* XXX TBD */ 1647 "NONCE timestamp out of range") }, 1648 /* DT R MAEBKV */ 1649 { SST(0x24, 0x08, SS_RDEF, /* XXX TBD */ 1650 "Invalid XCDB") }, 1651 /* DTLPWROMAEBKVF */ 1652 { SST(0x25, 0x00, SS_FATAL | ENXIO | SSQ_LOST, 1653 "Logical unit not supported") }, 1654 /* DTLPWROMAEBKVF */ 1655 { SST(0x26, 0x00, SS_FATAL | EINVAL, 1656 "Invalid field in parameter list") }, 1657 /* DTLPWROMAEBKVF */ 1658 { SST(0x26, 0x01, SS_FATAL | EINVAL, 1659 "Parameter not supported") }, 1660 /* DTLPWROMAEBKVF */ 1661 { SST(0x26, 0x02, SS_FATAL | EINVAL, 1662 "Parameter value invalid") }, 1663 /* DTLPWROMAE K */ 1664 { SST(0x26, 0x03, SS_FATAL | EINVAL, 1665 "Threshold parameters not supported") }, 1666 /* DTLPWROMAEBKVF */ 1667 { SST(0x26, 0x04, SS_FATAL | EINVAL, 1668 "Invalid release of persistent reservation") }, 1669 /* DTLPWRO A BK */ 1670 { SST(0x26, 0x05, SS_RDEF, /* XXX TBD */ 1671 "Data decryption error") }, 1672 /* DTLPWRO K */ 1673 { SST(0x26, 0x06, SS_RDEF, /* XXX TBD */ 1674 "Too many target descriptors") }, 1675 /* DTLPWRO K */ 1676 { SST(0x26, 0x07, SS_RDEF, /* XXX TBD */ 1677 "Unsupported target descriptor type code") }, 1678 /* DTLPWRO K */ 1679 { SST(0x26, 0x08, SS_RDEF, /* XXX TBD */ 1680 "Too many segment descriptors") }, 1681 /* DTLPWRO K */ 1682 { SST(0x26, 0x09, SS_RDEF, /* XXX TBD */ 1683 "Unsupported segment descriptor type code") }, 1684 /* DTLPWRO K */ 1685 { SST(0x26, 0x0A, SS_RDEF, /* XXX TBD */ 1686 "Unexpected inexact segment") }, 1687 /* DTLPWRO K */ 1688 { SST(0x26, 0x0B, SS_RDEF, /* XXX TBD */ 1689 "Inline data length exceeded") }, 1690 /* DTLPWRO K */ 1691 { SST(0x26, 0x0C, SS_RDEF, /* XXX TBD */ 1692 "Invalid operation for copy source or destination") }, 1693 /* DTLPWRO K */ 1694 { SST(0x26, 0x0D, SS_RDEF, /* XXX TBD */ 1695 "Copy segment granularity violation") }, 1696 /* DT PWROMAEBK */ 1697 { SST(0x26, 0x0E, SS_RDEF, /* XXX TBD */ 1698 "Invalid parameter while port is enabled") }, 1699 /* F */ 1700 { SST(0x26, 0x0F, SS_RDEF, /* XXX TBD */ 1701 "Invalid data-out buffer integrity check value") }, 1702 /* T */ 1703 { SST(0x26, 0x10, SS_RDEF, /* XXX TBD */ 1704 "Data decryption key fail limit reached") }, 1705 /* T */ 1706 { SST(0x26, 0x11, SS_RDEF, /* XXX TBD */ 1707 "Incomplete key-associated data set") }, 1708 /* T */ 1709 { SST(0x26, 0x12, SS_RDEF, /* XXX TBD */ 1710 "Vendor specific key reference not found") }, 1711 /* DT WRO BK */ 1712 { SST(0x27, 0x00, SS_FATAL | EACCES, 1713 "Write protected") }, 1714 /* DT WRO BK */ 1715 { SST(0x27, 0x01, SS_FATAL | EACCES, 1716 "Hardware write protected") }, 1717 /* DT WRO BK */ 1718 { SST(0x27, 0x02, SS_FATAL | EACCES, 1719 "Logical unit software write protected") }, 1720 /* T R */ 1721 { SST(0x27, 0x03, SS_FATAL | EACCES, 1722 "Associated write protect") }, 1723 /* T R */ 1724 { SST(0x27, 0x04, SS_FATAL | EACCES, 1725 "Persistent write protect") }, 1726 /* T R */ 1727 { SST(0x27, 0x05, SS_FATAL | EACCES, 1728 "Permanent write protect") }, 1729 /* R F */ 1730 { SST(0x27, 0x06, SS_RDEF, /* XXX TBD */ 1731 "Conditional write protect") }, 1732 /* D B */ 1733 { SST(0x27, 0x07, SS_RDEF, /* XXX TBD */ 1734 "Space allocation failed write protect") }, 1735 /* DTLPWROMAEBKVF */ 1736 { SST(0x28, 0x00, SS_FATAL | ENXIO, 1737 "Not ready to ready change, medium may have changed") }, 1738 /* DT WROM B */ 1739 { SST(0x28, 0x01, SS_FATAL | ENXIO, 1740 "Import or export element accessed") }, 1741 /* R */ 1742 { SST(0x28, 0x02, SS_RDEF, /* XXX TBD */ 1743 "Format-layer may have changed") }, 1744 /* M */ 1745 { SST(0x28, 0x03, SS_RDEF, /* XXX TBD */ 1746 "Import/export element accessed, medium changed") }, 1747 /* 1748 * XXX JGibbs - All of these should use the same errno, but I don't 1749 * think ENXIO is the correct choice. Should we borrow from 1750 * the networking errnos? ECONNRESET anyone? 1751 */ 1752 /* DTLPWROMAEBKVF */ 1753 { SST(0x29, 0x00, SS_FATAL | ENXIO, 1754 "Power on, reset, or bus device reset occurred") }, 1755 /* DTLPWROMAEBKVF */ 1756 { SST(0x29, 0x01, SS_RDEF, 1757 "Power on occurred") }, 1758 /* DTLPWROMAEBKVF */ 1759 { SST(0x29, 0x02, SS_RDEF, 1760 "SCSI bus reset occurred") }, 1761 /* DTLPWROMAEBKVF */ 1762 { SST(0x29, 0x03, SS_RDEF, 1763 "Bus device reset function occurred") }, 1764 /* DTLPWROMAEBKVF */ 1765 { SST(0x29, 0x04, SS_RDEF, 1766 "Device internal reset") }, 1767 /* DTLPWROMAEBKVF */ 1768 { SST(0x29, 0x05, SS_RDEF, 1769 "Transceiver mode changed to single-ended") }, 1770 /* DTLPWROMAEBKVF */ 1771 { SST(0x29, 0x06, SS_RDEF, 1772 "Transceiver mode changed to LVD") }, 1773 /* DTLPWROMAEBKVF */ 1774 { SST(0x29, 0x07, SS_RDEF, /* XXX TBD */ 1775 "I_T nexus loss occurred") }, 1776 /* DTL WROMAEBKVF */ 1777 { SST(0x2A, 0x00, SS_RDEF, 1778 "Parameters changed") }, 1779 /* DTL WROMAEBKVF */ 1780 { SST(0x2A, 0x01, SS_RDEF, 1781 "Mode parameters changed") }, 1782 /* DTL WROMAE K */ 1783 { SST(0x2A, 0x02, SS_RDEF, 1784 "Log parameters changed") }, 1785 /* DTLPWROMAE K */ 1786 { SST(0x2A, 0x03, SS_RDEF, 1787 "Reservations preempted") }, 1788 /* DTLPWROMAE */ 1789 { SST(0x2A, 0x04, SS_RDEF, /* XXX TBD */ 1790 "Reservations released") }, 1791 /* DTLPWROMAE */ 1792 { SST(0x2A, 0x05, SS_RDEF, /* XXX TBD */ 1793 "Registrations preempted") }, 1794 /* DTLPWROMAEBKVF */ 1795 { SST(0x2A, 0x06, SS_RDEF, /* XXX TBD */ 1796 "Asymmetric access state changed") }, 1797 /* DTLPWROMAEBKVF */ 1798 { SST(0x2A, 0x07, SS_RDEF, /* XXX TBD */ 1799 "Implicit asymmetric access state transition failed") }, 1800 /* DT WROMAEBKVF */ 1801 { SST(0x2A, 0x08, SS_RDEF, /* XXX TBD */ 1802 "Priority changed") }, 1803 /* D */ 1804 { SST(0x2A, 0x09, SS_RDEF, /* XXX TBD */ 1805 "Capacity data has changed") }, 1806 /* DT */ 1807 { SST(0x2A, 0x0A, SS_RDEF, /* XXX TBD */ 1808 "Error history I_T nexus cleared") }, 1809 /* DT */ 1810 { SST(0x2A, 0x0B, SS_RDEF, /* XXX TBD */ 1811 "Error history snapshot released") }, 1812 /* F */ 1813 { SST(0x2A, 0x0C, SS_RDEF, /* XXX TBD */ 1814 "Error recovery attributes have changed") }, 1815 /* T */ 1816 { SST(0x2A, 0x0D, SS_RDEF, /* XXX TBD */ 1817 "Data encryption capabilities changed") }, 1818 /* DT M E V */ 1819 { SST(0x2A, 0x10, SS_RDEF, /* XXX TBD */ 1820 "Timestamp changed") }, 1821 /* T */ 1822 { SST(0x2A, 0x11, SS_RDEF, /* XXX TBD */ 1823 "Data encryption parameters changed by another I_T nexus") }, 1824 /* T */ 1825 { SST(0x2A, 0x12, SS_RDEF, /* XXX TBD */ 1826 "Data encryption parameters changed by vendor specific event") }, 1827 /* T */ 1828 { SST(0x2A, 0x13, SS_RDEF, /* XXX TBD */ 1829 "Data encryption key instance counter has changed") }, 1830 /* DT R MAEBKV */ 1831 { SST(0x2A, 0x14, SS_RDEF, /* XXX TBD */ 1832 "SA creation capabilities data has changed") }, 1833 /* T M V */ 1834 { SST(0x2A, 0x15, SS_RDEF, /* XXX TBD */ 1835 "Medium removal prevention preempted") }, 1836 /* DTLPWRO K */ 1837 { SST(0x2B, 0x00, SS_RDEF, 1838 "Copy cannot execute since host cannot disconnect") }, 1839 /* DTLPWROMAEBKVF */ 1840 { SST(0x2C, 0x00, SS_RDEF, 1841 "Command sequence error") }, 1842 /* */ 1843 { SST(0x2C, 0x01, SS_RDEF, 1844 "Too many windows specified") }, 1845 /* */ 1846 { SST(0x2C, 0x02, SS_RDEF, 1847 "Invalid combination of windows specified") }, 1848 /* R */ 1849 { SST(0x2C, 0x03, SS_RDEF, 1850 "Current program area is not empty") }, 1851 /* R */ 1852 { SST(0x2C, 0x04, SS_RDEF, 1853 "Current program area is empty") }, 1854 /* B */ 1855 { SST(0x2C, 0x05, SS_RDEF, /* XXX TBD */ 1856 "Illegal power condition request") }, 1857 /* R */ 1858 { SST(0x2C, 0x06, SS_RDEF, /* XXX TBD */ 1859 "Persistent prevent conflict") }, 1860 /* DTLPWROMAEBKVF */ 1861 { SST(0x2C, 0x07, SS_RDEF, /* XXX TBD */ 1862 "Previous busy status") }, 1863 /* DTLPWROMAEBKVF */ 1864 { SST(0x2C, 0x08, SS_RDEF, /* XXX TBD */ 1865 "Previous task set full status") }, 1866 /* DTLPWROM EBKVF */ 1867 { SST(0x2C, 0x09, SS_RDEF, /* XXX TBD */ 1868 "Previous reservation conflict status") }, 1869 /* F */ 1870 { SST(0x2C, 0x0A, SS_RDEF, /* XXX TBD */ 1871 "Partition or collection contains user objects") }, 1872 /* T */ 1873 { SST(0x2C, 0x0B, SS_RDEF, /* XXX TBD */ 1874 "Not reserved") }, 1875 /* D */ 1876 { SST(0x2C, 0x0C, SS_RDEF, /* XXX TBD */ 1877 "ORWRITE generation does not match") }, 1878 /* T */ 1879 { SST(0x2D, 0x00, SS_RDEF, 1880 "Overwrite error on update in place") }, 1881 /* R */ 1882 { SST(0x2E, 0x00, SS_RDEF, /* XXX TBD */ 1883 "Insufficient time for operation") }, 1884 /* DTLPWROMAEBKVF */ 1885 { SST(0x2F, 0x00, SS_RDEF, 1886 "Commands cleared by another initiator") }, 1887 /* D */ 1888 { SST(0x2F, 0x01, SS_RDEF, /* XXX TBD */ 1889 "Commands cleared by power loss notification") }, 1890 /* DTLPWROMAEBKVF */ 1891 { SST(0x2F, 0x02, SS_RDEF, /* XXX TBD */ 1892 "Commands cleared by device server") }, 1893 /* DT WROM BK */ 1894 { SST(0x30, 0x00, SS_RDEF, 1895 "Incompatible medium installed") }, 1896 /* DT WRO BK */ 1897 { SST(0x30, 0x01, SS_RDEF, 1898 "Cannot read medium - unknown format") }, 1899 /* DT WRO BK */ 1900 { SST(0x30, 0x02, SS_RDEF, 1901 "Cannot read medium - incompatible format") }, 1902 /* DT R K */ 1903 { SST(0x30, 0x03, SS_RDEF, 1904 "Cleaning cartridge installed") }, 1905 /* DT WRO BK */ 1906 { SST(0x30, 0x04, SS_RDEF, 1907 "Cannot write medium - unknown format") }, 1908 /* DT WRO BK */ 1909 { SST(0x30, 0x05, SS_RDEF, 1910 "Cannot write medium - incompatible format") }, 1911 /* DT WRO B */ 1912 { SST(0x30, 0x06, SS_RDEF, 1913 "Cannot format medium - incompatible medium") }, 1914 /* DTL WROMAEBKVF */ 1915 { SST(0x30, 0x07, SS_RDEF, 1916 "Cleaning failure") }, 1917 /* R */ 1918 { SST(0x30, 0x08, SS_RDEF, 1919 "Cannot write - application code mismatch") }, 1920 /* R */ 1921 { SST(0x30, 0x09, SS_RDEF, 1922 "Current session not fixated for append") }, 1923 /* DT WRO AEBK */ 1924 { SST(0x30, 0x0A, SS_RDEF, /* XXX TBD */ 1925 "Cleaning request rejected") }, 1926 /* T */ 1927 { SST(0x30, 0x0C, SS_RDEF, /* XXX TBD */ 1928 "WORM medium - overwrite attempted") }, 1929 /* T */ 1930 { SST(0x30, 0x0D, SS_RDEF, /* XXX TBD */ 1931 "WORM medium - integrity check") }, 1932 /* R */ 1933 { SST(0x30, 0x10, SS_RDEF, /* XXX TBD */ 1934 "Medium not formatted") }, 1935 /* M */ 1936 { SST(0x30, 0x11, SS_RDEF, /* XXX TBD */ 1937 "Incompatible volume type") }, 1938 /* M */ 1939 { SST(0x30, 0x12, SS_RDEF, /* XXX TBD */ 1940 "Incompatible volume qualifier") }, 1941 /* M */ 1942 { SST(0x30, 0x13, SS_RDEF, /* XXX TBD */ 1943 "Cleaning volume expired") }, 1944 /* DT WRO BK */ 1945 { SST(0x31, 0x00, SS_RDEF, 1946 "Medium format corrupted") }, 1947 /* D L RO B */ 1948 { SST(0x31, 0x01, SS_RDEF, 1949 "Format command failed") }, 1950 /* R */ 1951 { SST(0x31, 0x02, SS_RDEF, /* XXX TBD */ 1952 "Zoned formatting failed due to spare linking") }, 1953 /* D B */ 1954 { SST(0x31, 0x03, SS_RDEF, /* XXX TBD */ 1955 "SANITIZE command failed") }, 1956 /* D W O BK */ 1957 { SST(0x32, 0x00, SS_RDEF, 1958 "No defect spare location available") }, 1959 /* D W O BK */ 1960 { SST(0x32, 0x01, SS_RDEF, 1961 "Defect list update failure") }, 1962 /* T */ 1963 { SST(0x33, 0x00, SS_RDEF, 1964 "Tape length error") }, 1965 /* DTLPWROMAEBKVF */ 1966 { SST(0x34, 0x00, SS_RDEF, 1967 "Enclosure failure") }, 1968 /* DTLPWROMAEBKVF */ 1969 { SST(0x35, 0x00, SS_RDEF, 1970 "Enclosure services failure") }, 1971 /* DTLPWROMAEBKVF */ 1972 { SST(0x35, 0x01, SS_RDEF, 1973 "Unsupported enclosure function") }, 1974 /* DTLPWROMAEBKVF */ 1975 { SST(0x35, 0x02, SS_RDEF, 1976 "Enclosure services unavailable") }, 1977 /* DTLPWROMAEBKVF */ 1978 { SST(0x35, 0x03, SS_RDEF, 1979 "Enclosure services transfer failure") }, 1980 /* DTLPWROMAEBKVF */ 1981 { SST(0x35, 0x04, SS_RDEF, 1982 "Enclosure services transfer refused") }, 1983 /* DTL WROMAEBKVF */ 1984 { SST(0x35, 0x05, SS_RDEF, /* XXX TBD */ 1985 "Enclosure services checksum error") }, 1986 /* L */ 1987 { SST(0x36, 0x00, SS_RDEF, 1988 "Ribbon, ink, or toner failure") }, 1989 /* DTL WROMAEBKVF */ 1990 { SST(0x37, 0x00, SS_RDEF, 1991 "Rounded parameter") }, 1992 /* B */ 1993 { SST(0x38, 0x00, SS_RDEF, /* XXX TBD */ 1994 "Event status notification") }, 1995 /* B */ 1996 { SST(0x38, 0x02, SS_RDEF, /* XXX TBD */ 1997 "ESN - power management class event") }, 1998 /* B */ 1999 { SST(0x38, 0x04, SS_RDEF, /* XXX TBD */ 2000 "ESN - media class event") }, 2001 /* B */ 2002 { SST(0x38, 0x06, SS_RDEF, /* XXX TBD */ 2003 "ESN - device busy class event") }, 2004 /* D */ 2005 { SST(0x38, 0x07, SS_RDEF, /* XXX TBD */ 2006 "Thin provisioning soft threshold reached") }, 2007 /* DTL WROMAE K */ 2008 { SST(0x39, 0x00, SS_RDEF, 2009 "Saving parameters not supported") }, 2010 /* DTL WROM BK */ 2011 { SST(0x3A, 0x00, SS_FATAL | ENXIO, 2012 "Medium not present") }, 2013 /* DT WROM BK */ 2014 { SST(0x3A, 0x01, SS_FATAL | ENXIO, 2015 "Medium not present - tray closed") }, 2016 /* DT WROM BK */ 2017 { SST(0x3A, 0x02, SS_FATAL | ENXIO, 2018 "Medium not present - tray open") }, 2019 /* DT WROM B */ 2020 { SST(0x3A, 0x03, SS_RDEF, /* XXX TBD */ 2021 "Medium not present - loadable") }, 2022 /* DT WRO B */ 2023 { SST(0x3A, 0x04, SS_RDEF, /* XXX TBD */ 2024 "Medium not present - medium auxiliary memory accessible") }, 2025 /* TL */ 2026 { SST(0x3B, 0x00, SS_RDEF, 2027 "Sequential positioning error") }, 2028 /* T */ 2029 { SST(0x3B, 0x01, SS_RDEF, 2030 "Tape position error at beginning-of-medium") }, 2031 /* T */ 2032 { SST(0x3B, 0x02, SS_RDEF, 2033 "Tape position error at end-of-medium") }, 2034 /* L */ 2035 { SST(0x3B, 0x03, SS_RDEF, 2036 "Tape or electronic vertical forms unit not ready") }, 2037 /* L */ 2038 { SST(0x3B, 0x04, SS_RDEF, 2039 "Slew failure") }, 2040 /* L */ 2041 { SST(0x3B, 0x05, SS_RDEF, 2042 "Paper jam") }, 2043 /* L */ 2044 { SST(0x3B, 0x06, SS_RDEF, 2045 "Failed to sense top-of-form") }, 2046 /* L */ 2047 { SST(0x3B, 0x07, SS_RDEF, 2048 "Failed to sense bottom-of-form") }, 2049 /* T */ 2050 { SST(0x3B, 0x08, SS_RDEF, 2051 "Reposition error") }, 2052 /* */ 2053 { SST(0x3B, 0x09, SS_RDEF, 2054 "Read past end of medium") }, 2055 /* */ 2056 { SST(0x3B, 0x0A, SS_RDEF, 2057 "Read past beginning of medium") }, 2058 /* */ 2059 { SST(0x3B, 0x0B, SS_RDEF, 2060 "Position past end of medium") }, 2061 /* T */ 2062 { SST(0x3B, 0x0C, SS_RDEF, 2063 "Position past beginning of medium") }, 2064 /* DT WROM BK */ 2065 { SST(0x3B, 0x0D, SS_FATAL | ENOSPC, 2066 "Medium destination element full") }, 2067 /* DT WROM BK */ 2068 { SST(0x3B, 0x0E, SS_RDEF, 2069 "Medium source element empty") }, 2070 /* R */ 2071 { SST(0x3B, 0x0F, SS_RDEF, 2072 "End of medium reached") }, 2073 /* DT WROM BK */ 2074 { SST(0x3B, 0x11, SS_RDEF, 2075 "Medium magazine not accessible") }, 2076 /* DT WROM BK */ 2077 { SST(0x3B, 0x12, SS_RDEF, 2078 "Medium magazine removed") }, 2079 /* DT WROM BK */ 2080 { SST(0x3B, 0x13, SS_RDEF, 2081 "Medium magazine inserted") }, 2082 /* DT WROM BK */ 2083 { SST(0x3B, 0x14, SS_RDEF, 2084 "Medium magazine locked") }, 2085 /* DT WROM BK */ 2086 { SST(0x3B, 0x15, SS_RDEF, 2087 "Medium magazine unlocked") }, 2088 /* R */ 2089 { SST(0x3B, 0x16, SS_RDEF, /* XXX TBD */ 2090 "Mechanical positioning or changer error") }, 2091 /* F */ 2092 { SST(0x3B, 0x17, SS_RDEF, /* XXX TBD */ 2093 "Read past end of user object") }, 2094 /* M */ 2095 { SST(0x3B, 0x18, SS_RDEF, /* XXX TBD */ 2096 "Element disabled") }, 2097 /* M */ 2098 { SST(0x3B, 0x19, SS_RDEF, /* XXX TBD */ 2099 "Element enabled") }, 2100 /* M */ 2101 { SST(0x3B, 0x1A, SS_RDEF, /* XXX TBD */ 2102 "Data transfer device removed") }, 2103 /* M */ 2104 { SST(0x3B, 0x1B, SS_RDEF, /* XXX TBD */ 2105 "Data transfer device inserted") }, 2106 /* T */ 2107 { SST(0x3B, 0x1C, SS_RDEF, /* XXX TBD */ 2108 "Too many logical objects on partition to support operation") }, 2109 /* DTLPWROMAE K */ 2110 { SST(0x3D, 0x00, SS_RDEF, 2111 "Invalid bits in IDENTIFY message") }, 2112 /* DTLPWROMAEBKVF */ 2113 { SST(0x3E, 0x00, SS_RDEF, 2114 "Logical unit has not self-configured yet") }, 2115 /* DTLPWROMAEBKVF */ 2116 { SST(0x3E, 0x01, SS_RDEF, 2117 "Logical unit failure") }, 2118 /* DTLPWROMAEBKVF */ 2119 { SST(0x3E, 0x02, SS_RDEF, 2120 "Timeout on logical unit") }, 2121 /* DTLPWROMAEBKVF */ 2122 { SST(0x3E, 0x03, SS_RDEF, /* XXX TBD */ 2123 "Logical unit failed self-test") }, 2124 /* DTLPWROMAEBKVF */ 2125 { SST(0x3E, 0x04, SS_RDEF, /* XXX TBD */ 2126 "Logical unit unable to update self-test log") }, 2127 /* DTLPWROMAEBKVF */ 2128 { SST(0x3F, 0x00, SS_RDEF, 2129 "Target operating conditions have changed") }, 2130 /* DTLPWROMAEBKVF */ 2131 { SST(0x3F, 0x01, SS_RDEF, 2132 "Microcode has been changed") }, 2133 /* DTLPWROM BK */ 2134 { SST(0x3F, 0x02, SS_RDEF, 2135 "Changed operating definition") }, 2136 /* DTLPWROMAEBKVF */ 2137 { SST(0x3F, 0x03, SS_RDEF, 2138 "INQUIRY data has changed") }, 2139 /* DT WROMAEBK */ 2140 { SST(0x3F, 0x04, SS_RDEF, 2141 "Component device attached") }, 2142 /* DT WROMAEBK */ 2143 { SST(0x3F, 0x05, SS_RDEF, 2144 "Device identifier changed") }, 2145 /* DT WROMAEB */ 2146 { SST(0x3F, 0x06, SS_RDEF, 2147 "Redundancy group created or modified") }, 2148 /* DT WROMAEB */ 2149 { SST(0x3F, 0x07, SS_RDEF, 2150 "Redundancy group deleted") }, 2151 /* DT WROMAEB */ 2152 { SST(0x3F, 0x08, SS_RDEF, 2153 "Spare created or modified") }, 2154 /* DT WROMAEB */ 2155 { SST(0x3F, 0x09, SS_RDEF, 2156 "Spare deleted") }, 2157 /* DT WROMAEBK */ 2158 { SST(0x3F, 0x0A, SS_RDEF, 2159 "Volume set created or modified") }, 2160 /* DT WROMAEBK */ 2161 { SST(0x3F, 0x0B, SS_RDEF, 2162 "Volume set deleted") }, 2163 /* DT WROMAEBK */ 2164 { SST(0x3F, 0x0C, SS_RDEF, 2165 "Volume set deassigned") }, 2166 /* DT WROMAEBK */ 2167 { SST(0x3F, 0x0D, SS_RDEF, 2168 "Volume set reassigned") }, 2169 /* DTLPWROMAE */ 2170 { SST(0x3F, 0x0E, SS_RDEF | SSQ_RESCAN , 2171 "Reported LUNs data has changed") }, 2172 /* DTLPWROMAEBKVF */ 2173 { SST(0x3F, 0x0F, SS_RDEF, /* XXX TBD */ 2174 "Echo buffer overwritten") }, 2175 /* DT WROM B */ 2176 { SST(0x3F, 0x10, SS_RDEF, /* XXX TBD */ 2177 "Medium loadable") }, 2178 /* DT WROM B */ 2179 { SST(0x3F, 0x11, SS_RDEF, /* XXX TBD */ 2180 "Medium auxiliary memory accessible") }, 2181 /* DTLPWR MAEBK F */ 2182 { SST(0x3F, 0x12, SS_RDEF, /* XXX TBD */ 2183 "iSCSI IP address added") }, 2184 /* DTLPWR MAEBK F */ 2185 { SST(0x3F, 0x13, SS_RDEF, /* XXX TBD */ 2186 "iSCSI IP address removed") }, 2187 /* DTLPWR MAEBK F */ 2188 { SST(0x3F, 0x14, SS_RDEF, /* XXX TBD */ 2189 "iSCSI IP address changed") }, 2190 /* D */ 2191 { SST(0x40, 0x00, SS_RDEF, 2192 "RAM failure") }, /* deprecated - use 40 NN instead */ 2193 /* DTLPWROMAEBKVF */ 2194 { SST(0x40, 0x80, SS_RDEF, 2195 "Diagnostic failure: ASCQ = Component ID") }, 2196 /* DTLPWROMAEBKVF */ 2197 { SST(0x40, 0xFF, SS_RDEF | SSQ_RANGE, 2198 NULL) }, /* Range 0x80->0xFF */ 2199 /* D */ 2200 { SST(0x41, 0x00, SS_RDEF, 2201 "Data path failure") }, /* deprecated - use 40 NN instead */ 2202 /* D */ 2203 { SST(0x42, 0x00, SS_RDEF, 2204 "Power-on or self-test failure") }, 2205 /* deprecated - use 40 NN instead */ 2206 /* DTLPWROMAEBKVF */ 2207 { SST(0x43, 0x00, SS_RDEF, 2208 "Message error") }, 2209 /* DTLPWROMAEBKVF */ 2210 { SST(0x44, 0x00, SS_RDEF, 2211 "Internal target failure") }, 2212 /* DT P MAEBKVF */ 2213 { SST(0x44, 0x01, SS_RDEF, /* XXX TBD */ 2214 "Persistent reservation information lost") }, 2215 /* DT B */ 2216 { SST(0x44, 0x71, SS_RDEF, /* XXX TBD */ 2217 "ATA device failed set features") }, 2218 /* DTLPWROMAEBKVF */ 2219 { SST(0x45, 0x00, SS_RDEF, 2220 "Select or reselect failure") }, 2221 /* DTLPWROM BK */ 2222 { SST(0x46, 0x00, SS_RDEF, 2223 "Unsuccessful soft reset") }, 2224 /* DTLPWROMAEBKVF */ 2225 { SST(0x47, 0x00, SS_RDEF, 2226 "SCSI parity error") }, 2227 /* DTLPWROMAEBKVF */ 2228 { SST(0x47, 0x01, SS_RDEF, /* XXX TBD */ 2229 "Data phase CRC error detected") }, 2230 /* DTLPWROMAEBKVF */ 2231 { SST(0x47, 0x02, SS_RDEF, /* XXX TBD */ 2232 "SCSI parity error detected during ST data phase") }, 2233 /* DTLPWROMAEBKVF */ 2234 { SST(0x47, 0x03, SS_RDEF, /* XXX TBD */ 2235 "Information unit iuCRC error detected") }, 2236 /* DTLPWROMAEBKVF */ 2237 { SST(0x47, 0x04, SS_RDEF, /* XXX TBD */ 2238 "Asynchronous information protection error detected") }, 2239 /* DTLPWROMAEBKVF */ 2240 { SST(0x47, 0x05, SS_RDEF, /* XXX TBD */ 2241 "Protocol service CRC error") }, 2242 /* DT MAEBKVF */ 2243 { SST(0x47, 0x06, SS_RDEF, /* XXX TBD */ 2244 "PHY test function in progress") }, 2245 /* DT PWROMAEBK */ 2246 { SST(0x47, 0x7F, SS_RDEF, /* XXX TBD */ 2247 "Some commands cleared by iSCSI protocol event") }, 2248 /* DTLPWROMAEBKVF */ 2249 { SST(0x48, 0x00, SS_RDEF, 2250 "Initiator detected error message received") }, 2251 /* DTLPWROMAEBKVF */ 2252 { SST(0x49, 0x00, SS_RDEF, 2253 "Invalid message error") }, 2254 /* DTLPWROMAEBKVF */ 2255 { SST(0x4A, 0x00, SS_RDEF, 2256 "Command phase error") }, 2257 /* DTLPWROMAEBKVF */ 2258 { SST(0x4B, 0x00, SS_RDEF, 2259 "Data phase error") }, 2260 /* DT PWROMAEBK */ 2261 { SST(0x4B, 0x01, SS_RDEF, /* XXX TBD */ 2262 "Invalid target port transfer tag received") }, 2263 /* DT PWROMAEBK */ 2264 { SST(0x4B, 0x02, SS_RDEF, /* XXX TBD */ 2265 "Too much write data") }, 2266 /* DT PWROMAEBK */ 2267 { SST(0x4B, 0x03, SS_RDEF, /* XXX TBD */ 2268 "ACK/NAK timeout") }, 2269 /* DT PWROMAEBK */ 2270 { SST(0x4B, 0x04, SS_RDEF, /* XXX TBD */ 2271 "NAK received") }, 2272 /* DT PWROMAEBK */ 2273 { SST(0x4B, 0x05, SS_RDEF, /* XXX TBD */ 2274 "Data offset error") }, 2275 /* DT PWROMAEBK */ 2276 { SST(0x4B, 0x06, SS_RDEF, /* XXX TBD */ 2277 "Initiator response timeout") }, 2278 /* DT PWROMAEBK F */ 2279 { SST(0x4B, 0x07, SS_RDEF, /* XXX TBD */ 2280 "Connection lost") }, 2281 /* DT PWROMAEBK F */ 2282 { SST(0x4B, 0x08, SS_RDEF, /* XXX TBD */ 2283 "Data-in buffer overflow - data buffer size") }, 2284 /* DT PWROMAEBK F */ 2285 { SST(0x4B, 0x09, SS_RDEF, /* XXX TBD */ 2286 "Data-in buffer overflow - data buffer descriptor area") }, 2287 /* DT PWROMAEBK F */ 2288 { SST(0x4B, 0x0A, SS_RDEF, /* XXX TBD */ 2289 "Data-in buffer error") }, 2290 /* DT PWROMAEBK F */ 2291 { SST(0x4B, 0x0B, SS_RDEF, /* XXX TBD */ 2292 "Data-out buffer overflow - data buffer size") }, 2293 /* DT PWROMAEBK F */ 2294 { SST(0x4B, 0x0C, SS_RDEF, /* XXX TBD */ 2295 "Data-out buffer overflow - data buffer descriptor area") }, 2296 /* DT PWROMAEBK F */ 2297 { SST(0x4B, 0x0D, SS_RDEF, /* XXX TBD */ 2298 "Data-out buffer error") }, 2299 /* DTLPWROMAEBKVF */ 2300 { SST(0x4C, 0x00, SS_RDEF, 2301 "Logical unit failed self-configuration") }, 2302 /* DTLPWROMAEBKVF */ 2303 { SST(0x4D, 0x00, SS_RDEF, 2304 "Tagged overlapped commands: ASCQ = Queue tag ID") }, 2305 /* DTLPWROMAEBKVF */ 2306 { SST(0x4D, 0xFF, SS_RDEF | SSQ_RANGE, 2307 NULL) }, /* Range 0x00->0xFF */ 2308 /* DTLPWROMAEBKVF */ 2309 { SST(0x4E, 0x00, SS_RDEF, 2310 "Overlapped commands attempted") }, 2311 /* T */ 2312 { SST(0x50, 0x00, SS_RDEF, 2313 "Write append error") }, 2314 /* T */ 2315 { SST(0x50, 0x01, SS_RDEF, 2316 "Write append position error") }, 2317 /* T */ 2318 { SST(0x50, 0x02, SS_RDEF, 2319 "Position error related to timing") }, 2320 /* T RO */ 2321 { SST(0x51, 0x00, SS_RDEF, 2322 "Erase failure") }, 2323 /* R */ 2324 { SST(0x51, 0x01, SS_RDEF, /* XXX TBD */ 2325 "Erase failure - incomplete erase operation detected") }, 2326 /* T */ 2327 { SST(0x52, 0x00, SS_RDEF, 2328 "Cartridge fault") }, 2329 /* DTL WROM BK */ 2330 { SST(0x53, 0x00, SS_RDEF, 2331 "Media load or eject failed") }, 2332 /* T */ 2333 { SST(0x53, 0x01, SS_RDEF, 2334 "Unload tape failure") }, 2335 /* DT WROM BK */ 2336 { SST(0x53, 0x02, SS_RDEF, 2337 "Medium removal prevented") }, 2338 /* M */ 2339 { SST(0x53, 0x03, SS_RDEF, /* XXX TBD */ 2340 "Medium removal prevented by data transfer element") }, 2341 /* T */ 2342 { SST(0x53, 0x04, SS_RDEF, /* XXX TBD */ 2343 "Medium thread or unthread failure") }, 2344 /* M */ 2345 { SST(0x53, 0x05, SS_RDEF, /* XXX TBD */ 2346 "Volume identifier invalid") }, 2347 /* T */ 2348 { SST(0x53, 0x06, SS_RDEF, /* XXX TBD */ 2349 "Volume identifier missing") }, 2350 /* M */ 2351 { SST(0x53, 0x07, SS_RDEF, /* XXX TBD */ 2352 "Duplicate volume identifier") }, 2353 /* M */ 2354 { SST(0x53, 0x08, SS_RDEF, /* XXX TBD */ 2355 "Element status unknown") }, 2356 /* P */ 2357 { SST(0x54, 0x00, SS_RDEF, 2358 "SCSI to host system interface failure") }, 2359 /* P */ 2360 { SST(0x55, 0x00, SS_RDEF, 2361 "System resource failure") }, 2362 /* D O BK */ 2363 { SST(0x55, 0x01, SS_FATAL | ENOSPC, 2364 "System buffer full") }, 2365 /* DTLPWROMAE K */ 2366 { SST(0x55, 0x02, SS_RDEF, /* XXX TBD */ 2367 "Insufficient reservation resources") }, 2368 /* DTLPWROMAE K */ 2369 { SST(0x55, 0x03, SS_RDEF, /* XXX TBD */ 2370 "Insufficient resources") }, 2371 /* DTLPWROMAE K */ 2372 { SST(0x55, 0x04, SS_RDEF, /* XXX TBD */ 2373 "Insufficient registration resources") }, 2374 /* DT PWROMAEBK */ 2375 { SST(0x55, 0x05, SS_RDEF, /* XXX TBD */ 2376 "Insufficient access control resources") }, 2377 /* DT WROM B */ 2378 { SST(0x55, 0x06, SS_RDEF, /* XXX TBD */ 2379 "Auxiliary memory out of space") }, 2380 /* F */ 2381 { SST(0x55, 0x07, SS_RDEF, /* XXX TBD */ 2382 "Quota error") }, 2383 /* T */ 2384 { SST(0x55, 0x08, SS_RDEF, /* XXX TBD */ 2385 "Maximum number of supplemental decryption keys exceeded") }, 2386 /* M */ 2387 { SST(0x55, 0x09, SS_RDEF, /* XXX TBD */ 2388 "Medium auxiliary memory not accessible") }, 2389 /* M */ 2390 { SST(0x55, 0x0A, SS_RDEF, /* XXX TBD */ 2391 "Data currently unavailable") }, 2392 /* DTLPWROMAEBKVF */ 2393 { SST(0x55, 0x0B, SS_RDEF, /* XXX TBD */ 2394 "Insufficient power for operation") }, 2395 /* DT P B */ 2396 { SST(0x55, 0x0C, SS_RDEF, /* XXX TBD */ 2397 "Insufficient resources to create ROD") }, 2398 /* DT P B */ 2399 { SST(0x55, 0x0D, SS_RDEF, /* XXX TBD */ 2400 "Insufficient resources to create ROD token") }, 2401 /* R */ 2402 { SST(0x57, 0x00, SS_RDEF, 2403 "Unable to recover table-of-contents") }, 2404 /* O */ 2405 { SST(0x58, 0x00, SS_RDEF, 2406 "Generation does not exist") }, 2407 /* O */ 2408 { SST(0x59, 0x00, SS_RDEF, 2409 "Updated block read") }, 2410 /* DTLPWRO BK */ 2411 { SST(0x5A, 0x00, SS_RDEF, 2412 "Operator request or state change input") }, 2413 /* DT WROM BK */ 2414 { SST(0x5A, 0x01, SS_RDEF, 2415 "Operator medium removal request") }, 2416 /* DT WRO A BK */ 2417 { SST(0x5A, 0x02, SS_RDEF, 2418 "Operator selected write protect") }, 2419 /* DT WRO A BK */ 2420 { SST(0x5A, 0x03, SS_RDEF, 2421 "Operator selected write permit") }, 2422 /* DTLPWROM K */ 2423 { SST(0x5B, 0x00, SS_RDEF, 2424 "Log exception") }, 2425 /* DTLPWROM K */ 2426 { SST(0x5B, 0x01, SS_RDEF, 2427 "Threshold condition met") }, 2428 /* DTLPWROM K */ 2429 { SST(0x5B, 0x02, SS_RDEF, 2430 "Log counter at maximum") }, 2431 /* DTLPWROM K */ 2432 { SST(0x5B, 0x03, SS_RDEF, 2433 "Log list codes exhausted") }, 2434 /* D O */ 2435 { SST(0x5C, 0x00, SS_RDEF, 2436 "RPL status change") }, 2437 /* D O */ 2438 { SST(0x5C, 0x01, SS_NOP | SSQ_PRINT_SENSE, 2439 "Spindles synchronized") }, 2440 /* D O */ 2441 { SST(0x5C, 0x02, SS_RDEF, 2442 "Spindles not synchronized") }, 2443 /* DTLPWROMAEBKVF */ 2444 { SST(0x5D, 0x00, SS_RDEF, 2445 "Failure prediction threshold exceeded") }, 2446 /* R B */ 2447 { SST(0x5D, 0x01, SS_RDEF, /* XXX TBD */ 2448 "Media failure prediction threshold exceeded") }, 2449 /* R */ 2450 { SST(0x5D, 0x02, SS_RDEF, /* XXX TBD */ 2451 "Logical unit failure prediction threshold exceeded") }, 2452 /* R */ 2453 { SST(0x5D, 0x03, SS_RDEF, /* XXX TBD */ 2454 "Spare area exhaustion prediction threshold exceeded") }, 2455 /* D B */ 2456 { SST(0x5D, 0x10, SS_RDEF, /* XXX TBD */ 2457 "Hardware impending failure general hard drive failure") }, 2458 /* D B */ 2459 { SST(0x5D, 0x11, SS_RDEF, /* XXX TBD */ 2460 "Hardware impending failure drive error rate too high") }, 2461 /* D B */ 2462 { SST(0x5D, 0x12, SS_RDEF, /* XXX TBD */ 2463 "Hardware impending failure data error rate too high") }, 2464 /* D B */ 2465 { SST(0x5D, 0x13, SS_RDEF, /* XXX TBD */ 2466 "Hardware impending failure seek error rate too high") }, 2467 /* D B */ 2468 { SST(0x5D, 0x14, SS_RDEF, /* XXX TBD */ 2469 "Hardware impending failure too many block reassigns") }, 2470 /* D B */ 2471 { SST(0x5D, 0x15, SS_RDEF, /* XXX TBD */ 2472 "Hardware impending failure access times too high") }, 2473 /* D B */ 2474 { SST(0x5D, 0x16, SS_RDEF, /* XXX TBD */ 2475 "Hardware impending failure start unit times too high") }, 2476 /* D B */ 2477 { SST(0x5D, 0x17, SS_RDEF, /* XXX TBD */ 2478 "Hardware impending failure channel parametrics") }, 2479 /* D B */ 2480 { SST(0x5D, 0x18, SS_RDEF, /* XXX TBD */ 2481 "Hardware impending failure controller detected") }, 2482 /* D B */ 2483 { SST(0x5D, 0x19, SS_RDEF, /* XXX TBD */ 2484 "Hardware impending failure throughput performance") }, 2485 /* D B */ 2486 { SST(0x5D, 0x1A, SS_RDEF, /* XXX TBD */ 2487 "Hardware impending failure seek time performance") }, 2488 /* D B */ 2489 { SST(0x5D, 0x1B, SS_RDEF, /* XXX TBD */ 2490 "Hardware impending failure spin-up retry count") }, 2491 /* D B */ 2492 { SST(0x5D, 0x1C, SS_RDEF, /* XXX TBD */ 2493 "Hardware impending failure drive calibration retry count") }, 2494 /* D B */ 2495 { SST(0x5D, 0x20, SS_RDEF, /* XXX TBD */ 2496 "Controller impending failure general hard drive failure") }, 2497 /* D B */ 2498 { SST(0x5D, 0x21, SS_RDEF, /* XXX TBD */ 2499 "Controller impending failure drive error rate too high") }, 2500 /* D B */ 2501 { SST(0x5D, 0x22, SS_RDEF, /* XXX TBD */ 2502 "Controller impending failure data error rate too high") }, 2503 /* D B */ 2504 { SST(0x5D, 0x23, SS_RDEF, /* XXX TBD */ 2505 "Controller impending failure seek error rate too high") }, 2506 /* D B */ 2507 { SST(0x5D, 0x24, SS_RDEF, /* XXX TBD */ 2508 "Controller impending failure too many block reassigns") }, 2509 /* D B */ 2510 { SST(0x5D, 0x25, SS_RDEF, /* XXX TBD */ 2511 "Controller impending failure access times too high") }, 2512 /* D B */ 2513 { SST(0x5D, 0x26, SS_RDEF, /* XXX TBD */ 2514 "Controller impending failure start unit times too high") }, 2515 /* D B */ 2516 { SST(0x5D, 0x27, SS_RDEF, /* XXX TBD */ 2517 "Controller impending failure channel parametrics") }, 2518 /* D B */ 2519 { SST(0x5D, 0x28, SS_RDEF, /* XXX TBD */ 2520 "Controller impending failure controller detected") }, 2521 /* D B */ 2522 { SST(0x5D, 0x29, SS_RDEF, /* XXX TBD */ 2523 "Controller impending failure throughput performance") }, 2524 /* D B */ 2525 { SST(0x5D, 0x2A, SS_RDEF, /* XXX TBD */ 2526 "Controller impending failure seek time performance") }, 2527 /* D B */ 2528 { SST(0x5D, 0x2B, SS_RDEF, /* XXX TBD */ 2529 "Controller impending failure spin-up retry count") }, 2530 /* D B */ 2531 { SST(0x5D, 0x2C, SS_RDEF, /* XXX TBD */ 2532 "Controller impending failure drive calibration retry count") }, 2533 /* D B */ 2534 { SST(0x5D, 0x30, SS_RDEF, /* XXX TBD */ 2535 "Data channel impending failure general hard drive failure") }, 2536 /* D B */ 2537 { SST(0x5D, 0x31, SS_RDEF, /* XXX TBD */ 2538 "Data channel impending failure drive error rate too high") }, 2539 /* D B */ 2540 { SST(0x5D, 0x32, SS_RDEF, /* XXX TBD */ 2541 "Data channel impending failure data error rate too high") }, 2542 /* D B */ 2543 { SST(0x5D, 0x33, SS_RDEF, /* XXX TBD */ 2544 "Data channel impending failure seek error rate too high") }, 2545 /* D B */ 2546 { SST(0x5D, 0x34, SS_RDEF, /* XXX TBD */ 2547 "Data channel impending failure too many block reassigns") }, 2548 /* D B */ 2549 { SST(0x5D, 0x35, SS_RDEF, /* XXX TBD */ 2550 "Data channel impending failure access times too high") }, 2551 /* D B */ 2552 { SST(0x5D, 0x36, SS_RDEF, /* XXX TBD */ 2553 "Data channel impending failure start unit times too high") }, 2554 /* D B */ 2555 { SST(0x5D, 0x37, SS_RDEF, /* XXX TBD */ 2556 "Data channel impending failure channel parametrics") }, 2557 /* D B */ 2558 { SST(0x5D, 0x38, SS_RDEF, /* XXX TBD */ 2559 "Data channel impending failure controller detected") }, 2560 /* D B */ 2561 { SST(0x5D, 0x39, SS_RDEF, /* XXX TBD */ 2562 "Data channel impending failure throughput performance") }, 2563 /* D B */ 2564 { SST(0x5D, 0x3A, SS_RDEF, /* XXX TBD */ 2565 "Data channel impending failure seek time performance") }, 2566 /* D B */ 2567 { SST(0x5D, 0x3B, SS_RDEF, /* XXX TBD */ 2568 "Data channel impending failure spin-up retry count") }, 2569 /* D B */ 2570 { SST(0x5D, 0x3C, SS_RDEF, /* XXX TBD */ 2571 "Data channel impending failure drive calibration retry count") }, 2572 /* D B */ 2573 { SST(0x5D, 0x40, SS_RDEF, /* XXX TBD */ 2574 "Servo impending failure general hard drive failure") }, 2575 /* D B */ 2576 { SST(0x5D, 0x41, SS_RDEF, /* XXX TBD */ 2577 "Servo impending failure drive error rate too high") }, 2578 /* D B */ 2579 { SST(0x5D, 0x42, SS_RDEF, /* XXX TBD */ 2580 "Servo impending failure data error rate too high") }, 2581 /* D B */ 2582 { SST(0x5D, 0x43, SS_RDEF, /* XXX TBD */ 2583 "Servo impending failure seek error rate too high") }, 2584 /* D B */ 2585 { SST(0x5D, 0x44, SS_RDEF, /* XXX TBD */ 2586 "Servo impending failure too many block reassigns") }, 2587 /* D B */ 2588 { SST(0x5D, 0x45, SS_RDEF, /* XXX TBD */ 2589 "Servo impending failure access times too high") }, 2590 /* D B */ 2591 { SST(0x5D, 0x46, SS_RDEF, /* XXX TBD */ 2592 "Servo impending failure start unit times too high") }, 2593 /* D B */ 2594 { SST(0x5D, 0x47, SS_RDEF, /* XXX TBD */ 2595 "Servo impending failure channel parametrics") }, 2596 /* D B */ 2597 { SST(0x5D, 0x48, SS_RDEF, /* XXX TBD */ 2598 "Servo impending failure controller detected") }, 2599 /* D B */ 2600 { SST(0x5D, 0x49, SS_RDEF, /* XXX TBD */ 2601 "Servo impending failure throughput performance") }, 2602 /* D B */ 2603 { SST(0x5D, 0x4A, SS_RDEF, /* XXX TBD */ 2604 "Servo impending failure seek time performance") }, 2605 /* D B */ 2606 { SST(0x5D, 0x4B, SS_RDEF, /* XXX TBD */ 2607 "Servo impending failure spin-up retry count") }, 2608 /* D B */ 2609 { SST(0x5D, 0x4C, SS_RDEF, /* XXX TBD */ 2610 "Servo impending failure drive calibration retry count") }, 2611 /* D B */ 2612 { SST(0x5D, 0x50, SS_RDEF, /* XXX TBD */ 2613 "Spindle impending failure general hard drive failure") }, 2614 /* D B */ 2615 { SST(0x5D, 0x51, SS_RDEF, /* XXX TBD */ 2616 "Spindle impending failure drive error rate too high") }, 2617 /* D B */ 2618 { SST(0x5D, 0x52, SS_RDEF, /* XXX TBD */ 2619 "Spindle impending failure data error rate too high") }, 2620 /* D B */ 2621 { SST(0x5D, 0x53, SS_RDEF, /* XXX TBD */ 2622 "Spindle impending failure seek error rate too high") }, 2623 /* D B */ 2624 { SST(0x5D, 0x54, SS_RDEF, /* XXX TBD */ 2625 "Spindle impending failure too many block reassigns") }, 2626 /* D B */ 2627 { SST(0x5D, 0x55, SS_RDEF, /* XXX TBD */ 2628 "Spindle impending failure access times too high") }, 2629 /* D B */ 2630 { SST(0x5D, 0x56, SS_RDEF, /* XXX TBD */ 2631 "Spindle impending failure start unit times too high") }, 2632 /* D B */ 2633 { SST(0x5D, 0x57, SS_RDEF, /* XXX TBD */ 2634 "Spindle impending failure channel parametrics") }, 2635 /* D B */ 2636 { SST(0x5D, 0x58, SS_RDEF, /* XXX TBD */ 2637 "Spindle impending failure controller detected") }, 2638 /* D B */ 2639 { SST(0x5D, 0x59, SS_RDEF, /* XXX TBD */ 2640 "Spindle impending failure throughput performance") }, 2641 /* D B */ 2642 { SST(0x5D, 0x5A, SS_RDEF, /* XXX TBD */ 2643 "Spindle impending failure seek time performance") }, 2644 /* D B */ 2645 { SST(0x5D, 0x5B, SS_RDEF, /* XXX TBD */ 2646 "Spindle impending failure spin-up retry count") }, 2647 /* D B */ 2648 { SST(0x5D, 0x5C, SS_RDEF, /* XXX TBD */ 2649 "Spindle impending failure drive calibration retry count") }, 2650 /* D B */ 2651 { SST(0x5D, 0x60, SS_RDEF, /* XXX TBD */ 2652 "Firmware impending failure general hard drive failure") }, 2653 /* D B */ 2654 { SST(0x5D, 0x61, SS_RDEF, /* XXX TBD */ 2655 "Firmware impending failure drive error rate too high") }, 2656 /* D B */ 2657 { SST(0x5D, 0x62, SS_RDEF, /* XXX TBD */ 2658 "Firmware impending failure data error rate too high") }, 2659 /* D B */ 2660 { SST(0x5D, 0x63, SS_RDEF, /* XXX TBD */ 2661 "Firmware impending failure seek error rate too high") }, 2662 /* D B */ 2663 { SST(0x5D, 0x64, SS_RDEF, /* XXX TBD */ 2664 "Firmware impending failure too many block reassigns") }, 2665 /* D B */ 2666 { SST(0x5D, 0x65, SS_RDEF, /* XXX TBD */ 2667 "Firmware impending failure access times too high") }, 2668 /* D B */ 2669 { SST(0x5D, 0x66, SS_RDEF, /* XXX TBD */ 2670 "Firmware impending failure start unit times too high") }, 2671 /* D B */ 2672 { SST(0x5D, 0x67, SS_RDEF, /* XXX TBD */ 2673 "Firmware impending failure channel parametrics") }, 2674 /* D B */ 2675 { SST(0x5D, 0x68, SS_RDEF, /* XXX TBD */ 2676 "Firmware impending failure controller detected") }, 2677 /* D B */ 2678 { SST(0x5D, 0x69, SS_RDEF, /* XXX TBD */ 2679 "Firmware impending failure throughput performance") }, 2680 /* D B */ 2681 { SST(0x5D, 0x6A, SS_RDEF, /* XXX TBD */ 2682 "Firmware impending failure seek time performance") }, 2683 /* D B */ 2684 { SST(0x5D, 0x6B, SS_RDEF, /* XXX TBD */ 2685 "Firmware impending failure spin-up retry count") }, 2686 /* D B */ 2687 { SST(0x5D, 0x6C, SS_RDEF, /* XXX TBD */ 2688 "Firmware impending failure drive calibration retry count") }, 2689 /* DTLPWROMAEBKVF */ 2690 { SST(0x5D, 0xFF, SS_RDEF, 2691 "Failure prediction threshold exceeded (false)") }, 2692 /* DTLPWRO A K */ 2693 { SST(0x5E, 0x00, SS_RDEF, 2694 "Low power condition on") }, 2695 /* DTLPWRO A K */ 2696 { SST(0x5E, 0x01, SS_RDEF, 2697 "Idle condition activated by timer") }, 2698 /* DTLPWRO A K */ 2699 { SST(0x5E, 0x02, SS_RDEF, 2700 "Standby condition activated by timer") }, 2701 /* DTLPWRO A K */ 2702 { SST(0x5E, 0x03, SS_RDEF, 2703 "Idle condition activated by command") }, 2704 /* DTLPWRO A K */ 2705 { SST(0x5E, 0x04, SS_RDEF, 2706 "Standby condition activated by command") }, 2707 /* DTLPWRO A K */ 2708 { SST(0x5E, 0x05, SS_RDEF, 2709 "Idle-B condition activated by timer") }, 2710 /* DTLPWRO A K */ 2711 { SST(0x5E, 0x06, SS_RDEF, 2712 "Idle-B condition activated by command") }, 2713 /* DTLPWRO A K */ 2714 { SST(0x5E, 0x07, SS_RDEF, 2715 "Idle-C condition activated by timer") }, 2716 /* DTLPWRO A K */ 2717 { SST(0x5E, 0x08, SS_RDEF, 2718 "Idle-C condition activated by command") }, 2719 /* DTLPWRO A K */ 2720 { SST(0x5E, 0x09, SS_RDEF, 2721 "Standby-Y condition activated by timer") }, 2722 /* DTLPWRO A K */ 2723 { SST(0x5E, 0x0A, SS_RDEF, 2724 "Standby-Y condition activated by command") }, 2725 /* B */ 2726 { SST(0x5E, 0x41, SS_RDEF, /* XXX TBD */ 2727 "Power state change to active") }, 2728 /* B */ 2729 { SST(0x5E, 0x42, SS_RDEF, /* XXX TBD */ 2730 "Power state change to idle") }, 2731 /* B */ 2732 { SST(0x5E, 0x43, SS_RDEF, /* XXX TBD */ 2733 "Power state change to standby") }, 2734 /* B */ 2735 { SST(0x5E, 0x45, SS_RDEF, /* XXX TBD */ 2736 "Power state change to sleep") }, 2737 /* BK */ 2738 { SST(0x5E, 0x47, SS_RDEF, /* XXX TBD */ 2739 "Power state change to device control") }, 2740 /* */ 2741 { SST(0x60, 0x00, SS_RDEF, 2742 "Lamp failure") }, 2743 /* */ 2744 { SST(0x61, 0x00, SS_RDEF, 2745 "Video acquisition error") }, 2746 /* */ 2747 { SST(0x61, 0x01, SS_RDEF, 2748 "Unable to acquire video") }, 2749 /* */ 2750 { SST(0x61, 0x02, SS_RDEF, 2751 "Out of focus") }, 2752 /* */ 2753 { SST(0x62, 0x00, SS_RDEF, 2754 "Scan head positioning error") }, 2755 /* R */ 2756 { SST(0x63, 0x00, SS_RDEF, 2757 "End of user area encountered on this track") }, 2758 /* R */ 2759 { SST(0x63, 0x01, SS_FATAL | ENOSPC, 2760 "Packet does not fit in available space") }, 2761 /* R */ 2762 { SST(0x64, 0x00, SS_FATAL | ENXIO, 2763 "Illegal mode for this track") }, 2764 /* R */ 2765 { SST(0x64, 0x01, SS_RDEF, 2766 "Invalid packet size") }, 2767 /* DTLPWROMAEBKVF */ 2768 { SST(0x65, 0x00, SS_RDEF, 2769 "Voltage fault") }, 2770 /* */ 2771 { SST(0x66, 0x00, SS_RDEF, 2772 "Automatic document feeder cover up") }, 2773 /* */ 2774 { SST(0x66, 0x01, SS_RDEF, 2775 "Automatic document feeder lift up") }, 2776 /* */ 2777 { SST(0x66, 0x02, SS_RDEF, 2778 "Document jam in automatic document feeder") }, 2779 /* */ 2780 { SST(0x66, 0x03, SS_RDEF, 2781 "Document miss feed automatic in document feeder") }, 2782 /* A */ 2783 { SST(0x67, 0x00, SS_RDEF, 2784 "Configuration failure") }, 2785 /* A */ 2786 { SST(0x67, 0x01, SS_RDEF, 2787 "Configuration of incapable logical units failed") }, 2788 /* A */ 2789 { SST(0x67, 0x02, SS_RDEF, 2790 "Add logical unit failed") }, 2791 /* A */ 2792 { SST(0x67, 0x03, SS_RDEF, 2793 "Modification of logical unit failed") }, 2794 /* A */ 2795 { SST(0x67, 0x04, SS_RDEF, 2796 "Exchange of logical unit failed") }, 2797 /* A */ 2798 { SST(0x67, 0x05, SS_RDEF, 2799 "Remove of logical unit failed") }, 2800 /* A */ 2801 { SST(0x67, 0x06, SS_RDEF, 2802 "Attachment of logical unit failed") }, 2803 /* A */ 2804 { SST(0x67, 0x07, SS_RDEF, 2805 "Creation of logical unit failed") }, 2806 /* A */ 2807 { SST(0x67, 0x08, SS_RDEF, /* XXX TBD */ 2808 "Assign failure occurred") }, 2809 /* A */ 2810 { SST(0x67, 0x09, SS_RDEF, /* XXX TBD */ 2811 "Multiply assigned logical unit") }, 2812 /* DTLPWROMAEBKVF */ 2813 { SST(0x67, 0x0A, SS_RDEF, /* XXX TBD */ 2814 "Set target port groups command failed") }, 2815 /* DT B */ 2816 { SST(0x67, 0x0B, SS_RDEF, /* XXX TBD */ 2817 "ATA device feature not enabled") }, 2818 /* A */ 2819 { SST(0x68, 0x00, SS_RDEF, 2820 "Logical unit not configured") }, 2821 /* A */ 2822 { SST(0x69, 0x00, SS_RDEF, 2823 "Data loss on logical unit") }, 2824 /* A */ 2825 { SST(0x69, 0x01, SS_RDEF, 2826 "Multiple logical unit failures") }, 2827 /* A */ 2828 { SST(0x69, 0x02, SS_RDEF, 2829 "Parity/data mismatch") }, 2830 /* A */ 2831 { SST(0x6A, 0x00, SS_RDEF, 2832 "Informational, refer to log") }, 2833 /* A */ 2834 { SST(0x6B, 0x00, SS_RDEF, 2835 "State change has occurred") }, 2836 /* A */ 2837 { SST(0x6B, 0x01, SS_RDEF, 2838 "Redundancy level got better") }, 2839 /* A */ 2840 { SST(0x6B, 0x02, SS_RDEF, 2841 "Redundancy level got worse") }, 2842 /* A */ 2843 { SST(0x6C, 0x00, SS_RDEF, 2844 "Rebuild failure occurred") }, 2845 /* A */ 2846 { SST(0x6D, 0x00, SS_RDEF, 2847 "Recalculate failure occurred") }, 2848 /* A */ 2849 { SST(0x6E, 0x00, SS_RDEF, 2850 "Command to logical unit failed") }, 2851 /* R */ 2852 { SST(0x6F, 0x00, SS_RDEF, /* XXX TBD */ 2853 "Copy protection key exchange failure - authentication failure") }, 2854 /* R */ 2855 { SST(0x6F, 0x01, SS_RDEF, /* XXX TBD */ 2856 "Copy protection key exchange failure - key not present") }, 2857 /* R */ 2858 { SST(0x6F, 0x02, SS_RDEF, /* XXX TBD */ 2859 "Copy protection key exchange failure - key not established") }, 2860 /* R */ 2861 { SST(0x6F, 0x03, SS_RDEF, /* XXX TBD */ 2862 "Read of scrambled sector without authentication") }, 2863 /* R */ 2864 { SST(0x6F, 0x04, SS_RDEF, /* XXX TBD */ 2865 "Media region code is mismatched to logical unit region") }, 2866 /* R */ 2867 { SST(0x6F, 0x05, SS_RDEF, /* XXX TBD */ 2868 "Drive region must be permanent/region reset count error") }, 2869 /* R */ 2870 { SST(0x6F, 0x06, SS_RDEF, /* XXX TBD */ 2871 "Insufficient block count for binding NONCE recording") }, 2872 /* R */ 2873 { SST(0x6F, 0x07, SS_RDEF, /* XXX TBD */ 2874 "Conflict in binding NONCE recording") }, 2875 /* T */ 2876 { SST(0x70, 0x00, SS_RDEF, 2877 "Decompression exception short: ASCQ = Algorithm ID") }, 2878 /* T */ 2879 { SST(0x70, 0xFF, SS_RDEF | SSQ_RANGE, 2880 NULL) }, /* Range 0x00 -> 0xFF */ 2881 /* T */ 2882 { SST(0x71, 0x00, SS_RDEF, 2883 "Decompression exception long: ASCQ = Algorithm ID") }, 2884 /* T */ 2885 { SST(0x71, 0xFF, SS_RDEF | SSQ_RANGE, 2886 NULL) }, /* Range 0x00 -> 0xFF */ 2887 /* R */ 2888 { SST(0x72, 0x00, SS_RDEF, 2889 "Session fixation error") }, 2890 /* R */ 2891 { SST(0x72, 0x01, SS_RDEF, 2892 "Session fixation error writing lead-in") }, 2893 /* R */ 2894 { SST(0x72, 0x02, SS_RDEF, 2895 "Session fixation error writing lead-out") }, 2896 /* R */ 2897 { SST(0x72, 0x03, SS_RDEF, 2898 "Session fixation error - incomplete track in session") }, 2899 /* R */ 2900 { SST(0x72, 0x04, SS_RDEF, 2901 "Empty or partially written reserved track") }, 2902 /* R */ 2903 { SST(0x72, 0x05, SS_RDEF, /* XXX TBD */ 2904 "No more track reservations allowed") }, 2905 /* R */ 2906 { SST(0x72, 0x06, SS_RDEF, /* XXX TBD */ 2907 "RMZ extension is not allowed") }, 2908 /* R */ 2909 { SST(0x72, 0x07, SS_RDEF, /* XXX TBD */ 2910 "No more test zone extensions are allowed") }, 2911 /* R */ 2912 { SST(0x73, 0x00, SS_RDEF, 2913 "CD control error") }, 2914 /* R */ 2915 { SST(0x73, 0x01, SS_RDEF, 2916 "Power calibration area almost full") }, 2917 /* R */ 2918 { SST(0x73, 0x02, SS_FATAL | ENOSPC, 2919 "Power calibration area is full") }, 2920 /* R */ 2921 { SST(0x73, 0x03, SS_RDEF, 2922 "Power calibration area error") }, 2923 /* R */ 2924 { SST(0x73, 0x04, SS_RDEF, 2925 "Program memory area update failure") }, 2926 /* R */ 2927 { SST(0x73, 0x05, SS_RDEF, 2928 "Program memory area is full") }, 2929 /* R */ 2930 { SST(0x73, 0x06, SS_RDEF, /* XXX TBD */ 2931 "RMA/PMA is almost full") }, 2932 /* R */ 2933 { SST(0x73, 0x10, SS_RDEF, /* XXX TBD */ 2934 "Current power calibration area almost full") }, 2935 /* R */ 2936 { SST(0x73, 0x11, SS_RDEF, /* XXX TBD */ 2937 "Current power calibration area is full") }, 2938 /* R */ 2939 { SST(0x73, 0x17, SS_RDEF, /* XXX TBD */ 2940 "RDZ is full") }, 2941 /* T */ 2942 { SST(0x74, 0x00, SS_RDEF, /* XXX TBD */ 2943 "Security error") }, 2944 /* T */ 2945 { SST(0x74, 0x01, SS_RDEF, /* XXX TBD */ 2946 "Unable to decrypt data") }, 2947 /* T */ 2948 { SST(0x74, 0x02, SS_RDEF, /* XXX TBD */ 2949 "Unencrypted data encountered while decrypting") }, 2950 /* T */ 2951 { SST(0x74, 0x03, SS_RDEF, /* XXX TBD */ 2952 "Incorrect data encryption key") }, 2953 /* T */ 2954 { SST(0x74, 0x04, SS_RDEF, /* XXX TBD */ 2955 "Cryptographic integrity validation failed") }, 2956 /* T */ 2957 { SST(0x74, 0x05, SS_RDEF, /* XXX TBD */ 2958 "Error decrypting data") }, 2959 /* T */ 2960 { SST(0x74, 0x06, SS_RDEF, /* XXX TBD */ 2961 "Unknown signature verification key") }, 2962 /* T */ 2963 { SST(0x74, 0x07, SS_RDEF, /* XXX TBD */ 2964 "Encryption parameters not useable") }, 2965 /* DT R M E VF */ 2966 { SST(0x74, 0x08, SS_RDEF, /* XXX TBD */ 2967 "Digital signature validation failure") }, 2968 /* T */ 2969 { SST(0x74, 0x09, SS_RDEF, /* XXX TBD */ 2970 "Encryption mode mismatch on read") }, 2971 /* T */ 2972 { SST(0x74, 0x0A, SS_RDEF, /* XXX TBD */ 2973 "Encrypted block not raw read enabled") }, 2974 /* T */ 2975 { SST(0x74, 0x0B, SS_RDEF, /* XXX TBD */ 2976 "Incorrect encryption parameters") }, 2977 /* DT R MAEBKV */ 2978 { SST(0x74, 0x0C, SS_RDEF, /* XXX TBD */ 2979 "Unable to decrypt parameter list") }, 2980 /* T */ 2981 { SST(0x74, 0x0D, SS_RDEF, /* XXX TBD */ 2982 "Encryption algorithm disabled") }, 2983 /* DT R MAEBKV */ 2984 { SST(0x74, 0x10, SS_RDEF, /* XXX TBD */ 2985 "SA creation parameter value invalid") }, 2986 /* DT R MAEBKV */ 2987 { SST(0x74, 0x11, SS_RDEF, /* XXX TBD */ 2988 "SA creation parameter value rejected") }, 2989 /* DT R MAEBKV */ 2990 { SST(0x74, 0x12, SS_RDEF, /* XXX TBD */ 2991 "Invalid SA usage") }, 2992 /* T */ 2993 { SST(0x74, 0x21, SS_RDEF, /* XXX TBD */ 2994 "Data encryption configuration prevented") }, 2995 /* DT R MAEBKV */ 2996 { SST(0x74, 0x30, SS_RDEF, /* XXX TBD */ 2997 "SA creation parameter not supported") }, 2998 /* DT R MAEBKV */ 2999 { SST(0x74, 0x40, SS_RDEF, /* XXX TBD */ 3000 "Authentication failed") }, 3001 /* V */ 3002 { SST(0x74, 0x61, SS_RDEF, /* XXX TBD */ 3003 "External data encryption key manager access error") }, 3004 /* V */ 3005 { SST(0x74, 0x62, SS_RDEF, /* XXX TBD */ 3006 "External data encryption key manager error") }, 3007 /* V */ 3008 { SST(0x74, 0x63, SS_RDEF, /* XXX TBD */ 3009 "External data encryption key not found") }, 3010 /* V */ 3011 { SST(0x74, 0x64, SS_RDEF, /* XXX TBD */ 3012 "External data encryption request not authorized") }, 3013 /* T */ 3014 { SST(0x74, 0x6E, SS_RDEF, /* XXX TBD */ 3015 "External data encryption control timeout") }, 3016 /* T */ 3017 { SST(0x74, 0x6F, SS_RDEF, /* XXX TBD */ 3018 "External data encryption control error") }, 3019 /* DT R M E V */ 3020 { SST(0x74, 0x71, SS_RDEF, /* XXX TBD */ 3021 "Logical unit access not authorized") }, 3022 /* D */ 3023 { SST(0x74, 0x79, SS_RDEF, /* XXX TBD */ 3024 "Security conflict in translated device") } 3025 }; 3026 3027 const int asc_table_size = sizeof(asc_table)/sizeof(asc_table[0]); 3028 3029 struct asc_key 3030 { 3031 int asc; 3032 int ascq; 3033 }; 3034 3035 static int 3036 ascentrycomp(const void *key, const void *member) 3037 { 3038 int asc; 3039 int ascq; 3040 const struct asc_table_entry *table_entry; 3041 3042 asc = ((const struct asc_key *)key)->asc; 3043 ascq = ((const struct asc_key *)key)->ascq; 3044 table_entry = (const struct asc_table_entry *)member; 3045 3046 if (asc >= table_entry->asc) { 3047 3048 if (asc > table_entry->asc) 3049 return (1); 3050 3051 if (ascq <= table_entry->ascq) { 3052 /* Check for ranges */ 3053 if (ascq == table_entry->ascq 3054 || ((table_entry->action & SSQ_RANGE) != 0 3055 && ascq >= (table_entry - 1)->ascq)) 3056 return (0); 3057 return (-1); 3058 } 3059 return (1); 3060 } 3061 return (-1); 3062 } 3063 3064 static int 3065 senseentrycomp(const void *key, const void *member) 3066 { 3067 int sense_key; 3068 const struct sense_key_table_entry *table_entry; 3069 3070 sense_key = *((const int *)key); 3071 table_entry = (const struct sense_key_table_entry *)member; 3072 3073 if (sense_key >= table_entry->sense_key) { 3074 if (sense_key == table_entry->sense_key) 3075 return (0); 3076 return (1); 3077 } 3078 return (-1); 3079 } 3080 3081 static void 3082 fetchtableentries(int sense_key, int asc, int ascq, 3083 struct scsi_inquiry_data *inq_data, 3084 const struct sense_key_table_entry **sense_entry, 3085 const struct asc_table_entry **asc_entry) 3086 { 3087 caddr_t match; 3088 const struct asc_table_entry *asc_tables[2]; 3089 const struct sense_key_table_entry *sense_tables[2]; 3090 struct asc_key asc_ascq; 3091 size_t asc_tables_size[2]; 3092 size_t sense_tables_size[2]; 3093 int num_asc_tables; 3094 int num_sense_tables; 3095 int i; 3096 3097 /* Default to failure */ 3098 *sense_entry = NULL; 3099 *asc_entry = NULL; 3100 match = NULL; 3101 if (inq_data != NULL) 3102 match = cam_quirkmatch((caddr_t)inq_data, 3103 (caddr_t)sense_quirk_table, 3104 sense_quirk_table_size, 3105 sizeof(*sense_quirk_table), 3106 scsi_inquiry_match); 3107 3108 if (match != NULL) { 3109 struct scsi_sense_quirk_entry *quirk; 3110 3111 quirk = (struct scsi_sense_quirk_entry *)match; 3112 asc_tables[0] = quirk->asc_info; 3113 asc_tables_size[0] = quirk->num_ascs; 3114 asc_tables[1] = asc_table; 3115 asc_tables_size[1] = asc_table_size; 3116 num_asc_tables = 2; 3117 sense_tables[0] = quirk->sense_key_info; 3118 sense_tables_size[0] = quirk->num_sense_keys; 3119 sense_tables[1] = sense_key_table; 3120 sense_tables_size[1] = sense_key_table_size; 3121 num_sense_tables = 2; 3122 } else { 3123 asc_tables[0] = asc_table; 3124 asc_tables_size[0] = asc_table_size; 3125 num_asc_tables = 1; 3126 sense_tables[0] = sense_key_table; 3127 sense_tables_size[0] = sense_key_table_size; 3128 num_sense_tables = 1; 3129 } 3130 3131 asc_ascq.asc = asc; 3132 asc_ascq.ascq = ascq; 3133 for (i = 0; i < num_asc_tables; i++) { 3134 void *found_entry; 3135 3136 found_entry = bsearch(&asc_ascq, asc_tables[i], 3137 asc_tables_size[i], 3138 sizeof(**asc_tables), 3139 ascentrycomp); 3140 3141 if (found_entry) { 3142 *asc_entry = (struct asc_table_entry *)found_entry; 3143 break; 3144 } 3145 } 3146 3147 for (i = 0; i < num_sense_tables; i++) { 3148 void *found_entry; 3149 3150 found_entry = bsearch(&sense_key, sense_tables[i], 3151 sense_tables_size[i], 3152 sizeof(**sense_tables), 3153 senseentrycomp); 3154 3155 if (found_entry) { 3156 *sense_entry = 3157 (struct sense_key_table_entry *)found_entry; 3158 break; 3159 } 3160 } 3161 } 3162 3163 void 3164 scsi_sense_desc(int sense_key, int asc, int ascq, 3165 struct scsi_inquiry_data *inq_data, 3166 const char **sense_key_desc, const char **asc_desc) 3167 { 3168 const struct asc_table_entry *asc_entry; 3169 const struct sense_key_table_entry *sense_entry; 3170 3171 fetchtableentries(sense_key, asc, ascq, 3172 inq_data, 3173 &sense_entry, 3174 &asc_entry); 3175 3176 if (sense_entry != NULL) 3177 *sense_key_desc = sense_entry->desc; 3178 else 3179 *sense_key_desc = "Invalid Sense Key"; 3180 3181 if (asc_entry != NULL) 3182 *asc_desc = asc_entry->desc; 3183 else if (asc >= 0x80 && asc <= 0xff) 3184 *asc_desc = "Vendor Specific ASC"; 3185 else if (ascq >= 0x80 && ascq <= 0xff) 3186 *asc_desc = "Vendor Specific ASCQ"; 3187 else 3188 *asc_desc = "Reserved ASC/ASCQ pair"; 3189 } 3190 3191 /* 3192 * Given sense and device type information, return the appropriate action. 3193 * If we do not understand the specific error as identified by the ASC/ASCQ 3194 * pair, fall back on the more generic actions derived from the sense key. 3195 */ 3196 scsi_sense_action 3197 scsi_error_action(struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data, 3198 u_int32_t sense_flags) 3199 { 3200 const struct asc_table_entry *asc_entry; 3201 const struct sense_key_table_entry *sense_entry; 3202 int error_code, sense_key, asc, ascq; 3203 scsi_sense_action action; 3204 3205 if (!scsi_extract_sense_ccb((union ccb *)csio, 3206 &error_code, &sense_key, &asc, &ascq)) { 3207 action = SS_RETRY | SSQ_DECREMENT_COUNT | SSQ_PRINT_SENSE | EIO; 3208 } else if ((error_code == SSD_DEFERRED_ERROR) 3209 || (error_code == SSD_DESC_DEFERRED_ERROR)) { 3210 /* 3211 * XXX dufault@FreeBSD.org 3212 * This error doesn't relate to the command associated 3213 * with this request sense. A deferred error is an error 3214 * for a command that has already returned GOOD status 3215 * (see SCSI2 8.2.14.2). 3216 * 3217 * By my reading of that section, it looks like the current 3218 * command has been cancelled, we should now clean things up 3219 * (hopefully recovering any lost data) and then retry the 3220 * current command. There are two easy choices, both wrong: 3221 * 3222 * 1. Drop through (like we had been doing), thus treating 3223 * this as if the error were for the current command and 3224 * return and stop the current command. 3225 * 3226 * 2. Issue a retry (like I made it do) thus hopefully 3227 * recovering the current transfer, and ignoring the 3228 * fact that we've dropped a command. 3229 * 3230 * These should probably be handled in a device specific 3231 * sense handler or punted back up to a user mode daemon 3232 */ 3233 action = SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE; 3234 } else { 3235 fetchtableentries(sense_key, asc, ascq, 3236 inq_data, 3237 &sense_entry, 3238 &asc_entry); 3239 3240 /* 3241 * Override the 'No additional Sense' entry (0,0) 3242 * with the error action of the sense key. 3243 */ 3244 if (asc_entry != NULL 3245 && (asc != 0 || ascq != 0)) 3246 action = asc_entry->action; 3247 else if (sense_entry != NULL) 3248 action = sense_entry->action; 3249 else 3250 action = SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE; 3251 3252 if (sense_key == SSD_KEY_RECOVERED_ERROR) { 3253 /* 3254 * The action succeeded but the device wants 3255 * the user to know that some recovery action 3256 * was required. 3257 */ 3258 action &= ~(SS_MASK|SSQ_MASK|SS_ERRMASK); 3259 action |= SS_NOP|SSQ_PRINT_SENSE; 3260 } else if (sense_key == SSD_KEY_ILLEGAL_REQUEST) { 3261 if ((sense_flags & SF_QUIET_IR) != 0) 3262 action &= ~SSQ_PRINT_SENSE; 3263 } else if (sense_key == SSD_KEY_UNIT_ATTENTION) { 3264 if ((sense_flags & SF_RETRY_UA) != 0 3265 && (action & SS_MASK) == SS_FAIL) { 3266 action &= ~(SS_MASK|SSQ_MASK); 3267 action |= SS_RETRY|SSQ_DECREMENT_COUNT| 3268 SSQ_PRINT_SENSE; 3269 } 3270 action |= SSQ_UA; 3271 } 3272 } 3273 if ((action & SS_MASK) >= SS_START && 3274 (sense_flags & SF_NO_RECOVERY)) { 3275 action &= ~SS_MASK; 3276 action |= SS_FAIL; 3277 } else if ((action & SS_MASK) == SS_RETRY && 3278 (sense_flags & SF_NO_RETRY)) { 3279 action &= ~SS_MASK; 3280 action |= SS_FAIL; 3281 } 3282 if ((sense_flags & SF_PRINT_ALWAYS) != 0) 3283 action |= SSQ_PRINT_SENSE; 3284 else if ((sense_flags & SF_NO_PRINT) != 0) 3285 action &= ~SSQ_PRINT_SENSE; 3286 3287 return (action); 3288 } 3289 3290 char * 3291 scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string, size_t len) 3292 { 3293 u_int8_t cdb_len; 3294 int i; 3295 3296 if (cdb_ptr == NULL) 3297 return(""); 3298 3299 /* Silence warnings */ 3300 cdb_len = 0; 3301 3302 /* 3303 * This is taken from the SCSI-3 draft spec. 3304 * (T10/1157D revision 0.3) 3305 * The top 3 bits of an opcode are the group code. The next 5 bits 3306 * are the command code. 3307 * Group 0: six byte commands 3308 * Group 1: ten byte commands 3309 * Group 2: ten byte commands 3310 * Group 3: reserved 3311 * Group 4: sixteen byte commands 3312 * Group 5: twelve byte commands 3313 * Group 6: vendor specific 3314 * Group 7: vendor specific 3315 */ 3316 switch((*cdb_ptr >> 5) & 0x7) { 3317 case 0: 3318 cdb_len = 6; 3319 break; 3320 case 1: 3321 case 2: 3322 cdb_len = 10; 3323 break; 3324 case 3: 3325 case 6: 3326 case 7: 3327 /* in this case, just print out the opcode */ 3328 cdb_len = 1; 3329 break; 3330 case 4: 3331 cdb_len = 16; 3332 break; 3333 case 5: 3334 cdb_len = 12; 3335 break; 3336 } 3337 *cdb_string = '\0'; 3338 for (i = 0; i < cdb_len; i++) 3339 snprintf(cdb_string + strlen(cdb_string), 3340 len - strlen(cdb_string), "%02hhx ", cdb_ptr[i]); 3341 3342 return(cdb_string); 3343 } 3344 3345 const char * 3346 scsi_status_string(struct ccb_scsiio *csio) 3347 { 3348 switch(csio->scsi_status) { 3349 case SCSI_STATUS_OK: 3350 return("OK"); 3351 case SCSI_STATUS_CHECK_COND: 3352 return("Check Condition"); 3353 case SCSI_STATUS_BUSY: 3354 return("Busy"); 3355 case SCSI_STATUS_INTERMED: 3356 return("Intermediate"); 3357 case SCSI_STATUS_INTERMED_COND_MET: 3358 return("Intermediate-Condition Met"); 3359 case SCSI_STATUS_RESERV_CONFLICT: 3360 return("Reservation Conflict"); 3361 case SCSI_STATUS_CMD_TERMINATED: 3362 return("Command Terminated"); 3363 case SCSI_STATUS_QUEUE_FULL: 3364 return("Queue Full"); 3365 case SCSI_STATUS_ACA_ACTIVE: 3366 return("ACA Active"); 3367 case SCSI_STATUS_TASK_ABORTED: 3368 return("Task Aborted"); 3369 default: { 3370 static char unkstr[64]; 3371 snprintf(unkstr, sizeof(unkstr), "Unknown %#x", 3372 csio->scsi_status); 3373 return(unkstr); 3374 } 3375 } 3376 } 3377 3378 /* 3379 * scsi_command_string() returns 0 for success and -1 for failure. 3380 */ 3381 #ifdef _KERNEL 3382 int 3383 scsi_command_string(struct ccb_scsiio *csio, struct sbuf *sb) 3384 #else /* !_KERNEL */ 3385 int 3386 scsi_command_string(struct cam_device *device, struct ccb_scsiio *csio, 3387 struct sbuf *sb) 3388 #endif /* _KERNEL/!_KERNEL */ 3389 { 3390 struct scsi_inquiry_data *inq_data; 3391 char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1]; 3392 #ifdef _KERNEL 3393 struct ccb_getdev *cgd; 3394 #endif /* _KERNEL */ 3395 3396 #ifdef _KERNEL 3397 if ((cgd = (struct ccb_getdev*)xpt_alloc_ccb_nowait()) == NULL) 3398 return(-1); 3399 /* 3400 * Get the device information. 3401 */ 3402 xpt_setup_ccb(&cgd->ccb_h, 3403 csio->ccb_h.path, 3404 CAM_PRIORITY_NORMAL); 3405 cgd->ccb_h.func_code = XPT_GDEV_TYPE; 3406 xpt_action((union ccb *)cgd); 3407 3408 /* 3409 * If the device is unconfigured, just pretend that it is a hard 3410 * drive. scsi_op_desc() needs this. 3411 */ 3412 if (cgd->ccb_h.status == CAM_DEV_NOT_THERE) 3413 cgd->inq_data.device = T_DIRECT; 3414 3415 inq_data = &cgd->inq_data; 3416 3417 #else /* !_KERNEL */ 3418 3419 inq_data = &device->inq_data; 3420 3421 #endif /* _KERNEL/!_KERNEL */ 3422 3423 if ((csio->ccb_h.flags & CAM_CDB_POINTER) != 0) { 3424 sbuf_printf(sb, "%s. CDB: %s", 3425 scsi_op_desc(csio->cdb_io.cdb_ptr[0], inq_data), 3426 scsi_cdb_string(csio->cdb_io.cdb_ptr, cdb_str, 3427 sizeof(cdb_str))); 3428 } else { 3429 sbuf_printf(sb, "%s. CDB: %s", 3430 scsi_op_desc(csio->cdb_io.cdb_bytes[0], inq_data), 3431 scsi_cdb_string(csio->cdb_io.cdb_bytes, cdb_str, 3432 sizeof(cdb_str))); 3433 } 3434 3435 #ifdef _KERNEL 3436 xpt_free_ccb((union ccb *)cgd); 3437 #endif 3438 3439 return(0); 3440 } 3441 3442 /* 3443 * Iterate over sense descriptors. Each descriptor is passed into iter_func(). 3444 * If iter_func() returns 0, list traversal continues. If iter_func() 3445 * returns non-zero, list traversal is stopped. 3446 */ 3447 void 3448 scsi_desc_iterate(struct scsi_sense_data_desc *sense, u_int sense_len, 3449 int (*iter_func)(struct scsi_sense_data_desc *sense, 3450 u_int, struct scsi_sense_desc_header *, 3451 void *), void *arg) 3452 { 3453 int cur_pos; 3454 int desc_len; 3455 3456 /* 3457 * First make sure the extra length field is present. 3458 */ 3459 if (SSD_DESC_IS_PRESENT(sense, sense_len, extra_len) == 0) 3460 return; 3461 3462 /* 3463 * The length of data actually returned may be different than the 3464 * extra_len recorded in the sturcture. 3465 */ 3466 desc_len = sense_len -offsetof(struct scsi_sense_data_desc, sense_desc); 3467 3468 /* 3469 * Limit this further by the extra length reported, and the maximum 3470 * allowed extra length. 3471 */ 3472 desc_len = MIN(desc_len, MIN(sense->extra_len, SSD_EXTRA_MAX)); 3473 3474 /* 3475 * Subtract the size of the header from the descriptor length. 3476 * This is to ensure that we have at least the header left, so we 3477 * don't have to check that inside the loop. This can wind up 3478 * being a negative value. 3479 */ 3480 desc_len -= sizeof(struct scsi_sense_desc_header); 3481 3482 for (cur_pos = 0; cur_pos < desc_len;) { 3483 struct scsi_sense_desc_header *header; 3484 3485 header = (struct scsi_sense_desc_header *) 3486 &sense->sense_desc[cur_pos]; 3487 3488 /* 3489 * Check to make sure we have the entire descriptor. We 3490 * don't call iter_func() unless we do. 3491 * 3492 * Note that although cur_pos is at the beginning of the 3493 * descriptor, desc_len already has the header length 3494 * subtracted. So the comparison of the length in the 3495 * header (which does not include the header itself) to 3496 * desc_len - cur_pos is correct. 3497 */ 3498 if (header->length > (desc_len - cur_pos)) 3499 break; 3500 3501 if (iter_func(sense, sense_len, header, arg) != 0) 3502 break; 3503 3504 cur_pos += sizeof(*header) + header->length; 3505 } 3506 } 3507 3508 struct scsi_find_desc_info { 3509 uint8_t desc_type; 3510 struct scsi_sense_desc_header *header; 3511 }; 3512 3513 static int 3514 scsi_find_desc_func(struct scsi_sense_data_desc *sense, u_int sense_len, 3515 struct scsi_sense_desc_header *header, void *arg) 3516 { 3517 struct scsi_find_desc_info *desc_info; 3518 3519 desc_info = (struct scsi_find_desc_info *)arg; 3520 3521 if (header->desc_type == desc_info->desc_type) { 3522 desc_info->header = header; 3523 3524 /* We found the descriptor, tell the iterator to stop. */ 3525 return (1); 3526 } else 3527 return (0); 3528 } 3529 3530 /* 3531 * Given a descriptor type, return a pointer to it if it is in the sense 3532 * data and not truncated. Avoiding truncating sense data will simplify 3533 * things significantly for the caller. 3534 */ 3535 uint8_t * 3536 scsi_find_desc(struct scsi_sense_data_desc *sense, u_int sense_len, 3537 uint8_t desc_type) 3538 { 3539 struct scsi_find_desc_info desc_info; 3540 3541 desc_info.desc_type = desc_type; 3542 desc_info.header = NULL; 3543 3544 scsi_desc_iterate(sense, sense_len, scsi_find_desc_func, &desc_info); 3545 3546 return ((uint8_t *)desc_info.header); 3547 } 3548 3549 /* 3550 * Fill in SCSI sense data with the specified parameters. This routine can 3551 * fill in either fixed or descriptor type sense data. 3552 */ 3553 void 3554 scsi_set_sense_data_va(struct scsi_sense_data *sense_data, 3555 scsi_sense_data_type sense_format, int current_error, 3556 int sense_key, int asc, int ascq, va_list ap) 3557 { 3558 int descriptor_sense; 3559 scsi_sense_elem_type elem_type; 3560 3561 /* 3562 * Determine whether to return fixed or descriptor format sense 3563 * data. If the user specifies SSD_TYPE_NONE for some reason, 3564 * they'll just get fixed sense data. 3565 */ 3566 if (sense_format == SSD_TYPE_DESC) 3567 descriptor_sense = 1; 3568 else 3569 descriptor_sense = 0; 3570 3571 /* 3572 * Zero the sense data, so that we don't pass back any garbage data 3573 * to the user. 3574 */ 3575 memset(sense_data, 0, sizeof(*sense_data)); 3576 3577 if (descriptor_sense != 0) { 3578 struct scsi_sense_data_desc *sense; 3579 3580 sense = (struct scsi_sense_data_desc *)sense_data; 3581 /* 3582 * The descriptor sense format eliminates the use of the 3583 * valid bit. 3584 */ 3585 if (current_error != 0) 3586 sense->error_code = SSD_DESC_CURRENT_ERROR; 3587 else 3588 sense->error_code = SSD_DESC_DEFERRED_ERROR; 3589 sense->sense_key = sense_key; 3590 sense->add_sense_code = asc; 3591 sense->add_sense_code_qual = ascq; 3592 /* 3593 * Start off with no extra length, since the above data 3594 * fits in the standard descriptor sense information. 3595 */ 3596 sense->extra_len = 0; 3597 while ((elem_type = (scsi_sense_elem_type)va_arg(ap, 3598 scsi_sense_elem_type)) != SSD_ELEM_NONE) { 3599 int sense_len, len_to_copy; 3600 uint8_t *data; 3601 3602 if (elem_type >= SSD_ELEM_MAX) { 3603 printf("%s: invalid sense type %d\n", __func__, 3604 elem_type); 3605 break; 3606 } 3607 3608 sense_len = (int)va_arg(ap, int); 3609 len_to_copy = MIN(sense_len, SSD_EXTRA_MAX - 3610 sense->extra_len); 3611 data = (uint8_t *)va_arg(ap, uint8_t *); 3612 3613 /* 3614 * We've already consumed the arguments for this one. 3615 */ 3616 if (elem_type == SSD_ELEM_SKIP) 3617 continue; 3618 3619 switch (elem_type) { 3620 case SSD_ELEM_DESC: { 3621 3622 /* 3623 * This is a straight descriptor. All we 3624 * need to do is copy the data in. 3625 */ 3626 bcopy(data, &sense->sense_desc[ 3627 sense->extra_len], len_to_copy); 3628 sense->extra_len += len_to_copy; 3629 break; 3630 } 3631 case SSD_ELEM_SKS: { 3632 struct scsi_sense_sks sks; 3633 3634 bzero(&sks, sizeof(sks)); 3635 3636 /* 3637 * This is already-formatted sense key 3638 * specific data. We just need to fill out 3639 * the header and copy everything in. 3640 */ 3641 bcopy(data, &sks.sense_key_spec, 3642 MIN(len_to_copy, 3643 sizeof(sks.sense_key_spec))); 3644 3645 sks.desc_type = SSD_DESC_SKS; 3646 sks.length = sizeof(sks) - 3647 offsetof(struct scsi_sense_sks, reserved1); 3648 bcopy(&sks,&sense->sense_desc[sense->extra_len], 3649 sizeof(sks)); 3650 sense->extra_len += sizeof(sks); 3651 break; 3652 } 3653 case SSD_ELEM_INFO: 3654 case SSD_ELEM_COMMAND: { 3655 struct scsi_sense_command cmd; 3656 struct scsi_sense_info info; 3657 uint8_t *data_dest; 3658 uint8_t *descriptor; 3659 int descriptor_size, i, copy_len; 3660 3661 bzero(&cmd, sizeof(cmd)); 3662 bzero(&info, sizeof(info)); 3663 3664 /* 3665 * Command or information data. The 3666 * operate in pretty much the same way. 3667 */ 3668 if (elem_type == SSD_ELEM_COMMAND) { 3669 len_to_copy = MIN(len_to_copy, 3670 sizeof(cmd.command_info)); 3671 descriptor = (uint8_t *)&cmd; 3672 descriptor_size = sizeof(cmd); 3673 data_dest =(uint8_t *)&cmd.command_info; 3674 cmd.desc_type = SSD_DESC_COMMAND; 3675 cmd.length = sizeof(cmd) - 3676 offsetof(struct scsi_sense_command, 3677 reserved); 3678 } else { 3679 len_to_copy = MIN(len_to_copy, 3680 sizeof(info.info)); 3681 descriptor = (uint8_t *)&info; 3682 descriptor_size = sizeof(cmd); 3683 data_dest = (uint8_t *)&info.info; 3684 info.desc_type = SSD_DESC_INFO; 3685 info.byte2 = SSD_INFO_VALID; 3686 info.length = sizeof(info) - 3687 offsetof(struct scsi_sense_info, 3688 byte2); 3689 } 3690 3691 /* 3692 * Copy this in reverse because the spec 3693 * (SPC-4) says that when 4 byte quantities 3694 * are stored in this 8 byte field, the 3695 * first four bytes shall be 0. 3696 * 3697 * So we fill the bytes in from the end, and 3698 * if we have less than 8 bytes to copy, 3699 * the initial, most significant bytes will 3700 * be 0. 3701 */ 3702 for (i = sense_len - 1; i >= 0 && 3703 len_to_copy > 0; i--, len_to_copy--) 3704 data_dest[len_to_copy - 1] = data[i]; 3705 3706 /* 3707 * This calculation looks much like the 3708 * initial len_to_copy calculation, but 3709 * we have to do it again here, because 3710 * we're looking at a larger amount that 3711 * may or may not fit. It's not only the 3712 * data the user passed in, but also the 3713 * rest of the descriptor. 3714 */ 3715 copy_len = MIN(descriptor_size, 3716 SSD_EXTRA_MAX - sense->extra_len); 3717 bcopy(descriptor, &sense->sense_desc[ 3718 sense->extra_len], copy_len); 3719 sense->extra_len += copy_len; 3720 break; 3721 } 3722 case SSD_ELEM_FRU: { 3723 struct scsi_sense_fru fru; 3724 int copy_len; 3725 3726 bzero(&fru, sizeof(fru)); 3727 3728 fru.desc_type = SSD_DESC_FRU; 3729 fru.length = sizeof(fru) - 3730 offsetof(struct scsi_sense_fru, reserved); 3731 fru.fru = *data; 3732 3733 copy_len = MIN(sizeof(fru), SSD_EXTRA_MAX - 3734 sense->extra_len); 3735 bcopy(&fru, &sense->sense_desc[ 3736 sense->extra_len], copy_len); 3737 sense->extra_len += copy_len; 3738 break; 3739 } 3740 case SSD_ELEM_STREAM: { 3741 struct scsi_sense_stream stream_sense; 3742 int copy_len; 3743 3744 bzero(&stream_sense, sizeof(stream_sense)); 3745 stream_sense.desc_type = SSD_DESC_STREAM; 3746 stream_sense.length = sizeof(stream_sense) - 3747 offsetof(struct scsi_sense_stream, reserved); 3748 stream_sense.byte3 = *data; 3749 3750 copy_len = MIN(sizeof(stream_sense), 3751 SSD_EXTRA_MAX - sense->extra_len); 3752 bcopy(&stream_sense, &sense->sense_desc[ 3753 sense->extra_len], copy_len); 3754 sense->extra_len += copy_len; 3755 break; 3756 } 3757 default: 3758 /* 3759 * We shouldn't get here, but if we do, do 3760 * nothing. We've already consumed the 3761 * arguments above. 3762 */ 3763 break; 3764 } 3765 } 3766 } else { 3767 struct scsi_sense_data_fixed *sense; 3768 3769 sense = (struct scsi_sense_data_fixed *)sense_data; 3770 3771 if (current_error != 0) 3772 sense->error_code = SSD_CURRENT_ERROR; 3773 else 3774 sense->error_code = SSD_DEFERRED_ERROR; 3775 3776 sense->flags = sense_key; 3777 sense->add_sense_code = asc; 3778 sense->add_sense_code_qual = ascq; 3779 /* 3780 * We've set the ASC and ASCQ, so we have 6 more bytes of 3781 * valid data. If we wind up setting any of the other 3782 * fields, we'll bump this to 10 extra bytes. 3783 */ 3784 sense->extra_len = 6; 3785 3786 while ((elem_type = (scsi_sense_elem_type)va_arg(ap, 3787 scsi_sense_elem_type)) != SSD_ELEM_NONE) { 3788 int sense_len, len_to_copy; 3789 uint8_t *data; 3790 3791 if (elem_type >= SSD_ELEM_MAX) { 3792 printf("%s: invalid sense type %d\n", __func__, 3793 elem_type); 3794 break; 3795 } 3796 /* 3797 * If we get in here, just bump the extra length to 3798 * 10 bytes. That will encompass anything we're 3799 * going to set here. 3800 */ 3801 sense->extra_len = 10; 3802 sense_len = (int)va_arg(ap, int); 3803 len_to_copy = MIN(sense_len, SSD_EXTRA_MAX - 3804 sense->extra_len); 3805 data = (uint8_t *)va_arg(ap, uint8_t *); 3806 3807 switch (elem_type) { 3808 case SSD_ELEM_SKS: 3809 /* 3810 * The user passed in pre-formatted sense 3811 * key specific data. 3812 */ 3813 bcopy(data, &sense->sense_key_spec[0], 3814 MIN(sizeof(sense->sense_key_spec), 3815 sense_len)); 3816 break; 3817 case SSD_ELEM_INFO: 3818 case SSD_ELEM_COMMAND: { 3819 uint8_t *data_dest; 3820 int i; 3821 3822 if (elem_type == SSD_ELEM_COMMAND) 3823 data_dest = &sense->cmd_spec_info[0]; 3824 else { 3825 data_dest = &sense->info[0]; 3826 /* 3827 * We're setting the info field, so 3828 * set the valid bit. 3829 */ 3830 sense->error_code |= SSD_ERRCODE_VALID; 3831 } 3832 3833 /* 3834 * Copy this in reverse so that if we have 3835 * less than 4 bytes to fill, the least 3836 * significant bytes will be at the end. 3837 * If we have more than 4 bytes, only the 3838 * least significant bytes will be included. 3839 */ 3840 for (i = sense_len - 1; i >= 0 && 3841 len_to_copy > 0; i--, len_to_copy--) 3842 data_dest[len_to_copy - 1] = data[i]; 3843 3844 break; 3845 } 3846 case SSD_ELEM_FRU: 3847 sense->fru = *data; 3848 break; 3849 case SSD_ELEM_STREAM: 3850 sense->flags |= *data; 3851 break; 3852 case SSD_ELEM_DESC: 3853 default: 3854 3855 /* 3856 * If the user passes in descriptor sense, 3857 * we can't handle that in fixed format. 3858 * So just skip it, and any unknown argument 3859 * types. 3860 */ 3861 break; 3862 } 3863 } 3864 } 3865 } 3866 3867 void 3868 scsi_set_sense_data(struct scsi_sense_data *sense_data, 3869 scsi_sense_data_type sense_format, int current_error, 3870 int sense_key, int asc, int ascq, ...) 3871 { 3872 va_list ap; 3873 3874 va_start(ap, ascq); 3875 scsi_set_sense_data_va(sense_data, sense_format, current_error, 3876 sense_key, asc, ascq, ap); 3877 va_end(ap); 3878 } 3879 3880 /* 3881 * Get sense information for three similar sense data types. 3882 */ 3883 int 3884 scsi_get_sense_info(struct scsi_sense_data *sense_data, u_int sense_len, 3885 uint8_t info_type, uint64_t *info, int64_t *signed_info) 3886 { 3887 scsi_sense_data_type sense_type; 3888 3889 if (sense_len == 0) 3890 goto bailout; 3891 3892 sense_type = scsi_sense_type(sense_data); 3893 3894 switch (sense_type) { 3895 case SSD_TYPE_DESC: { 3896 struct scsi_sense_data_desc *sense; 3897 uint8_t *desc; 3898 3899 sense = (struct scsi_sense_data_desc *)sense_data; 3900 3901 desc = scsi_find_desc(sense, sense_len, info_type); 3902 if (desc == NULL) 3903 goto bailout; 3904 3905 switch (info_type) { 3906 case SSD_DESC_INFO: { 3907 struct scsi_sense_info *info_desc; 3908 3909 info_desc = (struct scsi_sense_info *)desc; 3910 *info = scsi_8btou64(info_desc->info); 3911 if (signed_info != NULL) 3912 *signed_info = *info; 3913 break; 3914 } 3915 case SSD_DESC_COMMAND: { 3916 struct scsi_sense_command *cmd_desc; 3917 3918 cmd_desc = (struct scsi_sense_command *)desc; 3919 3920 *info = scsi_8btou64(cmd_desc->command_info); 3921 if (signed_info != NULL) 3922 *signed_info = *info; 3923 break; 3924 } 3925 case SSD_DESC_FRU: { 3926 struct scsi_sense_fru *fru_desc; 3927 3928 fru_desc = (struct scsi_sense_fru *)desc; 3929 3930 *info = fru_desc->fru; 3931 if (signed_info != NULL) 3932 *signed_info = (int8_t)fru_desc->fru; 3933 break; 3934 } 3935 default: 3936 goto bailout; 3937 break; 3938 } 3939 break; 3940 } 3941 case SSD_TYPE_FIXED: { 3942 struct scsi_sense_data_fixed *sense; 3943 3944 sense = (struct scsi_sense_data_fixed *)sense_data; 3945 3946 switch (info_type) { 3947 case SSD_DESC_INFO: { 3948 uint32_t info_val; 3949 3950 if ((sense->error_code & SSD_ERRCODE_VALID) == 0) 3951 goto bailout; 3952 3953 if (SSD_FIXED_IS_PRESENT(sense, sense_len, info) == 0) 3954 goto bailout; 3955 3956 info_val = scsi_4btoul(sense->info); 3957 3958 *info = info_val; 3959 if (signed_info != NULL) 3960 *signed_info = (int32_t)info_val; 3961 break; 3962 } 3963 case SSD_DESC_COMMAND: { 3964 uint32_t cmd_val; 3965 3966 if ((SSD_FIXED_IS_PRESENT(sense, sense_len, 3967 cmd_spec_info) == 0) 3968 || (SSD_FIXED_IS_FILLED(sense, cmd_spec_info) == 0)) 3969 goto bailout; 3970 3971 cmd_val = scsi_4btoul(sense->cmd_spec_info); 3972 if (cmd_val == 0) 3973 goto bailout; 3974 3975 *info = cmd_val; 3976 if (signed_info != NULL) 3977 *signed_info = (int32_t)cmd_val; 3978 break; 3979 } 3980 case SSD_DESC_FRU: 3981 if ((SSD_FIXED_IS_PRESENT(sense, sense_len, fru) == 0) 3982 || (SSD_FIXED_IS_FILLED(sense, fru) == 0)) 3983 goto bailout; 3984 3985 if (sense->fru == 0) 3986 goto bailout; 3987 3988 *info = sense->fru; 3989 if (signed_info != NULL) 3990 *signed_info = (int8_t)sense->fru; 3991 break; 3992 default: 3993 goto bailout; 3994 break; 3995 } 3996 break; 3997 } 3998 default: 3999 goto bailout; 4000 break; 4001 } 4002 4003 return (0); 4004 bailout: 4005 return (1); 4006 } 4007 4008 int 4009 scsi_get_sks(struct scsi_sense_data *sense_data, u_int sense_len, uint8_t *sks) 4010 { 4011 scsi_sense_data_type sense_type; 4012 4013 if (sense_len == 0) 4014 goto bailout; 4015 4016 sense_type = scsi_sense_type(sense_data); 4017 4018 switch (sense_type) { 4019 case SSD_TYPE_DESC: { 4020 struct scsi_sense_data_desc *sense; 4021 struct scsi_sense_sks *desc; 4022 4023 sense = (struct scsi_sense_data_desc *)sense_data; 4024 4025 desc = (struct scsi_sense_sks *)scsi_find_desc(sense, sense_len, 4026 SSD_DESC_SKS); 4027 if (desc == NULL) 4028 goto bailout; 4029 4030 /* 4031 * No need to check the SKS valid bit for descriptor sense. 4032 * If the descriptor is present, it is valid. 4033 */ 4034 bcopy(desc->sense_key_spec, sks, sizeof(desc->sense_key_spec)); 4035 break; 4036 } 4037 case SSD_TYPE_FIXED: { 4038 struct scsi_sense_data_fixed *sense; 4039 4040 sense = (struct scsi_sense_data_fixed *)sense_data; 4041 4042 if ((SSD_FIXED_IS_PRESENT(sense, sense_len, sense_key_spec)== 0) 4043 || (SSD_FIXED_IS_FILLED(sense, sense_key_spec) == 0)) 4044 goto bailout; 4045 4046 if ((sense->sense_key_spec[0] & SSD_SCS_VALID) == 0) 4047 goto bailout; 4048 4049 bcopy(sense->sense_key_spec, sks,sizeof(sense->sense_key_spec)); 4050 break; 4051 } 4052 default: 4053 goto bailout; 4054 break; 4055 } 4056 return (0); 4057 bailout: 4058 return (1); 4059 } 4060 4061 /* 4062 * Provide a common interface for fixed and descriptor sense to detect 4063 * whether we have block-specific sense information. It is clear by the 4064 * presence of the block descriptor in descriptor mode, but we have to 4065 * infer from the inquiry data and ILI bit in fixed mode. 4066 */ 4067 int 4068 scsi_get_block_info(struct scsi_sense_data *sense_data, u_int sense_len, 4069 struct scsi_inquiry_data *inq_data, uint8_t *block_bits) 4070 { 4071 scsi_sense_data_type sense_type; 4072 4073 if (inq_data != NULL) { 4074 switch (SID_TYPE(inq_data)) { 4075 case T_DIRECT: 4076 case T_RBC: 4077 break; 4078 default: 4079 goto bailout; 4080 break; 4081 } 4082 } 4083 4084 sense_type = scsi_sense_type(sense_data); 4085 4086 switch (sense_type) { 4087 case SSD_TYPE_DESC: { 4088 struct scsi_sense_data_desc *sense; 4089 struct scsi_sense_block *block; 4090 4091 sense = (struct scsi_sense_data_desc *)sense_data; 4092 4093 block = (struct scsi_sense_block *)scsi_find_desc(sense, 4094 sense_len, SSD_DESC_BLOCK); 4095 if (block == NULL) 4096 goto bailout; 4097 4098 *block_bits = block->byte3; 4099 break; 4100 } 4101 case SSD_TYPE_FIXED: { 4102 struct scsi_sense_data_fixed *sense; 4103 4104 sense = (struct scsi_sense_data_fixed *)sense_data; 4105 4106 if (SSD_FIXED_IS_PRESENT(sense, sense_len, flags) == 0) 4107 goto bailout; 4108 4109 if ((sense->flags & SSD_ILI) == 0) 4110 goto bailout; 4111 4112 *block_bits = sense->flags & SSD_ILI; 4113 break; 4114 } 4115 default: 4116 goto bailout; 4117 break; 4118 } 4119 return (0); 4120 bailout: 4121 return (1); 4122 } 4123 4124 int 4125 scsi_get_stream_info(struct scsi_sense_data *sense_data, u_int sense_len, 4126 struct scsi_inquiry_data *inq_data, uint8_t *stream_bits) 4127 { 4128 scsi_sense_data_type sense_type; 4129 4130 if (inq_data != NULL) { 4131 switch (SID_TYPE(inq_data)) { 4132 case T_SEQUENTIAL: 4133 break; 4134 default: 4135 goto bailout; 4136 break; 4137 } 4138 } 4139 4140 sense_type = scsi_sense_type(sense_data); 4141 4142 switch (sense_type) { 4143 case SSD_TYPE_DESC: { 4144 struct scsi_sense_data_desc *sense; 4145 struct scsi_sense_stream *stream; 4146 4147 sense = (struct scsi_sense_data_desc *)sense_data; 4148 4149 stream = (struct scsi_sense_stream *)scsi_find_desc(sense, 4150 sense_len, SSD_DESC_STREAM); 4151 if (stream == NULL) 4152 goto bailout; 4153 4154 *stream_bits = stream->byte3; 4155 break; 4156 } 4157 case SSD_TYPE_FIXED: { 4158 struct scsi_sense_data_fixed *sense; 4159 4160 sense = (struct scsi_sense_data_fixed *)sense_data; 4161 4162 if (SSD_FIXED_IS_PRESENT(sense, sense_len, flags) == 0) 4163 goto bailout; 4164 4165 if ((sense->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK)) == 0) 4166 goto bailout; 4167 4168 *stream_bits = sense->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK); 4169 break; 4170 } 4171 default: 4172 goto bailout; 4173 break; 4174 } 4175 return (0); 4176 bailout: 4177 return (1); 4178 } 4179 4180 void 4181 scsi_info_sbuf(struct sbuf *sb, uint8_t *cdb, int cdb_len, 4182 struct scsi_inquiry_data *inq_data, uint64_t info) 4183 { 4184 sbuf_printf(sb, "Info: %#jx", info); 4185 } 4186 4187 void 4188 scsi_command_sbuf(struct sbuf *sb, uint8_t *cdb, int cdb_len, 4189 struct scsi_inquiry_data *inq_data, uint64_t csi) 4190 { 4191 sbuf_printf(sb, "Command Specific Info: %#jx", csi); 4192 } 4193 4194 4195 void 4196 scsi_progress_sbuf(struct sbuf *sb, uint16_t progress) 4197 { 4198 sbuf_printf(sb, "Progress: %d%% (%d/%d) complete", 4199 (progress * 100) / SSD_SKS_PROGRESS_DENOM, 4200 progress, SSD_SKS_PROGRESS_DENOM); 4201 } 4202 4203 /* 4204 * Returns 1 for failure (i.e. SKS isn't valid) and 0 for success. 4205 */ 4206 int 4207 scsi_sks_sbuf(struct sbuf *sb, int sense_key, uint8_t *sks) 4208 { 4209 if ((sks[0] & SSD_SKS_VALID) == 0) 4210 return (1); 4211 4212 switch (sense_key) { 4213 case SSD_KEY_ILLEGAL_REQUEST: { 4214 struct scsi_sense_sks_field *field; 4215 int bad_command; 4216 char tmpstr[40]; 4217 4218 /*Field Pointer*/ 4219 field = (struct scsi_sense_sks_field *)sks; 4220 4221 if (field->byte0 & SSD_SKS_FIELD_CMD) 4222 bad_command = 1; 4223 else 4224 bad_command = 0; 4225 4226 tmpstr[0] = '\0'; 4227 4228 /* Bit pointer is valid */ 4229 if (field->byte0 & SSD_SKS_BPV) 4230 snprintf(tmpstr, sizeof(tmpstr), "bit %d ", 4231 field->byte0 & SSD_SKS_BIT_VALUE); 4232 4233 sbuf_printf(sb, "%s byte %d %sis invalid", 4234 bad_command ? "Command" : "Data", 4235 scsi_2btoul(field->field), tmpstr); 4236 break; 4237 } 4238 case SSD_KEY_UNIT_ATTENTION: { 4239 struct scsi_sense_sks_overflow *overflow; 4240 4241 overflow = (struct scsi_sense_sks_overflow *)sks; 4242 4243 /*UA Condition Queue Overflow*/ 4244 sbuf_printf(sb, "Unit Attention Condition Queue %s", 4245 (overflow->byte0 & SSD_SKS_OVERFLOW_SET) ? 4246 "Overflowed" : "Did Not Overflow??"); 4247 break; 4248 } 4249 case SSD_KEY_RECOVERED_ERROR: 4250 case SSD_KEY_HARDWARE_ERROR: 4251 case SSD_KEY_MEDIUM_ERROR: { 4252 struct scsi_sense_sks_retry *retry; 4253 4254 /*Actual Retry Count*/ 4255 retry = (struct scsi_sense_sks_retry *)sks; 4256 4257 sbuf_printf(sb, "Actual Retry Count: %d", 4258 scsi_2btoul(retry->actual_retry_count)); 4259 break; 4260 } 4261 case SSD_KEY_NO_SENSE: 4262 case SSD_KEY_NOT_READY: { 4263 struct scsi_sense_sks_progress *progress; 4264 int progress_val; 4265 4266 /*Progress Indication*/ 4267 progress = (struct scsi_sense_sks_progress *)sks; 4268 progress_val = scsi_2btoul(progress->progress); 4269 4270 scsi_progress_sbuf(sb, progress_val); 4271 break; 4272 } 4273 case SSD_KEY_COPY_ABORTED: { 4274 struct scsi_sense_sks_segment *segment; 4275 char tmpstr[40]; 4276 4277 /*Segment Pointer*/ 4278 segment = (struct scsi_sense_sks_segment *)sks; 4279 4280 tmpstr[0] = '\0'; 4281 4282 if (segment->byte0 & SSD_SKS_SEGMENT_BPV) 4283 snprintf(tmpstr, sizeof(tmpstr), "bit %d ", 4284 segment->byte0 & SSD_SKS_SEGMENT_BITPTR); 4285 4286 sbuf_printf(sb, "%s byte %d %sis invalid", (segment->byte0 & 4287 SSD_SKS_SEGMENT_SD) ? "Segment" : "Data", 4288 scsi_2btoul(segment->field), tmpstr); 4289 break; 4290 } 4291 default: 4292 sbuf_printf(sb, "Sense Key Specific: %#x,%#x", sks[0], 4293 scsi_2btoul(&sks[1])); 4294 break; 4295 } 4296 4297 return (0); 4298 } 4299 4300 void 4301 scsi_fru_sbuf(struct sbuf *sb, uint64_t fru) 4302 { 4303 sbuf_printf(sb, "Field Replaceable Unit: %d", (int)fru); 4304 } 4305 4306 void 4307 scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits, uint64_t info) 4308 { 4309 int need_comma; 4310 4311 need_comma = 0; 4312 /* 4313 * XXX KDM this needs more descriptive decoding. 4314 */ 4315 if (stream_bits & SSD_DESC_STREAM_FM) { 4316 sbuf_printf(sb, "Filemark"); 4317 need_comma = 1; 4318 } 4319 4320 if (stream_bits & SSD_DESC_STREAM_EOM) { 4321 sbuf_printf(sb, "%sEOM", (need_comma) ? "," : ""); 4322 need_comma = 1; 4323 } 4324 4325 if (stream_bits & SSD_DESC_STREAM_ILI) 4326 sbuf_printf(sb, "%sILI", (need_comma) ? "," : ""); 4327 4328 sbuf_printf(sb, ": Info: %#jx", (uintmax_t) info); 4329 } 4330 4331 void 4332 scsi_block_sbuf(struct sbuf *sb, uint8_t block_bits, uint64_t info) 4333 { 4334 if (block_bits & SSD_DESC_BLOCK_ILI) 4335 sbuf_printf(sb, "ILI: residue %#jx", (uintmax_t) info); 4336 } 4337 4338 void 4339 scsi_sense_info_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4340 u_int sense_len, uint8_t *cdb, int cdb_len, 4341 struct scsi_inquiry_data *inq_data, 4342 struct scsi_sense_desc_header *header) 4343 { 4344 struct scsi_sense_info *info; 4345 4346 info = (struct scsi_sense_info *)header; 4347 4348 scsi_info_sbuf(sb, cdb, cdb_len, inq_data, scsi_8btou64(info->info)); 4349 } 4350 4351 void 4352 scsi_sense_command_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4353 u_int sense_len, uint8_t *cdb, int cdb_len, 4354 struct scsi_inquiry_data *inq_data, 4355 struct scsi_sense_desc_header *header) 4356 { 4357 struct scsi_sense_command *command; 4358 4359 command = (struct scsi_sense_command *)header; 4360 4361 scsi_command_sbuf(sb, cdb, cdb_len, inq_data, 4362 scsi_8btou64(command->command_info)); 4363 } 4364 4365 void 4366 scsi_sense_sks_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4367 u_int sense_len, uint8_t *cdb, int cdb_len, 4368 struct scsi_inquiry_data *inq_data, 4369 struct scsi_sense_desc_header *header) 4370 { 4371 struct scsi_sense_sks *sks; 4372 int error_code, sense_key, asc, ascq; 4373 4374 sks = (struct scsi_sense_sks *)header; 4375 4376 scsi_extract_sense_len(sense, sense_len, &error_code, &sense_key, 4377 &asc, &ascq, /*show_errors*/ 1); 4378 4379 scsi_sks_sbuf(sb, sense_key, sks->sense_key_spec); 4380 } 4381 4382 void 4383 scsi_sense_fru_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4384 u_int sense_len, uint8_t *cdb, int cdb_len, 4385 struct scsi_inquiry_data *inq_data, 4386 struct scsi_sense_desc_header *header) 4387 { 4388 struct scsi_sense_fru *fru; 4389 4390 fru = (struct scsi_sense_fru *)header; 4391 4392 scsi_fru_sbuf(sb, (uint64_t)fru->fru); 4393 } 4394 4395 void 4396 scsi_sense_stream_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4397 u_int sense_len, uint8_t *cdb, int cdb_len, 4398 struct scsi_inquiry_data *inq_data, 4399 struct scsi_sense_desc_header *header) 4400 { 4401 struct scsi_sense_stream *stream; 4402 uint64_t info; 4403 4404 stream = (struct scsi_sense_stream *)header; 4405 info = 0; 4406 4407 scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info, NULL); 4408 4409 scsi_stream_sbuf(sb, stream->byte3, info); 4410 } 4411 4412 void 4413 scsi_sense_block_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4414 u_int sense_len, uint8_t *cdb, int cdb_len, 4415 struct scsi_inquiry_data *inq_data, 4416 struct scsi_sense_desc_header *header) 4417 { 4418 struct scsi_sense_block *block; 4419 uint64_t info; 4420 4421 block = (struct scsi_sense_block *)header; 4422 info = 0; 4423 4424 scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info, NULL); 4425 4426 scsi_block_sbuf(sb, block->byte3, info); 4427 } 4428 4429 void 4430 scsi_sense_progress_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4431 u_int sense_len, uint8_t *cdb, int cdb_len, 4432 struct scsi_inquiry_data *inq_data, 4433 struct scsi_sense_desc_header *header) 4434 { 4435 struct scsi_sense_progress *progress; 4436 const char *sense_key_desc; 4437 const char *asc_desc; 4438 int progress_val; 4439 4440 progress = (struct scsi_sense_progress *)header; 4441 4442 /* 4443 * Get descriptions for the sense key, ASC, and ASCQ in the 4444 * progress descriptor. These could be different than the values 4445 * in the overall sense data. 4446 */ 4447 scsi_sense_desc(progress->sense_key, progress->add_sense_code, 4448 progress->add_sense_code_qual, inq_data, 4449 &sense_key_desc, &asc_desc); 4450 4451 progress_val = scsi_2btoul(progress->progress); 4452 4453 /* 4454 * The progress indicator is for the operation described by the 4455 * sense key, ASC, and ASCQ in the descriptor. 4456 */ 4457 sbuf_cat(sb, sense_key_desc); 4458 sbuf_printf(sb, " asc:%x,%x (%s): ", progress->add_sense_code, 4459 progress->add_sense_code_qual, asc_desc); 4460 scsi_progress_sbuf(sb, progress_val); 4461 } 4462 4463 /* 4464 * Generic sense descriptor printing routine. This is used when we have 4465 * not yet implemented a specific printing routine for this descriptor. 4466 */ 4467 void 4468 scsi_sense_generic_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4469 u_int sense_len, uint8_t *cdb, int cdb_len, 4470 struct scsi_inquiry_data *inq_data, 4471 struct scsi_sense_desc_header *header) 4472 { 4473 int i; 4474 uint8_t *buf_ptr; 4475 4476 sbuf_printf(sb, "Descriptor %#x:", header->desc_type); 4477 4478 buf_ptr = (uint8_t *)&header[1]; 4479 4480 for (i = 0; i < header->length; i++, buf_ptr++) 4481 sbuf_printf(sb, " %02x", *buf_ptr); 4482 } 4483 4484 /* 4485 * Keep this list in numeric order. This speeds the array traversal. 4486 */ 4487 struct scsi_sense_desc_printer { 4488 uint8_t desc_type; 4489 /* 4490 * The function arguments here are the superset of what is needed 4491 * to print out various different descriptors. Command and 4492 * information descriptors need inquiry data and command type. 4493 * Sense key specific descriptors need the sense key. 4494 * 4495 * The sense, cdb, and inquiry data arguments may be NULL, but the 4496 * information printed may not be fully decoded as a result. 4497 */ 4498 void (*print_func)(struct sbuf *sb, struct scsi_sense_data *sense, 4499 u_int sense_len, uint8_t *cdb, int cdb_len, 4500 struct scsi_inquiry_data *inq_data, 4501 struct scsi_sense_desc_header *header); 4502 } scsi_sense_printers[] = { 4503 {SSD_DESC_INFO, scsi_sense_info_sbuf}, 4504 {SSD_DESC_COMMAND, scsi_sense_command_sbuf}, 4505 {SSD_DESC_SKS, scsi_sense_sks_sbuf}, 4506 {SSD_DESC_FRU, scsi_sense_fru_sbuf}, 4507 {SSD_DESC_STREAM, scsi_sense_stream_sbuf}, 4508 {SSD_DESC_BLOCK, scsi_sense_block_sbuf}, 4509 {SSD_DESC_PROGRESS, scsi_sense_progress_sbuf} 4510 }; 4511 4512 void 4513 scsi_sense_desc_sbuf(struct sbuf *sb, struct scsi_sense_data *sense, 4514 u_int sense_len, uint8_t *cdb, int cdb_len, 4515 struct scsi_inquiry_data *inq_data, 4516 struct scsi_sense_desc_header *header) 4517 { 4518 int i; 4519 4520 for (i = 0; i < (sizeof(scsi_sense_printers) / 4521 sizeof(scsi_sense_printers[0])); i++) { 4522 struct scsi_sense_desc_printer *printer; 4523 4524 printer = &scsi_sense_printers[i]; 4525 4526 /* 4527 * The list is sorted, so quit if we've passed our 4528 * descriptor number. 4529 */ 4530 if (printer->desc_type > header->desc_type) 4531 break; 4532 4533 if (printer->desc_type != header->desc_type) 4534 continue; 4535 4536 printer->print_func(sb, sense, sense_len, cdb, cdb_len, 4537 inq_data, header); 4538 4539 return; 4540 } 4541 4542 /* 4543 * No specific printing routine, so use the generic routine. 4544 */ 4545 scsi_sense_generic_sbuf(sb, sense, sense_len, cdb, cdb_len, 4546 inq_data, header); 4547 } 4548 4549 scsi_sense_data_type 4550 scsi_sense_type(struct scsi_sense_data *sense_data) 4551 { 4552 switch (sense_data->error_code & SSD_ERRCODE) { 4553 case SSD_DESC_CURRENT_ERROR: 4554 case SSD_DESC_DEFERRED_ERROR: 4555 return (SSD_TYPE_DESC); 4556 break; 4557 case SSD_CURRENT_ERROR: 4558 case SSD_DEFERRED_ERROR: 4559 return (SSD_TYPE_FIXED); 4560 break; 4561 default: 4562 break; 4563 } 4564 4565 return (SSD_TYPE_NONE); 4566 } 4567 4568 struct scsi_print_sense_info { 4569 struct sbuf *sb; 4570 char *path_str; 4571 uint8_t *cdb; 4572 int cdb_len; 4573 struct scsi_inquiry_data *inq_data; 4574 }; 4575 4576 static int 4577 scsi_print_desc_func(struct scsi_sense_data_desc *sense, u_int sense_len, 4578 struct scsi_sense_desc_header *header, void *arg) 4579 { 4580 struct scsi_print_sense_info *print_info; 4581 4582 print_info = (struct scsi_print_sense_info *)arg; 4583 4584 switch (header->desc_type) { 4585 case SSD_DESC_INFO: 4586 case SSD_DESC_FRU: 4587 case SSD_DESC_COMMAND: 4588 case SSD_DESC_SKS: 4589 case SSD_DESC_BLOCK: 4590 case SSD_DESC_STREAM: 4591 /* 4592 * We have already printed these descriptors, if they are 4593 * present. 4594 */ 4595 break; 4596 default: { 4597 sbuf_printf(print_info->sb, "%s", print_info->path_str); 4598 scsi_sense_desc_sbuf(print_info->sb, 4599 (struct scsi_sense_data *)sense, sense_len, 4600 print_info->cdb, print_info->cdb_len, 4601 print_info->inq_data, header); 4602 sbuf_printf(print_info->sb, "\n"); 4603 break; 4604 } 4605 } 4606 4607 /* 4608 * Tell the iterator that we want to see more descriptors if they 4609 * are present. 4610 */ 4611 return (0); 4612 } 4613 4614 void 4615 scsi_sense_only_sbuf(struct scsi_sense_data *sense, u_int sense_len, 4616 struct sbuf *sb, char *path_str, 4617 struct scsi_inquiry_data *inq_data, uint8_t *cdb, 4618 int cdb_len) 4619 { 4620 int error_code, sense_key, asc, ascq; 4621 4622 sbuf_cat(sb, path_str); 4623 4624 scsi_extract_sense_len(sense, sense_len, &error_code, &sense_key, 4625 &asc, &ascq, /*show_errors*/ 1); 4626 4627 sbuf_printf(sb, "SCSI sense: "); 4628 switch (error_code) { 4629 case SSD_DEFERRED_ERROR: 4630 case SSD_DESC_DEFERRED_ERROR: 4631 sbuf_printf(sb, "Deferred error: "); 4632 4633 /* FALLTHROUGH */ 4634 case SSD_CURRENT_ERROR: 4635 case SSD_DESC_CURRENT_ERROR: 4636 { 4637 struct scsi_sense_data_desc *desc_sense; 4638 struct scsi_print_sense_info print_info; 4639 const char *sense_key_desc; 4640 const char *asc_desc; 4641 uint8_t sks[3]; 4642 uint64_t val; 4643 int info_valid; 4644 4645 /* 4646 * Get descriptions for the sense key, ASC, and ASCQ. If 4647 * these aren't present in the sense data (i.e. the sense 4648 * data isn't long enough), the -1 values that 4649 * scsi_extract_sense_len() returns will yield default 4650 * or error descriptions. 4651 */ 4652 scsi_sense_desc(sense_key, asc, ascq, inq_data, 4653 &sense_key_desc, &asc_desc); 4654 4655 /* 4656 * We first print the sense key and ASC/ASCQ. 4657 */ 4658 sbuf_cat(sb, sense_key_desc); 4659 sbuf_printf(sb, " asc:%x,%x (%s)\n", asc, ascq, asc_desc); 4660 4661 /* 4662 * Get the info field if it is valid. 4663 */ 4664 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, 4665 &val, NULL) == 0) 4666 info_valid = 1; 4667 else 4668 info_valid = 0; 4669 4670 if (info_valid != 0) { 4671 uint8_t bits; 4672 4673 /* 4674 * Determine whether we have any block or stream 4675 * device-specific information. 4676 */ 4677 if (scsi_get_block_info(sense, sense_len, inq_data, 4678 &bits) == 0) { 4679 sbuf_cat(sb, path_str); 4680 scsi_block_sbuf(sb, bits, val); 4681 sbuf_printf(sb, "\n"); 4682 } else if (scsi_get_stream_info(sense, sense_len, 4683 inq_data, &bits) == 0) { 4684 sbuf_cat(sb, path_str); 4685 scsi_stream_sbuf(sb, bits, val); 4686 sbuf_printf(sb, "\n"); 4687 } else if (val != 0) { 4688 /* 4689 * The information field can be valid but 0. 4690 * If the block or stream bits aren't set, 4691 * and this is 0, it isn't terribly useful 4692 * to print it out. 4693 */ 4694 sbuf_cat(sb, path_str); 4695 scsi_info_sbuf(sb, cdb, cdb_len, inq_data, val); 4696 sbuf_printf(sb, "\n"); 4697 } 4698 } 4699 4700 /* 4701 * Print the FRU. 4702 */ 4703 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_FRU, 4704 &val, NULL) == 0) { 4705 sbuf_cat(sb, path_str); 4706 scsi_fru_sbuf(sb, val); 4707 sbuf_printf(sb, "\n"); 4708 } 4709 4710 /* 4711 * Print any command-specific information. 4712 */ 4713 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_COMMAND, 4714 &val, NULL) == 0) { 4715 sbuf_cat(sb, path_str); 4716 scsi_command_sbuf(sb, cdb, cdb_len, inq_data, val); 4717 sbuf_printf(sb, "\n"); 4718 } 4719 4720 /* 4721 * Print out any sense-key-specific information. 4722 */ 4723 if (scsi_get_sks(sense, sense_len, sks) == 0) { 4724 sbuf_cat(sb, path_str); 4725 scsi_sks_sbuf(sb, sense_key, sks); 4726 sbuf_printf(sb, "\n"); 4727 } 4728 4729 /* 4730 * If this is fixed sense, we're done. If we have 4731 * descriptor sense, we might have more information 4732 * available. 4733 */ 4734 if (scsi_sense_type(sense) != SSD_TYPE_DESC) 4735 break; 4736 4737 desc_sense = (struct scsi_sense_data_desc *)sense; 4738 4739 print_info.sb = sb; 4740 print_info.path_str = path_str; 4741 print_info.cdb = cdb; 4742 print_info.cdb_len = cdb_len; 4743 print_info.inq_data = inq_data; 4744 4745 /* 4746 * Print any sense descriptors that we have not already printed. 4747 */ 4748 scsi_desc_iterate(desc_sense, sense_len, scsi_print_desc_func, 4749 &print_info); 4750 break; 4751 4752 } 4753 case -1: 4754 /* 4755 * scsi_extract_sense_len() sets values to -1 if the 4756 * show_errors flag is set and they aren't present in the 4757 * sense data. This means that sense_len is 0. 4758 */ 4759 sbuf_printf(sb, "No sense data present\n"); 4760 break; 4761 default: { 4762 sbuf_printf(sb, "Error code 0x%x", error_code); 4763 if (sense->error_code & SSD_ERRCODE_VALID) { 4764 struct scsi_sense_data_fixed *fixed_sense; 4765 4766 fixed_sense = (struct scsi_sense_data_fixed *)sense; 4767 4768 if (SSD_FIXED_IS_PRESENT(fixed_sense, sense_len, info)){ 4769 uint32_t info; 4770 4771 info = scsi_4btoul(fixed_sense->info); 4772 4773 sbuf_printf(sb, " at block no. %d (decimal)", 4774 info); 4775 } 4776 } 4777 sbuf_printf(sb, "\n"); 4778 break; 4779 } 4780 } 4781 } 4782 4783 /* 4784 * scsi_sense_sbuf() returns 0 for success and -1 for failure. 4785 */ 4786 #ifdef _KERNEL 4787 int 4788 scsi_sense_sbuf(struct ccb_scsiio *csio, struct sbuf *sb, 4789 scsi_sense_string_flags flags) 4790 #else /* !_KERNEL */ 4791 int 4792 scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio, 4793 struct sbuf *sb, scsi_sense_string_flags flags) 4794 #endif /* _KERNEL/!_KERNEL */ 4795 { 4796 struct scsi_sense_data *sense; 4797 struct scsi_inquiry_data *inq_data; 4798 #ifdef _KERNEL 4799 struct ccb_getdev *cgd; 4800 #endif /* _KERNEL */ 4801 char path_str[64]; 4802 uint8_t *cdb; 4803 4804 #ifndef _KERNEL 4805 if (device == NULL) 4806 return(-1); 4807 #endif /* !_KERNEL */ 4808 if ((csio == NULL) || (sb == NULL)) 4809 return(-1); 4810 4811 /* 4812 * If the CDB is a physical address, we can't deal with it.. 4813 */ 4814 if ((csio->ccb_h.flags & CAM_CDB_PHYS) != 0) 4815 flags &= ~SSS_FLAG_PRINT_COMMAND; 4816 4817 #ifdef _KERNEL 4818 xpt_path_string(csio->ccb_h.path, path_str, sizeof(path_str)); 4819 #else /* !_KERNEL */ 4820 cam_path_string(device, path_str, sizeof(path_str)); 4821 #endif /* _KERNEL/!_KERNEL */ 4822 4823 #ifdef _KERNEL 4824 if ((cgd = (struct ccb_getdev*)xpt_alloc_ccb_nowait()) == NULL) 4825 return(-1); 4826 /* 4827 * Get the device information. 4828 */ 4829 xpt_setup_ccb(&cgd->ccb_h, 4830 csio->ccb_h.path, 4831 CAM_PRIORITY_NORMAL); 4832 cgd->ccb_h.func_code = XPT_GDEV_TYPE; 4833 xpt_action((union ccb *)cgd); 4834 4835 /* 4836 * If the device is unconfigured, just pretend that it is a hard 4837 * drive. scsi_op_desc() needs this. 4838 */ 4839 if (cgd->ccb_h.status == CAM_DEV_NOT_THERE) 4840 cgd->inq_data.device = T_DIRECT; 4841 4842 inq_data = &cgd->inq_data; 4843 4844 #else /* !_KERNEL */ 4845 4846 inq_data = &device->inq_data; 4847 4848 #endif /* _KERNEL/!_KERNEL */ 4849 4850 sense = NULL; 4851 4852 if (flags & SSS_FLAG_PRINT_COMMAND) { 4853 4854 sbuf_cat(sb, path_str); 4855 4856 #ifdef _KERNEL 4857 scsi_command_string(csio, sb); 4858 #else /* !_KERNEL */ 4859 scsi_command_string(device, csio, sb); 4860 #endif /* _KERNEL/!_KERNEL */ 4861 sbuf_printf(sb, "\n"); 4862 } 4863 4864 /* 4865 * If the sense data is a physical pointer, forget it. 4866 */ 4867 if (csio->ccb_h.flags & CAM_SENSE_PTR) { 4868 if (csio->ccb_h.flags & CAM_SENSE_PHYS) { 4869 #ifdef _KERNEL 4870 xpt_free_ccb((union ccb*)cgd); 4871 #endif /* _KERNEL/!_KERNEL */ 4872 return(-1); 4873 } else { 4874 /* 4875 * bcopy the pointer to avoid unaligned access 4876 * errors on finicky architectures. We don't 4877 * ensure that the sense data is pointer aligned. 4878 */ 4879 bcopy(&csio->sense_data, &sense, 4880 sizeof(struct scsi_sense_data *)); 4881 } 4882 } else { 4883 /* 4884 * If the physical sense flag is set, but the sense pointer 4885 * is not also set, we assume that the user is an idiot and 4886 * return. (Well, okay, it could be that somehow, the 4887 * entire csio is physical, but we would have probably core 4888 * dumped on one of the bogus pointer deferences above 4889 * already.) 4890 */ 4891 if (csio->ccb_h.flags & CAM_SENSE_PHYS) { 4892 #ifdef _KERNEL 4893 xpt_free_ccb((union ccb*)cgd); 4894 #endif /* _KERNEL/!_KERNEL */ 4895 return(-1); 4896 } else 4897 sense = &csio->sense_data; 4898 } 4899 4900 if (csio->ccb_h.flags & CAM_CDB_POINTER) 4901 cdb = csio->cdb_io.cdb_ptr; 4902 else 4903 cdb = csio->cdb_io.cdb_bytes; 4904 4905 scsi_sense_only_sbuf(sense, csio->sense_len - csio->sense_resid, sb, 4906 path_str, inq_data, cdb, csio->cdb_len); 4907 4908 #ifdef _KERNEL 4909 xpt_free_ccb((union ccb*)cgd); 4910 #endif /* _KERNEL/!_KERNEL */ 4911 return(0); 4912 } 4913 4914 4915 4916 #ifdef _KERNEL 4917 char * 4918 scsi_sense_string(struct ccb_scsiio *csio, char *str, int str_len) 4919 #else /* !_KERNEL */ 4920 char * 4921 scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio, 4922 char *str, int str_len) 4923 #endif /* _KERNEL/!_KERNEL */ 4924 { 4925 struct sbuf sb; 4926 4927 sbuf_new(&sb, str, str_len, 0); 4928 4929 #ifdef _KERNEL 4930 scsi_sense_sbuf(csio, &sb, SSS_FLAG_PRINT_COMMAND); 4931 #else /* !_KERNEL */ 4932 scsi_sense_sbuf(device, csio, &sb, SSS_FLAG_PRINT_COMMAND); 4933 #endif /* _KERNEL/!_KERNEL */ 4934 4935 sbuf_finish(&sb); 4936 4937 return(sbuf_data(&sb)); 4938 } 4939 4940 #ifdef _KERNEL 4941 void 4942 scsi_sense_print(struct ccb_scsiio *csio) 4943 { 4944 struct sbuf sb; 4945 char str[512]; 4946 4947 sbuf_new(&sb, str, sizeof(str), 0); 4948 4949 scsi_sense_sbuf(csio, &sb, SSS_FLAG_PRINT_COMMAND); 4950 4951 sbuf_finish(&sb); 4952 4953 printf("%s", sbuf_data(&sb)); 4954 } 4955 4956 #else /* !_KERNEL */ 4957 void 4958 scsi_sense_print(struct cam_device *device, struct ccb_scsiio *csio, 4959 FILE *ofile) 4960 { 4961 struct sbuf sb; 4962 char str[512]; 4963 4964 if ((device == NULL) || (csio == NULL) || (ofile == NULL)) 4965 return; 4966 4967 sbuf_new(&sb, str, sizeof(str), 0); 4968 4969 scsi_sense_sbuf(device, csio, &sb, SSS_FLAG_PRINT_COMMAND); 4970 4971 sbuf_finish(&sb); 4972 4973 fprintf(ofile, "%s", sbuf_data(&sb)); 4974 } 4975 4976 #endif /* _KERNEL/!_KERNEL */ 4977 4978 /* 4979 * Extract basic sense information. This is backward-compatible with the 4980 * previous implementation. For new implementations, 4981 * scsi_extract_sense_len() is recommended. 4982 */ 4983 void 4984 scsi_extract_sense(struct scsi_sense_data *sense_data, int *error_code, 4985 int *sense_key, int *asc, int *ascq) 4986 { 4987 scsi_extract_sense_len(sense_data, sizeof(*sense_data), error_code, 4988 sense_key, asc, ascq, /*show_errors*/ 0); 4989 } 4990 4991 /* 4992 * Extract basic sense information from SCSI I/O CCB structure. 4993 */ 4994 int 4995 scsi_extract_sense_ccb(union ccb *ccb, 4996 int *error_code, int *sense_key, int *asc, int *ascq) 4997 { 4998 struct scsi_sense_data *sense_data; 4999 5000 /* Make sure there are some sense data we can access. */ 5001 if (ccb->ccb_h.func_code != XPT_SCSI_IO || 5002 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR || 5003 (ccb->csio.scsi_status != SCSI_STATUS_CHECK_COND) || 5004 (ccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0 || 5005 (ccb->ccb_h.flags & CAM_SENSE_PHYS)) 5006 return (0); 5007 5008 if (ccb->ccb_h.flags & CAM_SENSE_PTR) 5009 bcopy(&ccb->csio.sense_data, &sense_data, 5010 sizeof(struct scsi_sense_data *)); 5011 else 5012 sense_data = &ccb->csio.sense_data; 5013 scsi_extract_sense_len(sense_data, 5014 ccb->csio.sense_len - ccb->csio.sense_resid, 5015 error_code, sense_key, asc, ascq, 1); 5016 if (*error_code == -1) 5017 return (0); 5018 return (1); 5019 } 5020 5021 /* 5022 * Extract basic sense information. If show_errors is set, sense values 5023 * will be set to -1 if they are not present. 5024 */ 5025 void 5026 scsi_extract_sense_len(struct scsi_sense_data *sense_data, u_int sense_len, 5027 int *error_code, int *sense_key, int *asc, int *ascq, 5028 int show_errors) 5029 { 5030 /* 5031 * If we have no length, we have no sense. 5032 */ 5033 if (sense_len == 0) { 5034 if (show_errors == 0) { 5035 *error_code = 0; 5036 *sense_key = 0; 5037 *asc = 0; 5038 *ascq = 0; 5039 } else { 5040 *error_code = -1; 5041 *sense_key = -1; 5042 *asc = -1; 5043 *ascq = -1; 5044 } 5045 return; 5046 } 5047 5048 *error_code = sense_data->error_code & SSD_ERRCODE; 5049 5050 switch (*error_code) { 5051 case SSD_DESC_CURRENT_ERROR: 5052 case SSD_DESC_DEFERRED_ERROR: { 5053 struct scsi_sense_data_desc *sense; 5054 5055 sense = (struct scsi_sense_data_desc *)sense_data; 5056 5057 if (SSD_DESC_IS_PRESENT(sense, sense_len, sense_key)) 5058 *sense_key = sense->sense_key & SSD_KEY; 5059 else 5060 *sense_key = (show_errors) ? -1 : 0; 5061 5062 if (SSD_DESC_IS_PRESENT(sense, sense_len, add_sense_code)) 5063 *asc = sense->add_sense_code; 5064 else 5065 *asc = (show_errors) ? -1 : 0; 5066 5067 if (SSD_DESC_IS_PRESENT(sense, sense_len, add_sense_code_qual)) 5068 *ascq = sense->add_sense_code_qual; 5069 else 5070 *ascq = (show_errors) ? -1 : 0; 5071 break; 5072 } 5073 case SSD_CURRENT_ERROR: 5074 case SSD_DEFERRED_ERROR: 5075 default: { 5076 struct scsi_sense_data_fixed *sense; 5077 5078 sense = (struct scsi_sense_data_fixed *)sense_data; 5079 5080 if (SSD_FIXED_IS_PRESENT(sense, sense_len, flags)) 5081 *sense_key = sense->flags & SSD_KEY; 5082 else 5083 *sense_key = (show_errors) ? -1 : 0; 5084 5085 if ((SSD_FIXED_IS_PRESENT(sense, sense_len, add_sense_code)) 5086 && (SSD_FIXED_IS_FILLED(sense, add_sense_code))) 5087 *asc = sense->add_sense_code; 5088 else 5089 *asc = (show_errors) ? -1 : 0; 5090 5091 if ((SSD_FIXED_IS_PRESENT(sense, sense_len,add_sense_code_qual)) 5092 && (SSD_FIXED_IS_FILLED(sense, add_sense_code_qual))) 5093 *ascq = sense->add_sense_code_qual; 5094 else 5095 *ascq = (show_errors) ? -1 : 0; 5096 break; 5097 } 5098 } 5099 } 5100 5101 int 5102 scsi_get_sense_key(struct scsi_sense_data *sense_data, u_int sense_len, 5103 int show_errors) 5104 { 5105 int error_code, sense_key, asc, ascq; 5106 5107 scsi_extract_sense_len(sense_data, sense_len, &error_code, 5108 &sense_key, &asc, &ascq, show_errors); 5109 5110 return (sense_key); 5111 } 5112 5113 int 5114 scsi_get_asc(struct scsi_sense_data *sense_data, u_int sense_len, 5115 int show_errors) 5116 { 5117 int error_code, sense_key, asc, ascq; 5118 5119 scsi_extract_sense_len(sense_data, sense_len, &error_code, 5120 &sense_key, &asc, &ascq, show_errors); 5121 5122 return (asc); 5123 } 5124 5125 int 5126 scsi_get_ascq(struct scsi_sense_data *sense_data, u_int sense_len, 5127 int show_errors) 5128 { 5129 int error_code, sense_key, asc, ascq; 5130 5131 scsi_extract_sense_len(sense_data, sense_len, &error_code, 5132 &sense_key, &asc, &ascq, show_errors); 5133 5134 return (ascq); 5135 } 5136 5137 /* 5138 * This function currently requires at least 36 bytes, or 5139 * SHORT_INQUIRY_LENGTH, worth of data to function properly. If this 5140 * function needs more or less data in the future, another length should be 5141 * defined in scsi_all.h to indicate the minimum amount of data necessary 5142 * for this routine to function properly. 5143 */ 5144 void 5145 scsi_print_inquiry(struct scsi_inquiry_data *inq_data) 5146 { 5147 u_int8_t type; 5148 char *dtype, *qtype; 5149 char vendor[16], product[48], revision[16], rstr[4]; 5150 5151 type = SID_TYPE(inq_data); 5152 5153 /* 5154 * Figure out basic device type and qualifier. 5155 */ 5156 if (SID_QUAL_IS_VENDOR_UNIQUE(inq_data)) { 5157 qtype = "(vendor-unique qualifier)"; 5158 } else { 5159 switch (SID_QUAL(inq_data)) { 5160 case SID_QUAL_LU_CONNECTED: 5161 qtype = ""; 5162 break; 5163 5164 case SID_QUAL_LU_OFFLINE: 5165 qtype = "(offline)"; 5166 break; 5167 5168 case SID_QUAL_RSVD: 5169 qtype = "(reserved qualifier)"; 5170 break; 5171 default: 5172 case SID_QUAL_BAD_LU: 5173 qtype = "(LUN not supported)"; 5174 break; 5175 } 5176 } 5177 5178 switch (type) { 5179 case T_DIRECT: 5180 dtype = "Direct Access"; 5181 break; 5182 case T_SEQUENTIAL: 5183 dtype = "Sequential Access"; 5184 break; 5185 case T_PRINTER: 5186 dtype = "Printer"; 5187 break; 5188 case T_PROCESSOR: 5189 dtype = "Processor"; 5190 break; 5191 case T_WORM: 5192 dtype = "WORM"; 5193 break; 5194 case T_CDROM: 5195 dtype = "CD-ROM"; 5196 break; 5197 case T_SCANNER: 5198 dtype = "Scanner"; 5199 break; 5200 case T_OPTICAL: 5201 dtype = "Optical"; 5202 break; 5203 case T_CHANGER: 5204 dtype = "Changer"; 5205 break; 5206 case T_COMM: 5207 dtype = "Communication"; 5208 break; 5209 case T_STORARRAY: 5210 dtype = "Storage Array"; 5211 break; 5212 case T_ENCLOSURE: 5213 dtype = "Enclosure Services"; 5214 break; 5215 case T_RBC: 5216 dtype = "Simplified Direct Access"; 5217 break; 5218 case T_OCRW: 5219 dtype = "Optical Card Read/Write"; 5220 break; 5221 case T_OSD: 5222 dtype = "Object-Based Storage"; 5223 break; 5224 case T_ADC: 5225 dtype = "Automation/Drive Interface"; 5226 break; 5227 case T_NODEVICE: 5228 dtype = "Uninstalled"; 5229 break; 5230 default: 5231 dtype = "unknown"; 5232 break; 5233 } 5234 5235 cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor), 5236 sizeof(vendor)); 5237 cam_strvis(product, inq_data->product, sizeof(inq_data->product), 5238 sizeof(product)); 5239 cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision), 5240 sizeof(revision)); 5241 5242 if (SID_ANSI_REV(inq_data) == SCSI_REV_CCS) 5243 bcopy("CCS", rstr, 4); 5244 else 5245 snprintf(rstr, sizeof (rstr), "%d", SID_ANSI_REV(inq_data)); 5246 printf("<%s %s %s> %s %s SCSI-%s device %s\n", 5247 vendor, product, revision, 5248 SID_IS_REMOVABLE(inq_data) ? "Removable" : "Fixed", 5249 dtype, rstr, qtype); 5250 } 5251 5252 /* 5253 * Table of syncrates that don't follow the "divisible by 4" 5254 * rule. This table will be expanded in future SCSI specs. 5255 */ 5256 static struct { 5257 u_int period_factor; 5258 u_int period; /* in 100ths of ns */ 5259 } scsi_syncrates[] = { 5260 { 0x08, 625 }, /* FAST-160 */ 5261 { 0x09, 1250 }, /* FAST-80 */ 5262 { 0x0a, 2500 }, /* FAST-40 40MHz */ 5263 { 0x0b, 3030 }, /* FAST-40 33MHz */ 5264 { 0x0c, 5000 } /* FAST-20 */ 5265 }; 5266 5267 /* 5268 * Return the frequency in kHz corresponding to the given 5269 * sync period factor. 5270 */ 5271 u_int 5272 scsi_calc_syncsrate(u_int period_factor) 5273 { 5274 int i; 5275 int num_syncrates; 5276 5277 /* 5278 * It's a bug if period is zero, but if it is anyway, don't 5279 * die with a divide fault- instead return something which 5280 * 'approximates' async 5281 */ 5282 if (period_factor == 0) { 5283 return (3300); 5284 } 5285 5286 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); 5287 /* See if the period is in the "exception" table */ 5288 for (i = 0; i < num_syncrates; i++) { 5289 5290 if (period_factor == scsi_syncrates[i].period_factor) { 5291 /* Period in kHz */ 5292 return (100000000 / scsi_syncrates[i].period); 5293 } 5294 } 5295 5296 /* 5297 * Wasn't in the table, so use the standard 5298 * 4 times conversion. 5299 */ 5300 return (10000000 / (period_factor * 4 * 10)); 5301 } 5302 5303 /* 5304 * Return the SCSI sync parameter that corresponsd to 5305 * the passed in period in 10ths of ns. 5306 */ 5307 u_int 5308 scsi_calc_syncparam(u_int period) 5309 { 5310 int i; 5311 int num_syncrates; 5312 5313 if (period == 0) 5314 return (~0); /* Async */ 5315 5316 /* Adjust for exception table being in 100ths. */ 5317 period *= 10; 5318 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); 5319 /* See if the period is in the "exception" table */ 5320 for (i = 0; i < num_syncrates; i++) { 5321 5322 if (period <= scsi_syncrates[i].period) { 5323 /* Period in 100ths of ns */ 5324 return (scsi_syncrates[i].period_factor); 5325 } 5326 } 5327 5328 /* 5329 * Wasn't in the table, so use the standard 5330 * 1/4 period in ns conversion. 5331 */ 5332 return (period/400); 5333 } 5334 5335 int 5336 scsi_devid_is_naa_ieee_reg(uint8_t *bufp) 5337 { 5338 struct scsi_vpd_id_descriptor *descr; 5339 struct scsi_vpd_id_naa_basic *naa; 5340 5341 descr = (struct scsi_vpd_id_descriptor *)bufp; 5342 naa = (struct scsi_vpd_id_naa_basic *)descr->identifier; 5343 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_NAA) 5344 return 0; 5345 if (descr->length < sizeof(struct scsi_vpd_id_naa_ieee_reg)) 5346 return 0; 5347 if ((naa->naa >> SVPD_ID_NAA_NAA_SHIFT) != SVPD_ID_NAA_IEEE_REG) 5348 return 0; 5349 return 1; 5350 } 5351 5352 int 5353 scsi_devid_is_sas_target(uint8_t *bufp) 5354 { 5355 struct scsi_vpd_id_descriptor *descr; 5356 5357 descr = (struct scsi_vpd_id_descriptor *)bufp; 5358 if (!scsi_devid_is_naa_ieee_reg(bufp)) 5359 return 0; 5360 if ((descr->id_type & SVPD_ID_PIV) == 0) /* proto field reserved */ 5361 return 0; 5362 if ((descr->proto_codeset >> SVPD_ID_PROTO_SHIFT) != SCSI_PROTO_SAS) 5363 return 0; 5364 return 1; 5365 } 5366 5367 int 5368 scsi_devid_is_lun_eui64(uint8_t *bufp) 5369 { 5370 struct scsi_vpd_id_descriptor *descr; 5371 5372 descr = (struct scsi_vpd_id_descriptor *)bufp; 5373 if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN) 5374 return 0; 5375 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_EUI64) 5376 return 0; 5377 return 1; 5378 } 5379 5380 int 5381 scsi_devid_is_lun_naa(uint8_t *bufp) 5382 { 5383 struct scsi_vpd_id_descriptor *descr; 5384 5385 descr = (struct scsi_vpd_id_descriptor *)bufp; 5386 if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN) 5387 return 0; 5388 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_NAA) 5389 return 0; 5390 return 1; 5391 } 5392 5393 int 5394 scsi_devid_is_lun_t10(uint8_t *bufp) 5395 { 5396 struct scsi_vpd_id_descriptor *descr; 5397 5398 descr = (struct scsi_vpd_id_descriptor *)bufp; 5399 if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN) 5400 return 0; 5401 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_T10) 5402 return 0; 5403 return 1; 5404 } 5405 5406 int 5407 scsi_devid_is_lun_name(uint8_t *bufp) 5408 { 5409 struct scsi_vpd_id_descriptor *descr; 5410 5411 descr = (struct scsi_vpd_id_descriptor *)bufp; 5412 if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN) 5413 return 0; 5414 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_SCSI_NAME) 5415 return 0; 5416 return 1; 5417 } 5418 5419 struct scsi_vpd_id_descriptor * 5420 scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t page_len, 5421 scsi_devid_checkfn_t ck_fn) 5422 { 5423 struct scsi_vpd_id_descriptor *desc; 5424 uint8_t *page_end; 5425 uint8_t *desc_buf_end; 5426 5427 page_end = (uint8_t *)id + page_len; 5428 if (page_end < id->desc_list) 5429 return (NULL); 5430 5431 desc_buf_end = MIN(id->desc_list + scsi_2btoul(id->length), page_end); 5432 5433 for (desc = (struct scsi_vpd_id_descriptor *)id->desc_list; 5434 desc->identifier <= desc_buf_end 5435 && desc->identifier + desc->length <= desc_buf_end; 5436 desc = (struct scsi_vpd_id_descriptor *)(desc->identifier 5437 + desc->length)) { 5438 5439 if (ck_fn == NULL || ck_fn((uint8_t *)desc) != 0) 5440 return (desc); 5441 } 5442 5443 return (NULL); 5444 } 5445 5446 void 5447 scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries, 5448 void (*cbfcnp)(struct cam_periph *, union ccb *), 5449 u_int8_t tag_action, u_int8_t sense_len, u_int32_t timeout) 5450 { 5451 struct scsi_test_unit_ready *scsi_cmd; 5452 5453 cam_fill_csio(csio, 5454 retries, 5455 cbfcnp, 5456 CAM_DIR_NONE, 5457 tag_action, 5458 /*data_ptr*/NULL, 5459 /*dxfer_len*/0, 5460 sense_len, 5461 sizeof(*scsi_cmd), 5462 timeout); 5463 5464 scsi_cmd = (struct scsi_test_unit_ready *)&csio->cdb_io.cdb_bytes; 5465 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5466 scsi_cmd->opcode = TEST_UNIT_READY; 5467 } 5468 5469 void 5470 scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries, 5471 void (*cbfcnp)(struct cam_periph *, union ccb *), 5472 void *data_ptr, u_int8_t dxfer_len, u_int8_t tag_action, 5473 u_int8_t sense_len, u_int32_t timeout) 5474 { 5475 struct scsi_request_sense *scsi_cmd; 5476 5477 cam_fill_csio(csio, 5478 retries, 5479 cbfcnp, 5480 CAM_DIR_IN, 5481 tag_action, 5482 data_ptr, 5483 dxfer_len, 5484 sense_len, 5485 sizeof(*scsi_cmd), 5486 timeout); 5487 5488 scsi_cmd = (struct scsi_request_sense *)&csio->cdb_io.cdb_bytes; 5489 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5490 scsi_cmd->opcode = REQUEST_SENSE; 5491 scsi_cmd->length = dxfer_len; 5492 } 5493 5494 void 5495 scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries, 5496 void (*cbfcnp)(struct cam_periph *, union ccb *), 5497 u_int8_t tag_action, u_int8_t *inq_buf, u_int32_t inq_len, 5498 int evpd, u_int8_t page_code, u_int8_t sense_len, 5499 u_int32_t timeout) 5500 { 5501 struct scsi_inquiry *scsi_cmd; 5502 5503 cam_fill_csio(csio, 5504 retries, 5505 cbfcnp, 5506 /*flags*/CAM_DIR_IN, 5507 tag_action, 5508 /*data_ptr*/inq_buf, 5509 /*dxfer_len*/inq_len, 5510 sense_len, 5511 sizeof(*scsi_cmd), 5512 timeout); 5513 5514 scsi_cmd = (struct scsi_inquiry *)&csio->cdb_io.cdb_bytes; 5515 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5516 scsi_cmd->opcode = INQUIRY; 5517 if (evpd) { 5518 scsi_cmd->byte2 |= SI_EVPD; 5519 scsi_cmd->page_code = page_code; 5520 } 5521 scsi_ulto2b(inq_len, scsi_cmd->length); 5522 } 5523 5524 void 5525 scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries, 5526 void (*cbfcnp)(struct cam_periph *, union ccb *), 5527 u_int8_t tag_action, int dbd, u_int8_t page_code, 5528 u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, 5529 u_int8_t sense_len, u_int32_t timeout) 5530 { 5531 5532 scsi_mode_sense_len(csio, retries, cbfcnp, tag_action, dbd, 5533 page_code, page, param_buf, param_len, 0, 5534 sense_len, timeout); 5535 } 5536 5537 void 5538 scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, 5539 void (*cbfcnp)(struct cam_periph *, union ccb *), 5540 u_int8_t tag_action, int dbd, u_int8_t page_code, 5541 u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, 5542 int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout) 5543 { 5544 u_int8_t cdb_len; 5545 5546 /* 5547 * Use the smallest possible command to perform the operation. 5548 */ 5549 if ((param_len < 256) 5550 && (minimum_cmd_size < 10)) { 5551 /* 5552 * We can fit in a 6 byte cdb. 5553 */ 5554 struct scsi_mode_sense_6 *scsi_cmd; 5555 5556 scsi_cmd = (struct scsi_mode_sense_6 *)&csio->cdb_io.cdb_bytes; 5557 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5558 scsi_cmd->opcode = MODE_SENSE_6; 5559 if (dbd != 0) 5560 scsi_cmd->byte2 |= SMS_DBD; 5561 scsi_cmd->page = page_code | page; 5562 scsi_cmd->length = param_len; 5563 cdb_len = sizeof(*scsi_cmd); 5564 } else { 5565 /* 5566 * Need a 10 byte cdb. 5567 */ 5568 struct scsi_mode_sense_10 *scsi_cmd; 5569 5570 scsi_cmd = (struct scsi_mode_sense_10 *)&csio->cdb_io.cdb_bytes; 5571 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5572 scsi_cmd->opcode = MODE_SENSE_10; 5573 if (dbd != 0) 5574 scsi_cmd->byte2 |= SMS_DBD; 5575 scsi_cmd->page = page_code | page; 5576 scsi_ulto2b(param_len, scsi_cmd->length); 5577 cdb_len = sizeof(*scsi_cmd); 5578 } 5579 cam_fill_csio(csio, 5580 retries, 5581 cbfcnp, 5582 CAM_DIR_IN, 5583 tag_action, 5584 param_buf, 5585 param_len, 5586 sense_len, 5587 cdb_len, 5588 timeout); 5589 } 5590 5591 void 5592 scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, 5593 void (*cbfcnp)(struct cam_periph *, union ccb *), 5594 u_int8_t tag_action, int scsi_page_fmt, int save_pages, 5595 u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, 5596 u_int32_t timeout) 5597 { 5598 scsi_mode_select_len(csio, retries, cbfcnp, tag_action, 5599 scsi_page_fmt, save_pages, param_buf, 5600 param_len, 0, sense_len, timeout); 5601 } 5602 5603 void 5604 scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries, 5605 void (*cbfcnp)(struct cam_periph *, union ccb *), 5606 u_int8_t tag_action, int scsi_page_fmt, int save_pages, 5607 u_int8_t *param_buf, u_int32_t param_len, 5608 int minimum_cmd_size, u_int8_t sense_len, 5609 u_int32_t timeout) 5610 { 5611 u_int8_t cdb_len; 5612 5613 /* 5614 * Use the smallest possible command to perform the operation. 5615 */ 5616 if ((param_len < 256) 5617 && (minimum_cmd_size < 10)) { 5618 /* 5619 * We can fit in a 6 byte cdb. 5620 */ 5621 struct scsi_mode_select_6 *scsi_cmd; 5622 5623 scsi_cmd = (struct scsi_mode_select_6 *)&csio->cdb_io.cdb_bytes; 5624 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5625 scsi_cmd->opcode = MODE_SELECT_6; 5626 if (scsi_page_fmt != 0) 5627 scsi_cmd->byte2 |= SMS_PF; 5628 if (save_pages != 0) 5629 scsi_cmd->byte2 |= SMS_SP; 5630 scsi_cmd->length = param_len; 5631 cdb_len = sizeof(*scsi_cmd); 5632 } else { 5633 /* 5634 * Need a 10 byte cdb. 5635 */ 5636 struct scsi_mode_select_10 *scsi_cmd; 5637 5638 scsi_cmd = 5639 (struct scsi_mode_select_10 *)&csio->cdb_io.cdb_bytes; 5640 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5641 scsi_cmd->opcode = MODE_SELECT_10; 5642 if (scsi_page_fmt != 0) 5643 scsi_cmd->byte2 |= SMS_PF; 5644 if (save_pages != 0) 5645 scsi_cmd->byte2 |= SMS_SP; 5646 scsi_ulto2b(param_len, scsi_cmd->length); 5647 cdb_len = sizeof(*scsi_cmd); 5648 } 5649 cam_fill_csio(csio, 5650 retries, 5651 cbfcnp, 5652 CAM_DIR_OUT, 5653 tag_action, 5654 param_buf, 5655 param_len, 5656 sense_len, 5657 cdb_len, 5658 timeout); 5659 } 5660 5661 void 5662 scsi_log_sense(struct ccb_scsiio *csio, u_int32_t retries, 5663 void (*cbfcnp)(struct cam_periph *, union ccb *), 5664 u_int8_t tag_action, u_int8_t page_code, u_int8_t page, 5665 int save_pages, int ppc, u_int32_t paramptr, 5666 u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, 5667 u_int32_t timeout) 5668 { 5669 struct scsi_log_sense *scsi_cmd; 5670 u_int8_t cdb_len; 5671 5672 scsi_cmd = (struct scsi_log_sense *)&csio->cdb_io.cdb_bytes; 5673 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5674 scsi_cmd->opcode = LOG_SENSE; 5675 scsi_cmd->page = page_code | page; 5676 if (save_pages != 0) 5677 scsi_cmd->byte2 |= SLS_SP; 5678 if (ppc != 0) 5679 scsi_cmd->byte2 |= SLS_PPC; 5680 scsi_ulto2b(paramptr, scsi_cmd->paramptr); 5681 scsi_ulto2b(param_len, scsi_cmd->length); 5682 cdb_len = sizeof(*scsi_cmd); 5683 5684 cam_fill_csio(csio, 5685 retries, 5686 cbfcnp, 5687 /*flags*/CAM_DIR_IN, 5688 tag_action, 5689 /*data_ptr*/param_buf, 5690 /*dxfer_len*/param_len, 5691 sense_len, 5692 cdb_len, 5693 timeout); 5694 } 5695 5696 void 5697 scsi_log_select(struct ccb_scsiio *csio, u_int32_t retries, 5698 void (*cbfcnp)(struct cam_periph *, union ccb *), 5699 u_int8_t tag_action, u_int8_t page_code, int save_pages, 5700 int pc_reset, u_int8_t *param_buf, u_int32_t param_len, 5701 u_int8_t sense_len, u_int32_t timeout) 5702 { 5703 struct scsi_log_select *scsi_cmd; 5704 u_int8_t cdb_len; 5705 5706 scsi_cmd = (struct scsi_log_select *)&csio->cdb_io.cdb_bytes; 5707 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5708 scsi_cmd->opcode = LOG_SELECT; 5709 scsi_cmd->page = page_code & SLS_PAGE_CODE; 5710 if (save_pages != 0) 5711 scsi_cmd->byte2 |= SLS_SP; 5712 if (pc_reset != 0) 5713 scsi_cmd->byte2 |= SLS_PCR; 5714 scsi_ulto2b(param_len, scsi_cmd->length); 5715 cdb_len = sizeof(*scsi_cmd); 5716 5717 cam_fill_csio(csio, 5718 retries, 5719 cbfcnp, 5720 /*flags*/CAM_DIR_OUT, 5721 tag_action, 5722 /*data_ptr*/param_buf, 5723 /*dxfer_len*/param_len, 5724 sense_len, 5725 cdb_len, 5726 timeout); 5727 } 5728 5729 /* 5730 * Prevent or allow the user to remove the media 5731 */ 5732 void 5733 scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries, 5734 void (*cbfcnp)(struct cam_periph *, union ccb *), 5735 u_int8_t tag_action, u_int8_t action, 5736 u_int8_t sense_len, u_int32_t timeout) 5737 { 5738 struct scsi_prevent *scsi_cmd; 5739 5740 cam_fill_csio(csio, 5741 retries, 5742 cbfcnp, 5743 /*flags*/CAM_DIR_NONE, 5744 tag_action, 5745 /*data_ptr*/NULL, 5746 /*dxfer_len*/0, 5747 sense_len, 5748 sizeof(*scsi_cmd), 5749 timeout); 5750 5751 scsi_cmd = (struct scsi_prevent *)&csio->cdb_io.cdb_bytes; 5752 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5753 scsi_cmd->opcode = PREVENT_ALLOW; 5754 scsi_cmd->how = action; 5755 } 5756 5757 /* XXX allow specification of address and PMI bit and LBA */ 5758 void 5759 scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries, 5760 void (*cbfcnp)(struct cam_periph *, union ccb *), 5761 u_int8_t tag_action, 5762 struct scsi_read_capacity_data *rcap_buf, 5763 u_int8_t sense_len, u_int32_t timeout) 5764 { 5765 struct scsi_read_capacity *scsi_cmd; 5766 5767 cam_fill_csio(csio, 5768 retries, 5769 cbfcnp, 5770 /*flags*/CAM_DIR_IN, 5771 tag_action, 5772 /*data_ptr*/(u_int8_t *)rcap_buf, 5773 /*dxfer_len*/sizeof(*rcap_buf), 5774 sense_len, 5775 sizeof(*scsi_cmd), 5776 timeout); 5777 5778 scsi_cmd = (struct scsi_read_capacity *)&csio->cdb_io.cdb_bytes; 5779 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5780 scsi_cmd->opcode = READ_CAPACITY; 5781 } 5782 5783 void 5784 scsi_read_capacity_16(struct ccb_scsiio *csio, uint32_t retries, 5785 void (*cbfcnp)(struct cam_periph *, union ccb *), 5786 uint8_t tag_action, uint64_t lba, int reladr, int pmi, 5787 uint8_t *rcap_buf, int rcap_buf_len, uint8_t sense_len, 5788 uint32_t timeout) 5789 { 5790 struct scsi_read_capacity_16 *scsi_cmd; 5791 5792 5793 cam_fill_csio(csio, 5794 retries, 5795 cbfcnp, 5796 /*flags*/CAM_DIR_IN, 5797 tag_action, 5798 /*data_ptr*/(u_int8_t *)rcap_buf, 5799 /*dxfer_len*/rcap_buf_len, 5800 sense_len, 5801 sizeof(*scsi_cmd), 5802 timeout); 5803 scsi_cmd = (struct scsi_read_capacity_16 *)&csio->cdb_io.cdb_bytes; 5804 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5805 scsi_cmd->opcode = SERVICE_ACTION_IN; 5806 scsi_cmd->service_action = SRC16_SERVICE_ACTION; 5807 scsi_u64to8b(lba, scsi_cmd->addr); 5808 scsi_ulto4b(rcap_buf_len, scsi_cmd->alloc_len); 5809 if (pmi) 5810 reladr |= SRC16_PMI; 5811 if (reladr) 5812 reladr |= SRC16_RELADR; 5813 } 5814 5815 void 5816 scsi_report_luns(struct ccb_scsiio *csio, u_int32_t retries, 5817 void (*cbfcnp)(struct cam_periph *, union ccb *), 5818 u_int8_t tag_action, u_int8_t select_report, 5819 struct scsi_report_luns_data *rpl_buf, u_int32_t alloc_len, 5820 u_int8_t sense_len, u_int32_t timeout) 5821 { 5822 struct scsi_report_luns *scsi_cmd; 5823 5824 cam_fill_csio(csio, 5825 retries, 5826 cbfcnp, 5827 /*flags*/CAM_DIR_IN, 5828 tag_action, 5829 /*data_ptr*/(u_int8_t *)rpl_buf, 5830 /*dxfer_len*/alloc_len, 5831 sense_len, 5832 sizeof(*scsi_cmd), 5833 timeout); 5834 scsi_cmd = (struct scsi_report_luns *)&csio->cdb_io.cdb_bytes; 5835 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5836 scsi_cmd->opcode = REPORT_LUNS; 5837 scsi_cmd->select_report = select_report; 5838 scsi_ulto4b(alloc_len, scsi_cmd->length); 5839 } 5840 5841 void 5842 scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries, 5843 void (*cbfcnp)(struct cam_periph *, union ccb *), 5844 u_int8_t tag_action, u_int8_t pdf, 5845 void *buf, u_int32_t alloc_len, 5846 u_int8_t sense_len, u_int32_t timeout) 5847 { 5848 struct scsi_target_group *scsi_cmd; 5849 5850 cam_fill_csio(csio, 5851 retries, 5852 cbfcnp, 5853 /*flags*/CAM_DIR_IN, 5854 tag_action, 5855 /*data_ptr*/(u_int8_t *)buf, 5856 /*dxfer_len*/alloc_len, 5857 sense_len, 5858 sizeof(*scsi_cmd), 5859 timeout); 5860 scsi_cmd = (struct scsi_target_group *)&csio->cdb_io.cdb_bytes; 5861 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5862 scsi_cmd->opcode = MAINTENANCE_IN; 5863 scsi_cmd->service_action = REPORT_TARGET_PORT_GROUPS | pdf; 5864 scsi_ulto4b(alloc_len, scsi_cmd->length); 5865 } 5866 5867 void 5868 scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries, 5869 void (*cbfcnp)(struct cam_periph *, union ccb *), 5870 u_int8_t tag_action, void *buf, u_int32_t alloc_len, 5871 u_int8_t sense_len, u_int32_t timeout) 5872 { 5873 struct scsi_target_group *scsi_cmd; 5874 5875 cam_fill_csio(csio, 5876 retries, 5877 cbfcnp, 5878 /*flags*/CAM_DIR_OUT, 5879 tag_action, 5880 /*data_ptr*/(u_int8_t *)buf, 5881 /*dxfer_len*/alloc_len, 5882 sense_len, 5883 sizeof(*scsi_cmd), 5884 timeout); 5885 scsi_cmd = (struct scsi_target_group *)&csio->cdb_io.cdb_bytes; 5886 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5887 scsi_cmd->opcode = MAINTENANCE_OUT; 5888 scsi_cmd->service_action = SET_TARGET_PORT_GROUPS; 5889 scsi_ulto4b(alloc_len, scsi_cmd->length); 5890 } 5891 5892 /* 5893 * Syncronize the media to the contents of the cache for 5894 * the given lba/count pair. Specifying 0/0 means sync 5895 * the whole cache. 5896 */ 5897 void 5898 scsi_synchronize_cache(struct ccb_scsiio *csio, u_int32_t retries, 5899 void (*cbfcnp)(struct cam_periph *, union ccb *), 5900 u_int8_t tag_action, u_int32_t begin_lba, 5901 u_int16_t lb_count, u_int8_t sense_len, 5902 u_int32_t timeout) 5903 { 5904 struct scsi_sync_cache *scsi_cmd; 5905 5906 cam_fill_csio(csio, 5907 retries, 5908 cbfcnp, 5909 /*flags*/CAM_DIR_NONE, 5910 tag_action, 5911 /*data_ptr*/NULL, 5912 /*dxfer_len*/0, 5913 sense_len, 5914 sizeof(*scsi_cmd), 5915 timeout); 5916 5917 scsi_cmd = (struct scsi_sync_cache *)&csio->cdb_io.cdb_bytes; 5918 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5919 scsi_cmd->opcode = SYNCHRONIZE_CACHE; 5920 scsi_ulto4b(begin_lba, scsi_cmd->begin_lba); 5921 scsi_ulto2b(lb_count, scsi_cmd->lb_count); 5922 } 5923 5924 void 5925 scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries, 5926 void (*cbfcnp)(struct cam_periph *, union ccb *), 5927 u_int8_t tag_action, int readop, u_int8_t byte2, 5928 int minimum_cmd_size, u_int64_t lba, u_int32_t block_count, 5929 u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, 5930 u_int32_t timeout) 5931 { 5932 int read; 5933 u_int8_t cdb_len; 5934 5935 read = (readop & SCSI_RW_DIRMASK) == SCSI_RW_READ; 5936 5937 /* 5938 * Use the smallest possible command to perform the operation 5939 * as some legacy hardware does not support the 10 byte commands. 5940 * If any of the bits in byte2 is set, we have to go with a larger 5941 * command. 5942 */ 5943 if ((minimum_cmd_size < 10) 5944 && ((lba & 0x1fffff) == lba) 5945 && ((block_count & 0xff) == block_count) 5946 && (byte2 == 0)) { 5947 /* 5948 * We can fit in a 6 byte cdb. 5949 */ 5950 struct scsi_rw_6 *scsi_cmd; 5951 5952 scsi_cmd = (struct scsi_rw_6 *)&csio->cdb_io.cdb_bytes; 5953 scsi_cmd->opcode = read ? READ_6 : WRITE_6; 5954 scsi_ulto3b(lba, scsi_cmd->addr); 5955 scsi_cmd->length = block_count & 0xff; 5956 scsi_cmd->control = 0; 5957 cdb_len = sizeof(*scsi_cmd); 5958 5959 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 5960 ("6byte: %x%x%x:%d:%d\n", scsi_cmd->addr[0], 5961 scsi_cmd->addr[1], scsi_cmd->addr[2], 5962 scsi_cmd->length, dxfer_len)); 5963 } else if ((minimum_cmd_size < 12) 5964 && ((block_count & 0xffff) == block_count) 5965 && ((lba & 0xffffffff) == lba)) { 5966 /* 5967 * Need a 10 byte cdb. 5968 */ 5969 struct scsi_rw_10 *scsi_cmd; 5970 5971 scsi_cmd = (struct scsi_rw_10 *)&csio->cdb_io.cdb_bytes; 5972 scsi_cmd->opcode = read ? READ_10 : WRITE_10; 5973 scsi_cmd->byte2 = byte2; 5974 scsi_ulto4b(lba, scsi_cmd->addr); 5975 scsi_cmd->reserved = 0; 5976 scsi_ulto2b(block_count, scsi_cmd->length); 5977 scsi_cmd->control = 0; 5978 cdb_len = sizeof(*scsi_cmd); 5979 5980 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 5981 ("10byte: %x%x%x%x:%x%x: %d\n", scsi_cmd->addr[0], 5982 scsi_cmd->addr[1], scsi_cmd->addr[2], 5983 scsi_cmd->addr[3], scsi_cmd->length[0], 5984 scsi_cmd->length[1], dxfer_len)); 5985 } else if ((minimum_cmd_size < 16) 5986 && ((block_count & 0xffffffff) == block_count) 5987 && ((lba & 0xffffffff) == lba)) { 5988 /* 5989 * The block count is too big for a 10 byte CDB, use a 12 5990 * byte CDB. 5991 */ 5992 struct scsi_rw_12 *scsi_cmd; 5993 5994 scsi_cmd = (struct scsi_rw_12 *)&csio->cdb_io.cdb_bytes; 5995 scsi_cmd->opcode = read ? READ_12 : WRITE_12; 5996 scsi_cmd->byte2 = byte2; 5997 scsi_ulto4b(lba, scsi_cmd->addr); 5998 scsi_cmd->reserved = 0; 5999 scsi_ulto4b(block_count, scsi_cmd->length); 6000 scsi_cmd->control = 0; 6001 cdb_len = sizeof(*scsi_cmd); 6002 6003 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 6004 ("12byte: %x%x%x%x:%x%x%x%x: %d\n", scsi_cmd->addr[0], 6005 scsi_cmd->addr[1], scsi_cmd->addr[2], 6006 scsi_cmd->addr[3], scsi_cmd->length[0], 6007 scsi_cmd->length[1], scsi_cmd->length[2], 6008 scsi_cmd->length[3], dxfer_len)); 6009 } else { 6010 /* 6011 * 16 byte CDB. We'll only get here if the LBA is larger 6012 * than 2^32, or if the user asks for a 16 byte command. 6013 */ 6014 struct scsi_rw_16 *scsi_cmd; 6015 6016 scsi_cmd = (struct scsi_rw_16 *)&csio->cdb_io.cdb_bytes; 6017 scsi_cmd->opcode = read ? READ_16 : WRITE_16; 6018 scsi_cmd->byte2 = byte2; 6019 scsi_u64to8b(lba, scsi_cmd->addr); 6020 scsi_cmd->reserved = 0; 6021 scsi_ulto4b(block_count, scsi_cmd->length); 6022 scsi_cmd->control = 0; 6023 cdb_len = sizeof(*scsi_cmd); 6024 } 6025 cam_fill_csio(csio, 6026 retries, 6027 cbfcnp, 6028 (read ? CAM_DIR_IN : CAM_DIR_OUT) | 6029 ((readop & SCSI_RW_BIO) != 0 ? CAM_DATA_BIO : 0), 6030 tag_action, 6031 data_ptr, 6032 dxfer_len, 6033 sense_len, 6034 cdb_len, 6035 timeout); 6036 } 6037 6038 void 6039 scsi_write_same(struct ccb_scsiio *csio, u_int32_t retries, 6040 void (*cbfcnp)(struct cam_periph *, union ccb *), 6041 u_int8_t tag_action, u_int8_t byte2, 6042 int minimum_cmd_size, u_int64_t lba, u_int32_t block_count, 6043 u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, 6044 u_int32_t timeout) 6045 { 6046 u_int8_t cdb_len; 6047 if ((minimum_cmd_size < 16) && 6048 ((block_count & 0xffff) == block_count) && 6049 ((lba & 0xffffffff) == lba)) { 6050 /* 6051 * Need a 10 byte cdb. 6052 */ 6053 struct scsi_write_same_10 *scsi_cmd; 6054 6055 scsi_cmd = (struct scsi_write_same_10 *)&csio->cdb_io.cdb_bytes; 6056 scsi_cmd->opcode = WRITE_SAME_10; 6057 scsi_cmd->byte2 = byte2; 6058 scsi_ulto4b(lba, scsi_cmd->addr); 6059 scsi_cmd->group = 0; 6060 scsi_ulto2b(block_count, scsi_cmd->length); 6061 scsi_cmd->control = 0; 6062 cdb_len = sizeof(*scsi_cmd); 6063 6064 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 6065 ("10byte: %x%x%x%x:%x%x: %d\n", scsi_cmd->addr[0], 6066 scsi_cmd->addr[1], scsi_cmd->addr[2], 6067 scsi_cmd->addr[3], scsi_cmd->length[0], 6068 scsi_cmd->length[1], dxfer_len)); 6069 } else { 6070 /* 6071 * 16 byte CDB. We'll only get here if the LBA is larger 6072 * than 2^32, or if the user asks for a 16 byte command. 6073 */ 6074 struct scsi_write_same_16 *scsi_cmd; 6075 6076 scsi_cmd = (struct scsi_write_same_16 *)&csio->cdb_io.cdb_bytes; 6077 scsi_cmd->opcode = WRITE_SAME_16; 6078 scsi_cmd->byte2 = byte2; 6079 scsi_u64to8b(lba, scsi_cmd->addr); 6080 scsi_ulto4b(block_count, scsi_cmd->length); 6081 scsi_cmd->group = 0; 6082 scsi_cmd->control = 0; 6083 cdb_len = sizeof(*scsi_cmd); 6084 6085 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 6086 ("16byte: %x%x%x%x%x%x%x%x:%x%x%x%x: %d\n", 6087 scsi_cmd->addr[0], scsi_cmd->addr[1], 6088 scsi_cmd->addr[2], scsi_cmd->addr[3], 6089 scsi_cmd->addr[4], scsi_cmd->addr[5], 6090 scsi_cmd->addr[6], scsi_cmd->addr[7], 6091 scsi_cmd->length[0], scsi_cmd->length[1], 6092 scsi_cmd->length[2], scsi_cmd->length[3], 6093 dxfer_len)); 6094 } 6095 cam_fill_csio(csio, 6096 retries, 6097 cbfcnp, 6098 /*flags*/CAM_DIR_OUT, 6099 tag_action, 6100 data_ptr, 6101 dxfer_len, 6102 sense_len, 6103 cdb_len, 6104 timeout); 6105 } 6106 6107 void 6108 scsi_ata_identify(struct ccb_scsiio *csio, u_int32_t retries, 6109 void (*cbfcnp)(struct cam_periph *, union ccb *), 6110 u_int8_t tag_action, u_int8_t *data_ptr, 6111 u_int16_t dxfer_len, u_int8_t sense_len, 6112 u_int32_t timeout) 6113 { 6114 scsi_ata_pass_16(csio, 6115 retries, 6116 cbfcnp, 6117 /*flags*/CAM_DIR_IN, 6118 tag_action, 6119 /*protocol*/AP_PROTO_PIO_IN, 6120 /*ata_flags*/AP_FLAG_TDIR_FROM_DEV| 6121 AP_FLAG_BYT_BLOK_BYTES|AP_FLAG_TLEN_SECT_CNT, 6122 /*features*/0, 6123 /*sector_count*/dxfer_len, 6124 /*lba*/0, 6125 /*command*/ATA_ATA_IDENTIFY, 6126 /*control*/0, 6127 data_ptr, 6128 dxfer_len, 6129 sense_len, 6130 timeout); 6131 } 6132 6133 void 6134 scsi_ata_trim(struct ccb_scsiio *csio, u_int32_t retries, 6135 void (*cbfcnp)(struct cam_periph *, union ccb *), 6136 u_int8_t tag_action, u_int16_t block_count, 6137 u_int8_t *data_ptr, u_int16_t dxfer_len, u_int8_t sense_len, 6138 u_int32_t timeout) 6139 { 6140 scsi_ata_pass_16(csio, 6141 retries, 6142 cbfcnp, 6143 /*flags*/CAM_DIR_OUT, 6144 tag_action, 6145 /*protocol*/AP_EXTEND|AP_PROTO_DMA, 6146 /*ata_flags*/AP_FLAG_TLEN_SECT_CNT|AP_FLAG_BYT_BLOK_BLOCKS, 6147 /*features*/ATA_DSM_TRIM, 6148 /*sector_count*/block_count, 6149 /*lba*/0, 6150 /*command*/ATA_DATA_SET_MANAGEMENT, 6151 /*control*/0, 6152 data_ptr, 6153 dxfer_len, 6154 sense_len, 6155 timeout); 6156 } 6157 6158 void 6159 scsi_ata_pass_16(struct ccb_scsiio *csio, u_int32_t retries, 6160 void (*cbfcnp)(struct cam_periph *, union ccb *), 6161 u_int32_t flags, u_int8_t tag_action, 6162 u_int8_t protocol, u_int8_t ata_flags, u_int16_t features, 6163 u_int16_t sector_count, uint64_t lba, u_int8_t command, 6164 u_int8_t control, u_int8_t *data_ptr, u_int16_t dxfer_len, 6165 u_int8_t sense_len, u_int32_t timeout) 6166 { 6167 struct ata_pass_16 *ata_cmd; 6168 6169 ata_cmd = (struct ata_pass_16 *)&csio->cdb_io.cdb_bytes; 6170 ata_cmd->opcode = ATA_PASS_16; 6171 ata_cmd->protocol = protocol; 6172 ata_cmd->flags = ata_flags; 6173 ata_cmd->features_ext = features >> 8; 6174 ata_cmd->features = features; 6175 ata_cmd->sector_count_ext = sector_count >> 8; 6176 ata_cmd->sector_count = sector_count; 6177 ata_cmd->lba_low = lba; 6178 ata_cmd->lba_mid = lba >> 8; 6179 ata_cmd->lba_high = lba >> 16; 6180 ata_cmd->device = ATA_DEV_LBA; 6181 if (protocol & AP_EXTEND) { 6182 ata_cmd->lba_low_ext = lba >> 24; 6183 ata_cmd->lba_mid_ext = lba >> 32; 6184 ata_cmd->lba_high_ext = lba >> 40; 6185 } else 6186 ata_cmd->device |= (lba >> 24) & 0x0f; 6187 ata_cmd->command = command; 6188 ata_cmd->control = control; 6189 6190 cam_fill_csio(csio, 6191 retries, 6192 cbfcnp, 6193 flags, 6194 tag_action, 6195 data_ptr, 6196 dxfer_len, 6197 sense_len, 6198 sizeof(*ata_cmd), 6199 timeout); 6200 } 6201 6202 void 6203 scsi_unmap(struct ccb_scsiio *csio, u_int32_t retries, 6204 void (*cbfcnp)(struct cam_periph *, union ccb *), 6205 u_int8_t tag_action, u_int8_t byte2, 6206 u_int8_t *data_ptr, u_int16_t dxfer_len, u_int8_t sense_len, 6207 u_int32_t timeout) 6208 { 6209 struct scsi_unmap *scsi_cmd; 6210 6211 scsi_cmd = (struct scsi_unmap *)&csio->cdb_io.cdb_bytes; 6212 scsi_cmd->opcode = UNMAP; 6213 scsi_cmd->byte2 = byte2; 6214 scsi_ulto4b(0, scsi_cmd->reserved); 6215 scsi_cmd->group = 0; 6216 scsi_ulto2b(dxfer_len, scsi_cmd->length); 6217 scsi_cmd->control = 0; 6218 6219 cam_fill_csio(csio, 6220 retries, 6221 cbfcnp, 6222 /*flags*/CAM_DIR_OUT, 6223 tag_action, 6224 data_ptr, 6225 dxfer_len, 6226 sense_len, 6227 sizeof(*scsi_cmd), 6228 timeout); 6229 } 6230 6231 void 6232 scsi_receive_diagnostic_results(struct ccb_scsiio *csio, u_int32_t retries, 6233 void (*cbfcnp)(struct cam_periph *, union ccb*), 6234 uint8_t tag_action, int pcv, uint8_t page_code, 6235 uint8_t *data_ptr, uint16_t allocation_length, 6236 uint8_t sense_len, uint32_t timeout) 6237 { 6238 struct scsi_receive_diag *scsi_cmd; 6239 6240 scsi_cmd = (struct scsi_receive_diag *)&csio->cdb_io.cdb_bytes; 6241 memset(scsi_cmd, 0, sizeof(*scsi_cmd)); 6242 scsi_cmd->opcode = RECEIVE_DIAGNOSTIC; 6243 if (pcv) { 6244 scsi_cmd->byte2 |= SRD_PCV; 6245 scsi_cmd->page_code = page_code; 6246 } 6247 scsi_ulto2b(allocation_length, scsi_cmd->length); 6248 6249 cam_fill_csio(csio, 6250 retries, 6251 cbfcnp, 6252 /*flags*/CAM_DIR_IN, 6253 tag_action, 6254 data_ptr, 6255 allocation_length, 6256 sense_len, 6257 sizeof(*scsi_cmd), 6258 timeout); 6259 } 6260 6261 void 6262 scsi_send_diagnostic(struct ccb_scsiio *csio, u_int32_t retries, 6263 void (*cbfcnp)(struct cam_periph *, union ccb *), 6264 uint8_t tag_action, int unit_offline, int device_offline, 6265 int self_test, int page_format, int self_test_code, 6266 uint8_t *data_ptr, uint16_t param_list_length, 6267 uint8_t sense_len, uint32_t timeout) 6268 { 6269 struct scsi_send_diag *scsi_cmd; 6270 6271 scsi_cmd = (struct scsi_send_diag *)&csio->cdb_io.cdb_bytes; 6272 memset(scsi_cmd, 0, sizeof(*scsi_cmd)); 6273 scsi_cmd->opcode = SEND_DIAGNOSTIC; 6274 6275 /* 6276 * The default self-test mode control and specific test 6277 * control are mutually exclusive. 6278 */ 6279 if (self_test) 6280 self_test_code = SSD_SELF_TEST_CODE_NONE; 6281 6282 scsi_cmd->byte2 = ((self_test_code << SSD_SELF_TEST_CODE_SHIFT) 6283 & SSD_SELF_TEST_CODE_MASK) 6284 | (unit_offline ? SSD_UNITOFFL : 0) 6285 | (device_offline ? SSD_DEVOFFL : 0) 6286 | (self_test ? SSD_SELFTEST : 0) 6287 | (page_format ? SSD_PF : 0); 6288 scsi_ulto2b(param_list_length, scsi_cmd->length); 6289 6290 cam_fill_csio(csio, 6291 retries, 6292 cbfcnp, 6293 /*flags*/param_list_length ? CAM_DIR_OUT : CAM_DIR_NONE, 6294 tag_action, 6295 data_ptr, 6296 param_list_length, 6297 sense_len, 6298 sizeof(*scsi_cmd), 6299 timeout); 6300 } 6301 6302 void 6303 scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries, 6304 void (*cbfcnp)(struct cam_periph *, union ccb*), 6305 uint8_t tag_action, int mode, 6306 uint8_t buffer_id, u_int32_t offset, 6307 uint8_t *data_ptr, uint32_t allocation_length, 6308 uint8_t sense_len, uint32_t timeout) 6309 { 6310 struct scsi_read_buffer *scsi_cmd; 6311 6312 scsi_cmd = (struct scsi_read_buffer *)&csio->cdb_io.cdb_bytes; 6313 memset(scsi_cmd, 0, sizeof(*scsi_cmd)); 6314 scsi_cmd->opcode = READ_BUFFER; 6315 scsi_cmd->byte2 = mode; 6316 scsi_cmd->buffer_id = buffer_id; 6317 scsi_ulto3b(offset, scsi_cmd->offset); 6318 scsi_ulto3b(allocation_length, scsi_cmd->length); 6319 6320 cam_fill_csio(csio, 6321 retries, 6322 cbfcnp, 6323 /*flags*/CAM_DIR_IN, 6324 tag_action, 6325 data_ptr, 6326 allocation_length, 6327 sense_len, 6328 sizeof(*scsi_cmd), 6329 timeout); 6330 } 6331 6332 void 6333 scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries, 6334 void (*cbfcnp)(struct cam_periph *, union ccb *), 6335 uint8_t tag_action, int mode, 6336 uint8_t buffer_id, u_int32_t offset, 6337 uint8_t *data_ptr, uint32_t param_list_length, 6338 uint8_t sense_len, uint32_t timeout) 6339 { 6340 struct scsi_write_buffer *scsi_cmd; 6341 6342 scsi_cmd = (struct scsi_write_buffer *)&csio->cdb_io.cdb_bytes; 6343 memset(scsi_cmd, 0, sizeof(*scsi_cmd)); 6344 scsi_cmd->opcode = WRITE_BUFFER; 6345 scsi_cmd->byte2 = mode; 6346 scsi_cmd->buffer_id = buffer_id; 6347 scsi_ulto3b(offset, scsi_cmd->offset); 6348 scsi_ulto3b(param_list_length, scsi_cmd->length); 6349 6350 cam_fill_csio(csio, 6351 retries, 6352 cbfcnp, 6353 /*flags*/param_list_length ? CAM_DIR_OUT : CAM_DIR_NONE, 6354 tag_action, 6355 data_ptr, 6356 param_list_length, 6357 sense_len, 6358 sizeof(*scsi_cmd), 6359 timeout); 6360 } 6361 6362 void 6363 scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries, 6364 void (*cbfcnp)(struct cam_periph *, union ccb *), 6365 u_int8_t tag_action, int start, int load_eject, 6366 int immediate, u_int8_t sense_len, u_int32_t timeout) 6367 { 6368 struct scsi_start_stop_unit *scsi_cmd; 6369 int extra_flags = 0; 6370 6371 scsi_cmd = (struct scsi_start_stop_unit *)&csio->cdb_io.cdb_bytes; 6372 bzero(scsi_cmd, sizeof(*scsi_cmd)); 6373 scsi_cmd->opcode = START_STOP_UNIT; 6374 if (start != 0) { 6375 scsi_cmd->how |= SSS_START; 6376 /* it takes a lot of power to start a drive */ 6377 extra_flags |= CAM_HIGH_POWER; 6378 } 6379 if (load_eject != 0) 6380 scsi_cmd->how |= SSS_LOEJ; 6381 if (immediate != 0) 6382 scsi_cmd->byte2 |= SSS_IMMED; 6383 6384 cam_fill_csio(csio, 6385 retries, 6386 cbfcnp, 6387 /*flags*/CAM_DIR_NONE | extra_flags, 6388 tag_action, 6389 /*data_ptr*/NULL, 6390 /*dxfer_len*/0, 6391 sense_len, 6392 sizeof(*scsi_cmd), 6393 timeout); 6394 } 6395 6396 6397 /* 6398 * Try make as good a match as possible with 6399 * available sub drivers 6400 */ 6401 int 6402 scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry) 6403 { 6404 struct scsi_inquiry_pattern *entry; 6405 struct scsi_inquiry_data *inq; 6406 6407 entry = (struct scsi_inquiry_pattern *)table_entry; 6408 inq = (struct scsi_inquiry_data *)inqbuffer; 6409 6410 if (((SID_TYPE(inq) == entry->type) 6411 || (entry->type == T_ANY)) 6412 && (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE 6413 : entry->media_type & SIP_MEDIA_FIXED) 6414 && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) 6415 && (cam_strmatch(inq->product, entry->product, 6416 sizeof(inq->product)) == 0) 6417 && (cam_strmatch(inq->revision, entry->revision, 6418 sizeof(inq->revision)) == 0)) { 6419 return (0); 6420 } 6421 return (-1); 6422 } 6423 6424 /* 6425 * Try make as good a match as possible with 6426 * available sub drivers 6427 */ 6428 int 6429 scsi_static_inquiry_match(caddr_t inqbuffer, caddr_t table_entry) 6430 { 6431 struct scsi_static_inquiry_pattern *entry; 6432 struct scsi_inquiry_data *inq; 6433 6434 entry = (struct scsi_static_inquiry_pattern *)table_entry; 6435 inq = (struct scsi_inquiry_data *)inqbuffer; 6436 6437 if (((SID_TYPE(inq) == entry->type) 6438 || (entry->type == T_ANY)) 6439 && (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE 6440 : entry->media_type & SIP_MEDIA_FIXED) 6441 && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) 6442 && (cam_strmatch(inq->product, entry->product, 6443 sizeof(inq->product)) == 0) 6444 && (cam_strmatch(inq->revision, entry->revision, 6445 sizeof(inq->revision)) == 0)) { 6446 return (0); 6447 } 6448 return (-1); 6449 } 6450 6451 /** 6452 * Compare two buffers of vpd device descriptors for a match. 6453 * 6454 * \param lhs Pointer to first buffer of descriptors to compare. 6455 * \param lhs_len The length of the first buffer. 6456 * \param rhs Pointer to second buffer of descriptors to compare. 6457 * \param rhs_len The length of the second buffer. 6458 * 6459 * \return 0 on a match, -1 otherwise. 6460 * 6461 * Treat rhs and lhs as arrays of vpd device id descriptors. Walk lhs matching 6462 * agains each element in rhs until all data are exhausted or we have found 6463 * a match. 6464 */ 6465 int 6466 scsi_devid_match(uint8_t *lhs, size_t lhs_len, uint8_t *rhs, size_t rhs_len) 6467 { 6468 struct scsi_vpd_id_descriptor *lhs_id; 6469 struct scsi_vpd_id_descriptor *lhs_last; 6470 struct scsi_vpd_id_descriptor *rhs_last; 6471 uint8_t *lhs_end; 6472 uint8_t *rhs_end; 6473 6474 lhs_end = lhs + lhs_len; 6475 rhs_end = rhs + rhs_len; 6476 6477 /* 6478 * rhs_last and lhs_last are the last posible position of a valid 6479 * descriptor assuming it had a zero length identifier. We use 6480 * these variables to insure we can safely dereference the length 6481 * field in our loop termination tests. 6482 */ 6483 lhs_last = (struct scsi_vpd_id_descriptor *) 6484 (lhs_end - __offsetof(struct scsi_vpd_id_descriptor, identifier)); 6485 rhs_last = (struct scsi_vpd_id_descriptor *) 6486 (rhs_end - __offsetof(struct scsi_vpd_id_descriptor, identifier)); 6487 6488 lhs_id = (struct scsi_vpd_id_descriptor *)lhs; 6489 while (lhs_id <= lhs_last 6490 && (lhs_id->identifier + lhs_id->length) <= lhs_end) { 6491 struct scsi_vpd_id_descriptor *rhs_id; 6492 6493 rhs_id = (struct scsi_vpd_id_descriptor *)rhs; 6494 while (rhs_id <= rhs_last 6495 && (rhs_id->identifier + rhs_id->length) <= rhs_end) { 6496 6497 if (rhs_id->length == lhs_id->length 6498 && memcmp(rhs_id->identifier, lhs_id->identifier, 6499 rhs_id->length) == 0) 6500 return (0); 6501 6502 rhs_id = (struct scsi_vpd_id_descriptor *) 6503 (rhs_id->identifier + rhs_id->length); 6504 } 6505 lhs_id = (struct scsi_vpd_id_descriptor *) 6506 (lhs_id->identifier + lhs_id->length); 6507 } 6508 return (-1); 6509 } 6510 6511 #ifdef _KERNEL 6512 int 6513 scsi_vpd_supported_page(struct cam_periph *periph, uint8_t page_id) 6514 { 6515 struct cam_ed *device; 6516 struct scsi_vpd_supported_pages *vpds; 6517 int i, num_pages; 6518 6519 device = periph->path->device; 6520 vpds = (struct scsi_vpd_supported_pages *)device->supported_vpds; 6521 6522 if (vpds != NULL) { 6523 num_pages = device->supported_vpds_len - 6524 SVPD_SUPPORTED_PAGES_HDR_LEN; 6525 for (i = 0; i < num_pages; i++) { 6526 if (vpds->page_list[i] == page_id) 6527 return (1); 6528 } 6529 } 6530 6531 return (0); 6532 } 6533 6534 static void 6535 init_scsi_delay(void) 6536 { 6537 int delay; 6538 6539 delay = SCSI_DELAY; 6540 TUNABLE_INT_FETCH("kern.cam.scsi_delay", &delay); 6541 6542 if (set_scsi_delay(delay) != 0) { 6543 printf("cam: invalid value for tunable kern.cam.scsi_delay\n"); 6544 set_scsi_delay(SCSI_DELAY); 6545 } 6546 } 6547 SYSINIT(scsi_delay, SI_SUB_TUNABLES, SI_ORDER_ANY, init_scsi_delay, NULL); 6548 6549 static int 6550 sysctl_scsi_delay(SYSCTL_HANDLER_ARGS) 6551 { 6552 int error, delay; 6553 6554 delay = scsi_delay; 6555 error = sysctl_handle_int(oidp, &delay, 0, req); 6556 if (error != 0 || req->newptr == NULL) 6557 return (error); 6558 return (set_scsi_delay(delay)); 6559 } 6560 SYSCTL_PROC(_kern_cam, OID_AUTO, scsi_delay, CTLTYPE_INT|CTLFLAG_RW, 6561 0, 0, sysctl_scsi_delay, "I", 6562 "Delay to allow devices to settle after a SCSI bus reset (ms)"); 6563 6564 static int 6565 set_scsi_delay(int delay) 6566 { 6567 /* 6568 * If someone sets this to 0, we assume that they want the 6569 * minimum allowable bus settle delay. 6570 */ 6571 if (delay == 0) { 6572 printf("cam: using minimum scsi_delay (%dms)\n", 6573 SCSI_MIN_DELAY); 6574 delay = SCSI_MIN_DELAY; 6575 } 6576 if (delay < SCSI_MIN_DELAY) 6577 return (EINVAL); 6578 scsi_delay = delay; 6579 return (0); 6580 } 6581 #endif /* _KERNEL */ 6582