1*275c9da8Seschrock /*
2*275c9da8Seschrock * CDDL HEADER START
3*275c9da8Seschrock *
4*275c9da8Seschrock * The contents of this file are subject to the terms of the
5*275c9da8Seschrock * Common Development and Distribution License (the "License").
6*275c9da8Seschrock * You may not use this file except in compliance with the License.
7*275c9da8Seschrock *
8*275c9da8Seschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*275c9da8Seschrock * or http://www.opensolaris.org/os/licensing.
10*275c9da8Seschrock * See the License for the specific language governing permissions
11*275c9da8Seschrock * and limitations under the License.
12*275c9da8Seschrock *
13*275c9da8Seschrock * When distributing Covered Code, include this CDDL HEADER in each
14*275c9da8Seschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*275c9da8Seschrock * If applicable, add the following below this CDDL HEADER, with the
16*275c9da8Seschrock * fields enclosed by brackets "[]" replaced with your own identifying
17*275c9da8Seschrock * information: Portions Copyright [yyyy] [name of copyright owner]
18*275c9da8Seschrock *
19*275c9da8Seschrock * CDDL HEADER END
20*275c9da8Seschrock */
21*275c9da8Seschrock
22*275c9da8Seschrock /*
23*275c9da8Seschrock * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24*275c9da8Seschrock * Use is subject to license terms.
25*275c9da8Seschrock */
26*275c9da8Seschrock
27*275c9da8Seschrock #include <sys/types.h>
28*275c9da8Seschrock #include <sys/scsi/generic/sense.h>
29*275c9da8Seschrock #include <sys/scsi/generic/status.h>
30*275c9da8Seschrock
31*275c9da8Seschrock #include <stddef.h>
32*275c9da8Seschrock #include <stdio.h>
33*275c9da8Seschrock
34*275c9da8Seschrock #include <scsi/libscsi.h>
35*275c9da8Seschrock #include "libscsi_impl.h"
36*275c9da8Seschrock
37*275c9da8Seschrock typedef struct slist {
38*275c9da8Seschrock char *str;
39*275c9da8Seschrock int value;
40*275c9da8Seschrock } slist_t;
41*275c9da8Seschrock
42*275c9da8Seschrock static slist_t sensekey_strings[] = {
43*275c9da8Seschrock { "No sense error", KEY_NO_SENSE },
44*275c9da8Seschrock { "Recoverable error", KEY_RECOVERABLE_ERROR },
45*275c9da8Seschrock { "Not ready error", KEY_NOT_READY },
46*275c9da8Seschrock { "Medium error", KEY_MEDIUM_ERROR },
47*275c9da8Seschrock { "Hardware error", KEY_HARDWARE_ERROR },
48*275c9da8Seschrock { "Illegal request", KEY_ILLEGAL_REQUEST },
49*275c9da8Seschrock { "Unit attention error", KEY_UNIT_ATTENTION },
50*275c9da8Seschrock { "Write protect error", KEY_WRITE_PROTECT },
51*275c9da8Seschrock { "Blank check error", KEY_BLANK_CHECK },
52*275c9da8Seschrock { "Vendor unique error", KEY_VENDOR_UNIQUE },
53*275c9da8Seschrock { "Copy aborted error", KEY_COPY_ABORTED },
54*275c9da8Seschrock { "Aborted command", KEY_ABORTED_COMMAND },
55*275c9da8Seschrock { "Equal error", KEY_EQUAL },
56*275c9da8Seschrock { "Volume overflow", KEY_VOLUME_OVERFLOW },
57*275c9da8Seschrock { "Miscompare error", KEY_MISCOMPARE },
58*275c9da8Seschrock { "Reserved error", KEY_RESERVED },
59*275c9da8Seschrock { NULL, 0 }
60*275c9da8Seschrock };
61*275c9da8Seschrock
62*275c9da8Seschrock static struct asq_key_strings {
63*275c9da8Seschrock uint_t asc;
64*275c9da8Seschrock uint_t ascq;
65*275c9da8Seschrock const char *message;
66*275c9da8Seschrock } extended_sense_list[] = {
67*275c9da8Seschrock { 0x00, 0x00, "no additional sense info" },
68*275c9da8Seschrock { 0x00, 0x01, "filemark detected" },
69*275c9da8Seschrock { 0x00, 0x02, "end of partition/medium detected" },
70*275c9da8Seschrock { 0x00, 0x03, "setmark detected" },
71*275c9da8Seschrock { 0x00, 0x04, "begining of partition/medium detected" },
72*275c9da8Seschrock { 0x00, 0x05, "end of data detected" },
73*275c9da8Seschrock { 0x00, 0x06, "i/o process terminated" },
74*275c9da8Seschrock { 0x00, 0x11, "audio play operation in progress" },
75*275c9da8Seschrock { 0x00, 0x12, "audio play operation paused" },
76*275c9da8Seschrock { 0x00, 0x13, "audio play operation successfully completed" },
77*275c9da8Seschrock { 0x00, 0x14, "audio play operation stopped due to error" },
78*275c9da8Seschrock { 0x00, 0x15, "no current audio status to return" },
79*275c9da8Seschrock { 0x00, 0x16, "operation in progress" },
80*275c9da8Seschrock { 0x00, 0x17, "cleaning requested" },
81*275c9da8Seschrock { 0x00, 0x18, "erase operation in progress" },
82*275c9da8Seschrock { 0x00, 0x19, "locate operation in progress" },
83*275c9da8Seschrock { 0x00, 0x1A, "rewind operation in progress" },
84*275c9da8Seschrock { 0x00, 0x1B, "set capacity operation in progress" },
85*275c9da8Seschrock { 0x00, 0x1C, "verify operation in progress" },
86*275c9da8Seschrock { 0x01, 0x00, "no index/sector signal" },
87*275c9da8Seschrock { 0x02, 0x00, "no seek complete" },
88*275c9da8Seschrock { 0x03, 0x00, "peripheral device write fault" },
89*275c9da8Seschrock { 0x03, 0x01, "no write current" },
90*275c9da8Seschrock { 0x03, 0x02, "excessive write errors" },
91*275c9da8Seschrock { 0x04, 0x00, "LUN not ready" },
92*275c9da8Seschrock { 0x04, 0x01, "LUN is becoming ready" },
93*275c9da8Seschrock { 0x04, 0x02, "LUN initializing command required" },
94*275c9da8Seschrock { 0x04, 0x03, "LUN not ready intervention required" },
95*275c9da8Seschrock { 0x04, 0x04, "LUN not ready format in progress" },
96*275c9da8Seschrock { 0x04, 0x05, "LUN not ready, rebuild in progress" },
97*275c9da8Seschrock { 0x04, 0x06, "LUN not ready, recalculation in progress" },
98*275c9da8Seschrock { 0x04, 0x07, "LUN not ready, operation in progress" },
99*275c9da8Seschrock { 0x04, 0x08, "LUN not ready, long write in progress" },
100*275c9da8Seschrock { 0x04, 0x09, "LUN not ready, self-test in progress" },
101*275c9da8Seschrock { 0x04, 0x0A, "LUN not accessible, asymmetric access state "
102*275c9da8Seschrock "transition" },
103*275c9da8Seschrock { 0x04, 0x0B, "LUN not accessible, target port in standby state" },
104*275c9da8Seschrock { 0x04, 0x0C, "LUN not accessible, target port in unavailable state" },
105*275c9da8Seschrock { 0x04, 0x10, "LUN not ready, auxiliary memory not accessible" },
106*275c9da8Seschrock { 0x05, 0x00, "LUN does not respond to selection" },
107*275c9da8Seschrock { 0x06, 0x00, "reference position found" },
108*275c9da8Seschrock { 0x07, 0x00, "multiple peripheral devices selected" },
109*275c9da8Seschrock { 0x08, 0x00, "LUN communication failure" },
110*275c9da8Seschrock { 0x08, 0x01, "LUN communication time-out" },
111*275c9da8Seschrock { 0x08, 0x02, "LUN communication parity error" },
112*275c9da8Seschrock { 0x08, 0x03, "LUN communication crc error (ultra-DMA/32)" },
113*275c9da8Seschrock { 0x08, 0x04, "unreachable copy target" },
114*275c9da8Seschrock { 0x09, 0x00, "track following error" },
115*275c9da8Seschrock { 0x09, 0x01, "tracking servo failure" },
116*275c9da8Seschrock { 0x09, 0x02, "focus servo failure" },
117*275c9da8Seschrock { 0x09, 0x03, "spindle servo failure" },
118*275c9da8Seschrock { 0x09, 0x04, "head select fault" },
119*275c9da8Seschrock { 0x0a, 0x00, "error log overflow" },
120*275c9da8Seschrock { 0x0b, 0x00, "warning" },
121*275c9da8Seschrock { 0x0b, 0x01, "warning - specified temperature exceeded" },
122*275c9da8Seschrock { 0x0b, 0x02, "warning - enclosure degraded" },
123*275c9da8Seschrock { 0x0c, 0x00, "write error" },
124*275c9da8Seschrock { 0x0c, 0x01, "write error - recovered with auto reallocation" },
125*275c9da8Seschrock { 0x0c, 0x02, "write error - auto reallocation failed" },
126*275c9da8Seschrock { 0x0c, 0x03, "write error - recommend reassignment" },
127*275c9da8Seschrock { 0x0c, 0x04, "compression check miscompare error" },
128*275c9da8Seschrock { 0x0c, 0x05, "data expansion occurred during compression" },
129*275c9da8Seschrock { 0x0c, 0x06, "block not compressible" },
130*275c9da8Seschrock { 0x0c, 0x07, "write error - recovery needed" },
131*275c9da8Seschrock { 0x0c, 0x08, "write error - recovery failed" },
132*275c9da8Seschrock { 0x0c, 0x09, "write error - loss of streaming" },
133*275c9da8Seschrock { 0x0c, 0x0a, "write error - padding blocks added" },
134*275c9da8Seschrock { 0x0c, 0x0b, "auxiliary memory write error" },
135*275c9da8Seschrock { 0x0c, 0x0c, "write error - unexpected unsolicited data" },
136*275c9da8Seschrock { 0x0c, 0x0d, "write error - not enough unsolicited data" },
137*275c9da8Seschrock { 0x0d, 0x00, "error detected by third party temporary initiator" },
138*275c9da8Seschrock { 0x0d, 0x01, "third party device failure" },
139*275c9da8Seschrock { 0x0d, 0x02, "copy target device not reachable" },
140*275c9da8Seschrock { 0x0d, 0x03, "incorrect copy target device type" },
141*275c9da8Seschrock { 0x0d, 0x04, "copy target device data underrun" },
142*275c9da8Seschrock { 0x0d, 0x05, "copy target device data overrun" },
143*275c9da8Seschrock { 0x0e, 0x00, "invalid information unit" },
144*275c9da8Seschrock { 0x0e, 0x01, "information unit too short" },
145*275c9da8Seschrock { 0x0e, 0x02, "information unit too long" },
146*275c9da8Seschrock { 0x10, 0x00, "ID CRC or ECC error" },
147*275c9da8Seschrock { 0x11, 0x00, "unrecovered read error" },
148*275c9da8Seschrock { 0x11, 0x01, "read retries exhausted" },
149*275c9da8Seschrock { 0x11, 0x02, "error too long to correct" },
150*275c9da8Seschrock { 0x11, 0x03, "multiple read errors" },
151*275c9da8Seschrock { 0x11, 0x04, "unrecovered read error - auto reallocate failed" },
152*275c9da8Seschrock { 0x11, 0x05, "L-EC uncorrectable error" },
153*275c9da8Seschrock { 0x11, 0x06, "CIRC unrecovered error" },
154*275c9da8Seschrock { 0x11, 0x07, "data re-synchronization error" },
155*275c9da8Seschrock { 0x11, 0x08, "incomplete block read" },
156*275c9da8Seschrock { 0x11, 0x09, "no gap found" },
157*275c9da8Seschrock { 0x11, 0x0a, "miscorrected error" },
158*275c9da8Seschrock { 0x11, 0x0b, "unrecovered read error - recommend reassignment" },
159*275c9da8Seschrock { 0x11, 0x0c, "unrecovered read error - recommend rewrite the data" },
160*275c9da8Seschrock { 0x11, 0x0d, "de-compression crc error" },
161*275c9da8Seschrock { 0x11, 0x0e, "cannot decompress using declared algorithm" },
162*275c9da8Seschrock { 0x11, 0x0f, "error reading UPC/EAN number" },
163*275c9da8Seschrock { 0x11, 0x10, "error reading ISRC number" },
164*275c9da8Seschrock { 0x11, 0x11, "read error - loss of streaming" },
165*275c9da8Seschrock { 0x11, 0x12, "auxiliary memory read error" },
166*275c9da8Seschrock { 0x11, 0x13, "read error - failed retransmission request" },
167*275c9da8Seschrock { 0x12, 0x00, "address mark not found for ID field" },
168*275c9da8Seschrock { 0x13, 0x00, "address mark not found for data field" },
169*275c9da8Seschrock { 0x14, 0x00, "recorded entity not found" },
170*275c9da8Seschrock { 0x14, 0x01, "record not found" },
171*275c9da8Seschrock { 0x14, 0x02, "filemark or setmark not found" },
172*275c9da8Seschrock { 0x14, 0x03, "end-of-data not found" },
173*275c9da8Seschrock { 0x14, 0x04, "block sequence error" },
174*275c9da8Seschrock { 0x14, 0x05, "record not found - recommend reassignment" },
175*275c9da8Seschrock { 0x14, 0x06, "record not found - data auto-reallocated" },
176*275c9da8Seschrock { 0x14, 0x07, "locate operation failure" },
177*275c9da8Seschrock { 0x15, 0x00, "random positioning error" },
178*275c9da8Seschrock { 0x15, 0x01, "mechanical positioning error" },
179*275c9da8Seschrock { 0x15, 0x02, "positioning error detected by read of medium" },
180*275c9da8Seschrock { 0x16, 0x00, "data sync mark error" },
181*275c9da8Seschrock { 0x16, 0x01, "data sync error - data rewritten" },
182*275c9da8Seschrock { 0x16, 0x02, "data sync error - recommend rewrite" },
183*275c9da8Seschrock { 0x16, 0x03, "data sync error - data auto-reallocated" },
184*275c9da8Seschrock { 0x16, 0x04, "data sync error - recommend reassignment" },
185*275c9da8Seschrock { 0x17, 0x00, "recovered data with no error correction" },
186*275c9da8Seschrock { 0x17, 0x01, "recovered data with retries" },
187*275c9da8Seschrock { 0x17, 0x02, "recovered data with positive head offset" },
188*275c9da8Seschrock { 0x17, 0x03, "recovered data with negative head offset" },
189*275c9da8Seschrock { 0x17, 0x04, "recovered data with retries and/or CIRC applied" },
190*275c9da8Seschrock { 0x17, 0x05, "recovered data using previous sector id" },
191*275c9da8Seschrock { 0x17, 0x06, "recovered data without ECC - data auto-reallocated" },
192*275c9da8Seschrock { 0x17, 0x07, "recovered data without ECC - recommend reassignment" },
193*275c9da8Seschrock { 0x17, 0x08, "recovered data without ECC - recommend rewrite" },
194*275c9da8Seschrock { 0x17, 0x09, "recovered data without ECC - data rewritten" },
195*275c9da8Seschrock { 0x18, 0x00, "recovered data with error correction" },
196*275c9da8Seschrock { 0x18, 0x01, "recovered data with error corr. & retries applied" },
197*275c9da8Seschrock { 0x18, 0x02, "recovered data - data auto-reallocated" },
198*275c9da8Seschrock { 0x18, 0x03, "recovered data with CIRC" },
199*275c9da8Seschrock { 0x18, 0x04, "recovered data with L-EC" },
200*275c9da8Seschrock { 0x18, 0x05, "recovered data - recommend reassignment" },
201*275c9da8Seschrock { 0x18, 0x06, "recovered data - recommend rewrite" },
202*275c9da8Seschrock { 0x18, 0x07, "recovered data with ECC - data rewritten" },
203*275c9da8Seschrock { 0x18, 0x08, "recovered data with linking" },
204*275c9da8Seschrock { 0x19, 0x00, "defect list error" },
205*275c9da8Seschrock { 0x1a, 0x00, "parameter list length error" },
206*275c9da8Seschrock { 0x1b, 0x00, "synchronous data xfer error" },
207*275c9da8Seschrock { 0x1c, 0x00, "defect list not found" },
208*275c9da8Seschrock { 0x1c, 0x01, "primary defect list not found" },
209*275c9da8Seschrock { 0x1c, 0x02, "grown defect list not found" },
210*275c9da8Seschrock { 0x1d, 0x00, "miscompare during verify" },
211*275c9da8Seschrock { 0x1e, 0x00, "recovered ID with ECC" },
212*275c9da8Seschrock { 0x1f, 0x00, "partial defect list transfer" },
213*275c9da8Seschrock { 0x20, 0x00, "invalid command operation code" },
214*275c9da8Seschrock { 0x20, 0x01, "access denied - initiator pending-enrolled" },
215*275c9da8Seschrock { 0x20, 0x02, "access denied - no access rights" },
216*275c9da8Seschrock { 0x20, 0x03, "access denied - invalid mgmt id key" },
217*275c9da8Seschrock { 0x20, 0x04, "illegal command while in write capable state" },
218*275c9da8Seschrock { 0x20, 0x06, "illegal command while in explicit address mode" },
219*275c9da8Seschrock { 0x20, 0x07, "illegal command while in implicit address mode" },
220*275c9da8Seschrock { 0x20, 0x08, "access denied - enrollment conflict" },
221*275c9da8Seschrock { 0x20, 0x09, "access denied - invalid lu identifier" },
222*275c9da8Seschrock { 0x20, 0x0a, "access denied - invalid proxy token" },
223*275c9da8Seschrock { 0x20, 0x0b, "access denied - ACL LUN conflict" },
224*275c9da8Seschrock { 0x21, 0x00, "logical block address out of range" },
225*275c9da8Seschrock { 0x21, 0x01, "invalid element address" },
226*275c9da8Seschrock { 0x21, 0x02, "invalid address for write" },
227*275c9da8Seschrock { 0x22, 0x00, "illegal function" },
228*275c9da8Seschrock { 0x24, 0x00, "invalid field in cdb" },
229*275c9da8Seschrock { 0x24, 0x01, "cdb decryption error" },
230*275c9da8Seschrock { 0x25, 0x00, "LUN not supported" },
231*275c9da8Seschrock { 0x26, 0x00, "invalid field in param list" },
232*275c9da8Seschrock { 0x26, 0x01, "parameter not supported" },
233*275c9da8Seschrock { 0x26, 0x02, "parameter value invalid" },
234*275c9da8Seschrock { 0x26, 0x03, "threshold parameters not supported" },
235*275c9da8Seschrock { 0x26, 0x04, "invalid release of persistent reservation" },
236*275c9da8Seschrock { 0x26, 0x05, "data decryption error" },
237*275c9da8Seschrock { 0x26, 0x06, "too many target descriptors" },
238*275c9da8Seschrock { 0x26, 0x07, "unsupported target descriptor type code" },
239*275c9da8Seschrock { 0x26, 0x08, "too many segment descriptors" },
240*275c9da8Seschrock { 0x26, 0x09, "unsupported segment descriptor type code" },
241*275c9da8Seschrock { 0x26, 0x0a, "unexpected inexact segment" },
242*275c9da8Seschrock { 0x26, 0x0b, "inline data length exceeded" },
243*275c9da8Seschrock { 0x26, 0x0c, "invalid operation for copy source or destination" },
244*275c9da8Seschrock { 0x26, 0x0d, "copy segment granularity violation" },
245*275c9da8Seschrock { 0x27, 0x00, "write protected" },
246*275c9da8Seschrock { 0x27, 0x01, "hardware write protected" },
247*275c9da8Seschrock { 0x27, 0x02, "LUN software write protected" },
248*275c9da8Seschrock { 0x27, 0x03, "associated write protect" },
249*275c9da8Seschrock { 0x27, 0x04, "persistent write protect" },
250*275c9da8Seschrock { 0x27, 0x05, "permanent write protect" },
251*275c9da8Seschrock { 0x27, 0x06, "conditional write protect" },
252*275c9da8Seschrock { 0x28, 0x00, "medium may have changed" },
253*275c9da8Seschrock { 0x28, 0x01, "import or export element accessed" },
254*275c9da8Seschrock { 0x29, 0x00, "power on, reset, or bus reset occurred" },
255*275c9da8Seschrock { 0x29, 0x01, "power on occurred" },
256*275c9da8Seschrock { 0x29, 0x02, "scsi bus reset occurred" },
257*275c9da8Seschrock { 0x29, 0x03, "bus device reset message occurred" },
258*275c9da8Seschrock { 0x29, 0x04, "device internal reset" },
259*275c9da8Seschrock { 0x29, 0x05, "transceiver mode changed to single-ended" },
260*275c9da8Seschrock { 0x29, 0x06, "transceiver mode changed to LVD" },
261*275c9da8Seschrock { 0x29, 0x07, "i_t nexus loss occurred" },
262*275c9da8Seschrock { 0x2a, 0x00, "parameters changed" },
263*275c9da8Seschrock { 0x2a, 0x01, "mode parameters changed" },
264*275c9da8Seschrock { 0x2a, 0x02, "log parameters changed" },
265*275c9da8Seschrock { 0x2a, 0x03, "reservations preempted" },
266*275c9da8Seschrock { 0x2a, 0x04, "reservations released" },
267*275c9da8Seschrock { 0x2a, 0x05, "registrations preempted" },
268*275c9da8Seschrock { 0x2a, 0x06, "asymmetric access state changed" },
269*275c9da8Seschrock { 0x2a, 0x07, "implicit asymmetric access state transition failed" },
270*275c9da8Seschrock { 0x2b, 0x00, "copy cannot execute since host cannot disconnect" },
271*275c9da8Seschrock { 0x2c, 0x00, "command sequence error" },
272*275c9da8Seschrock { 0x2c, 0x03, "current program area is not empty" },
273*275c9da8Seschrock { 0x2c, 0x04, "current program area is empty" },
274*275c9da8Seschrock { 0x2c, 0x06, "persistent prevent conflict" },
275*275c9da8Seschrock { 0x2c, 0x07, "previous busy status" },
276*275c9da8Seschrock { 0x2c, 0x08, "previous task set full status" },
277*275c9da8Seschrock { 0x2c, 0x09, "previous reservation conflict status" },
278*275c9da8Seschrock { 0x2d, 0x00, "overwrite error on update in place" },
279*275c9da8Seschrock { 0x2e, 0x00, "insufficient time for operation" },
280*275c9da8Seschrock { 0x2f, 0x00, "commands cleared by another initiator" },
281*275c9da8Seschrock { 0x30, 0x00, "incompatible medium installed" },
282*275c9da8Seschrock { 0x30, 0x01, "cannot read medium - unknown format" },
283*275c9da8Seschrock { 0x30, 0x02, "cannot read medium - incompatible format" },
284*275c9da8Seschrock { 0x30, 0x03, "cleaning cartridge installed" },
285*275c9da8Seschrock { 0x30, 0x04, "cannot write medium - unknown format" },
286*275c9da8Seschrock { 0x30, 0x05, "cannot write medium - incompatible format" },
287*275c9da8Seschrock { 0x30, 0x06, "cannot format medium - incompatible medium" },
288*275c9da8Seschrock { 0x30, 0x07, "cleaning failure" },
289*275c9da8Seschrock { 0x30, 0x08, "cannot write - application code mismatch" },
290*275c9da8Seschrock { 0x30, 0x09, "current session not fixated for append" },
291*275c9da8Seschrock { 0x30, 0x10, "medium not formatted" },
292*275c9da8Seschrock { 0x31, 0x00, "medium format corrupted" },
293*275c9da8Seschrock { 0x31, 0x01, "format command failed" },
294*275c9da8Seschrock { 0x31, 0x02, "zoned formatting failed due to spare linking" },
295*275c9da8Seschrock { 0x32, 0x00, "no defect spare location available" },
296*275c9da8Seschrock { 0x32, 0x01, "defect list update failure" },
297*275c9da8Seschrock { 0x33, 0x00, "tape length error" },
298*275c9da8Seschrock { 0x34, 0x00, "enclosure failure" },
299*275c9da8Seschrock { 0x35, 0x00, "enclosure services failure" },
300*275c9da8Seschrock { 0x35, 0x01, "unsupported enclosure function" },
301*275c9da8Seschrock { 0x35, 0x02, "enclosure services unavailable" },
302*275c9da8Seschrock { 0x35, 0x03, "enclosure services transfer failure" },
303*275c9da8Seschrock { 0x35, 0x04, "enclosure services transfer refused" },
304*275c9da8Seschrock { 0x36, 0x00, "ribbon, ink, or toner failure" },
305*275c9da8Seschrock { 0x37, 0x00, "rounded parameter" },
306*275c9da8Seschrock { 0x39, 0x00, "saving parameters not supported" },
307*275c9da8Seschrock { 0x3a, 0x00, "medium not present" },
308*275c9da8Seschrock { 0x3a, 0x01, "medium not present - tray closed" },
309*275c9da8Seschrock { 0x3a, 0x02, "medium not present - tray open" },
310*275c9da8Seschrock { 0x3a, 0x03, "medium not present - loadable" },
311*275c9da8Seschrock { 0x3a, 0x04, "medium not present - medium auxiliary memory "
312*275c9da8Seschrock "accessible" },
313*275c9da8Seschrock { 0x3b, 0x00, "sequential positioning error" },
314*275c9da8Seschrock { 0x3b, 0x01, "tape position error at beginning-of-medium" },
315*275c9da8Seschrock { 0x3b, 0x02, "tape position error at end-of-medium" },
316*275c9da8Seschrock { 0x3b, 0x08, "reposition error" },
317*275c9da8Seschrock { 0x3b, 0x0c, "position past beginning of medium" },
318*275c9da8Seschrock { 0x3b, 0x0d, "medium destination element full" },
319*275c9da8Seschrock { 0x3b, 0x0e, "medium source element empty" },
320*275c9da8Seschrock { 0x3b, 0x0f, "end of medium reached" },
321*275c9da8Seschrock { 0x3b, 0x11, "medium magazine not accessible" },
322*275c9da8Seschrock { 0x3b, 0x12, "medium magazine removed" },
323*275c9da8Seschrock { 0x3b, 0x13, "medium magazine inserted" },
324*275c9da8Seschrock { 0x3b, 0x14, "medium magazine locked" },
325*275c9da8Seschrock { 0x3b, 0x15, "medium magazine unlocked" },
326*275c9da8Seschrock { 0x3b, 0x16, "mechanical positioning or changer error" },
327*275c9da8Seschrock { 0x3d, 0x00, "invalid bits in indentify message" },
328*275c9da8Seschrock { 0x3e, 0x00, "LUN has not self-configured yet" },
329*275c9da8Seschrock { 0x3e, 0x01, "LUN failure" },
330*275c9da8Seschrock { 0x3e, 0x02, "timeout on LUN" },
331*275c9da8Seschrock { 0x3e, 0x03, "LUN failed self-test" },
332*275c9da8Seschrock { 0x3e, 0x04, "LUN unable to update self-test log" },
333*275c9da8Seschrock { 0x3f, 0x00, "target operating conditions have changed" },
334*275c9da8Seschrock { 0x3f, 0x01, "microcode has been changed" },
335*275c9da8Seschrock { 0x3f, 0x02, "changed operating definition" },
336*275c9da8Seschrock { 0x3f, 0x03, "inquiry data has changed" },
337*275c9da8Seschrock { 0x3f, 0x04, "component device attached" },
338*275c9da8Seschrock { 0x3f, 0x05, "device identifier changed" },
339*275c9da8Seschrock { 0x3f, 0x06, "redundancy group created or modified" },
340*275c9da8Seschrock { 0x3f, 0x07, "redundancy group deleted" },
341*275c9da8Seschrock { 0x3f, 0x08, "spare created or modified" },
342*275c9da8Seschrock { 0x3f, 0x09, "spare deleted" },
343*275c9da8Seschrock { 0x3f, 0x0a, "volume set created or modified" },
344*275c9da8Seschrock { 0x3f, 0x0b, "volume set deleted" },
345*275c9da8Seschrock { 0x3f, 0x0c, "volume set deassigned" },
346*275c9da8Seschrock { 0x3f, 0x0d, "volume set reassigned" },
347*275c9da8Seschrock { 0x3f, 0x0e, "reported LUNs data has changed" },
348*275c9da8Seschrock { 0x3f, 0x0f, "echo buffer overwritten" },
349*275c9da8Seschrock { 0x3f, 0x10, "medium loadable" },
350*275c9da8Seschrock { 0x3f, 0x11, "medium auxiliary memory accessible" },
351*275c9da8Seschrock { 0x40, 0x00, "ram failure" },
352*275c9da8Seschrock { 0x41, 0x00, "data path failure" },
353*275c9da8Seschrock { 0x42, 0x00, "power-on or self-test failure" },
354*275c9da8Seschrock { 0x43, 0x00, "message error" },
355*275c9da8Seschrock { 0x44, 0x00, "internal target failure" },
356*275c9da8Seschrock { 0x45, 0x00, "select or reselect failure" },
357*275c9da8Seschrock { 0x46, 0x00, "unsuccessful soft reset" },
358*275c9da8Seschrock { 0x47, 0x00, "scsi parity error" },
359*275c9da8Seschrock { 0x47, 0x01, "data phase crc error detected" },
360*275c9da8Seschrock { 0x47, 0x02, "scsi parity error detected during st data phase" },
361*275c9da8Seschrock { 0x47, 0x03, "information unit iucrc error detected" },
362*275c9da8Seschrock { 0x47, 0x04, "asynchronous information protection error detected" },
363*275c9da8Seschrock { 0x47, 0x05, "protocol service crc error" },
364*275c9da8Seschrock { 0x47, 0x7f, "some commands cleared by iscsi protocol event" },
365*275c9da8Seschrock { 0x48, 0x00, "initiator detected error message received" },
366*275c9da8Seschrock { 0x49, 0x00, "invalid message error" },
367*275c9da8Seschrock { 0x4a, 0x00, "command phase error" },
368*275c9da8Seschrock { 0x4b, 0x00, "data phase error" },
369*275c9da8Seschrock { 0x4b, 0x01, "invalid target port transfer tag received" },
370*275c9da8Seschrock { 0x4b, 0x02, "too much write data" },
371*275c9da8Seschrock { 0x4b, 0x03, "ack/nak timeout" },
372*275c9da8Seschrock { 0x4b, 0x04, "nak received" },
373*275c9da8Seschrock { 0x4b, 0x05, "data offset error" },
374*275c9da8Seschrock { 0x4c, 0x00, "logical unit failed self-configuration" },
375*275c9da8Seschrock { 0x4d, 0x00, "tagged overlapped commands (ASCQ = queue tag)" },
376*275c9da8Seschrock { 0x4e, 0x00, "overlapped commands attempted" },
377*275c9da8Seschrock { 0x50, 0x00, "write append error" },
378*275c9da8Seschrock { 0x51, 0x00, "erase failure" },
379*275c9da8Seschrock { 0x52, 0x00, "cartridge fault" },
380*275c9da8Seschrock { 0x53, 0x00, "media load or eject failed" },
381*275c9da8Seschrock { 0x53, 0x01, "unload tape failure" },
382*275c9da8Seschrock { 0x53, 0x02, "medium removal prevented" },
383*275c9da8Seschrock { 0x54, 0x00, "scsi to host system interface failure" },
384*275c9da8Seschrock { 0x55, 0x00, "system resource failure" },
385*275c9da8Seschrock { 0x55, 0x01, "system buffer full" },
386*275c9da8Seschrock { 0x55, 0x02, "insufficient reservation resources" },
387*275c9da8Seschrock { 0x55, 0x03, "insufficient resources" },
388*275c9da8Seschrock { 0x55, 0x04, "insufficient registration resources" },
389*275c9da8Seschrock { 0x55, 0x05, "insufficient access control resources" },
390*275c9da8Seschrock { 0x55, 0x06, "auxiliary memory out of space" },
391*275c9da8Seschrock { 0x57, 0x00, "unable to recover TOC" },
392*275c9da8Seschrock { 0x58, 0x00, "generation does not exist" },
393*275c9da8Seschrock { 0x59, 0x00, "updated block read" },
394*275c9da8Seschrock { 0x5a, 0x00, "operator request or state change input" },
395*275c9da8Seschrock { 0x5a, 0x01, "operator medium removal request" },
396*275c9da8Seschrock { 0x5a, 0x02, "operator selected write protect" },
397*275c9da8Seschrock { 0x5a, 0x03, "operator selected write permit" },
398*275c9da8Seschrock { 0x5b, 0x00, "log exception" },
399*275c9da8Seschrock { 0x5b, 0x01, "threshold condition met" },
400*275c9da8Seschrock { 0x5b, 0x02, "log counter at maximum" },
401*275c9da8Seschrock { 0x5b, 0x03, "log list codes exhausted" },
402*275c9da8Seschrock { 0x5c, 0x00, "RPL status change" },
403*275c9da8Seschrock { 0x5c, 0x01, "spindles synchronized" },
404*275c9da8Seschrock { 0x5c, 0x02, "spindles not synchronized" },
405*275c9da8Seschrock { 0x5d, 0x00, "drive operation marginal, service immediately"
406*275c9da8Seschrock " (failure prediction threshold exceeded)" },
407*275c9da8Seschrock { 0x5d, 0x01, "media failure prediction threshold exceeded" },
408*275c9da8Seschrock { 0x5d, 0x02, "LUN failure prediction threshold exceeded" },
409*275c9da8Seschrock { 0x5d, 0x03, "spare area exhaustion prediction threshold exceeded" },
410*275c9da8Seschrock { 0x5d, 0x10, "hardware impending failure general hard drive failure" },
411*275c9da8Seschrock { 0x5d, 0x11, "hardware impending failure drive error rate too high" },
412*275c9da8Seschrock { 0x5d, 0x12, "hardware impending failure data error rate too high" },
413*275c9da8Seschrock { 0x5d, 0x13, "hardware impending failure seek error rate too high" },
414*275c9da8Seschrock { 0x5d, 0x14, "hardware impending failure too many block reassigns" },
415*275c9da8Seschrock { 0x5d, 0x15, "hardware impending failure access times too high" },
416*275c9da8Seschrock { 0x5d, 0x16, "hardware impending failure start unit times too high" },
417*275c9da8Seschrock { 0x5d, 0x17, "hardware impending failure channel parametrics" },
418*275c9da8Seschrock { 0x5d, 0x18, "hardware impending failure controller detected" },
419*275c9da8Seschrock { 0x5d, 0x19, "hardware impending failure throughput performance" },
420*275c9da8Seschrock { 0x5d, 0x1a, "hardware impending failure seek time performance" },
421*275c9da8Seschrock { 0x5d, 0x1b, "hardware impending failure spin-up retry count" },
422*275c9da8Seschrock { 0x5d, 0x1c, "hardware impending failure drive calibration retry "
423*275c9da8Seschrock "count" },
424*275c9da8Seschrock { 0x5d, 0x20, "controller impending failure general hard drive "
425*275c9da8Seschrock "failure" },
426*275c9da8Seschrock { 0x5d, 0x21, "controller impending failure drive error rate too "
427*275c9da8Seschrock "high" },
428*275c9da8Seschrock { 0x5d, 0x22, "controller impending failure data error rate too high" },
429*275c9da8Seschrock { 0x5d, 0x23, "controller impending failure seek error rate too high" },
430*275c9da8Seschrock { 0x5d, 0x24, "controller impending failure too many block reassigns" },
431*275c9da8Seschrock { 0x5d, 0x25, "controller impending failure access times too high" },
432*275c9da8Seschrock { 0x5d, 0x26, "controller impending failure start unit times too "
433*275c9da8Seschrock "high" },
434*275c9da8Seschrock { 0x5d, 0x27, "controller impending failure channel parametrics" },
435*275c9da8Seschrock { 0x5d, 0x28, "controller impending failure controller detected" },
436*275c9da8Seschrock { 0x5d, 0x29, "controller impending failure throughput performance" },
437*275c9da8Seschrock { 0x5d, 0x2a, "controller impending failure seek time performance" },
438*275c9da8Seschrock { 0x5d, 0x2b, "controller impending failure spin-up retry count" },
439*275c9da8Seschrock { 0x5d, 0x2c, "controller impending failure drive calibration retry "
440*275c9da8Seschrock "cnt" },
441*275c9da8Seschrock { 0x5d, 0x30, "data channel impending failure general hard drive "
442*275c9da8Seschrock "failure" },
443*275c9da8Seschrock { 0x5d, 0x31, "data channel impending failure drive error rate too "
444*275c9da8Seschrock "high" },
445*275c9da8Seschrock { 0x5d, 0x32, "data channel impending failure data error rate too "
446*275c9da8Seschrock "high" },
447*275c9da8Seschrock { 0x5d, 0x33, "data channel impending failure seek error rate too "
448*275c9da8Seschrock "high" },
449*275c9da8Seschrock { 0x5d, 0x34, "data channel impending failure too many block "
450*275c9da8Seschrock "reassigns" },
451*275c9da8Seschrock { 0x5d, 0x35, "data channel impending failure access times too high" },
452*275c9da8Seschrock { 0x5d, 0x36, "data channel impending failure start unit times too "
453*275c9da8Seschrock "high" },
454*275c9da8Seschrock { 0x5d, 0x37, "data channel impending failure channel parametrics" },
455*275c9da8Seschrock { 0x5d, 0x38, "data channel impending failure controller detected" },
456*275c9da8Seschrock { 0x5d, 0x39, "data channel impending failure throughput performance" },
457*275c9da8Seschrock { 0x5d, 0x3a, "data channel impending failure seek time performance" },
458*275c9da8Seschrock { 0x5d, 0x3b, "data channel impending failure spin-up retry count" },
459*275c9da8Seschrock { 0x5d, 0x3c, "data channel impending failure drive calibrate retry "
460*275c9da8Seschrock "cnt" },
461*275c9da8Seschrock { 0x5d, 0x40, "servo impending failure general hard drive failure" },
462*275c9da8Seschrock { 0x5d, 0x41, "servo impending failure drive error rate too high" },
463*275c9da8Seschrock { 0x5d, 0x42, "servo impending failure data error rate too high" },
464*275c9da8Seschrock { 0x5d, 0x43, "servo impending failure seek error rate too high" },
465*275c9da8Seschrock { 0x5d, 0x44, "servo impending failure too many block reassigns" },
466*275c9da8Seschrock { 0x5d, 0x45, "servo impending failure access times too high" },
467*275c9da8Seschrock { 0x5d, 0x46, "servo impending failure start unit times too high" },
468*275c9da8Seschrock { 0x5d, 0x47, "servo impending failure channel parametrics" },
469*275c9da8Seschrock { 0x5d, 0x48, "servo impending failure controller detected" },
470*275c9da8Seschrock { 0x5d, 0x49, "servo impending failure throughput performance" },
471*275c9da8Seschrock { 0x5d, 0x4a, "servo impending failure seek time performance" },
472*275c9da8Seschrock { 0x5d, 0x4b, "servo impending failure spin-up retry count" },
473*275c9da8Seschrock { 0x5d, 0x4c, "servo impending failure drive calibration retry count" },
474*275c9da8Seschrock { 0x5d, 0x50, "spindle impending failure general hard drive failure" },
475*275c9da8Seschrock { 0x5d, 0x51, "spindle impending failure drive error rate too high" },
476*275c9da8Seschrock { 0x5d, 0x52, "spindle impending failure data error rate too high" },
477*275c9da8Seschrock { 0x5d, 0x53, "spindle impending failure seek error rate too high" },
478*275c9da8Seschrock { 0x5d, 0x54, "spindle impending failure too many block reassigns" },
479*275c9da8Seschrock { 0x5d, 0x55, "spindle impending failure access times too high" },
480*275c9da8Seschrock { 0x5d, 0x56, "spindle impending failure start unit times too high" },
481*275c9da8Seschrock { 0x5d, 0x57, "spindle impending failure channel parametrics" },
482*275c9da8Seschrock { 0x5d, 0x58, "spindle impending failure controller detected" },
483*275c9da8Seschrock { 0x5d, 0x59, "spindle impending failure throughput performance" },
484*275c9da8Seschrock { 0x5d, 0x5a, "spindle impending failure seek time performance" },
485*275c9da8Seschrock { 0x5d, 0x5b, "spindle impending failure spin-up retry count" },
486*275c9da8Seschrock { 0x5d, 0x5c, "spindle impending failure drive calibration retry "
487*275c9da8Seschrock "count" },
488*275c9da8Seschrock { 0x5d, 0x60, "firmware impending failure general hard drive failure" },
489*275c9da8Seschrock { 0x5d, 0x61, "firmware impending failure drive error rate too high" },
490*275c9da8Seschrock { 0x5d, 0x62, "firmware impending failure data error rate too high" },
491*275c9da8Seschrock { 0x5d, 0x63, "firmware impending failure seek error rate too high" },
492*275c9da8Seschrock { 0x5d, 0x64, "firmware impending failure too many block reassigns" },
493*275c9da8Seschrock { 0x5d, 0x65, "firmware impending failure access times too high" },
494*275c9da8Seschrock { 0x5d, 0x66, "firmware impending failure start unit times too high" },
495*275c9da8Seschrock { 0x5d, 0x67, "firmware impending failure channel parametrics" },
496*275c9da8Seschrock { 0x5d, 0x68, "firmware impending failure controller detected" },
497*275c9da8Seschrock { 0x5d, 0x69, "firmware impending failure throughput performance" },
498*275c9da8Seschrock { 0x5d, 0x6a, "firmware impending failure seek time performance" },
499*275c9da8Seschrock { 0x5d, 0x6b, "firmware impending failure spin-up retry count" },
500*275c9da8Seschrock { 0x5d, 0x6c, "firmware impending failure drive calibration retry "
501*275c9da8Seschrock "count" },
502*275c9da8Seschrock { 0x5d, 0xff, "failure prediction threshold exceeded (false)" },
503*275c9da8Seschrock { 0x5e, 0x00, "low power condition active" },
504*275c9da8Seschrock { 0x5e, 0x01, "idle condition activated by timer" },
505*275c9da8Seschrock { 0x5e, 0x02, "standby condition activated by timer" },
506*275c9da8Seschrock { 0x5e, 0x03, "idle condition activated by command" },
507*275c9da8Seschrock { 0x5e, 0x04, "standby condition activated by command" },
508*275c9da8Seschrock { 0x60, 0x00, "lamp failure" },
509*275c9da8Seschrock { 0x61, 0x00, "video aquisition error" },
510*275c9da8Seschrock { 0x62, 0x00, "scan head positioning error" },
511*275c9da8Seschrock { 0x63, 0x00, "end of user area encountered on this track" },
512*275c9da8Seschrock { 0x63, 0x01, "packet does not fit in available space" },
513*275c9da8Seschrock { 0x64, 0x00, "illegal mode for this track" },
514*275c9da8Seschrock { 0x64, 0x01, "invalid packet size" },
515*275c9da8Seschrock { 0x65, 0x00, "voltage fault" },
516*275c9da8Seschrock { 0x66, 0x00, "automatic document feeder cover up" },
517*275c9da8Seschrock { 0x67, 0x00, "configuration failure" },
518*275c9da8Seschrock { 0x67, 0x01, "configuration of incapable LUNs failed" },
519*275c9da8Seschrock { 0x67, 0x02, "add LUN failed" },
520*275c9da8Seschrock { 0x67, 0x03, "modification of LUN failed" },
521*275c9da8Seschrock { 0x67, 0x04, "exchange of LUN failed" },
522*275c9da8Seschrock { 0x67, 0x05, "remove of LUN failed" },
523*275c9da8Seschrock { 0x67, 0x06, "attachment of LUN failed" },
524*275c9da8Seschrock { 0x67, 0x07, "creation of LUN failed" },
525*275c9da8Seschrock { 0x67, 0x08, "assign failure occurred" },
526*275c9da8Seschrock { 0x67, 0x09, "multiply assigned LUN" },
527*275c9da8Seschrock { 0x67, 0x0a, "set target port groups command failed" },
528*275c9da8Seschrock { 0x68, 0x00, "logical unit not configured" },
529*275c9da8Seschrock { 0x69, 0x00, "data loss on logical unit" },
530*275c9da8Seschrock { 0x69, 0x01, "multiple LUN failures" },
531*275c9da8Seschrock { 0x69, 0x02, "parity/data mismatch" },
532*275c9da8Seschrock { 0x6a, 0x00, "informational, refer to log" },
533*275c9da8Seschrock { 0x6b, 0x00, "state change has occured" },
534*275c9da8Seschrock { 0x6b, 0x01, "redundancy level got better" },
535*275c9da8Seschrock { 0x6b, 0x02, "redundancy level got worse" },
536*275c9da8Seschrock { 0x6c, 0x00, "rebuild failure occured" },
537*275c9da8Seschrock { 0x6d, 0x00, "recalculate failure occured" },
538*275c9da8Seschrock { 0x6e, 0x00, "command to logical unit failed" },
539*275c9da8Seschrock { 0x6f, 0x00, "copy protect key exchange failure authentication "
540*275c9da8Seschrock "failure" },
541*275c9da8Seschrock { 0x6f, 0x01, "copy protect key exchange failure key not present" },
542*275c9da8Seschrock { 0x6f, 0x02, "copy protect key exchange failure key not established" },
543*275c9da8Seschrock { 0x6f, 0x03, "read of scrambled sector without authentication" },
544*275c9da8Seschrock { 0x6f, 0x04, "media region code is mismatched to LUN region" },
545*275c9da8Seschrock { 0x6f, 0x05, "drive region must be permanent/region reset count "
546*275c9da8Seschrock "error" },
547*275c9da8Seschrock { 0x70, 0xffff, "decompression exception short algorithm id of ASCQ" },
548*275c9da8Seschrock { 0x71, 0x00, "decompression exception long algorithm id" },
549*275c9da8Seschrock { 0x72, 0x00, "session fixation error" },
550*275c9da8Seschrock { 0x72, 0x01, "session fixation error writing lead-in" },
551*275c9da8Seschrock { 0x72, 0x02, "session fixation error writing lead-out" },
552*275c9da8Seschrock { 0x72, 0x03, "session fixation error - incomplete track in session" },
553*275c9da8Seschrock { 0x72, 0x04, "empty or partially written reserved track" },
554*275c9da8Seschrock { 0x72, 0x05, "no more track reservations allowed" },
555*275c9da8Seschrock { 0x73, 0x00, "cd control error" },
556*275c9da8Seschrock { 0x73, 0x01, "power calibration area almost full" },
557*275c9da8Seschrock { 0x73, 0x02, "power calibration area is full" },
558*275c9da8Seschrock { 0x73, 0x03, "power calibration area error" },
559*275c9da8Seschrock { 0x73, 0x04, "program memory area update failure" },
560*275c9da8Seschrock { 0x73, 0x05, "program memory area is full" },
561*275c9da8Seschrock { 0x73, 0x06, "rma/pma is almost full" },
562*275c9da8Seschrock { 0xffff, 0xffff, NULL }
563*275c9da8Seschrock };
564*275c9da8Seschrock
565*275c9da8Seschrock static const char *
find_string(slist_t * slist,int match_value)566*275c9da8Seschrock find_string(slist_t *slist, int match_value)
567*275c9da8Seschrock {
568*275c9da8Seschrock for (; slist->str != NULL; slist++) {
569*275c9da8Seschrock if (slist->value == match_value) {
570*275c9da8Seschrock return (slist->str);
571*275c9da8Seschrock }
572*275c9da8Seschrock }
573*275c9da8Seschrock
574*275c9da8Seschrock return (NULL);
575*275c9da8Seschrock }
576*275c9da8Seschrock
577*275c9da8Seschrock const char *
libscsi_sense_key_name(uint64_t key)578*275c9da8Seschrock libscsi_sense_key_name(uint64_t key)
579*275c9da8Seschrock {
580*275c9da8Seschrock return (find_string(sensekey_strings, (int)key));
581*275c9da8Seschrock }
582*275c9da8Seschrock
583*275c9da8Seschrock /*
584*275c9da8Seschrock * Given an asc (Additional Sense Code) and ascq (Additional Sense Code
585*275c9da8Seschrock * Qualifier), return a string describing the error information.
586*275c9da8Seschrock */
587*275c9da8Seschrock const char *
libscsi_sense_code_name(uint64_t asc,uint64_t ascq)588*275c9da8Seschrock libscsi_sense_code_name(uint64_t asc, uint64_t ascq)
589*275c9da8Seschrock {
590*275c9da8Seschrock int i = 0;
591*275c9da8Seschrock
592*275c9da8Seschrock while (extended_sense_list[i].asc != 0xffff) {
593*275c9da8Seschrock if ((asc == extended_sense_list[i].asc) &&
594*275c9da8Seschrock ((ascq == extended_sense_list[i].ascq) ||
595*275c9da8Seschrock (extended_sense_list[i].ascq == 0xffff))) {
596*275c9da8Seschrock return ((char *)extended_sense_list[i].message);
597*275c9da8Seschrock }
598*275c9da8Seschrock i++;
599*275c9da8Seschrock }
600*275c9da8Seschrock
601*275c9da8Seschrock return (NULL);
602*275c9da8Seschrock }
603*275c9da8Seschrock
604*275c9da8Seschrock /*
605*275c9da8Seschrock * Retrieve "information" field from descriptor format sense data. Iterates
606*275c9da8Seschrock * through each sense descriptor looking for the information descriptor and
607*275c9da8Seschrock * returns the information field from that descriptor.
608*275c9da8Seschrock */
609*275c9da8Seschrock static diskaddr_t
scsi_extract_sense_info_descr(struct scsi_descr_sense_hdr * sdsp,size_t len)610*275c9da8Seschrock scsi_extract_sense_info_descr(struct scsi_descr_sense_hdr *sdsp, size_t len)
611*275c9da8Seschrock {
612*275c9da8Seschrock diskaddr_t result;
613*275c9da8Seschrock uint8_t *descr_offset;
614*275c9da8Seschrock size_t valid_sense_length;
615*275c9da8Seschrock struct scsi_information_sense_descr *isd;
616*275c9da8Seschrock
617*275c9da8Seschrock /*
618*275c9da8Seschrock * Initialize result to -1 indicating there is no information
619*275c9da8Seschrock * descriptor
620*275c9da8Seschrock */
621*275c9da8Seschrock result = (diskaddr_t)-1;
622*275c9da8Seschrock
623*275c9da8Seschrock /*
624*275c9da8Seschrock * The first descriptor will immediately follow the header
625*275c9da8Seschrock */
626*275c9da8Seschrock descr_offset = (uint8_t *)(sdsp+1);
627*275c9da8Seschrock
628*275c9da8Seschrock /*
629*275c9da8Seschrock * Calculate the amount of valid sense data
630*275c9da8Seschrock */
631*275c9da8Seschrock valid_sense_length =
632*275c9da8Seschrock MIN((sizeof (struct scsi_descr_sense_hdr) +
633*275c9da8Seschrock sdsp->ds_addl_sense_length), len);
634*275c9da8Seschrock
635*275c9da8Seschrock /*
636*275c9da8Seschrock * Iterate through the list of descriptors, stopping when we run out of
637*275c9da8Seschrock * sense data
638*275c9da8Seschrock */
639*275c9da8Seschrock while ((descr_offset + sizeof (struct scsi_information_sense_descr)) <=
640*275c9da8Seschrock (uint8_t *)sdsp + valid_sense_length) {
641*275c9da8Seschrock /*
642*275c9da8Seschrock * Check if this is an information descriptor. We can use the
643*275c9da8Seschrock * scsi_information_sense_descr structure as a template since
644*275c9da8Seschrock * the first two fields are always the same
645*275c9da8Seschrock */
646*275c9da8Seschrock isd = (struct scsi_information_sense_descr *)descr_offset;
647*275c9da8Seschrock if (isd->isd_descr_type == DESCR_INFORMATION) {
648*275c9da8Seschrock /*
649*275c9da8Seschrock * Found an information descriptor. Copy the
650*275c9da8Seschrock * information field. There will only be one
651*275c9da8Seschrock * information descriptor so we can stop looking.
652*275c9da8Seschrock */
653*275c9da8Seschrock result =
654*275c9da8Seschrock (((diskaddr_t)isd->isd_information[0] << 56) |
655*275c9da8Seschrock ((diskaddr_t)isd->isd_information[1] << 48) |
656*275c9da8Seschrock ((diskaddr_t)isd->isd_information[2] << 40) |
657*275c9da8Seschrock ((diskaddr_t)isd->isd_information[3] << 32) |
658*275c9da8Seschrock ((diskaddr_t)isd->isd_information[4] << 24) |
659*275c9da8Seschrock ((diskaddr_t)isd->isd_information[5] << 16) |
660*275c9da8Seschrock ((diskaddr_t)isd->isd_information[6] << 8) |
661*275c9da8Seschrock ((diskaddr_t)isd->isd_information[7]));
662*275c9da8Seschrock break;
663*275c9da8Seschrock }
664*275c9da8Seschrock
665*275c9da8Seschrock /*
666*275c9da8Seschrock * Get pointer to the next descriptor. The "additional length"
667*275c9da8Seschrock * field holds the length of the descriptor except for the
668*275c9da8Seschrock * "type" and "additional length" fields, so we need to add 2 to
669*275c9da8Seschrock * get the total length.
670*275c9da8Seschrock */
671*275c9da8Seschrock descr_offset += (isd->isd_addl_length + 2);
672*275c9da8Seschrock }
673*275c9da8Seschrock
674*275c9da8Seschrock return (result);
675*275c9da8Seschrock }
676*275c9da8Seschrock
677*275c9da8Seschrock int
libscsi_action_parse_sense(const libscsi_action_t * ap,uint64_t * keyp,uint64_t * ascp,uint64_t * ascqp,diskaddr_t * blkp)678*275c9da8Seschrock libscsi_action_parse_sense(const libscsi_action_t *ap, uint64_t *keyp,
679*275c9da8Seschrock uint64_t *ascp, uint64_t *ascqp, diskaddr_t *blkp)
680*275c9da8Seschrock {
681*275c9da8Seschrock struct scsi_extended_sense *xsp;
682*275c9da8Seschrock struct scsi_descr_sense_hdr *sdsp;
683*275c9da8Seschrock size_t len;
684*275c9da8Seschrock
685*275c9da8Seschrock if (libscsi_action_get_sense(ap, (uint8_t **)&xsp, NULL, &len) != 0)
686*275c9da8Seschrock return (-1);
687*275c9da8Seschrock
688*275c9da8Seschrock sdsp = (struct scsi_descr_sense_hdr *)xsp;
689*275c9da8Seschrock
690*275c9da8Seschrock if (keyp != NULL)
691*275c9da8Seschrock *keyp = (uint64_t)xsp->es_key;
692*275c9da8Seschrock
693*275c9da8Seschrock switch (xsp->es_code) {
694*275c9da8Seschrock case CODE_FMT_DESCR_CURRENT:
695*275c9da8Seschrock case CODE_FMT_DESCR_DEFERRED:
696*275c9da8Seschrock if (blkp != NULL)
697*275c9da8Seschrock *blkp = (diskaddr_t)
698*275c9da8Seschrock scsi_extract_sense_info_descr(sdsp, len);
699*275c9da8Seschrock if (ascp != NULL)
700*275c9da8Seschrock *ascp = (uint64_t)sdsp->ds_add_code;
701*275c9da8Seschrock if (ascqp != NULL)
702*275c9da8Seschrock *ascqp = (uint64_t)sdsp->ds_qual_code;
703*275c9da8Seschrock break;
704*275c9da8Seschrock case CODE_FMT_FIXED_CURRENT:
705*275c9da8Seschrock case CODE_FMT_FIXED_DEFERRED:
706*275c9da8Seschrock default:
707*275c9da8Seschrock if (xsp->es_valid && blkp != NULL)
708*275c9da8Seschrock *blkp = (diskaddr_t)
709*275c9da8Seschrock ((xsp->es_info_1 << 24) | (xsp->es_info_2 << 16) |
710*275c9da8Seschrock (xsp->es_info_3 << 8) | xsp->es_info_4);
711*275c9da8Seschrock if (xsp->es_add_len >= 6) {
712*275c9da8Seschrock if (ascp != NULL)
713*275c9da8Seschrock *ascp = (uint64_t)xsp->es_add_code;
714*275c9da8Seschrock if (ascqp != NULL)
715*275c9da8Seschrock *ascqp = (uint64_t)xsp->es_qual_code;
716*275c9da8Seschrock }
717*275c9da8Seschrock break;
718*275c9da8Seschrock }
719*275c9da8Seschrock
720*275c9da8Seschrock return (0);
721*275c9da8Seschrock }
722