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