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