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[12]; 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_0) 5246 snprintf(rstr, sizeof(rstr), "SCSI"); 5247 else if (SID_ANSI_REV(inq_data) <= SCSI_REV_SPC) { 5248 snprintf(rstr, sizeof(rstr), "SCSI-%d", 5249 SID_ANSI_REV(inq_data)); 5250 } else { 5251 snprintf(rstr, sizeof(rstr), "SPC-%d SCSI", 5252 SID_ANSI_REV(inq_data) - 2); 5253 } 5254 printf("<%s %s %s> %s %s %s device%s\n", 5255 vendor, product, revision, 5256 SID_IS_REMOVABLE(inq_data) ? "Removable" : "Fixed", 5257 dtype, rstr, qtype); 5258 } 5259 5260 void 5261 scsi_print_inquiry_short(struct scsi_inquiry_data *inq_data) 5262 { 5263 char vendor[16], product[48], revision[16]; 5264 5265 cam_strvis(vendor, inq_data->vendor, sizeof(inq_data->vendor), 5266 sizeof(vendor)); 5267 cam_strvis(product, inq_data->product, sizeof(inq_data->product), 5268 sizeof(product)); 5269 cam_strvis(revision, inq_data->revision, sizeof(inq_data->revision), 5270 sizeof(revision)); 5271 5272 printf("<%s %s %s>", vendor, product, revision); 5273 } 5274 5275 /* 5276 * Table of syncrates that don't follow the "divisible by 4" 5277 * rule. This table will be expanded in future SCSI specs. 5278 */ 5279 static struct { 5280 u_int period_factor; 5281 u_int period; /* in 100ths of ns */ 5282 } scsi_syncrates[] = { 5283 { 0x08, 625 }, /* FAST-160 */ 5284 { 0x09, 1250 }, /* FAST-80 */ 5285 { 0x0a, 2500 }, /* FAST-40 40MHz */ 5286 { 0x0b, 3030 }, /* FAST-40 33MHz */ 5287 { 0x0c, 5000 } /* FAST-20 */ 5288 }; 5289 5290 /* 5291 * Return the frequency in kHz corresponding to the given 5292 * sync period factor. 5293 */ 5294 u_int 5295 scsi_calc_syncsrate(u_int period_factor) 5296 { 5297 int i; 5298 int num_syncrates; 5299 5300 /* 5301 * It's a bug if period is zero, but if it is anyway, don't 5302 * die with a divide fault- instead return something which 5303 * 'approximates' async 5304 */ 5305 if (period_factor == 0) { 5306 return (3300); 5307 } 5308 5309 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); 5310 /* See if the period is in the "exception" table */ 5311 for (i = 0; i < num_syncrates; i++) { 5312 5313 if (period_factor == scsi_syncrates[i].period_factor) { 5314 /* Period in kHz */ 5315 return (100000000 / scsi_syncrates[i].period); 5316 } 5317 } 5318 5319 /* 5320 * Wasn't in the table, so use the standard 5321 * 4 times conversion. 5322 */ 5323 return (10000000 / (period_factor * 4 * 10)); 5324 } 5325 5326 /* 5327 * Return the SCSI sync parameter that corresponsd to 5328 * the passed in period in 10ths of ns. 5329 */ 5330 u_int 5331 scsi_calc_syncparam(u_int period) 5332 { 5333 int i; 5334 int num_syncrates; 5335 5336 if (period == 0) 5337 return (~0); /* Async */ 5338 5339 /* Adjust for exception table being in 100ths. */ 5340 period *= 10; 5341 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); 5342 /* See if the period is in the "exception" table */ 5343 for (i = 0; i < num_syncrates; i++) { 5344 5345 if (period <= scsi_syncrates[i].period) { 5346 /* Period in 100ths of ns */ 5347 return (scsi_syncrates[i].period_factor); 5348 } 5349 } 5350 5351 /* 5352 * Wasn't in the table, so use the standard 5353 * 1/4 period in ns conversion. 5354 */ 5355 return (period/400); 5356 } 5357 5358 int 5359 scsi_devid_is_naa_ieee_reg(uint8_t *bufp) 5360 { 5361 struct scsi_vpd_id_descriptor *descr; 5362 struct scsi_vpd_id_naa_basic *naa; 5363 5364 descr = (struct scsi_vpd_id_descriptor *)bufp; 5365 naa = (struct scsi_vpd_id_naa_basic *)descr->identifier; 5366 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_NAA) 5367 return 0; 5368 if (descr->length < sizeof(struct scsi_vpd_id_naa_ieee_reg)) 5369 return 0; 5370 if ((naa->naa >> SVPD_ID_NAA_NAA_SHIFT) != SVPD_ID_NAA_IEEE_REG) 5371 return 0; 5372 return 1; 5373 } 5374 5375 int 5376 scsi_devid_is_sas_target(uint8_t *bufp) 5377 { 5378 struct scsi_vpd_id_descriptor *descr; 5379 5380 descr = (struct scsi_vpd_id_descriptor *)bufp; 5381 if (!scsi_devid_is_naa_ieee_reg(bufp)) 5382 return 0; 5383 if ((descr->id_type & SVPD_ID_PIV) == 0) /* proto field reserved */ 5384 return 0; 5385 if ((descr->proto_codeset >> SVPD_ID_PROTO_SHIFT) != SCSI_PROTO_SAS) 5386 return 0; 5387 return 1; 5388 } 5389 5390 int 5391 scsi_devid_is_lun_eui64(uint8_t *bufp) 5392 { 5393 struct scsi_vpd_id_descriptor *descr; 5394 5395 descr = (struct scsi_vpd_id_descriptor *)bufp; 5396 if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN) 5397 return 0; 5398 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_EUI64) 5399 return 0; 5400 return 1; 5401 } 5402 5403 int 5404 scsi_devid_is_lun_naa(uint8_t *bufp) 5405 { 5406 struct scsi_vpd_id_descriptor *descr; 5407 5408 descr = (struct scsi_vpd_id_descriptor *)bufp; 5409 if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN) 5410 return 0; 5411 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_NAA) 5412 return 0; 5413 return 1; 5414 } 5415 5416 int 5417 scsi_devid_is_lun_t10(uint8_t *bufp) 5418 { 5419 struct scsi_vpd_id_descriptor *descr; 5420 5421 descr = (struct scsi_vpd_id_descriptor *)bufp; 5422 if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN) 5423 return 0; 5424 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_T10) 5425 return 0; 5426 return 1; 5427 } 5428 5429 int 5430 scsi_devid_is_lun_name(uint8_t *bufp) 5431 { 5432 struct scsi_vpd_id_descriptor *descr; 5433 5434 descr = (struct scsi_vpd_id_descriptor *)bufp; 5435 if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN) 5436 return 0; 5437 if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_SCSI_NAME) 5438 return 0; 5439 return 1; 5440 } 5441 5442 struct scsi_vpd_id_descriptor * 5443 scsi_get_devid_desc(struct scsi_vpd_id_descriptor *desc, uint32_t len, 5444 scsi_devid_checkfn_t ck_fn) 5445 { 5446 uint8_t *desc_buf_end; 5447 5448 desc_buf_end = (uint8_t *)desc + len; 5449 5450 for (; desc->identifier <= desc_buf_end && 5451 desc->identifier + desc->length <= desc_buf_end; 5452 desc = (struct scsi_vpd_id_descriptor *)(desc->identifier 5453 + desc->length)) { 5454 5455 if (ck_fn == NULL || ck_fn((uint8_t *)desc) != 0) 5456 return (desc); 5457 } 5458 return (NULL); 5459 } 5460 5461 struct scsi_vpd_id_descriptor * 5462 scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t page_len, 5463 scsi_devid_checkfn_t ck_fn) 5464 { 5465 uint32_t len; 5466 5467 if (page_len < sizeof(*id)) 5468 return (NULL); 5469 len = MIN(scsi_2btoul(id->length), page_len - sizeof(*id)); 5470 return (scsi_get_devid_desc((struct scsi_vpd_id_descriptor *) 5471 id->desc_list, len, ck_fn)); 5472 } 5473 5474 int 5475 scsi_transportid_sbuf(struct sbuf *sb, struct scsi_transportid_header *hdr, 5476 uint32_t valid_len) 5477 { 5478 switch (hdr->format_protocol & SCSI_TRN_PROTO_MASK) { 5479 case SCSI_PROTO_FC: { 5480 struct scsi_transportid_fcp *fcp; 5481 uint64_t n_port_name; 5482 5483 fcp = (struct scsi_transportid_fcp *)hdr; 5484 5485 n_port_name = scsi_8btou64(fcp->n_port_name); 5486 5487 sbuf_printf(sb, "FCP address: 0x%.16jx",(uintmax_t)n_port_name); 5488 break; 5489 } 5490 case SCSI_PROTO_SPI: { 5491 struct scsi_transportid_spi *spi; 5492 5493 spi = (struct scsi_transportid_spi *)hdr; 5494 5495 sbuf_printf(sb, "SPI address: %u,%u", 5496 scsi_2btoul(spi->scsi_addr), 5497 scsi_2btoul(spi->rel_trgt_port_id)); 5498 break; 5499 } 5500 case SCSI_PROTO_SSA: 5501 /* 5502 * XXX KDM there is no transport ID defined in SPC-4 for 5503 * SSA. 5504 */ 5505 break; 5506 case SCSI_PROTO_1394: { 5507 struct scsi_transportid_1394 *sbp; 5508 uint64_t eui64; 5509 5510 sbp = (struct scsi_transportid_1394 *)hdr; 5511 5512 eui64 = scsi_8btou64(sbp->eui64); 5513 sbuf_printf(sb, "SBP address: 0x%.16jx", (uintmax_t)eui64); 5514 break; 5515 } 5516 case SCSI_PROTO_RDMA: { 5517 struct scsi_transportid_rdma *rdma; 5518 unsigned int i; 5519 5520 rdma = (struct scsi_transportid_rdma *)hdr; 5521 5522 sbuf_printf(sb, "RDMA address: 0x"); 5523 for (i = 0; i < sizeof(rdma->initiator_port_id); i++) 5524 sbuf_printf(sb, "%02x", rdma->initiator_port_id[i]); 5525 break; 5526 } 5527 case SCSI_PROTO_ISCSI: { 5528 uint32_t add_len, i; 5529 uint8_t *iscsi_name = NULL; 5530 int nul_found = 0; 5531 5532 sbuf_printf(sb, "iSCSI address: "); 5533 if ((hdr->format_protocol & SCSI_TRN_FORMAT_MASK) == 5534 SCSI_TRN_ISCSI_FORMAT_DEVICE) { 5535 struct scsi_transportid_iscsi_device *dev; 5536 5537 dev = (struct scsi_transportid_iscsi_device *)hdr; 5538 5539 /* 5540 * Verify how much additional data we really have. 5541 */ 5542 add_len = scsi_2btoul(dev->additional_length); 5543 add_len = MIN(add_len, valid_len - 5544 __offsetof(struct scsi_transportid_iscsi_device, 5545 iscsi_name)); 5546 iscsi_name = &dev->iscsi_name[0]; 5547 5548 } else if ((hdr->format_protocol & SCSI_TRN_FORMAT_MASK) == 5549 SCSI_TRN_ISCSI_FORMAT_PORT) { 5550 struct scsi_transportid_iscsi_port *port; 5551 5552 port = (struct scsi_transportid_iscsi_port *)hdr; 5553 5554 add_len = scsi_2btoul(port->additional_length); 5555 add_len = MIN(add_len, valid_len - 5556 __offsetof(struct scsi_transportid_iscsi_port, 5557 iscsi_name)); 5558 iscsi_name = &port->iscsi_name[0]; 5559 } else { 5560 sbuf_printf(sb, "unknown format %x", 5561 (hdr->format_protocol & 5562 SCSI_TRN_FORMAT_MASK) >> 5563 SCSI_TRN_FORMAT_SHIFT); 5564 break; 5565 } 5566 if (add_len == 0) { 5567 sbuf_printf(sb, "not enough data"); 5568 break; 5569 } 5570 /* 5571 * This is supposed to be a NUL-terminated ASCII 5572 * string, but you never know. So we're going to 5573 * check. We need to do this because there is no 5574 * sbuf equivalent of strncat(). 5575 */ 5576 for (i = 0; i < add_len; i++) { 5577 if (iscsi_name[i] == '\0') { 5578 nul_found = 1; 5579 break; 5580 } 5581 } 5582 /* 5583 * If there is a NUL in the name, we can just use 5584 * sbuf_cat(). Otherwise we need to use sbuf_bcat(). 5585 */ 5586 if (nul_found != 0) 5587 sbuf_cat(sb, iscsi_name); 5588 else 5589 sbuf_bcat(sb, iscsi_name, add_len); 5590 break; 5591 } 5592 case SCSI_PROTO_SAS: { 5593 struct scsi_transportid_sas *sas; 5594 uint64_t sas_addr; 5595 5596 sas = (struct scsi_transportid_sas *)hdr; 5597 5598 sas_addr = scsi_8btou64(sas->sas_address); 5599 sbuf_printf(sb, "SAS address: 0x%.16jx", (uintmax_t)sas_addr); 5600 break; 5601 } 5602 case SCSI_PROTO_ADITP: 5603 case SCSI_PROTO_ATA: 5604 case SCSI_PROTO_UAS: 5605 /* 5606 * No Transport ID format for ADI, ATA or USB is defined in 5607 * SPC-4. 5608 */ 5609 sbuf_printf(sb, "No known Transport ID format for protocol " 5610 "%#x", hdr->format_protocol & SCSI_TRN_PROTO_MASK); 5611 break; 5612 case SCSI_PROTO_SOP: { 5613 struct scsi_transportid_sop *sop; 5614 struct scsi_sop_routing_id_norm *rid; 5615 5616 sop = (struct scsi_transportid_sop *)hdr; 5617 rid = (struct scsi_sop_routing_id_norm *)sop->routing_id; 5618 5619 /* 5620 * Note that there is no alternate format specified in SPC-4 5621 * for the PCIe routing ID, so we don't really have a way 5622 * to know whether the second byte of the routing ID is 5623 * a device and function or just a function. So we just 5624 * assume bus,device,function. 5625 */ 5626 sbuf_printf(sb, "SOP Routing ID: %u,%u,%u", 5627 rid->bus, rid->devfunc >> SCSI_TRN_SOP_DEV_SHIFT, 5628 rid->devfunc & SCSI_TRN_SOP_FUNC_NORM_MAX); 5629 break; 5630 } 5631 case SCSI_PROTO_NONE: 5632 default: 5633 sbuf_printf(sb, "Unknown protocol %#x", 5634 hdr->format_protocol & SCSI_TRN_PROTO_MASK); 5635 break; 5636 } 5637 5638 return (0); 5639 } 5640 5641 struct scsi_nv scsi_proto_map[] = { 5642 { "fcp", SCSI_PROTO_FC }, 5643 { "spi", SCSI_PROTO_SPI }, 5644 { "ssa", SCSI_PROTO_SSA }, 5645 { "sbp", SCSI_PROTO_1394 }, 5646 { "1394", SCSI_PROTO_1394 }, 5647 { "srp", SCSI_PROTO_RDMA }, 5648 { "rdma", SCSI_PROTO_RDMA }, 5649 { "iscsi", SCSI_PROTO_ISCSI }, 5650 { "iqn", SCSI_PROTO_ISCSI }, 5651 { "sas", SCSI_PROTO_SAS }, 5652 { "aditp", SCSI_PROTO_ADITP }, 5653 { "ata", SCSI_PROTO_ATA }, 5654 { "uas", SCSI_PROTO_UAS }, 5655 { "usb", SCSI_PROTO_UAS }, 5656 { "sop", SCSI_PROTO_SOP } 5657 }; 5658 5659 const char * 5660 scsi_nv_to_str(struct scsi_nv *table, int num_table_entries, uint64_t value) 5661 { 5662 int i; 5663 5664 for (i = 0; i < num_table_entries; i++) { 5665 if (table[i].value == value) 5666 return (table[i].name); 5667 } 5668 5669 return (NULL); 5670 } 5671 5672 /* 5673 * Given a name/value table, find a value matching the given name. 5674 * Return values: 5675 * SCSI_NV_FOUND - match found 5676 * SCSI_NV_AMBIGUOUS - more than one match, none of them exact 5677 * SCSI_NV_NOT_FOUND - no match found 5678 */ 5679 scsi_nv_status 5680 scsi_get_nv(struct scsi_nv *table, int num_table_entries, 5681 char *name, int *table_entry, scsi_nv_flags flags) 5682 { 5683 int i, num_matches = 0; 5684 5685 for (i = 0; i < num_table_entries; i++) { 5686 size_t table_len, name_len; 5687 5688 table_len = strlen(table[i].name); 5689 name_len = strlen(name); 5690 5691 if ((((flags & SCSI_NV_FLAG_IG_CASE) != 0) 5692 && (strncasecmp(table[i].name, name, name_len) == 0)) 5693 || (((flags & SCSI_NV_FLAG_IG_CASE) == 0) 5694 && (strncmp(table[i].name, name, name_len) == 0))) { 5695 *table_entry = i; 5696 5697 /* 5698 * Check for an exact match. If we have the same 5699 * number of characters in the table as the argument, 5700 * and we already know they're the same, we have 5701 * an exact match. 5702 */ 5703 if (table_len == name_len) 5704 return (SCSI_NV_FOUND); 5705 5706 /* 5707 * Otherwise, bump up the number of matches. We'll 5708 * see later how many we have. 5709 */ 5710 num_matches++; 5711 } 5712 } 5713 5714 if (num_matches > 1) 5715 return (SCSI_NV_AMBIGUOUS); 5716 else if (num_matches == 1) 5717 return (SCSI_NV_FOUND); 5718 else 5719 return (SCSI_NV_NOT_FOUND); 5720 } 5721 5722 /* 5723 * Parse transport IDs for Fibre Channel, 1394 and SAS. Since these are 5724 * all 64-bit numbers, the code is similar. 5725 */ 5726 int 5727 scsi_parse_transportid_64bit(int proto_id, char *id_str, 5728 struct scsi_transportid_header **hdr, 5729 unsigned int *alloc_len, 5730 #ifdef _KERNEL 5731 struct malloc_type *type, int flags, 5732 #endif 5733 char *error_str, int error_str_len) 5734 { 5735 uint64_t value; 5736 char *endptr; 5737 int retval; 5738 size_t alloc_size; 5739 5740 retval = 0; 5741 5742 value = strtouq(id_str, &endptr, 0); 5743 if (*endptr != '\0') { 5744 if (error_str != NULL) { 5745 snprintf(error_str, error_str_len, "%s: error " 5746 "parsing ID %s, 64-bit number required", 5747 __func__, id_str); 5748 } 5749 retval = 1; 5750 goto bailout; 5751 } 5752 5753 switch (proto_id) { 5754 case SCSI_PROTO_FC: 5755 alloc_size = sizeof(struct scsi_transportid_fcp); 5756 break; 5757 case SCSI_PROTO_1394: 5758 alloc_size = sizeof(struct scsi_transportid_1394); 5759 break; 5760 case SCSI_PROTO_SAS: 5761 alloc_size = sizeof(struct scsi_transportid_sas); 5762 break; 5763 default: 5764 if (error_str != NULL) { 5765 snprintf(error_str, error_str_len, "%s: unsupoprted " 5766 "protocol %d", __func__, proto_id); 5767 } 5768 retval = 1; 5769 goto bailout; 5770 break; /* NOTREACHED */ 5771 } 5772 #ifdef _KERNEL 5773 *hdr = malloc(alloc_size, type, flags); 5774 #else /* _KERNEL */ 5775 *hdr = malloc(alloc_size); 5776 #endif /*_KERNEL */ 5777 if (*hdr == NULL) { 5778 if (error_str != NULL) { 5779 snprintf(error_str, error_str_len, "%s: unable to " 5780 "allocate %zu bytes", __func__, alloc_size); 5781 } 5782 retval = 1; 5783 goto bailout; 5784 } 5785 5786 *alloc_len = alloc_size; 5787 5788 bzero(*hdr, alloc_size); 5789 5790 switch (proto_id) { 5791 case SCSI_PROTO_FC: { 5792 struct scsi_transportid_fcp *fcp; 5793 5794 fcp = (struct scsi_transportid_fcp *)(*hdr); 5795 fcp->format_protocol = SCSI_PROTO_FC | 5796 SCSI_TRN_FCP_FORMAT_DEFAULT; 5797 scsi_u64to8b(value, fcp->n_port_name); 5798 break; 5799 } 5800 case SCSI_PROTO_1394: { 5801 struct scsi_transportid_1394 *sbp; 5802 5803 sbp = (struct scsi_transportid_1394 *)(*hdr); 5804 sbp->format_protocol = SCSI_PROTO_1394 | 5805 SCSI_TRN_1394_FORMAT_DEFAULT; 5806 scsi_u64to8b(value, sbp->eui64); 5807 break; 5808 } 5809 case SCSI_PROTO_SAS: { 5810 struct scsi_transportid_sas *sas; 5811 5812 sas = (struct scsi_transportid_sas *)(*hdr); 5813 sas->format_protocol = SCSI_PROTO_SAS | 5814 SCSI_TRN_SAS_FORMAT_DEFAULT; 5815 scsi_u64to8b(value, sas->sas_address); 5816 break; 5817 } 5818 default: 5819 break; 5820 } 5821 bailout: 5822 return (retval); 5823 } 5824 5825 /* 5826 * Parse a SPI (Parallel SCSI) address of the form: id,rel_tgt_port 5827 */ 5828 int 5829 scsi_parse_transportid_spi(char *id_str, struct scsi_transportid_header **hdr, 5830 unsigned int *alloc_len, 5831 #ifdef _KERNEL 5832 struct malloc_type *type, int flags, 5833 #endif 5834 char *error_str, int error_str_len) 5835 { 5836 unsigned long scsi_addr, target_port; 5837 struct scsi_transportid_spi *spi; 5838 char *tmpstr, *endptr; 5839 int retval; 5840 5841 retval = 0; 5842 5843 tmpstr = strsep(&id_str, ","); 5844 if (tmpstr == NULL) { 5845 if (error_str != NULL) { 5846 snprintf(error_str, error_str_len, 5847 "%s: no ID found", __func__); 5848 } 5849 retval = 1; 5850 goto bailout; 5851 } 5852 scsi_addr = strtoul(tmpstr, &endptr, 0); 5853 if (*endptr != '\0') { 5854 if (error_str != NULL) { 5855 snprintf(error_str, error_str_len, "%s: error " 5856 "parsing SCSI ID %s, number required", 5857 __func__, tmpstr); 5858 } 5859 retval = 1; 5860 goto bailout; 5861 } 5862 5863 if (id_str == NULL) { 5864 if (error_str != NULL) { 5865 snprintf(error_str, error_str_len, "%s: no relative " 5866 "target port found", __func__); 5867 } 5868 retval = 1; 5869 goto bailout; 5870 } 5871 5872 target_port = strtoul(id_str, &endptr, 0); 5873 if (*endptr != '\0') { 5874 if (error_str != NULL) { 5875 snprintf(error_str, error_str_len, "%s: error " 5876 "parsing relative target port %s, number " 5877 "required", __func__, id_str); 5878 } 5879 retval = 1; 5880 goto bailout; 5881 } 5882 #ifdef _KERNEL 5883 spi = malloc(sizeof(*spi), type, flags); 5884 #else 5885 spi = malloc(sizeof(*spi)); 5886 #endif 5887 if (spi == NULL) { 5888 if (error_str != NULL) { 5889 snprintf(error_str, error_str_len, "%s: unable to " 5890 "allocate %zu bytes", __func__, 5891 sizeof(*spi)); 5892 } 5893 retval = 1; 5894 goto bailout; 5895 } 5896 *alloc_len = sizeof(*spi); 5897 bzero(spi, sizeof(*spi)); 5898 5899 spi->format_protocol = SCSI_PROTO_SPI | SCSI_TRN_SPI_FORMAT_DEFAULT; 5900 scsi_ulto2b(scsi_addr, spi->scsi_addr); 5901 scsi_ulto2b(target_port, spi->rel_trgt_port_id); 5902 5903 *hdr = (struct scsi_transportid_header *)spi; 5904 bailout: 5905 return (retval); 5906 } 5907 5908 /* 5909 * Parse an RDMA/SRP Initiator Port ID string. This is 32 hexadecimal digits, 5910 * optionally prefixed by "0x" or "0X". 5911 */ 5912 int 5913 scsi_parse_transportid_rdma(char *id_str, struct scsi_transportid_header **hdr, 5914 unsigned int *alloc_len, 5915 #ifdef _KERNEL 5916 struct malloc_type *type, int flags, 5917 #endif 5918 char *error_str, int error_str_len) 5919 { 5920 struct scsi_transportid_rdma *rdma; 5921 int retval; 5922 size_t id_len, rdma_id_size; 5923 uint8_t rdma_id[SCSI_TRN_RDMA_PORT_LEN]; 5924 char *tmpstr; 5925 unsigned int i, j; 5926 5927 retval = 0; 5928 id_len = strlen(id_str); 5929 rdma_id_size = SCSI_TRN_RDMA_PORT_LEN; 5930 5931 /* 5932 * Check the size. It needs to be either 32 or 34 characters long. 5933 */ 5934 if ((id_len != (rdma_id_size * 2)) 5935 && (id_len != ((rdma_id_size * 2) + 2))) { 5936 if (error_str != NULL) { 5937 snprintf(error_str, error_str_len, "%s: RDMA ID " 5938 "must be 32 hex digits (0x prefix " 5939 "optional), only %zu seen", __func__, id_len); 5940 } 5941 retval = 1; 5942 goto bailout; 5943 } 5944 5945 tmpstr = id_str; 5946 /* 5947 * If the user gave us 34 characters, the string needs to start 5948 * with '0x'. 5949 */ 5950 if (id_len == ((rdma_id_size * 2) + 2)) { 5951 if ((tmpstr[0] == '0') 5952 && ((tmpstr[1] == 'x') || (tmpstr[1] == 'X'))) { 5953 tmpstr += 2; 5954 } else { 5955 if (error_str != NULL) { 5956 snprintf(error_str, error_str_len, "%s: RDMA " 5957 "ID prefix, if used, must be \"0x\", " 5958 "got %s", __func__, tmpstr); 5959 } 5960 retval = 1; 5961 goto bailout; 5962 } 5963 } 5964 bzero(rdma_id, sizeof(rdma_id)); 5965 5966 /* 5967 * Convert ASCII hex into binary bytes. There is no standard 5968 * 128-bit integer type, and so no strtou128t() routine to convert 5969 * from hex into a large integer. In the end, we're not going to 5970 * an integer, but rather to a byte array, so that and the fact 5971 * that we require the user to give us 32 hex digits simplifies the 5972 * logic. 5973 */ 5974 for (i = 0; i < (rdma_id_size * 2); i++) { 5975 int cur_shift; 5976 unsigned char c; 5977 5978 /* Increment the byte array one for every 2 hex digits */ 5979 j = i >> 1; 5980 5981 /* 5982 * The first digit in every pair is the most significant 5983 * 4 bits. The second is the least significant 4 bits. 5984 */ 5985 if ((i % 2) == 0) 5986 cur_shift = 4; 5987 else 5988 cur_shift = 0; 5989 5990 c = tmpstr[i]; 5991 /* Convert the ASCII hex character into a number */ 5992 if (isdigit(c)) 5993 c -= '0'; 5994 else if (isalpha(c)) 5995 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 5996 else { 5997 if (error_str != NULL) { 5998 snprintf(error_str, error_str_len, "%s: " 5999 "RDMA ID must be hex digits, got " 6000 "invalid character %c", __func__, 6001 tmpstr[i]); 6002 } 6003 retval = 1; 6004 goto bailout; 6005 } 6006 /* 6007 * The converted number can't be less than 0; the type is 6008 * unsigned, and the subtraction logic will not give us 6009 * a negative number. So we only need to make sure that 6010 * the value is not greater than 0xf. (i.e. make sure the 6011 * user didn't give us a value like "0x12jklmno"). 6012 */ 6013 if (c > 0xf) { 6014 if (error_str != NULL) { 6015 snprintf(error_str, error_str_len, "%s: " 6016 "RDMA ID must be hex digits, got " 6017 "invalid character %c", __func__, 6018 tmpstr[i]); 6019 } 6020 retval = 1; 6021 goto bailout; 6022 } 6023 6024 rdma_id[j] |= c << cur_shift; 6025 } 6026 6027 #ifdef _KERNEL 6028 rdma = malloc(sizeof(*rdma), type, flags); 6029 #else 6030 rdma = malloc(sizeof(*rdma)); 6031 #endif 6032 if (rdma == NULL) { 6033 if (error_str != NULL) { 6034 snprintf(error_str, error_str_len, "%s: unable to " 6035 "allocate %zu bytes", __func__, 6036 sizeof(*rdma)); 6037 } 6038 retval = 1; 6039 goto bailout; 6040 } 6041 *alloc_len = sizeof(*rdma); 6042 bzero(rdma, *alloc_len); 6043 6044 rdma->format_protocol = SCSI_PROTO_RDMA | SCSI_TRN_RDMA_FORMAT_DEFAULT; 6045 bcopy(rdma_id, rdma->initiator_port_id, SCSI_TRN_RDMA_PORT_LEN); 6046 6047 *hdr = (struct scsi_transportid_header *)rdma; 6048 6049 bailout: 6050 return (retval); 6051 } 6052 6053 /* 6054 * Parse an iSCSI name. The format is either just the name: 6055 * 6056 * iqn.2012-06.com.example:target0 6057 * or the name, separator and initiator session ID: 6058 * 6059 * iqn.2012-06.com.example:target0,i,0x123 6060 * 6061 * The separator format is exact. 6062 */ 6063 int 6064 scsi_parse_transportid_iscsi(char *id_str, struct scsi_transportid_header **hdr, 6065 unsigned int *alloc_len, 6066 #ifdef _KERNEL 6067 struct malloc_type *type, int flags, 6068 #endif 6069 char *error_str, int error_str_len) 6070 { 6071 size_t id_len, sep_len, id_size, name_len; 6072 int retval; 6073 unsigned int i, sep_pos, sep_found; 6074 const char *sep_template = ",i,0x"; 6075 const char *iqn_prefix = "iqn."; 6076 struct scsi_transportid_iscsi_device *iscsi; 6077 6078 retval = 0; 6079 sep_found = 0; 6080 6081 id_len = strlen(id_str); 6082 sep_len = strlen(sep_template); 6083 6084 /* 6085 * The separator is defined as exactly ',i,0x'. Any other commas, 6086 * or any other form, is an error. So look for a comma, and once 6087 * we find that, the next few characters must match the separator 6088 * exactly. Once we get through the separator, there should be at 6089 * least one character. 6090 */ 6091 for (i = 0, sep_pos = 0; i < id_len; i++) { 6092 if (sep_pos == 0) { 6093 if (id_str[i] == sep_template[sep_pos]) 6094 sep_pos++; 6095 6096 continue; 6097 } 6098 if (sep_pos < sep_len) { 6099 if (id_str[i] == sep_template[sep_pos]) { 6100 sep_pos++; 6101 continue; 6102 } 6103 if (error_str != NULL) { 6104 snprintf(error_str, error_str_len, "%s: " 6105 "invalid separator in iSCSI name " 6106 "\"%s\"", 6107 __func__, id_str); 6108 } 6109 retval = 1; 6110 goto bailout; 6111 } else { 6112 sep_found = 1; 6113 break; 6114 } 6115 } 6116 6117 /* 6118 * Check to see whether we have a separator but no digits after it. 6119 */ 6120 if ((sep_pos != 0) 6121 && (sep_found == 0)) { 6122 if (error_str != NULL) { 6123 snprintf(error_str, error_str_len, "%s: no digits " 6124 "found after separator in iSCSI name \"%s\"", 6125 __func__, id_str); 6126 } 6127 retval = 1; 6128 goto bailout; 6129 } 6130 6131 /* 6132 * The incoming ID string has the "iqn." prefix stripped off. We 6133 * need enough space for the base structure (the structures are the 6134 * same for the two iSCSI forms), the prefix, the ID string and a 6135 * terminating NUL. 6136 */ 6137 id_size = sizeof(*iscsi) + strlen(iqn_prefix) + id_len + 1; 6138 6139 #ifdef _KERNEL 6140 iscsi = malloc(id_size, type, flags); 6141 #else 6142 iscsi = malloc(id_size); 6143 #endif 6144 if (iscsi == NULL) { 6145 if (error_str != NULL) { 6146 snprintf(error_str, error_str_len, "%s: unable to " 6147 "allocate %zu bytes", __func__, id_size); 6148 } 6149 retval = 1; 6150 goto bailout; 6151 } 6152 *alloc_len = id_size; 6153 bzero(iscsi, id_size); 6154 6155 iscsi->format_protocol = SCSI_PROTO_ISCSI; 6156 if (sep_found == 0) 6157 iscsi->format_protocol |= SCSI_TRN_ISCSI_FORMAT_DEVICE; 6158 else 6159 iscsi->format_protocol |= SCSI_TRN_ISCSI_FORMAT_PORT; 6160 name_len = id_size - sizeof(*iscsi); 6161 scsi_ulto2b(name_len, iscsi->additional_length); 6162 snprintf(iscsi->iscsi_name, name_len, "%s%s", iqn_prefix, id_str); 6163 6164 *hdr = (struct scsi_transportid_header *)iscsi; 6165 6166 bailout: 6167 return (retval); 6168 } 6169 6170 /* 6171 * Parse a SCSI over PCIe (SOP) identifier. The Routing ID can either be 6172 * of the form 'bus,device,function' or 'bus,function'. 6173 */ 6174 int 6175 scsi_parse_transportid_sop(char *id_str, struct scsi_transportid_header **hdr, 6176 unsigned int *alloc_len, 6177 #ifdef _KERNEL 6178 struct malloc_type *type, int flags, 6179 #endif 6180 char *error_str, int error_str_len) 6181 { 6182 struct scsi_transportid_sop *sop; 6183 unsigned long bus, device, function; 6184 char *tmpstr, *endptr; 6185 int retval, device_spec; 6186 6187 retval = 0; 6188 device_spec = 0; 6189 device = 0; 6190 6191 tmpstr = strsep(&id_str, ","); 6192 if ((tmpstr == NULL) 6193 || (*tmpstr == '\0')) { 6194 if (error_str != NULL) { 6195 snprintf(error_str, error_str_len, "%s: no ID found", 6196 __func__); 6197 } 6198 retval = 1; 6199 goto bailout; 6200 } 6201 bus = strtoul(tmpstr, &endptr, 0); 6202 if (*endptr != '\0') { 6203 if (error_str != NULL) { 6204 snprintf(error_str, error_str_len, "%s: error " 6205 "parsing PCIe bus %s, number required", 6206 __func__, tmpstr); 6207 } 6208 retval = 1; 6209 goto bailout; 6210 } 6211 if ((id_str == NULL) 6212 || (*id_str == '\0')) { 6213 if (error_str != NULL) { 6214 snprintf(error_str, error_str_len, "%s: no PCIe " 6215 "device or function found", __func__); 6216 } 6217 retval = 1; 6218 goto bailout; 6219 } 6220 tmpstr = strsep(&id_str, ","); 6221 function = strtoul(tmpstr, &endptr, 0); 6222 if (*endptr != '\0') { 6223 if (error_str != NULL) { 6224 snprintf(error_str, error_str_len, "%s: error " 6225 "parsing PCIe device/function %s, number " 6226 "required", __func__, tmpstr); 6227 } 6228 retval = 1; 6229 goto bailout; 6230 } 6231 /* 6232 * Check to see whether the user specified a third value. If so, 6233 * the second is the device. 6234 */ 6235 if (id_str != NULL) { 6236 if (*id_str == '\0') { 6237 if (error_str != NULL) { 6238 snprintf(error_str, error_str_len, "%s: " 6239 "no PCIe function found", __func__); 6240 } 6241 retval = 1; 6242 goto bailout; 6243 } 6244 device = function; 6245 device_spec = 1; 6246 function = strtoul(id_str, &endptr, 0); 6247 if (*endptr != '\0') { 6248 if (error_str != NULL) { 6249 snprintf(error_str, error_str_len, "%s: " 6250 "error parsing PCIe function %s, " 6251 "number required", __func__, id_str); 6252 } 6253 retval = 1; 6254 goto bailout; 6255 } 6256 } 6257 if (bus > SCSI_TRN_SOP_BUS_MAX) { 6258 if (error_str != NULL) { 6259 snprintf(error_str, error_str_len, "%s: bus value " 6260 "%lu greater than maximum %u", __func__, 6261 bus, SCSI_TRN_SOP_BUS_MAX); 6262 } 6263 retval = 1; 6264 goto bailout; 6265 } 6266 6267 if ((device_spec != 0) 6268 && (device > SCSI_TRN_SOP_DEV_MASK)) { 6269 if (error_str != NULL) { 6270 snprintf(error_str, error_str_len, "%s: device value " 6271 "%lu greater than maximum %u", __func__, 6272 device, SCSI_TRN_SOP_DEV_MAX); 6273 } 6274 retval = 1; 6275 goto bailout; 6276 } 6277 6278 if (((device_spec != 0) 6279 && (function > SCSI_TRN_SOP_FUNC_NORM_MAX)) 6280 || ((device_spec == 0) 6281 && (function > SCSI_TRN_SOP_FUNC_ALT_MAX))) { 6282 if (error_str != NULL) { 6283 snprintf(error_str, error_str_len, "%s: function value " 6284 "%lu greater than maximum %u", __func__, 6285 function, (device_spec == 0) ? 6286 SCSI_TRN_SOP_FUNC_ALT_MAX : 6287 SCSI_TRN_SOP_FUNC_NORM_MAX); 6288 } 6289 retval = 1; 6290 goto bailout; 6291 } 6292 6293 #ifdef _KERNEL 6294 sop = malloc(sizeof(*sop), type, flags); 6295 #else 6296 sop = malloc(sizeof(*sop)); 6297 #endif 6298 if (sop == NULL) { 6299 if (error_str != NULL) { 6300 snprintf(error_str, error_str_len, "%s: unable to " 6301 "allocate %zu bytes", __func__, sizeof(*sop)); 6302 } 6303 retval = 1; 6304 goto bailout; 6305 } 6306 *alloc_len = sizeof(*sop); 6307 bzero(sop, sizeof(*sop)); 6308 sop->format_protocol = SCSI_PROTO_SOP | SCSI_TRN_SOP_FORMAT_DEFAULT; 6309 if (device_spec != 0) { 6310 struct scsi_sop_routing_id_norm rid; 6311 6312 rid.bus = bus; 6313 rid.devfunc = (device << SCSI_TRN_SOP_DEV_SHIFT) | function; 6314 bcopy(&rid, sop->routing_id, MIN(sizeof(rid), 6315 sizeof(sop->routing_id))); 6316 } else { 6317 struct scsi_sop_routing_id_alt rid; 6318 6319 rid.bus = bus; 6320 rid.function = function; 6321 bcopy(&rid, sop->routing_id, MIN(sizeof(rid), 6322 sizeof(sop->routing_id))); 6323 } 6324 6325 *hdr = (struct scsi_transportid_header *)sop; 6326 bailout: 6327 return (retval); 6328 } 6329 6330 /* 6331 * transportid_str: NUL-terminated string with format: protcol,id 6332 * The ID is protocol specific. 6333 * hdr: Storage will be allocated for the transport ID. 6334 * alloc_len: The amount of memory allocated is returned here. 6335 * type: Malloc bucket (kernel only). 6336 * flags: Malloc flags (kernel only). 6337 * error_str: If non-NULL, it will contain error information (without 6338 * a terminating newline) if an error is returned. 6339 * error_str_len: Allocated length of the error string. 6340 * 6341 * Returns 0 for success, non-zero for failure. 6342 */ 6343 int 6344 scsi_parse_transportid(char *transportid_str, 6345 struct scsi_transportid_header **hdr, 6346 unsigned int *alloc_len, 6347 #ifdef _KERNEL 6348 struct malloc_type *type, int flags, 6349 #endif 6350 char *error_str, int error_str_len) 6351 { 6352 char *tmpstr; 6353 scsi_nv_status status; 6354 int retval, num_proto_entries, table_entry; 6355 6356 retval = 0; 6357 table_entry = 0; 6358 6359 /* 6360 * We do allow a period as well as a comma to separate the protocol 6361 * from the ID string. This is to accommodate iSCSI names, which 6362 * start with "iqn.". 6363 */ 6364 tmpstr = strsep(&transportid_str, ",."); 6365 if (tmpstr == NULL) { 6366 if (error_str != NULL) { 6367 snprintf(error_str, error_str_len, 6368 "%s: transportid_str is NULL", __func__); 6369 } 6370 retval = 1; 6371 goto bailout; 6372 } 6373 6374 num_proto_entries = sizeof(scsi_proto_map) / 6375 sizeof(scsi_proto_map[0]); 6376 status = scsi_get_nv(scsi_proto_map, num_proto_entries, tmpstr, 6377 &table_entry, SCSI_NV_FLAG_IG_CASE); 6378 if (status != SCSI_NV_FOUND) { 6379 if (error_str != NULL) { 6380 snprintf(error_str, error_str_len, "%s: %s protocol " 6381 "name %s", __func__, 6382 (status == SCSI_NV_AMBIGUOUS) ? "ambiguous" : 6383 "invalid", tmpstr); 6384 } 6385 retval = 1; 6386 goto bailout; 6387 } 6388 switch (scsi_proto_map[table_entry].value) { 6389 case SCSI_PROTO_FC: 6390 case SCSI_PROTO_1394: 6391 case SCSI_PROTO_SAS: 6392 retval = scsi_parse_transportid_64bit( 6393 scsi_proto_map[table_entry].value, transportid_str, hdr, 6394 alloc_len, 6395 #ifdef _KERNEL 6396 type, flags, 6397 #endif 6398 error_str, error_str_len); 6399 break; 6400 case SCSI_PROTO_SPI: 6401 retval = scsi_parse_transportid_spi(transportid_str, hdr, 6402 alloc_len, 6403 #ifdef _KERNEL 6404 type, flags, 6405 #endif 6406 error_str, error_str_len); 6407 break; 6408 case SCSI_PROTO_RDMA: 6409 retval = scsi_parse_transportid_rdma(transportid_str, hdr, 6410 alloc_len, 6411 #ifdef _KERNEL 6412 type, flags, 6413 #endif 6414 error_str, error_str_len); 6415 break; 6416 case SCSI_PROTO_ISCSI: 6417 retval = scsi_parse_transportid_iscsi(transportid_str, hdr, 6418 alloc_len, 6419 #ifdef _KERNEL 6420 type, flags, 6421 #endif 6422 error_str, error_str_len); 6423 break; 6424 case SCSI_PROTO_SOP: 6425 retval = scsi_parse_transportid_sop(transportid_str, hdr, 6426 alloc_len, 6427 #ifdef _KERNEL 6428 type, flags, 6429 #endif 6430 error_str, error_str_len); 6431 break; 6432 case SCSI_PROTO_SSA: 6433 case SCSI_PROTO_ADITP: 6434 case SCSI_PROTO_ATA: 6435 case SCSI_PROTO_UAS: 6436 case SCSI_PROTO_NONE: 6437 default: 6438 /* 6439 * There is no format defined for a Transport ID for these 6440 * protocols. So even if the user gives us something, we 6441 * have no way to turn it into a standard SCSI Transport ID. 6442 */ 6443 retval = 1; 6444 if (error_str != NULL) { 6445 snprintf(error_str, error_str_len, "%s: no Transport " 6446 "ID format exists for protocol %s", 6447 __func__, tmpstr); 6448 } 6449 goto bailout; 6450 break; /* NOTREACHED */ 6451 } 6452 bailout: 6453 return (retval); 6454 } 6455 6456 struct scsi_attrib_table_entry scsi_mam_attr_table[] = { 6457 { SMA_ATTR_REM_CAP_PARTITION, SCSI_ATTR_FLAG_NONE, 6458 "Remaining Capacity in Partition", 6459 /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,/*parse_str*/ NULL }, 6460 { SMA_ATTR_MAX_CAP_PARTITION, SCSI_ATTR_FLAG_NONE, 6461 "Maximum Capacity in Partition", 6462 /*suffix*/"MB", /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL }, 6463 { SMA_ATTR_TAPEALERT_FLAGS, SCSI_ATTR_FLAG_HEX, 6464 "TapeAlert Flags", 6465 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL }, 6466 { SMA_ATTR_LOAD_COUNT, SCSI_ATTR_FLAG_NONE, 6467 "Load Count", 6468 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL }, 6469 { SMA_ATTR_MAM_SPACE_REMAINING, SCSI_ATTR_FLAG_NONE, 6470 "MAM Space Remaining", 6471 /*suffix*/"bytes", /*to_str*/ scsi_attrib_int_sbuf, 6472 /*parse_str*/ NULL }, 6473 { SMA_ATTR_DEV_ASSIGNING_ORG, SCSI_ATTR_FLAG_NONE, 6474 "Assigning Organization", 6475 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6476 /*parse_str*/ NULL }, 6477 { SMA_ATTR_FORMAT_DENSITY_CODE, SCSI_ATTR_FLAG_HEX, 6478 "Format Density Code", 6479 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL }, 6480 { SMA_ATTR_INITIALIZATION_COUNT, SCSI_ATTR_FLAG_NONE, 6481 "Initialization Count", 6482 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL }, 6483 { SMA_ATTR_VOLUME_ID, SCSI_ATTR_FLAG_NONE, 6484 "Volume Identifier", 6485 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6486 /*parse_str*/ NULL }, 6487 { SMA_ATTR_VOLUME_CHANGE_REF, SCSI_ATTR_FLAG_HEX, 6488 "Volume Change Reference", 6489 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, 6490 /*parse_str*/ NULL }, 6491 { SMA_ATTR_DEV_SERIAL_LAST_LOAD, SCSI_ATTR_FLAG_NONE, 6492 "Device Vendor/Serial at Last Load", 6493 /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf, 6494 /*parse_str*/ NULL }, 6495 { SMA_ATTR_DEV_SERIAL_LAST_LOAD_1, SCSI_ATTR_FLAG_NONE, 6496 "Device Vendor/Serial at Last Load - 1", 6497 /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf, 6498 /*parse_str*/ NULL }, 6499 { SMA_ATTR_DEV_SERIAL_LAST_LOAD_2, SCSI_ATTR_FLAG_NONE, 6500 "Device Vendor/Serial at Last Load - 2", 6501 /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf, 6502 /*parse_str*/ NULL }, 6503 { SMA_ATTR_DEV_SERIAL_LAST_LOAD_3, SCSI_ATTR_FLAG_NONE, 6504 "Device Vendor/Serial at Last Load - 3", 6505 /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf, 6506 /*parse_str*/ NULL }, 6507 { SMA_ATTR_TOTAL_MB_WRITTEN_LT, SCSI_ATTR_FLAG_NONE, 6508 "Total MB Written in Medium Life", 6509 /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf, 6510 /*parse_str*/ NULL }, 6511 { SMA_ATTR_TOTAL_MB_READ_LT, SCSI_ATTR_FLAG_NONE, 6512 "Total MB Read in Medium Life", 6513 /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf, 6514 /*parse_str*/ NULL }, 6515 { SMA_ATTR_TOTAL_MB_WRITTEN_CUR, SCSI_ATTR_FLAG_NONE, 6516 "Total MB Written in Current/Last Load", 6517 /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf, 6518 /*parse_str*/ NULL }, 6519 { SMA_ATTR_TOTAL_MB_READ_CUR, SCSI_ATTR_FLAG_NONE, 6520 "Total MB Read in Current/Last Load", 6521 /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf, 6522 /*parse_str*/ NULL }, 6523 { SMA_ATTR_FIRST_ENC_BLOCK, SCSI_ATTR_FLAG_NONE, 6524 "Logical Position of First Encrypted Block", 6525 /*suffix*/ NULL, /*to_str*/ scsi_attrib_int_sbuf, 6526 /*parse_str*/ NULL }, 6527 { SMA_ATTR_NEXT_UNENC_BLOCK, SCSI_ATTR_FLAG_NONE, 6528 "Logical Position of First Unencrypted Block after First " 6529 "Encrypted Block", 6530 /*suffix*/ NULL, /*to_str*/ scsi_attrib_int_sbuf, 6531 /*parse_str*/ NULL }, 6532 { SMA_ATTR_MEDIUM_USAGE_HIST, SCSI_ATTR_FLAG_NONE, 6533 "Medium Usage History", 6534 /*suffix*/ NULL, /*to_str*/ NULL, 6535 /*parse_str*/ NULL }, 6536 { SMA_ATTR_PART_USAGE_HIST, SCSI_ATTR_FLAG_NONE, 6537 "Partition Usage History", 6538 /*suffix*/ NULL, /*to_str*/ NULL, 6539 /*parse_str*/ NULL }, 6540 { SMA_ATTR_MED_MANUF, SCSI_ATTR_FLAG_NONE, 6541 "Medium Manufacturer", 6542 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6543 /*parse_str*/ NULL }, 6544 { SMA_ATTR_MED_SERIAL, SCSI_ATTR_FLAG_NONE, 6545 "Medium Serial Number", 6546 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6547 /*parse_str*/ NULL }, 6548 { SMA_ATTR_MED_LENGTH, SCSI_ATTR_FLAG_NONE, 6549 "Medium Length", 6550 /*suffix*/"m", /*to_str*/ scsi_attrib_int_sbuf, 6551 /*parse_str*/ NULL }, 6552 { SMA_ATTR_MED_WIDTH, SCSI_ATTR_FLAG_FP | SCSI_ATTR_FLAG_DIV_10 | 6553 SCSI_ATTR_FLAG_FP_1DIGIT, 6554 "Medium Width", 6555 /*suffix*/"mm", /*to_str*/ scsi_attrib_int_sbuf, 6556 /*parse_str*/ NULL }, 6557 { SMA_ATTR_MED_ASSIGNING_ORG, SCSI_ATTR_FLAG_NONE, 6558 "Assigning Organization", 6559 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6560 /*parse_str*/ NULL }, 6561 { SMA_ATTR_MED_DENSITY_CODE, SCSI_ATTR_FLAG_HEX, 6562 "Medium Density Code", 6563 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, 6564 /*parse_str*/ NULL }, 6565 { SMA_ATTR_MED_MANUF_DATE, SCSI_ATTR_FLAG_NONE, 6566 "Medium Manufacture Date", 6567 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6568 /*parse_str*/ NULL }, 6569 { SMA_ATTR_MAM_CAPACITY, SCSI_ATTR_FLAG_NONE, 6570 "MAM Capacity", 6571 /*suffix*/"bytes", /*to_str*/ scsi_attrib_int_sbuf, 6572 /*parse_str*/ NULL }, 6573 { SMA_ATTR_MED_TYPE, SCSI_ATTR_FLAG_HEX, 6574 "Medium Type", 6575 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, 6576 /*parse_str*/ NULL }, 6577 { SMA_ATTR_MED_TYPE_INFO, SCSI_ATTR_FLAG_HEX, 6578 "Medium Type Information", 6579 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, 6580 /*parse_str*/ NULL }, 6581 { SMA_ATTR_MED_SERIAL_NUM, SCSI_ATTR_FLAG_NONE, 6582 "Medium Serial Number", 6583 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, 6584 /*parse_str*/ NULL }, 6585 { SMA_ATTR_APP_VENDOR, SCSI_ATTR_FLAG_NONE, 6586 "Application Vendor", 6587 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6588 /*parse_str*/ NULL }, 6589 { SMA_ATTR_APP_NAME, SCSI_ATTR_FLAG_NONE, 6590 "Application Name", 6591 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6592 /*parse_str*/ NULL }, 6593 { SMA_ATTR_APP_VERSION, SCSI_ATTR_FLAG_NONE, 6594 "Application Version", 6595 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6596 /*parse_str*/ NULL }, 6597 { SMA_ATTR_USER_MED_TEXT_LABEL, SCSI_ATTR_FLAG_NONE, 6598 "User Medium Text Label", 6599 /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf, 6600 /*parse_str*/ NULL }, 6601 { SMA_ATTR_LAST_WRITTEN_TIME, SCSI_ATTR_FLAG_NONE, 6602 "Date and Time Last Written", 6603 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6604 /*parse_str*/ NULL }, 6605 { SMA_ATTR_TEXT_LOCAL_ID, SCSI_ATTR_FLAG_HEX, 6606 "Text Localization Identifier", 6607 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, 6608 /*parse_str*/ NULL }, 6609 { SMA_ATTR_BARCODE, SCSI_ATTR_FLAG_NONE, 6610 "Barcode", 6611 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6612 /*parse_str*/ NULL }, 6613 { SMA_ATTR_HOST_OWNER_NAME, SCSI_ATTR_FLAG_NONE, 6614 "Owning Host Textual Name", 6615 /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf, 6616 /*parse_str*/ NULL }, 6617 { SMA_ATTR_MEDIA_POOL, SCSI_ATTR_FLAG_NONE, 6618 "Media Pool", 6619 /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf, 6620 /*parse_str*/ NULL }, 6621 { SMA_ATTR_PART_USER_LABEL, SCSI_ATTR_FLAG_NONE, 6622 "Partition User Text Label", 6623 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6624 /*parse_str*/ NULL }, 6625 { SMA_ATTR_LOAD_UNLOAD_AT_PART, SCSI_ATTR_FLAG_NONE, 6626 "Load/Unload at Partition", 6627 /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, 6628 /*parse_str*/ NULL }, 6629 { SMA_ATTR_APP_FORMAT_VERSION, SCSI_ATTR_FLAG_NONE, 6630 "Application Format Version", 6631 /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf, 6632 /*parse_str*/ NULL }, 6633 { SMA_ATTR_VOL_COHERENCY_INFO, SCSI_ATTR_FLAG_NONE, 6634 "Volume Coherency Information", 6635 /*suffix*/NULL, /*to_str*/ scsi_attrib_volcoh_sbuf, 6636 /*parse_str*/ NULL }, 6637 { 0x0ff1, SCSI_ATTR_FLAG_NONE, 6638 "Spectra MLM Creation", 6639 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6640 /*parse_str*/ NULL }, 6641 { 0x0ff2, SCSI_ATTR_FLAG_NONE, 6642 "Spectra MLM C3", 6643 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6644 /*parse_str*/ NULL }, 6645 { 0x0ff3, SCSI_ATTR_FLAG_NONE, 6646 "Spectra MLM RW", 6647 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6648 /*parse_str*/ NULL }, 6649 { 0x0ff4, SCSI_ATTR_FLAG_NONE, 6650 "Spectra MLM SDC List", 6651 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6652 /*parse_str*/ NULL }, 6653 { 0x0ff7, SCSI_ATTR_FLAG_NONE, 6654 "Spectra MLM Post Scan", 6655 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6656 /*parse_str*/ NULL }, 6657 { 0x0ffe, SCSI_ATTR_FLAG_NONE, 6658 "Spectra MLM Checksum", 6659 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6660 /*parse_str*/ NULL }, 6661 { 0x17f1, SCSI_ATTR_FLAG_NONE, 6662 "Spectra MLM Creation", 6663 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6664 /*parse_str*/ NULL }, 6665 { 0x17f2, SCSI_ATTR_FLAG_NONE, 6666 "Spectra MLM C3", 6667 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6668 /*parse_str*/ NULL }, 6669 { 0x17f3, SCSI_ATTR_FLAG_NONE, 6670 "Spectra MLM RW", 6671 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6672 /*parse_str*/ NULL }, 6673 { 0x17f4, SCSI_ATTR_FLAG_NONE, 6674 "Spectra MLM SDC List", 6675 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6676 /*parse_str*/ NULL }, 6677 { 0x17f7, SCSI_ATTR_FLAG_NONE, 6678 "Spectra MLM Post Scan", 6679 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6680 /*parse_str*/ NULL }, 6681 { 0x17ff, SCSI_ATTR_FLAG_NONE, 6682 "Spectra MLM Checksum", 6683 /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf, 6684 /*parse_str*/ NULL }, 6685 }; 6686 6687 /* 6688 * Print out Volume Coherency Information (Attribute 0x080c). 6689 * This field has two variable length members, including one at the 6690 * beginning, so it isn't practical to have a fixed structure definition. 6691 * This is current as of SSC4r03 (see section 4.2.21.3), dated March 25, 6692 * 2013. 6693 */ 6694 int 6695 scsi_attrib_volcoh_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr, 6696 uint32_t valid_len, uint32_t flags, 6697 uint32_t output_flags, char *error_str, 6698 int error_str_len) 6699 { 6700 size_t avail_len; 6701 uint32_t field_size; 6702 uint64_t tmp_val; 6703 uint8_t *cur_ptr; 6704 int retval; 6705 int vcr_len, as_len; 6706 6707 retval = 0; 6708 tmp_val = 0; 6709 6710 field_size = scsi_2btoul(hdr->length); 6711 avail_len = valid_len - sizeof(*hdr); 6712 if (field_size > avail_len) { 6713 if (error_str != NULL) { 6714 snprintf(error_str, error_str_len, "Available " 6715 "length of attribute ID 0x%.4x %zu < field " 6716 "length %u", scsi_2btoul(hdr->id), avail_len, 6717 field_size); 6718 } 6719 retval = 1; 6720 goto bailout; 6721 } else if (field_size == 0) { 6722 /* 6723 * It isn't clear from the spec whether a field length of 6724 * 0 is invalid here. It probably is, but be lenient here 6725 * to avoid inconveniencing the user. 6726 */ 6727 goto bailout; 6728 } 6729 cur_ptr = hdr->attribute; 6730 vcr_len = *cur_ptr; 6731 cur_ptr++; 6732 6733 sbuf_printf(sb, "\n\tVolume Change Reference Value:"); 6734 6735 switch (vcr_len) { 6736 case 0: 6737 if (error_str != NULL) { 6738 snprintf(error_str, error_str_len, "Volume Change " 6739 "Reference value has length of 0"); 6740 } 6741 retval = 1; 6742 goto bailout; 6743 break; /*NOTREACHED*/ 6744 case 1: 6745 tmp_val = *cur_ptr; 6746 break; 6747 case 2: 6748 tmp_val = scsi_2btoul(cur_ptr); 6749 break; 6750 case 3: 6751 tmp_val = scsi_3btoul(cur_ptr); 6752 break; 6753 case 4: 6754 tmp_val = scsi_4btoul(cur_ptr); 6755 break; 6756 case 8: 6757 tmp_val = scsi_8btou64(cur_ptr); 6758 break; 6759 default: 6760 sbuf_printf(sb, "\n"); 6761 sbuf_hexdump(sb, cur_ptr, vcr_len, NULL, 0); 6762 break; 6763 } 6764 if (vcr_len <= 8) 6765 sbuf_printf(sb, " 0x%jx\n", (uintmax_t)tmp_val); 6766 6767 cur_ptr += vcr_len; 6768 tmp_val = scsi_8btou64(cur_ptr); 6769 sbuf_printf(sb, "\tVolume Coherency Count: %ju\n", (uintmax_t)tmp_val); 6770 6771 cur_ptr += sizeof(tmp_val); 6772 tmp_val = scsi_8btou64(cur_ptr); 6773 sbuf_printf(sb, "\tVolume Coherency Set Identifier: 0x%jx\n", 6774 (uintmax_t)tmp_val); 6775 6776 /* 6777 * Figure out how long the Application Client Specific Information 6778 * is and produce a hexdump. 6779 */ 6780 cur_ptr += sizeof(tmp_val); 6781 as_len = scsi_2btoul(cur_ptr); 6782 cur_ptr += sizeof(uint16_t); 6783 sbuf_printf(sb, "\tApplication Client Specific Information: "); 6784 if (((as_len == SCSI_LTFS_VER0_LEN) 6785 || (as_len == SCSI_LTFS_VER1_LEN)) 6786 && (strncmp(cur_ptr, SCSI_LTFS_STR_NAME, SCSI_LTFS_STR_LEN) == 0)) { 6787 sbuf_printf(sb, "LTFS\n"); 6788 cur_ptr += SCSI_LTFS_STR_LEN + 1; 6789 if (cur_ptr[SCSI_LTFS_UUID_LEN] != '\0') 6790 cur_ptr[SCSI_LTFS_UUID_LEN] = '\0'; 6791 sbuf_printf(sb, "\tLTFS UUID: %s\n", cur_ptr); 6792 cur_ptr += SCSI_LTFS_UUID_LEN + 1; 6793 /* XXX KDM check the length */ 6794 sbuf_printf(sb, "\tLTFS Version: %d\n", *cur_ptr); 6795 } else { 6796 sbuf_printf(sb, "Unknown\n"); 6797 sbuf_hexdump(sb, cur_ptr, as_len, NULL, 0); 6798 } 6799 6800 bailout: 6801 return (retval); 6802 } 6803 6804 int 6805 scsi_attrib_vendser_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr, 6806 uint32_t valid_len, uint32_t flags, 6807 uint32_t output_flags, char *error_str, 6808 int error_str_len) 6809 { 6810 size_t avail_len; 6811 uint32_t field_size; 6812 struct scsi_attrib_vendser *vendser; 6813 cam_strvis_flags strvis_flags; 6814 int retval = 0; 6815 6816 field_size = scsi_2btoul(hdr->length); 6817 avail_len = valid_len - sizeof(*hdr); 6818 if (field_size > avail_len) { 6819 if (error_str != NULL) { 6820 snprintf(error_str, error_str_len, "Available " 6821 "length of attribute ID 0x%.4x %zu < field " 6822 "length %u", scsi_2btoul(hdr->id), avail_len, 6823 field_size); 6824 } 6825 retval = 1; 6826 goto bailout; 6827 } else if (field_size == 0) { 6828 /* 6829 * A field size of 0 doesn't make sense here. The device 6830 * can at least give you the vendor ID, even if it can't 6831 * give you the serial number. 6832 */ 6833 if (error_str != NULL) { 6834 snprintf(error_str, error_str_len, "The length of " 6835 "attribute ID 0x%.4x is 0", 6836 scsi_2btoul(hdr->id)); 6837 } 6838 retval = 1; 6839 goto bailout; 6840 } 6841 vendser = (struct scsi_attrib_vendser *)hdr->attribute; 6842 6843 switch (output_flags & SCSI_ATTR_OUTPUT_NONASCII_MASK) { 6844 case SCSI_ATTR_OUTPUT_NONASCII_TRIM: 6845 strvis_flags = CAM_STRVIS_FLAG_NONASCII_TRIM; 6846 break; 6847 case SCSI_ATTR_OUTPUT_NONASCII_RAW: 6848 strvis_flags = CAM_STRVIS_FLAG_NONASCII_RAW; 6849 break; 6850 case SCSI_ATTR_OUTPUT_NONASCII_ESC: 6851 default: 6852 strvis_flags = CAM_STRVIS_FLAG_NONASCII_ESC; 6853 break;; 6854 } 6855 cam_strvis_sbuf(sb, vendser->vendor, sizeof(vendser->vendor), 6856 strvis_flags); 6857 sbuf_putc(sb, ' '); 6858 cam_strvis_sbuf(sb, vendser->serial_num, sizeof(vendser->serial_num), 6859 strvis_flags); 6860 bailout: 6861 return (retval); 6862 } 6863 6864 int 6865 scsi_attrib_hexdump_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr, 6866 uint32_t valid_len, uint32_t flags, 6867 uint32_t output_flags, char *error_str, 6868 int error_str_len) 6869 { 6870 uint32_t field_size; 6871 ssize_t avail_len; 6872 uint32_t print_len; 6873 uint8_t *num_ptr; 6874 int retval = 0; 6875 6876 field_size = scsi_2btoul(hdr->length); 6877 avail_len = valid_len - sizeof(*hdr); 6878 print_len = MIN(avail_len, field_size); 6879 num_ptr = hdr->attribute; 6880 6881 if (print_len > 0) { 6882 sbuf_printf(sb, "\n"); 6883 sbuf_hexdump(sb, num_ptr, print_len, NULL, 0); 6884 } 6885 6886 return (retval); 6887 } 6888 6889 int 6890 scsi_attrib_int_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr, 6891 uint32_t valid_len, uint32_t flags, 6892 uint32_t output_flags, char *error_str, 6893 int error_str_len) 6894 { 6895 uint64_t print_number; 6896 size_t avail_len; 6897 uint32_t number_size; 6898 int retval = 0; 6899 6900 number_size = scsi_2btoul(hdr->length); 6901 6902 avail_len = valid_len - sizeof(*hdr); 6903 if (avail_len < number_size) { 6904 if (error_str != NULL) { 6905 snprintf(error_str, error_str_len, "Available " 6906 "length of attribute ID 0x%.4x %zu < field " 6907 "length %u", scsi_2btoul(hdr->id), avail_len, 6908 number_size); 6909 } 6910 retval = 1; 6911 goto bailout; 6912 } 6913 6914 switch (number_size) { 6915 case 0: 6916 /* 6917 * We don't treat this as an error, since there may be 6918 * scenarios where a device reports a field but then gives 6919 * a length of 0. See the note in scsi_attrib_ascii_sbuf(). 6920 */ 6921 goto bailout; 6922 break; /*NOTREACHED*/ 6923 case 1: 6924 print_number = hdr->attribute[0]; 6925 break; 6926 case 2: 6927 print_number = scsi_2btoul(hdr->attribute); 6928 break; 6929 case 3: 6930 print_number = scsi_3btoul(hdr->attribute); 6931 break; 6932 case 4: 6933 print_number = scsi_4btoul(hdr->attribute); 6934 break; 6935 case 8: 6936 print_number = scsi_8btou64(hdr->attribute); 6937 break; 6938 default: 6939 /* 6940 * If we wind up here, the number is too big to print 6941 * normally, so just do a hexdump. 6942 */ 6943 retval = scsi_attrib_hexdump_sbuf(sb, hdr, valid_len, 6944 flags, output_flags, 6945 error_str, error_str_len); 6946 goto bailout; 6947 break; 6948 } 6949 6950 if (flags & SCSI_ATTR_FLAG_FP) { 6951 #ifndef _KERNEL 6952 long double num_float; 6953 6954 num_float = (long double)print_number; 6955 6956 if (flags & SCSI_ATTR_FLAG_DIV_10) 6957 num_float /= 10; 6958 6959 sbuf_printf(sb, "%.*Lf", (flags & SCSI_ATTR_FLAG_FP_1DIGIT) ? 6960 1 : 0, num_float); 6961 #else /* _KERNEL */ 6962 sbuf_printf(sb, "%ju", (flags & SCSI_ATTR_FLAG_DIV_10) ? 6963 (print_number / 10) : print_number); 6964 #endif /* _KERNEL */ 6965 } else if (flags & SCSI_ATTR_FLAG_HEX) { 6966 sbuf_printf(sb, "0x%jx", (uintmax_t)print_number); 6967 } else 6968 sbuf_printf(sb, "%ju", (uintmax_t)print_number); 6969 6970 bailout: 6971 return (retval); 6972 } 6973 6974 int 6975 scsi_attrib_ascii_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr, 6976 uint32_t valid_len, uint32_t flags, 6977 uint32_t output_flags, char *error_str, 6978 int error_str_len) 6979 { 6980 size_t avail_len; 6981 uint32_t field_size, print_size; 6982 int retval = 0; 6983 6984 avail_len = valid_len - sizeof(*hdr); 6985 field_size = scsi_2btoul(hdr->length); 6986 print_size = MIN(avail_len, field_size); 6987 6988 if (print_size > 0) { 6989 cam_strvis_flags strvis_flags; 6990 6991 switch (output_flags & SCSI_ATTR_OUTPUT_NONASCII_MASK) { 6992 case SCSI_ATTR_OUTPUT_NONASCII_TRIM: 6993 strvis_flags = CAM_STRVIS_FLAG_NONASCII_TRIM; 6994 break; 6995 case SCSI_ATTR_OUTPUT_NONASCII_RAW: 6996 strvis_flags = CAM_STRVIS_FLAG_NONASCII_RAW; 6997 break; 6998 case SCSI_ATTR_OUTPUT_NONASCII_ESC: 6999 default: 7000 strvis_flags = CAM_STRVIS_FLAG_NONASCII_ESC; 7001 break; 7002 } 7003 cam_strvis_sbuf(sb, hdr->attribute, print_size, strvis_flags); 7004 } else if (avail_len < field_size) { 7005 /* 7006 * We only report an error if the user didn't allocate 7007 * enough space to hold the full value of this field. If 7008 * the field length is 0, that is allowed by the spec. 7009 * e.g. in SPC-4r37, section 7.4.2.2.5, VOLUME IDENTIFIER 7010 * "This attribute indicates the current volume identifier 7011 * (see SMC-3) of the medium. If the device server supports 7012 * this attribute but does not have access to the volume 7013 * identifier, the device server shall report this attribute 7014 * with an attribute length value of zero." 7015 */ 7016 if (error_str != NULL) { 7017 snprintf(error_str, error_str_len, "Available " 7018 "length of attribute ID 0x%.4x %zu < field " 7019 "length %u", scsi_2btoul(hdr->id), avail_len, 7020 field_size); 7021 } 7022 retval = 1; 7023 } 7024 7025 return (retval); 7026 } 7027 7028 int 7029 scsi_attrib_text_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr, 7030 uint32_t valid_len, uint32_t flags, 7031 uint32_t output_flags, char *error_str, 7032 int error_str_len) 7033 { 7034 size_t avail_len; 7035 uint32_t field_size, print_size; 7036 int retval = 0; 7037 int esc_text = 1; 7038 7039 avail_len = valid_len - sizeof(*hdr); 7040 field_size = scsi_2btoul(hdr->length); 7041 print_size = MIN(avail_len, field_size); 7042 7043 if ((output_flags & SCSI_ATTR_OUTPUT_TEXT_MASK) == 7044 SCSI_ATTR_OUTPUT_TEXT_RAW) 7045 esc_text = 0; 7046 7047 if (print_size > 0) { 7048 uint32_t i; 7049 7050 for (i = 0; i < print_size; i++) { 7051 if (hdr->attribute[i] == '\0') 7052 continue; 7053 else if (((unsigned char)hdr->attribute[i] < 0x80) 7054 || (esc_text == 0)) 7055 sbuf_putc(sb, hdr->attribute[i]); 7056 else 7057 sbuf_printf(sb, "%%%02x", 7058 (unsigned char)hdr->attribute[i]); 7059 } 7060 } else if (avail_len < field_size) { 7061 /* 7062 * We only report an error if the user didn't allocate 7063 * enough space to hold the full value of this field. 7064 */ 7065 if (error_str != NULL) { 7066 snprintf(error_str, error_str_len, "Available " 7067 "length of attribute ID 0x%.4x %zu < field " 7068 "length %u", scsi_2btoul(hdr->id), avail_len, 7069 field_size); 7070 } 7071 retval = 1; 7072 } 7073 7074 return (retval); 7075 } 7076 7077 struct scsi_attrib_table_entry * 7078 scsi_find_attrib_entry(struct scsi_attrib_table_entry *table, 7079 size_t num_table_entries, uint32_t id) 7080 { 7081 uint32_t i; 7082 7083 for (i = 0; i < num_table_entries; i++) { 7084 if (table[i].id == id) 7085 return (&table[i]); 7086 } 7087 7088 return (NULL); 7089 } 7090 7091 struct scsi_attrib_table_entry * 7092 scsi_get_attrib_entry(uint32_t id) 7093 { 7094 return (scsi_find_attrib_entry(scsi_mam_attr_table, 7095 sizeof(scsi_mam_attr_table) / sizeof(scsi_mam_attr_table[0]), 7096 id)); 7097 } 7098 7099 int 7100 scsi_attrib_value_sbuf(struct sbuf *sb, uint32_t valid_len, 7101 struct scsi_mam_attribute_header *hdr, uint32_t output_flags, 7102 char *error_str, size_t error_str_len) 7103 { 7104 int retval; 7105 7106 switch (hdr->byte2 & SMA_FORMAT_MASK) { 7107 case SMA_FORMAT_ASCII: 7108 retval = scsi_attrib_ascii_sbuf(sb, hdr, valid_len, 7109 SCSI_ATTR_FLAG_NONE, output_flags, error_str,error_str_len); 7110 break; 7111 case SMA_FORMAT_BINARY: 7112 if (scsi_2btoul(hdr->length) <= 8) 7113 retval = scsi_attrib_int_sbuf(sb, hdr, valid_len, 7114 SCSI_ATTR_FLAG_NONE, output_flags, error_str, 7115 error_str_len); 7116 else 7117 retval = scsi_attrib_hexdump_sbuf(sb, hdr, valid_len, 7118 SCSI_ATTR_FLAG_NONE, output_flags, error_str, 7119 error_str_len); 7120 break; 7121 case SMA_FORMAT_TEXT: 7122 retval = scsi_attrib_text_sbuf(sb, hdr, valid_len, 7123 SCSI_ATTR_FLAG_NONE, output_flags, error_str, 7124 error_str_len); 7125 break; 7126 default: 7127 if (error_str != NULL) { 7128 snprintf(error_str, error_str_len, "Unknown attribute " 7129 "format 0x%x", hdr->byte2 & SMA_FORMAT_MASK); 7130 } 7131 retval = 1; 7132 goto bailout; 7133 break; /*NOTREACHED*/ 7134 } 7135 7136 sbuf_trim(sb); 7137 7138 bailout: 7139 7140 return (retval); 7141 } 7142 7143 void 7144 scsi_attrib_prefix_sbuf(struct sbuf *sb, uint32_t output_flags, 7145 struct scsi_mam_attribute_header *hdr, 7146 uint32_t valid_len, const char *desc) 7147 { 7148 int need_space = 0; 7149 uint32_t len; 7150 uint32_t id; 7151 7152 /* 7153 * We can't do anything if we don't have enough valid data for the 7154 * header. 7155 */ 7156 if (valid_len < sizeof(*hdr)) 7157 return; 7158 7159 id = scsi_2btoul(hdr->id); 7160 /* 7161 * Note that we print out the value of the attribute listed in the 7162 * header, regardless of whether we actually got that many bytes 7163 * back from the device through the controller. A truncated result 7164 * could be the result of a failure to ask for enough data; the 7165 * header indicates how many bytes are allocated for this attribute 7166 * in the MAM. 7167 */ 7168 len = scsi_2btoul(hdr->length); 7169 7170 if ((output_flags & SCSI_ATTR_OUTPUT_FIELD_MASK) == 7171 SCSI_ATTR_OUTPUT_FIELD_NONE) 7172 return; 7173 7174 if ((output_flags & SCSI_ATTR_OUTPUT_FIELD_DESC) 7175 && (desc != NULL)) { 7176 sbuf_printf(sb, "%s", desc); 7177 need_space = 1; 7178 } 7179 7180 if (output_flags & SCSI_ATTR_OUTPUT_FIELD_NUM) { 7181 sbuf_printf(sb, "%s(0x%.4x)", (need_space) ? " " : "", id); 7182 need_space = 0; 7183 } 7184 7185 if (output_flags & SCSI_ATTR_OUTPUT_FIELD_SIZE) { 7186 sbuf_printf(sb, "%s[%d]", (need_space) ? " " : "", len); 7187 need_space = 0; 7188 } 7189 if (output_flags & SCSI_ATTR_OUTPUT_FIELD_RW) { 7190 sbuf_printf(sb, "%s(%s)", (need_space) ? " " : "", 7191 (hdr->byte2 & SMA_READ_ONLY) ? "RO" : "RW"); 7192 } 7193 sbuf_printf(sb, ": "); 7194 } 7195 7196 int 7197 scsi_attrib_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr, 7198 uint32_t valid_len, struct scsi_attrib_table_entry *user_table, 7199 size_t num_user_entries, int prefer_user_table, 7200 uint32_t output_flags, char *error_str, int error_str_len) 7201 { 7202 int retval; 7203 struct scsi_attrib_table_entry *table1 = NULL, *table2 = NULL; 7204 struct scsi_attrib_table_entry *entry = NULL; 7205 size_t table1_size = 0, table2_size = 0; 7206 uint32_t id; 7207 7208 retval = 0; 7209 7210 if (valid_len < sizeof(*hdr)) { 7211 retval = 1; 7212 goto bailout; 7213 } 7214 7215 id = scsi_2btoul(hdr->id); 7216 7217 if (user_table != NULL) { 7218 if (prefer_user_table != 0) { 7219 table1 = user_table; 7220 table1_size = num_user_entries; 7221 table2 = scsi_mam_attr_table; 7222 table2_size = sizeof(scsi_mam_attr_table) / 7223 sizeof(scsi_mam_attr_table[0]); 7224 } else { 7225 table1 = scsi_mam_attr_table; 7226 table1_size = sizeof(scsi_mam_attr_table) / 7227 sizeof(scsi_mam_attr_table[0]); 7228 table2 = user_table; 7229 table2_size = num_user_entries; 7230 } 7231 } else { 7232 table1 = scsi_mam_attr_table; 7233 table1_size = sizeof(scsi_mam_attr_table) / 7234 sizeof(scsi_mam_attr_table[0]); 7235 } 7236 7237 entry = scsi_find_attrib_entry(table1, table1_size, id); 7238 if (entry != NULL) { 7239 scsi_attrib_prefix_sbuf(sb, output_flags, hdr, valid_len, 7240 entry->desc); 7241 if (entry->to_str == NULL) 7242 goto print_default; 7243 retval = entry->to_str(sb, hdr, valid_len, entry->flags, 7244 output_flags, error_str, error_str_len); 7245 goto bailout; 7246 } 7247 if (table2 != NULL) { 7248 entry = scsi_find_attrib_entry(table2, table2_size, id); 7249 if (entry != NULL) { 7250 if (entry->to_str == NULL) 7251 goto print_default; 7252 7253 scsi_attrib_prefix_sbuf(sb, output_flags, hdr, 7254 valid_len, entry->desc); 7255 retval = entry->to_str(sb, hdr, valid_len, entry->flags, 7256 output_flags, error_str, 7257 error_str_len); 7258 goto bailout; 7259 } 7260 } 7261 7262 scsi_attrib_prefix_sbuf(sb, output_flags, hdr, valid_len, NULL); 7263 7264 print_default: 7265 retval = scsi_attrib_value_sbuf(sb, valid_len, hdr, output_flags, 7266 error_str, error_str_len); 7267 bailout: 7268 if (retval == 0) { 7269 if ((entry != NULL) 7270 && (entry->suffix != NULL)) 7271 sbuf_printf(sb, " %s", entry->suffix); 7272 7273 sbuf_trim(sb); 7274 sbuf_printf(sb, "\n"); 7275 } 7276 7277 return (retval); 7278 } 7279 7280 void 7281 scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries, 7282 void (*cbfcnp)(struct cam_periph *, union ccb *), 7283 u_int8_t tag_action, u_int8_t sense_len, u_int32_t timeout) 7284 { 7285 struct scsi_test_unit_ready *scsi_cmd; 7286 7287 cam_fill_csio(csio, 7288 retries, 7289 cbfcnp, 7290 CAM_DIR_NONE, 7291 tag_action, 7292 /*data_ptr*/NULL, 7293 /*dxfer_len*/0, 7294 sense_len, 7295 sizeof(*scsi_cmd), 7296 timeout); 7297 7298 scsi_cmd = (struct scsi_test_unit_ready *)&csio->cdb_io.cdb_bytes; 7299 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7300 scsi_cmd->opcode = TEST_UNIT_READY; 7301 } 7302 7303 void 7304 scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries, 7305 void (*cbfcnp)(struct cam_periph *, union ccb *), 7306 void *data_ptr, u_int8_t dxfer_len, u_int8_t tag_action, 7307 u_int8_t sense_len, u_int32_t timeout) 7308 { 7309 struct scsi_request_sense *scsi_cmd; 7310 7311 cam_fill_csio(csio, 7312 retries, 7313 cbfcnp, 7314 CAM_DIR_IN, 7315 tag_action, 7316 data_ptr, 7317 dxfer_len, 7318 sense_len, 7319 sizeof(*scsi_cmd), 7320 timeout); 7321 7322 scsi_cmd = (struct scsi_request_sense *)&csio->cdb_io.cdb_bytes; 7323 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7324 scsi_cmd->opcode = REQUEST_SENSE; 7325 scsi_cmd->length = dxfer_len; 7326 } 7327 7328 void 7329 scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries, 7330 void (*cbfcnp)(struct cam_periph *, union ccb *), 7331 u_int8_t tag_action, u_int8_t *inq_buf, u_int32_t inq_len, 7332 int evpd, u_int8_t page_code, u_int8_t sense_len, 7333 u_int32_t timeout) 7334 { 7335 struct scsi_inquiry *scsi_cmd; 7336 7337 cam_fill_csio(csio, 7338 retries, 7339 cbfcnp, 7340 /*flags*/CAM_DIR_IN, 7341 tag_action, 7342 /*data_ptr*/inq_buf, 7343 /*dxfer_len*/inq_len, 7344 sense_len, 7345 sizeof(*scsi_cmd), 7346 timeout); 7347 7348 scsi_cmd = (struct scsi_inquiry *)&csio->cdb_io.cdb_bytes; 7349 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7350 scsi_cmd->opcode = INQUIRY; 7351 if (evpd) { 7352 scsi_cmd->byte2 |= SI_EVPD; 7353 scsi_cmd->page_code = page_code; 7354 } 7355 scsi_ulto2b(inq_len, scsi_cmd->length); 7356 } 7357 7358 void 7359 scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries, 7360 void (*cbfcnp)(struct cam_periph *, union ccb *), 7361 u_int8_t tag_action, int dbd, u_int8_t page_code, 7362 u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, 7363 u_int8_t sense_len, u_int32_t timeout) 7364 { 7365 7366 scsi_mode_sense_len(csio, retries, cbfcnp, tag_action, dbd, 7367 page_code, page, param_buf, param_len, 0, 7368 sense_len, timeout); 7369 } 7370 7371 void 7372 scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries, 7373 void (*cbfcnp)(struct cam_periph *, union ccb *), 7374 u_int8_t tag_action, int dbd, u_int8_t page_code, 7375 u_int8_t page, u_int8_t *param_buf, u_int32_t param_len, 7376 int minimum_cmd_size, u_int8_t sense_len, u_int32_t timeout) 7377 { 7378 u_int8_t cdb_len; 7379 7380 /* 7381 * Use the smallest possible command to perform the operation. 7382 */ 7383 if ((param_len < 256) 7384 && (minimum_cmd_size < 10)) { 7385 /* 7386 * We can fit in a 6 byte cdb. 7387 */ 7388 struct scsi_mode_sense_6 *scsi_cmd; 7389 7390 scsi_cmd = (struct scsi_mode_sense_6 *)&csio->cdb_io.cdb_bytes; 7391 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7392 scsi_cmd->opcode = MODE_SENSE_6; 7393 if (dbd != 0) 7394 scsi_cmd->byte2 |= SMS_DBD; 7395 scsi_cmd->page = page_code | page; 7396 scsi_cmd->length = param_len; 7397 cdb_len = sizeof(*scsi_cmd); 7398 } else { 7399 /* 7400 * Need a 10 byte cdb. 7401 */ 7402 struct scsi_mode_sense_10 *scsi_cmd; 7403 7404 scsi_cmd = (struct scsi_mode_sense_10 *)&csio->cdb_io.cdb_bytes; 7405 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7406 scsi_cmd->opcode = MODE_SENSE_10; 7407 if (dbd != 0) 7408 scsi_cmd->byte2 |= SMS_DBD; 7409 scsi_cmd->page = page_code | page; 7410 scsi_ulto2b(param_len, scsi_cmd->length); 7411 cdb_len = sizeof(*scsi_cmd); 7412 } 7413 cam_fill_csio(csio, 7414 retries, 7415 cbfcnp, 7416 CAM_DIR_IN, 7417 tag_action, 7418 param_buf, 7419 param_len, 7420 sense_len, 7421 cdb_len, 7422 timeout); 7423 } 7424 7425 void 7426 scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries, 7427 void (*cbfcnp)(struct cam_periph *, union ccb *), 7428 u_int8_t tag_action, int scsi_page_fmt, int save_pages, 7429 u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, 7430 u_int32_t timeout) 7431 { 7432 scsi_mode_select_len(csio, retries, cbfcnp, tag_action, 7433 scsi_page_fmt, save_pages, param_buf, 7434 param_len, 0, sense_len, timeout); 7435 } 7436 7437 void 7438 scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries, 7439 void (*cbfcnp)(struct cam_periph *, union ccb *), 7440 u_int8_t tag_action, int scsi_page_fmt, int save_pages, 7441 u_int8_t *param_buf, u_int32_t param_len, 7442 int minimum_cmd_size, u_int8_t sense_len, 7443 u_int32_t timeout) 7444 { 7445 u_int8_t cdb_len; 7446 7447 /* 7448 * Use the smallest possible command to perform the operation. 7449 */ 7450 if ((param_len < 256) 7451 && (minimum_cmd_size < 10)) { 7452 /* 7453 * We can fit in a 6 byte cdb. 7454 */ 7455 struct scsi_mode_select_6 *scsi_cmd; 7456 7457 scsi_cmd = (struct scsi_mode_select_6 *)&csio->cdb_io.cdb_bytes; 7458 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7459 scsi_cmd->opcode = MODE_SELECT_6; 7460 if (scsi_page_fmt != 0) 7461 scsi_cmd->byte2 |= SMS_PF; 7462 if (save_pages != 0) 7463 scsi_cmd->byte2 |= SMS_SP; 7464 scsi_cmd->length = param_len; 7465 cdb_len = sizeof(*scsi_cmd); 7466 } else { 7467 /* 7468 * Need a 10 byte cdb. 7469 */ 7470 struct scsi_mode_select_10 *scsi_cmd; 7471 7472 scsi_cmd = 7473 (struct scsi_mode_select_10 *)&csio->cdb_io.cdb_bytes; 7474 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7475 scsi_cmd->opcode = MODE_SELECT_10; 7476 if (scsi_page_fmt != 0) 7477 scsi_cmd->byte2 |= SMS_PF; 7478 if (save_pages != 0) 7479 scsi_cmd->byte2 |= SMS_SP; 7480 scsi_ulto2b(param_len, scsi_cmd->length); 7481 cdb_len = sizeof(*scsi_cmd); 7482 } 7483 cam_fill_csio(csio, 7484 retries, 7485 cbfcnp, 7486 CAM_DIR_OUT, 7487 tag_action, 7488 param_buf, 7489 param_len, 7490 sense_len, 7491 cdb_len, 7492 timeout); 7493 } 7494 7495 void 7496 scsi_log_sense(struct ccb_scsiio *csio, u_int32_t retries, 7497 void (*cbfcnp)(struct cam_periph *, union ccb *), 7498 u_int8_t tag_action, u_int8_t page_code, u_int8_t page, 7499 int save_pages, int ppc, u_int32_t paramptr, 7500 u_int8_t *param_buf, u_int32_t param_len, u_int8_t sense_len, 7501 u_int32_t timeout) 7502 { 7503 struct scsi_log_sense *scsi_cmd; 7504 u_int8_t cdb_len; 7505 7506 scsi_cmd = (struct scsi_log_sense *)&csio->cdb_io.cdb_bytes; 7507 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7508 scsi_cmd->opcode = LOG_SENSE; 7509 scsi_cmd->page = page_code | page; 7510 if (save_pages != 0) 7511 scsi_cmd->byte2 |= SLS_SP; 7512 if (ppc != 0) 7513 scsi_cmd->byte2 |= SLS_PPC; 7514 scsi_ulto2b(paramptr, scsi_cmd->paramptr); 7515 scsi_ulto2b(param_len, scsi_cmd->length); 7516 cdb_len = sizeof(*scsi_cmd); 7517 7518 cam_fill_csio(csio, 7519 retries, 7520 cbfcnp, 7521 /*flags*/CAM_DIR_IN, 7522 tag_action, 7523 /*data_ptr*/param_buf, 7524 /*dxfer_len*/param_len, 7525 sense_len, 7526 cdb_len, 7527 timeout); 7528 } 7529 7530 void 7531 scsi_log_select(struct ccb_scsiio *csio, u_int32_t retries, 7532 void (*cbfcnp)(struct cam_periph *, union ccb *), 7533 u_int8_t tag_action, u_int8_t page_code, int save_pages, 7534 int pc_reset, u_int8_t *param_buf, u_int32_t param_len, 7535 u_int8_t sense_len, u_int32_t timeout) 7536 { 7537 struct scsi_log_select *scsi_cmd; 7538 u_int8_t cdb_len; 7539 7540 scsi_cmd = (struct scsi_log_select *)&csio->cdb_io.cdb_bytes; 7541 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7542 scsi_cmd->opcode = LOG_SELECT; 7543 scsi_cmd->page = page_code & SLS_PAGE_CODE; 7544 if (save_pages != 0) 7545 scsi_cmd->byte2 |= SLS_SP; 7546 if (pc_reset != 0) 7547 scsi_cmd->byte2 |= SLS_PCR; 7548 scsi_ulto2b(param_len, scsi_cmd->length); 7549 cdb_len = sizeof(*scsi_cmd); 7550 7551 cam_fill_csio(csio, 7552 retries, 7553 cbfcnp, 7554 /*flags*/CAM_DIR_OUT, 7555 tag_action, 7556 /*data_ptr*/param_buf, 7557 /*dxfer_len*/param_len, 7558 sense_len, 7559 cdb_len, 7560 timeout); 7561 } 7562 7563 /* 7564 * Prevent or allow the user to remove the media 7565 */ 7566 void 7567 scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries, 7568 void (*cbfcnp)(struct cam_periph *, union ccb *), 7569 u_int8_t tag_action, u_int8_t action, 7570 u_int8_t sense_len, u_int32_t timeout) 7571 { 7572 struct scsi_prevent *scsi_cmd; 7573 7574 cam_fill_csio(csio, 7575 retries, 7576 cbfcnp, 7577 /*flags*/CAM_DIR_NONE, 7578 tag_action, 7579 /*data_ptr*/NULL, 7580 /*dxfer_len*/0, 7581 sense_len, 7582 sizeof(*scsi_cmd), 7583 timeout); 7584 7585 scsi_cmd = (struct scsi_prevent *)&csio->cdb_io.cdb_bytes; 7586 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7587 scsi_cmd->opcode = PREVENT_ALLOW; 7588 scsi_cmd->how = action; 7589 } 7590 7591 /* XXX allow specification of address and PMI bit and LBA */ 7592 void 7593 scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries, 7594 void (*cbfcnp)(struct cam_periph *, union ccb *), 7595 u_int8_t tag_action, 7596 struct scsi_read_capacity_data *rcap_buf, 7597 u_int8_t sense_len, u_int32_t timeout) 7598 { 7599 struct scsi_read_capacity *scsi_cmd; 7600 7601 cam_fill_csio(csio, 7602 retries, 7603 cbfcnp, 7604 /*flags*/CAM_DIR_IN, 7605 tag_action, 7606 /*data_ptr*/(u_int8_t *)rcap_buf, 7607 /*dxfer_len*/sizeof(*rcap_buf), 7608 sense_len, 7609 sizeof(*scsi_cmd), 7610 timeout); 7611 7612 scsi_cmd = (struct scsi_read_capacity *)&csio->cdb_io.cdb_bytes; 7613 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7614 scsi_cmd->opcode = READ_CAPACITY; 7615 } 7616 7617 void 7618 scsi_read_capacity_16(struct ccb_scsiio *csio, uint32_t retries, 7619 void (*cbfcnp)(struct cam_periph *, union ccb *), 7620 uint8_t tag_action, uint64_t lba, int reladr, int pmi, 7621 uint8_t *rcap_buf, int rcap_buf_len, uint8_t sense_len, 7622 uint32_t timeout) 7623 { 7624 struct scsi_read_capacity_16 *scsi_cmd; 7625 7626 7627 cam_fill_csio(csio, 7628 retries, 7629 cbfcnp, 7630 /*flags*/CAM_DIR_IN, 7631 tag_action, 7632 /*data_ptr*/(u_int8_t *)rcap_buf, 7633 /*dxfer_len*/rcap_buf_len, 7634 sense_len, 7635 sizeof(*scsi_cmd), 7636 timeout); 7637 scsi_cmd = (struct scsi_read_capacity_16 *)&csio->cdb_io.cdb_bytes; 7638 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7639 scsi_cmd->opcode = SERVICE_ACTION_IN; 7640 scsi_cmd->service_action = SRC16_SERVICE_ACTION; 7641 scsi_u64to8b(lba, scsi_cmd->addr); 7642 scsi_ulto4b(rcap_buf_len, scsi_cmd->alloc_len); 7643 if (pmi) 7644 reladr |= SRC16_PMI; 7645 if (reladr) 7646 reladr |= SRC16_RELADR; 7647 } 7648 7649 void 7650 scsi_report_luns(struct ccb_scsiio *csio, u_int32_t retries, 7651 void (*cbfcnp)(struct cam_periph *, union ccb *), 7652 u_int8_t tag_action, u_int8_t select_report, 7653 struct scsi_report_luns_data *rpl_buf, u_int32_t alloc_len, 7654 u_int8_t sense_len, u_int32_t timeout) 7655 { 7656 struct scsi_report_luns *scsi_cmd; 7657 7658 cam_fill_csio(csio, 7659 retries, 7660 cbfcnp, 7661 /*flags*/CAM_DIR_IN, 7662 tag_action, 7663 /*data_ptr*/(u_int8_t *)rpl_buf, 7664 /*dxfer_len*/alloc_len, 7665 sense_len, 7666 sizeof(*scsi_cmd), 7667 timeout); 7668 scsi_cmd = (struct scsi_report_luns *)&csio->cdb_io.cdb_bytes; 7669 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7670 scsi_cmd->opcode = REPORT_LUNS; 7671 scsi_cmd->select_report = select_report; 7672 scsi_ulto4b(alloc_len, scsi_cmd->length); 7673 } 7674 7675 void 7676 scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries, 7677 void (*cbfcnp)(struct cam_periph *, union ccb *), 7678 u_int8_t tag_action, u_int8_t pdf, 7679 void *buf, u_int32_t alloc_len, 7680 u_int8_t sense_len, u_int32_t timeout) 7681 { 7682 struct scsi_target_group *scsi_cmd; 7683 7684 cam_fill_csio(csio, 7685 retries, 7686 cbfcnp, 7687 /*flags*/CAM_DIR_IN, 7688 tag_action, 7689 /*data_ptr*/(u_int8_t *)buf, 7690 /*dxfer_len*/alloc_len, 7691 sense_len, 7692 sizeof(*scsi_cmd), 7693 timeout); 7694 scsi_cmd = (struct scsi_target_group *)&csio->cdb_io.cdb_bytes; 7695 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7696 scsi_cmd->opcode = MAINTENANCE_IN; 7697 scsi_cmd->service_action = REPORT_TARGET_PORT_GROUPS | pdf; 7698 scsi_ulto4b(alloc_len, scsi_cmd->length); 7699 } 7700 7701 void 7702 scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries, 7703 void (*cbfcnp)(struct cam_periph *, union ccb *), 7704 u_int8_t tag_action, void *buf, u_int32_t alloc_len, 7705 u_int8_t sense_len, u_int32_t timeout) 7706 { 7707 struct scsi_target_group *scsi_cmd; 7708 7709 cam_fill_csio(csio, 7710 retries, 7711 cbfcnp, 7712 /*flags*/CAM_DIR_OUT, 7713 tag_action, 7714 /*data_ptr*/(u_int8_t *)buf, 7715 /*dxfer_len*/alloc_len, 7716 sense_len, 7717 sizeof(*scsi_cmd), 7718 timeout); 7719 scsi_cmd = (struct scsi_target_group *)&csio->cdb_io.cdb_bytes; 7720 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7721 scsi_cmd->opcode = MAINTENANCE_OUT; 7722 scsi_cmd->service_action = SET_TARGET_PORT_GROUPS; 7723 scsi_ulto4b(alloc_len, scsi_cmd->length); 7724 } 7725 7726 /* 7727 * Syncronize the media to the contents of the cache for 7728 * the given lba/count pair. Specifying 0/0 means sync 7729 * the whole cache. 7730 */ 7731 void 7732 scsi_synchronize_cache(struct ccb_scsiio *csio, u_int32_t retries, 7733 void (*cbfcnp)(struct cam_periph *, union ccb *), 7734 u_int8_t tag_action, u_int32_t begin_lba, 7735 u_int16_t lb_count, u_int8_t sense_len, 7736 u_int32_t timeout) 7737 { 7738 struct scsi_sync_cache *scsi_cmd; 7739 7740 cam_fill_csio(csio, 7741 retries, 7742 cbfcnp, 7743 /*flags*/CAM_DIR_NONE, 7744 tag_action, 7745 /*data_ptr*/NULL, 7746 /*dxfer_len*/0, 7747 sense_len, 7748 sizeof(*scsi_cmd), 7749 timeout); 7750 7751 scsi_cmd = (struct scsi_sync_cache *)&csio->cdb_io.cdb_bytes; 7752 bzero(scsi_cmd, sizeof(*scsi_cmd)); 7753 scsi_cmd->opcode = SYNCHRONIZE_CACHE; 7754 scsi_ulto4b(begin_lba, scsi_cmd->begin_lba); 7755 scsi_ulto2b(lb_count, scsi_cmd->lb_count); 7756 } 7757 7758 void 7759 scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries, 7760 void (*cbfcnp)(struct cam_periph *, union ccb *), 7761 u_int8_t tag_action, int readop, u_int8_t byte2, 7762 int minimum_cmd_size, u_int64_t lba, u_int32_t block_count, 7763 u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, 7764 u_int32_t timeout) 7765 { 7766 int read; 7767 u_int8_t cdb_len; 7768 7769 read = (readop & SCSI_RW_DIRMASK) == SCSI_RW_READ; 7770 7771 /* 7772 * Use the smallest possible command to perform the operation 7773 * as some legacy hardware does not support the 10 byte commands. 7774 * If any of the bits in byte2 is set, we have to go with a larger 7775 * command. 7776 */ 7777 if ((minimum_cmd_size < 10) 7778 && ((lba & 0x1fffff) == lba) 7779 && ((block_count & 0xff) == block_count) 7780 && (byte2 == 0)) { 7781 /* 7782 * We can fit in a 6 byte cdb. 7783 */ 7784 struct scsi_rw_6 *scsi_cmd; 7785 7786 scsi_cmd = (struct scsi_rw_6 *)&csio->cdb_io.cdb_bytes; 7787 scsi_cmd->opcode = read ? READ_6 : WRITE_6; 7788 scsi_ulto3b(lba, scsi_cmd->addr); 7789 scsi_cmd->length = block_count & 0xff; 7790 scsi_cmd->control = 0; 7791 cdb_len = sizeof(*scsi_cmd); 7792 7793 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 7794 ("6byte: %x%x%x:%d:%d\n", scsi_cmd->addr[0], 7795 scsi_cmd->addr[1], scsi_cmd->addr[2], 7796 scsi_cmd->length, dxfer_len)); 7797 } else if ((minimum_cmd_size < 12) 7798 && ((block_count & 0xffff) == block_count) 7799 && ((lba & 0xffffffff) == lba)) { 7800 /* 7801 * Need a 10 byte cdb. 7802 */ 7803 struct scsi_rw_10 *scsi_cmd; 7804 7805 scsi_cmd = (struct scsi_rw_10 *)&csio->cdb_io.cdb_bytes; 7806 scsi_cmd->opcode = read ? READ_10 : WRITE_10; 7807 scsi_cmd->byte2 = byte2; 7808 scsi_ulto4b(lba, scsi_cmd->addr); 7809 scsi_cmd->reserved = 0; 7810 scsi_ulto2b(block_count, scsi_cmd->length); 7811 scsi_cmd->control = 0; 7812 cdb_len = sizeof(*scsi_cmd); 7813 7814 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 7815 ("10byte: %x%x%x%x:%x%x: %d\n", scsi_cmd->addr[0], 7816 scsi_cmd->addr[1], scsi_cmd->addr[2], 7817 scsi_cmd->addr[3], scsi_cmd->length[0], 7818 scsi_cmd->length[1], dxfer_len)); 7819 } else if ((minimum_cmd_size < 16) 7820 && ((block_count & 0xffffffff) == block_count) 7821 && ((lba & 0xffffffff) == lba)) { 7822 /* 7823 * The block count is too big for a 10 byte CDB, use a 12 7824 * byte CDB. 7825 */ 7826 struct scsi_rw_12 *scsi_cmd; 7827 7828 scsi_cmd = (struct scsi_rw_12 *)&csio->cdb_io.cdb_bytes; 7829 scsi_cmd->opcode = read ? READ_12 : WRITE_12; 7830 scsi_cmd->byte2 = byte2; 7831 scsi_ulto4b(lba, scsi_cmd->addr); 7832 scsi_cmd->reserved = 0; 7833 scsi_ulto4b(block_count, scsi_cmd->length); 7834 scsi_cmd->control = 0; 7835 cdb_len = sizeof(*scsi_cmd); 7836 7837 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 7838 ("12byte: %x%x%x%x:%x%x%x%x: %d\n", scsi_cmd->addr[0], 7839 scsi_cmd->addr[1], scsi_cmd->addr[2], 7840 scsi_cmd->addr[3], scsi_cmd->length[0], 7841 scsi_cmd->length[1], scsi_cmd->length[2], 7842 scsi_cmd->length[3], dxfer_len)); 7843 } else { 7844 /* 7845 * 16 byte CDB. We'll only get here if the LBA is larger 7846 * than 2^32, or if the user asks for a 16 byte command. 7847 */ 7848 struct scsi_rw_16 *scsi_cmd; 7849 7850 scsi_cmd = (struct scsi_rw_16 *)&csio->cdb_io.cdb_bytes; 7851 scsi_cmd->opcode = read ? READ_16 : WRITE_16; 7852 scsi_cmd->byte2 = byte2; 7853 scsi_u64to8b(lba, scsi_cmd->addr); 7854 scsi_cmd->reserved = 0; 7855 scsi_ulto4b(block_count, scsi_cmd->length); 7856 scsi_cmd->control = 0; 7857 cdb_len = sizeof(*scsi_cmd); 7858 } 7859 cam_fill_csio(csio, 7860 retries, 7861 cbfcnp, 7862 (read ? CAM_DIR_IN : CAM_DIR_OUT) | 7863 ((readop & SCSI_RW_BIO) != 0 ? CAM_DATA_BIO : 0), 7864 tag_action, 7865 data_ptr, 7866 dxfer_len, 7867 sense_len, 7868 cdb_len, 7869 timeout); 7870 } 7871 7872 void 7873 scsi_write_same(struct ccb_scsiio *csio, u_int32_t retries, 7874 void (*cbfcnp)(struct cam_periph *, union ccb *), 7875 u_int8_t tag_action, u_int8_t byte2, 7876 int minimum_cmd_size, u_int64_t lba, u_int32_t block_count, 7877 u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, 7878 u_int32_t timeout) 7879 { 7880 u_int8_t cdb_len; 7881 if ((minimum_cmd_size < 16) && 7882 ((block_count & 0xffff) == block_count) && 7883 ((lba & 0xffffffff) == lba)) { 7884 /* 7885 * Need a 10 byte cdb. 7886 */ 7887 struct scsi_write_same_10 *scsi_cmd; 7888 7889 scsi_cmd = (struct scsi_write_same_10 *)&csio->cdb_io.cdb_bytes; 7890 scsi_cmd->opcode = WRITE_SAME_10; 7891 scsi_cmd->byte2 = byte2; 7892 scsi_ulto4b(lba, scsi_cmd->addr); 7893 scsi_cmd->group = 0; 7894 scsi_ulto2b(block_count, scsi_cmd->length); 7895 scsi_cmd->control = 0; 7896 cdb_len = sizeof(*scsi_cmd); 7897 7898 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 7899 ("10byte: %x%x%x%x:%x%x: %d\n", scsi_cmd->addr[0], 7900 scsi_cmd->addr[1], scsi_cmd->addr[2], 7901 scsi_cmd->addr[3], scsi_cmd->length[0], 7902 scsi_cmd->length[1], dxfer_len)); 7903 } else { 7904 /* 7905 * 16 byte CDB. We'll only get here if the LBA is larger 7906 * than 2^32, or if the user asks for a 16 byte command. 7907 */ 7908 struct scsi_write_same_16 *scsi_cmd; 7909 7910 scsi_cmd = (struct scsi_write_same_16 *)&csio->cdb_io.cdb_bytes; 7911 scsi_cmd->opcode = WRITE_SAME_16; 7912 scsi_cmd->byte2 = byte2; 7913 scsi_u64to8b(lba, scsi_cmd->addr); 7914 scsi_ulto4b(block_count, scsi_cmd->length); 7915 scsi_cmd->group = 0; 7916 scsi_cmd->control = 0; 7917 cdb_len = sizeof(*scsi_cmd); 7918 7919 CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE, 7920 ("16byte: %x%x%x%x%x%x%x%x:%x%x%x%x: %d\n", 7921 scsi_cmd->addr[0], scsi_cmd->addr[1], 7922 scsi_cmd->addr[2], scsi_cmd->addr[3], 7923 scsi_cmd->addr[4], scsi_cmd->addr[5], 7924 scsi_cmd->addr[6], scsi_cmd->addr[7], 7925 scsi_cmd->length[0], scsi_cmd->length[1], 7926 scsi_cmd->length[2], scsi_cmd->length[3], 7927 dxfer_len)); 7928 } 7929 cam_fill_csio(csio, 7930 retries, 7931 cbfcnp, 7932 /*flags*/CAM_DIR_OUT, 7933 tag_action, 7934 data_ptr, 7935 dxfer_len, 7936 sense_len, 7937 cdb_len, 7938 timeout); 7939 } 7940 7941 void 7942 scsi_ata_identify(struct ccb_scsiio *csio, u_int32_t retries, 7943 void (*cbfcnp)(struct cam_periph *, union ccb *), 7944 u_int8_t tag_action, u_int8_t *data_ptr, 7945 u_int16_t dxfer_len, u_int8_t sense_len, 7946 u_int32_t timeout) 7947 { 7948 scsi_ata_pass_16(csio, 7949 retries, 7950 cbfcnp, 7951 /*flags*/CAM_DIR_IN, 7952 tag_action, 7953 /*protocol*/AP_PROTO_PIO_IN, 7954 /*ata_flags*/AP_FLAG_TDIR_FROM_DEV| 7955 AP_FLAG_BYT_BLOK_BYTES|AP_FLAG_TLEN_SECT_CNT, 7956 /*features*/0, 7957 /*sector_count*/dxfer_len, 7958 /*lba*/0, 7959 /*command*/ATA_ATA_IDENTIFY, 7960 /*control*/0, 7961 data_ptr, 7962 dxfer_len, 7963 sense_len, 7964 timeout); 7965 } 7966 7967 void 7968 scsi_ata_trim(struct ccb_scsiio *csio, u_int32_t retries, 7969 void (*cbfcnp)(struct cam_periph *, union ccb *), 7970 u_int8_t tag_action, u_int16_t block_count, 7971 u_int8_t *data_ptr, u_int16_t dxfer_len, u_int8_t sense_len, 7972 u_int32_t timeout) 7973 { 7974 scsi_ata_pass_16(csio, 7975 retries, 7976 cbfcnp, 7977 /*flags*/CAM_DIR_OUT, 7978 tag_action, 7979 /*protocol*/AP_EXTEND|AP_PROTO_DMA, 7980 /*ata_flags*/AP_FLAG_TLEN_SECT_CNT|AP_FLAG_BYT_BLOK_BLOCKS, 7981 /*features*/ATA_DSM_TRIM, 7982 /*sector_count*/block_count, 7983 /*lba*/0, 7984 /*command*/ATA_DATA_SET_MANAGEMENT, 7985 /*control*/0, 7986 data_ptr, 7987 dxfer_len, 7988 sense_len, 7989 timeout); 7990 } 7991 7992 void 7993 scsi_ata_pass_16(struct ccb_scsiio *csio, u_int32_t retries, 7994 void (*cbfcnp)(struct cam_periph *, union ccb *), 7995 u_int32_t flags, u_int8_t tag_action, 7996 u_int8_t protocol, u_int8_t ata_flags, u_int16_t features, 7997 u_int16_t sector_count, uint64_t lba, u_int8_t command, 7998 u_int8_t control, u_int8_t *data_ptr, u_int16_t dxfer_len, 7999 u_int8_t sense_len, u_int32_t timeout) 8000 { 8001 struct ata_pass_16 *ata_cmd; 8002 8003 ata_cmd = (struct ata_pass_16 *)&csio->cdb_io.cdb_bytes; 8004 ata_cmd->opcode = ATA_PASS_16; 8005 ata_cmd->protocol = protocol; 8006 ata_cmd->flags = ata_flags; 8007 ata_cmd->features_ext = features >> 8; 8008 ata_cmd->features = features; 8009 ata_cmd->sector_count_ext = sector_count >> 8; 8010 ata_cmd->sector_count = sector_count; 8011 ata_cmd->lba_low = lba; 8012 ata_cmd->lba_mid = lba >> 8; 8013 ata_cmd->lba_high = lba >> 16; 8014 ata_cmd->device = ATA_DEV_LBA; 8015 if (protocol & AP_EXTEND) { 8016 ata_cmd->lba_low_ext = lba >> 24; 8017 ata_cmd->lba_mid_ext = lba >> 32; 8018 ata_cmd->lba_high_ext = lba >> 40; 8019 } else 8020 ata_cmd->device |= (lba >> 24) & 0x0f; 8021 ata_cmd->command = command; 8022 ata_cmd->control = control; 8023 8024 cam_fill_csio(csio, 8025 retries, 8026 cbfcnp, 8027 flags, 8028 tag_action, 8029 data_ptr, 8030 dxfer_len, 8031 sense_len, 8032 sizeof(*ata_cmd), 8033 timeout); 8034 } 8035 8036 void 8037 scsi_unmap(struct ccb_scsiio *csio, u_int32_t retries, 8038 void (*cbfcnp)(struct cam_periph *, union ccb *), 8039 u_int8_t tag_action, u_int8_t byte2, 8040 u_int8_t *data_ptr, u_int16_t dxfer_len, u_int8_t sense_len, 8041 u_int32_t timeout) 8042 { 8043 struct scsi_unmap *scsi_cmd; 8044 8045 scsi_cmd = (struct scsi_unmap *)&csio->cdb_io.cdb_bytes; 8046 scsi_cmd->opcode = UNMAP; 8047 scsi_cmd->byte2 = byte2; 8048 scsi_ulto4b(0, scsi_cmd->reserved); 8049 scsi_cmd->group = 0; 8050 scsi_ulto2b(dxfer_len, scsi_cmd->length); 8051 scsi_cmd->control = 0; 8052 8053 cam_fill_csio(csio, 8054 retries, 8055 cbfcnp, 8056 /*flags*/CAM_DIR_OUT, 8057 tag_action, 8058 data_ptr, 8059 dxfer_len, 8060 sense_len, 8061 sizeof(*scsi_cmd), 8062 timeout); 8063 } 8064 8065 void 8066 scsi_receive_diagnostic_results(struct ccb_scsiio *csio, u_int32_t retries, 8067 void (*cbfcnp)(struct cam_periph *, union ccb*), 8068 uint8_t tag_action, int pcv, uint8_t page_code, 8069 uint8_t *data_ptr, uint16_t allocation_length, 8070 uint8_t sense_len, uint32_t timeout) 8071 { 8072 struct scsi_receive_diag *scsi_cmd; 8073 8074 scsi_cmd = (struct scsi_receive_diag *)&csio->cdb_io.cdb_bytes; 8075 memset(scsi_cmd, 0, sizeof(*scsi_cmd)); 8076 scsi_cmd->opcode = RECEIVE_DIAGNOSTIC; 8077 if (pcv) { 8078 scsi_cmd->byte2 |= SRD_PCV; 8079 scsi_cmd->page_code = page_code; 8080 } 8081 scsi_ulto2b(allocation_length, scsi_cmd->length); 8082 8083 cam_fill_csio(csio, 8084 retries, 8085 cbfcnp, 8086 /*flags*/CAM_DIR_IN, 8087 tag_action, 8088 data_ptr, 8089 allocation_length, 8090 sense_len, 8091 sizeof(*scsi_cmd), 8092 timeout); 8093 } 8094 8095 void 8096 scsi_send_diagnostic(struct ccb_scsiio *csio, u_int32_t retries, 8097 void (*cbfcnp)(struct cam_periph *, union ccb *), 8098 uint8_t tag_action, int unit_offline, int device_offline, 8099 int self_test, int page_format, int self_test_code, 8100 uint8_t *data_ptr, uint16_t param_list_length, 8101 uint8_t sense_len, uint32_t timeout) 8102 { 8103 struct scsi_send_diag *scsi_cmd; 8104 8105 scsi_cmd = (struct scsi_send_diag *)&csio->cdb_io.cdb_bytes; 8106 memset(scsi_cmd, 0, sizeof(*scsi_cmd)); 8107 scsi_cmd->opcode = SEND_DIAGNOSTIC; 8108 8109 /* 8110 * The default self-test mode control and specific test 8111 * control are mutually exclusive. 8112 */ 8113 if (self_test) 8114 self_test_code = SSD_SELF_TEST_CODE_NONE; 8115 8116 scsi_cmd->byte2 = ((self_test_code << SSD_SELF_TEST_CODE_SHIFT) 8117 & SSD_SELF_TEST_CODE_MASK) 8118 | (unit_offline ? SSD_UNITOFFL : 0) 8119 | (device_offline ? SSD_DEVOFFL : 0) 8120 | (self_test ? SSD_SELFTEST : 0) 8121 | (page_format ? SSD_PF : 0); 8122 scsi_ulto2b(param_list_length, scsi_cmd->length); 8123 8124 cam_fill_csio(csio, 8125 retries, 8126 cbfcnp, 8127 /*flags*/param_list_length ? CAM_DIR_OUT : CAM_DIR_NONE, 8128 tag_action, 8129 data_ptr, 8130 param_list_length, 8131 sense_len, 8132 sizeof(*scsi_cmd), 8133 timeout); 8134 } 8135 8136 void 8137 scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries, 8138 void (*cbfcnp)(struct cam_periph *, union ccb*), 8139 uint8_t tag_action, int mode, 8140 uint8_t buffer_id, u_int32_t offset, 8141 uint8_t *data_ptr, uint32_t allocation_length, 8142 uint8_t sense_len, uint32_t timeout) 8143 { 8144 struct scsi_read_buffer *scsi_cmd; 8145 8146 scsi_cmd = (struct scsi_read_buffer *)&csio->cdb_io.cdb_bytes; 8147 memset(scsi_cmd, 0, sizeof(*scsi_cmd)); 8148 scsi_cmd->opcode = READ_BUFFER; 8149 scsi_cmd->byte2 = mode; 8150 scsi_cmd->buffer_id = buffer_id; 8151 scsi_ulto3b(offset, scsi_cmd->offset); 8152 scsi_ulto3b(allocation_length, scsi_cmd->length); 8153 8154 cam_fill_csio(csio, 8155 retries, 8156 cbfcnp, 8157 /*flags*/CAM_DIR_IN, 8158 tag_action, 8159 data_ptr, 8160 allocation_length, 8161 sense_len, 8162 sizeof(*scsi_cmd), 8163 timeout); 8164 } 8165 8166 void 8167 scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries, 8168 void (*cbfcnp)(struct cam_periph *, union ccb *), 8169 uint8_t tag_action, int mode, 8170 uint8_t buffer_id, u_int32_t offset, 8171 uint8_t *data_ptr, uint32_t param_list_length, 8172 uint8_t sense_len, uint32_t timeout) 8173 { 8174 struct scsi_write_buffer *scsi_cmd; 8175 8176 scsi_cmd = (struct scsi_write_buffer *)&csio->cdb_io.cdb_bytes; 8177 memset(scsi_cmd, 0, sizeof(*scsi_cmd)); 8178 scsi_cmd->opcode = WRITE_BUFFER; 8179 scsi_cmd->byte2 = mode; 8180 scsi_cmd->buffer_id = buffer_id; 8181 scsi_ulto3b(offset, scsi_cmd->offset); 8182 scsi_ulto3b(param_list_length, scsi_cmd->length); 8183 8184 cam_fill_csio(csio, 8185 retries, 8186 cbfcnp, 8187 /*flags*/param_list_length ? CAM_DIR_OUT : CAM_DIR_NONE, 8188 tag_action, 8189 data_ptr, 8190 param_list_length, 8191 sense_len, 8192 sizeof(*scsi_cmd), 8193 timeout); 8194 } 8195 8196 void 8197 scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries, 8198 void (*cbfcnp)(struct cam_periph *, union ccb *), 8199 u_int8_t tag_action, int start, int load_eject, 8200 int immediate, u_int8_t sense_len, u_int32_t timeout) 8201 { 8202 struct scsi_start_stop_unit *scsi_cmd; 8203 int extra_flags = 0; 8204 8205 scsi_cmd = (struct scsi_start_stop_unit *)&csio->cdb_io.cdb_bytes; 8206 bzero(scsi_cmd, sizeof(*scsi_cmd)); 8207 scsi_cmd->opcode = START_STOP_UNIT; 8208 if (start != 0) { 8209 scsi_cmd->how |= SSS_START; 8210 /* it takes a lot of power to start a drive */ 8211 extra_flags |= CAM_HIGH_POWER; 8212 } 8213 if (load_eject != 0) 8214 scsi_cmd->how |= SSS_LOEJ; 8215 if (immediate != 0) 8216 scsi_cmd->byte2 |= SSS_IMMED; 8217 8218 cam_fill_csio(csio, 8219 retries, 8220 cbfcnp, 8221 /*flags*/CAM_DIR_NONE | extra_flags, 8222 tag_action, 8223 /*data_ptr*/NULL, 8224 /*dxfer_len*/0, 8225 sense_len, 8226 sizeof(*scsi_cmd), 8227 timeout); 8228 } 8229 8230 void 8231 scsi_read_attribute(struct ccb_scsiio *csio, u_int32_t retries, 8232 void (*cbfcnp)(struct cam_periph *, union ccb *), 8233 u_int8_t tag_action, u_int8_t service_action, 8234 uint32_t element, u_int8_t elem_type, int logical_volume, 8235 int partition, u_int32_t first_attribute, int cache, 8236 u_int8_t *data_ptr, u_int32_t length, int sense_len, 8237 u_int32_t timeout) 8238 { 8239 struct scsi_read_attribute *scsi_cmd; 8240 8241 scsi_cmd = (struct scsi_read_attribute *)&csio->cdb_io.cdb_bytes; 8242 bzero(scsi_cmd, sizeof(*scsi_cmd)); 8243 8244 scsi_cmd->opcode = READ_ATTRIBUTE; 8245 scsi_cmd->service_action = service_action, 8246 scsi_ulto2b(element, scsi_cmd->element); 8247 scsi_cmd->elem_type = elem_type; 8248 scsi_cmd->logical_volume = logical_volume; 8249 scsi_cmd->partition = partition; 8250 scsi_ulto2b(first_attribute, scsi_cmd->first_attribute); 8251 scsi_ulto4b(length, scsi_cmd->length); 8252 if (cache != 0) 8253 scsi_cmd->cache |= SRA_CACHE; 8254 8255 cam_fill_csio(csio, 8256 retries, 8257 cbfcnp, 8258 /*flags*/CAM_DIR_IN, 8259 tag_action, 8260 /*data_ptr*/data_ptr, 8261 /*dxfer_len*/length, 8262 sense_len, 8263 sizeof(*scsi_cmd), 8264 timeout); 8265 } 8266 8267 void 8268 scsi_write_attribute(struct ccb_scsiio *csio, u_int32_t retries, 8269 void (*cbfcnp)(struct cam_periph *, union ccb *), 8270 u_int8_t tag_action, uint32_t element, int logical_volume, 8271 int partition, int wtc, u_int8_t *data_ptr, 8272 u_int32_t length, int sense_len, u_int32_t timeout) 8273 { 8274 struct scsi_write_attribute *scsi_cmd; 8275 8276 scsi_cmd = (struct scsi_write_attribute *)&csio->cdb_io.cdb_bytes; 8277 bzero(scsi_cmd, sizeof(*scsi_cmd)); 8278 8279 scsi_cmd->opcode = WRITE_ATTRIBUTE; 8280 if (wtc != 0) 8281 scsi_cmd->byte2 = SWA_WTC; 8282 scsi_ulto3b(element, scsi_cmd->element); 8283 scsi_cmd->logical_volume = logical_volume; 8284 scsi_cmd->partition = partition; 8285 scsi_ulto4b(length, scsi_cmd->length); 8286 8287 cam_fill_csio(csio, 8288 retries, 8289 cbfcnp, 8290 /*flags*/CAM_DIR_OUT, 8291 tag_action, 8292 /*data_ptr*/data_ptr, 8293 /*dxfer_len*/length, 8294 sense_len, 8295 sizeof(*scsi_cmd), 8296 timeout); 8297 } 8298 8299 void 8300 scsi_persistent_reserve_in(struct ccb_scsiio *csio, uint32_t retries, 8301 void (*cbfcnp)(struct cam_periph *, union ccb *), 8302 uint8_t tag_action, int service_action, 8303 uint8_t *data_ptr, uint32_t dxfer_len, int sense_len, 8304 int timeout) 8305 { 8306 struct scsi_per_res_in *scsi_cmd; 8307 8308 scsi_cmd = (struct scsi_per_res_in *)&csio->cdb_io.cdb_bytes; 8309 bzero(scsi_cmd, sizeof(*scsi_cmd)); 8310 8311 scsi_cmd->opcode = PERSISTENT_RES_IN; 8312 scsi_cmd->action = service_action; 8313 scsi_ulto2b(dxfer_len, scsi_cmd->length); 8314 8315 cam_fill_csio(csio, 8316 retries, 8317 cbfcnp, 8318 /*flags*/CAM_DIR_IN, 8319 tag_action, 8320 data_ptr, 8321 dxfer_len, 8322 sense_len, 8323 sizeof(*scsi_cmd), 8324 timeout); 8325 } 8326 8327 void 8328 scsi_persistent_reserve_out(struct ccb_scsiio *csio, uint32_t retries, 8329 void (*cbfcnp)(struct cam_periph *, union ccb *), 8330 uint8_t tag_action, int service_action, 8331 int scope, int res_type, uint8_t *data_ptr, 8332 uint32_t dxfer_len, int sense_len, int timeout) 8333 { 8334 struct scsi_per_res_out *scsi_cmd; 8335 8336 scsi_cmd = (struct scsi_per_res_out *)&csio->cdb_io.cdb_bytes; 8337 bzero(scsi_cmd, sizeof(*scsi_cmd)); 8338 8339 scsi_cmd->opcode = PERSISTENT_RES_OUT; 8340 scsi_cmd->action = service_action; 8341 scsi_cmd->scope_type = scope | res_type; 8342 8343 cam_fill_csio(csio, 8344 retries, 8345 cbfcnp, 8346 /*flags*/CAM_DIR_OUT, 8347 tag_action, 8348 /*data_ptr*/data_ptr, 8349 /*dxfer_len*/dxfer_len, 8350 sense_len, 8351 sizeof(*scsi_cmd), 8352 timeout); 8353 } 8354 8355 void 8356 scsi_security_protocol_in(struct ccb_scsiio *csio, uint32_t retries, 8357 void (*cbfcnp)(struct cam_periph *, union ccb *), 8358 uint8_t tag_action, uint32_t security_protocol, 8359 uint32_t security_protocol_specific, int byte4, 8360 uint8_t *data_ptr, uint32_t dxfer_len, int sense_len, 8361 int timeout) 8362 { 8363 struct scsi_security_protocol_in *scsi_cmd; 8364 8365 scsi_cmd = (struct scsi_security_protocol_in *)&csio->cdb_io.cdb_bytes; 8366 bzero(scsi_cmd, sizeof(*scsi_cmd)); 8367 8368 scsi_cmd->opcode = SECURITY_PROTOCOL_IN; 8369 8370 scsi_cmd->security_protocol = security_protocol; 8371 scsi_ulto2b(security_protocol_specific, 8372 scsi_cmd->security_protocol_specific); 8373 scsi_cmd->byte4 = byte4; 8374 scsi_ulto4b(dxfer_len, scsi_cmd->length); 8375 8376 cam_fill_csio(csio, 8377 retries, 8378 cbfcnp, 8379 /*flags*/CAM_DIR_IN, 8380 tag_action, 8381 data_ptr, 8382 dxfer_len, 8383 sense_len, 8384 sizeof(*scsi_cmd), 8385 timeout); 8386 } 8387 8388 void 8389 scsi_security_protocol_out(struct ccb_scsiio *csio, uint32_t retries, 8390 void (*cbfcnp)(struct cam_periph *, union ccb *), 8391 uint8_t tag_action, uint32_t security_protocol, 8392 uint32_t security_protocol_specific, int byte4, 8393 uint8_t *data_ptr, uint32_t dxfer_len, int sense_len, 8394 int timeout) 8395 { 8396 struct scsi_security_protocol_out *scsi_cmd; 8397 8398 scsi_cmd = (struct scsi_security_protocol_out *)&csio->cdb_io.cdb_bytes; 8399 bzero(scsi_cmd, sizeof(*scsi_cmd)); 8400 8401 scsi_cmd->opcode = SECURITY_PROTOCOL_OUT; 8402 8403 scsi_cmd->security_protocol = security_protocol; 8404 scsi_ulto2b(security_protocol_specific, 8405 scsi_cmd->security_protocol_specific); 8406 scsi_cmd->byte4 = byte4; 8407 scsi_ulto4b(dxfer_len, scsi_cmd->length); 8408 8409 cam_fill_csio(csio, 8410 retries, 8411 cbfcnp, 8412 /*flags*/CAM_DIR_OUT, 8413 tag_action, 8414 data_ptr, 8415 dxfer_len, 8416 sense_len, 8417 sizeof(*scsi_cmd), 8418 timeout); 8419 } 8420 8421 /* 8422 * Try make as good a match as possible with 8423 * available sub drivers 8424 */ 8425 int 8426 scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry) 8427 { 8428 struct scsi_inquiry_pattern *entry; 8429 struct scsi_inquiry_data *inq; 8430 8431 entry = (struct scsi_inquiry_pattern *)table_entry; 8432 inq = (struct scsi_inquiry_data *)inqbuffer; 8433 8434 if (((SID_TYPE(inq) == entry->type) 8435 || (entry->type == T_ANY)) 8436 && (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE 8437 : entry->media_type & SIP_MEDIA_FIXED) 8438 && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) 8439 && (cam_strmatch(inq->product, entry->product, 8440 sizeof(inq->product)) == 0) 8441 && (cam_strmatch(inq->revision, entry->revision, 8442 sizeof(inq->revision)) == 0)) { 8443 return (0); 8444 } 8445 return (-1); 8446 } 8447 8448 /* 8449 * Try make as good a match as possible with 8450 * available sub drivers 8451 */ 8452 int 8453 scsi_static_inquiry_match(caddr_t inqbuffer, caddr_t table_entry) 8454 { 8455 struct scsi_static_inquiry_pattern *entry; 8456 struct scsi_inquiry_data *inq; 8457 8458 entry = (struct scsi_static_inquiry_pattern *)table_entry; 8459 inq = (struct scsi_inquiry_data *)inqbuffer; 8460 8461 if (((SID_TYPE(inq) == entry->type) 8462 || (entry->type == T_ANY)) 8463 && (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE 8464 : entry->media_type & SIP_MEDIA_FIXED) 8465 && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) 8466 && (cam_strmatch(inq->product, entry->product, 8467 sizeof(inq->product)) == 0) 8468 && (cam_strmatch(inq->revision, entry->revision, 8469 sizeof(inq->revision)) == 0)) { 8470 return (0); 8471 } 8472 return (-1); 8473 } 8474 8475 /** 8476 * Compare two buffers of vpd device descriptors for a match. 8477 * 8478 * \param lhs Pointer to first buffer of descriptors to compare. 8479 * \param lhs_len The length of the first buffer. 8480 * \param rhs Pointer to second buffer of descriptors to compare. 8481 * \param rhs_len The length of the second buffer. 8482 * 8483 * \return 0 on a match, -1 otherwise. 8484 * 8485 * Treat rhs and lhs as arrays of vpd device id descriptors. Walk lhs matching 8486 * agains each element in rhs until all data are exhausted or we have found 8487 * a match. 8488 */ 8489 int 8490 scsi_devid_match(uint8_t *lhs, size_t lhs_len, uint8_t *rhs, size_t rhs_len) 8491 { 8492 struct scsi_vpd_id_descriptor *lhs_id; 8493 struct scsi_vpd_id_descriptor *lhs_last; 8494 struct scsi_vpd_id_descriptor *rhs_last; 8495 uint8_t *lhs_end; 8496 uint8_t *rhs_end; 8497 8498 lhs_end = lhs + lhs_len; 8499 rhs_end = rhs + rhs_len; 8500 8501 /* 8502 * rhs_last and lhs_last are the last posible position of a valid 8503 * descriptor assuming it had a zero length identifier. We use 8504 * these variables to insure we can safely dereference the length 8505 * field in our loop termination tests. 8506 */ 8507 lhs_last = (struct scsi_vpd_id_descriptor *) 8508 (lhs_end - __offsetof(struct scsi_vpd_id_descriptor, identifier)); 8509 rhs_last = (struct scsi_vpd_id_descriptor *) 8510 (rhs_end - __offsetof(struct scsi_vpd_id_descriptor, identifier)); 8511 8512 lhs_id = (struct scsi_vpd_id_descriptor *)lhs; 8513 while (lhs_id <= lhs_last 8514 && (lhs_id->identifier + lhs_id->length) <= lhs_end) { 8515 struct scsi_vpd_id_descriptor *rhs_id; 8516 8517 rhs_id = (struct scsi_vpd_id_descriptor *)rhs; 8518 while (rhs_id <= rhs_last 8519 && (rhs_id->identifier + rhs_id->length) <= rhs_end) { 8520 8521 if ((rhs_id->id_type & 8522 (SVPD_ID_ASSOC_MASK | SVPD_ID_TYPE_MASK)) == 8523 (lhs_id->id_type & 8524 (SVPD_ID_ASSOC_MASK | SVPD_ID_TYPE_MASK)) 8525 && rhs_id->length == lhs_id->length 8526 && memcmp(rhs_id->identifier, lhs_id->identifier, 8527 rhs_id->length) == 0) 8528 return (0); 8529 8530 rhs_id = (struct scsi_vpd_id_descriptor *) 8531 (rhs_id->identifier + rhs_id->length); 8532 } 8533 lhs_id = (struct scsi_vpd_id_descriptor *) 8534 (lhs_id->identifier + lhs_id->length); 8535 } 8536 return (-1); 8537 } 8538 8539 #ifdef _KERNEL 8540 int 8541 scsi_vpd_supported_page(struct cam_periph *periph, uint8_t page_id) 8542 { 8543 struct cam_ed *device; 8544 struct scsi_vpd_supported_pages *vpds; 8545 int i, num_pages; 8546 8547 device = periph->path->device; 8548 vpds = (struct scsi_vpd_supported_pages *)device->supported_vpds; 8549 8550 if (vpds != NULL) { 8551 num_pages = device->supported_vpds_len - 8552 SVPD_SUPPORTED_PAGES_HDR_LEN; 8553 for (i = 0; i < num_pages; i++) { 8554 if (vpds->page_list[i] == page_id) 8555 return (1); 8556 } 8557 } 8558 8559 return (0); 8560 } 8561 8562 static void 8563 init_scsi_delay(void) 8564 { 8565 int delay; 8566 8567 delay = SCSI_DELAY; 8568 TUNABLE_INT_FETCH("kern.cam.scsi_delay", &delay); 8569 8570 if (set_scsi_delay(delay) != 0) { 8571 printf("cam: invalid value for tunable kern.cam.scsi_delay\n"); 8572 set_scsi_delay(SCSI_DELAY); 8573 } 8574 } 8575 SYSINIT(scsi_delay, SI_SUB_TUNABLES, SI_ORDER_ANY, init_scsi_delay, NULL); 8576 8577 static int 8578 sysctl_scsi_delay(SYSCTL_HANDLER_ARGS) 8579 { 8580 int error, delay; 8581 8582 delay = scsi_delay; 8583 error = sysctl_handle_int(oidp, &delay, 0, req); 8584 if (error != 0 || req->newptr == NULL) 8585 return (error); 8586 return (set_scsi_delay(delay)); 8587 } 8588 SYSCTL_PROC(_kern_cam, OID_AUTO, scsi_delay, CTLTYPE_INT|CTLFLAG_RW, 8589 0, 0, sysctl_scsi_delay, "I", 8590 "Delay to allow devices to settle after a SCSI bus reset (ms)"); 8591 8592 static int 8593 set_scsi_delay(int delay) 8594 { 8595 /* 8596 * If someone sets this to 0, we assume that they want the 8597 * minimum allowable bus settle delay. 8598 */ 8599 if (delay == 0) { 8600 printf("cam: using minimum scsi_delay (%dms)\n", 8601 SCSI_MIN_DELAY); 8602 delay = SCSI_MIN_DELAY; 8603 } 8604 if (delay < SCSI_MIN_DELAY) 8605 return (EINVAL); 8606 scsi_delay = delay; 8607 return (0); 8608 } 8609 #endif /* _KERNEL */ 8610