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