[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cam/scsi/scsi_all.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  1 /*-
  2  * Implementation of Utility functions for all SCSI device types.
  3  *
  4  * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
  5  * Copyright (c) 1997, 1998, 2003 Kenneth D. Merry.
  6  * All rights reserved.
  7  *
  8  * Redistribution and use in source and binary forms, with or without
  9  * modification, are permitted provided that the following conditions
 10  * are met:
 11  * 1. Redistributions of source code must retain the above copyright
 12  *    notice, this list of conditions, and the following disclaimer,
 13  *    without modification, immediately at the beginning of the file.
 14  * 2. The name of the author may not be used to endorse or promote products
 15  *    derived from this software without specific prior written permission.
 16  *
 17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 27  * SUCH DAMAGE.
 28  */
 29 
 30 #include <sys/cdefs.h>
 31 __FBSDID("$FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.53 2008/08/16 21:26:58 ken Exp $");
 32 
 33 #include <sys/param.h>
 34 
 35 #ifdef _KERNEL
 36 #include <opt_scsi.h>
 37 
 38 #include <sys/systm.h>
 39 #include <sys/libkern.h>
 40 #include <sys/kernel.h>
 41 #include <sys/sysctl.h>
 42 #else
 43 #include <errno.h>
 44 #include <stdio.h>
 45 #include <stdlib.h>
 46 #include <string.h>
 47 #endif
 48 
 49 #include <cam/cam.h>
 50 #include <cam/cam_ccb.h>
 51 #include <cam/cam_xpt.h>
 52 #include <cam/scsi/scsi_all.h>
 53 #include <sys/sbuf.h>
 54 #ifndef _KERNEL
 55 #include <camlib.h>
 56 
 57 #ifndef FALSE
 58 #define FALSE   0
 59 #endif /* FALSE */
 60 #ifndef TRUE
 61 #define TRUE    1
 62 #endif /* TRUE */
 63 #define ERESTART        -1              /* restart syscall */
 64 #define EJUSTRETURN     -2              /* don't modify regs, just return */
 65 #endif /* !_KERNEL */
 66 
 67 /*
 68  * This is the default number of milliseconds we wait for devices to settle
 69  * after a SCSI bus reset.
 70  */
 71 #ifndef SCSI_DELAY
 72 #define SCSI_DELAY 2000
 73 #endif
 74 /*
 75  * All devices need _some_ sort of bus settle delay, so we'll set it to
 76  * a minimum value of 100ms. Note that this is pertinent only for SPI-
 77  * not transport like Fibre Channel or iSCSI where 'delay' is completely
 78  * meaningless.
 79  */
 80 #ifndef SCSI_MIN_DELAY
 81 #define SCSI_MIN_DELAY 100
 82 #endif
 83 /*
 84  * Make sure the user isn't using seconds instead of milliseconds.
 85  */
 86 #if (SCSI_DELAY < SCSI_MIN_DELAY && SCSI_DELAY != 0)
 87 #error "SCSI_DELAY is in milliseconds, not seconds!  Please use a larger value"
 88 #endif
 89 
 90 int scsi_delay;
 91 
 92 static int      ascentrycomp(const void *key, const void *member);
 93 static int      senseentrycomp(const void *key, const void *member);
 94 static void     fetchtableentries(int sense_key, int asc, int ascq,
 95                                   struct scsi_inquiry_data *,
 96                                   const struct sense_key_table_entry **,
 97                                   const struct asc_table_entry **);
 98 #ifdef _KERNEL
 99 static void     init_scsi_delay(void);
100 static int      sysctl_scsi_delay(SYSCTL_HANDLER_ARGS);
101 static int      set_scsi_delay(int delay);
102 #endif
103 
104 #if !defined(SCSI_NO_OP_STRINGS)
105 
106 #define D       (1 << T_DIRECT)
107 #define T       (1 << T_SEQUENTIAL)
108 #define L       (1 << T_PRINTER)
109 #define P       (1 << T_PROCESSOR)
110 #define W       (1 << T_WORM)
111 #define R       (1 << T_CDROM)
112 #define O       (1 << T_OPTICAL)
113 #define M       (1 << T_CHANGER)
114 #define A       (1 << T_STORARRAY)
115 #define E       (1 << T_ENCLOSURE)
116 #define B       (1 << T_RBC)
117 #define K       (1 << T_OCRW)
118 #define V       (1 << T_ADC)
119 #define F       (1 << T_OSD)
120 #define S       (1 << T_SCANNER)
121 #define C       (1 << T_COMM)
122 
123 #define ALL     (D | T | L | P | W | R | O | M | A | E | B | K | V | F | S | C)
124 
125 static struct op_table_entry plextor_cd_ops[] = {
126         { 0xD8, R, "CD-DA READ" }
127 };
128 
129 static struct scsi_op_quirk_entry scsi_op_quirk_table[] = {
130         {
131                 /*
132                  * I believe that 0xD8 is the Plextor proprietary command
133                  * to read CD-DA data.  I'm not sure which Plextor CDROM
134                  * models support the command, though.  I know for sure
135                  * that the 4X, 8X, and 12X models do, and presumably the
136                  * 12-20X does.  I don't know about any earlier models,
137                  * though.  If anyone has any more complete information,
138                  * feel free to change this quirk entry.
139                  */
140                 {T_CDROM, SIP_MEDIA_REMOVABLE, "PLEXTOR", "CD-ROM PX*", "*"},
141                 sizeof(plextor_cd_ops)/sizeof(struct op_table_entry),
142                 plextor_cd_ops
143         }
144 };
145 
146 static struct op_table_entry scsi_op_codes[] = {
147         /*
148          * From: http://www.t10.org/lists/op-num.txt
149          * Modifications by Kenneth Merry (ken@FreeBSD.ORG)
150          *              and Jung-uk Kim (jkim@FreeBSD.org)
151          *
152          * Note:  order is important in this table, scsi_op_desc() currently
153          * depends on the opcodes in the table being in order to save
154          * search time.
155          * Note:  scanner and comm. devices are carried over from the previous
156          * version because they were removed in the latest spec.
157          */
158         /* File: OP-NUM.TXT
159          *
160          * SCSI Operation Codes
161          * Numeric Sorted Listing
162          * as of  3/11/08
163          *
164          *     D - DIRECT ACCESS DEVICE (SBC-2)                device column key
165          *     .T - SEQUENTIAL ACCESS DEVICE (SSC-2)           -----------------
166          *     . L - PRINTER DEVICE (SSC)                      M = Mandatory
167          *     .  P - PROCESSOR DEVICE (SPC)                   O = Optional
168          *     .  .W - WRITE ONCE READ MULTIPLE DEVICE (SBC-2) V = Vendor spec.
169          *     .  . R - CD/DVE DEVICE (MMC-3)                  Z = Obsolete
170          *     .  .  O - OPTICAL MEMORY DEVICE (SBC-2)
171          *     .  .  .M - MEDIA CHANGER DEVICE (SMC-2)
172          *     .  .  . A - STORAGE ARRAY DEVICE (SCC-2)
173          *     .  .  . .E - ENCLOSURE SERVICES DEVICE (SES)
174          *     .  .  .  .B - SIMPLIFIED DIRECT-ACCESS DEVICE (RBC)
175          *     .  .  .  . K - OPTICAL CARD READER/WRITER DEVICE (OCRW)
176          *     .  .  .  .  V - AUTOMATION/DRIVE INTERFACE (ADC)
177          *     .  .  .  .  .F - OBJECT-BASED STORAGE (OSD)
178          * OP  DTLPWROMAEBKVF  Description
179          * --  --------------  ---------------------------------------------- */
180         /* 00  MMMMMMMMMMMMMM  TEST UNIT READY */
181         { 0x00, ALL, "TEST UNIT READY" },
182         /* 01   M              REWIND */
183         { 0x01, T, "REWIND" },
184         /* 01  Z V ZZZZ        REZERO UNIT */
185         { 0x01, D | W | R | O | M, "REZERO UNIT" },
186         /* 02  VVVVVV V */
187         /* 03  MMMMMMMMMMOMMM  REQUEST SENSE */
188         { 0x03, ALL, "REQUEST SENSE" },
189         /* 04  M    OO         FORMAT UNIT */
190         { 0x04, D | R | O, "FORMAT UNIT" },
191         /* 04   O              FORMAT MEDIUM */
192         { 0x04, T, "FORMAT MEDIUM" },
193         /* 04    O             FORMAT */
194         { 0x04, L, "FORMAT" },
195         /* 05  VMVVVV V        READ BLOCK LIMITS */
196         { 0x05, T, "READ BLOCK LIMITS" },
197         /* 06  VVVVVV V */
198         /* 07  OVV O OV        REASSIGN BLOCKS */
199         { 0x07, D | W | O, "REASSIGN BLOCKS" },
200         /* 07         O        INITIALIZE ELEMENT STATUS */
201         { 0x07, M, "INITIALIZE ELEMENT STATUS" },
202         /* 08  MOV O OV        READ(6) */
203         { 0x08, D | T | W | O, "READ(6)" },
204         /* 08     O            RECEIVE */
205         { 0x08, P, "RECEIVE" },
206         /* 08                  GET MESSAGE(6) */
207         { 0x08, C, "GET MESSAGE(6)" },
208         /* 09  VVVVVV V */
209         /* 0A  OO  O OV        WRITE(6) */
210         { 0x0A, D | T | W | O, "WRITE(6)" },
211         /* 0A     M            SEND(6) */
212         { 0x0A, P, "SEND(6)" },
213         /* 0A                  SEND MESSAGE(6) */
214         { 0x0A, C, "SEND MESSAGE(6)" },
215         /* 0A    M             PRINT */
216         { 0x0A, L, "PRINT" },
217         /* 0B  Z   ZOZV        SEEK(6) */
218         { 0x0B, D | W | R | O, "SEEK(6)" },
219         /* 0B   O              SET CAPACITY */
220         { 0x0B, T, "SET CAPACITY" },
221         /* 0B    O             SLEW AND PRINT */
222         { 0x0B, L, "SLEW AND PRINT" },
223         /* 0C  VVVVVV V */
224         /* 0D  VVVVVV V */
225         /* 0E  VVVVVV V */
226         /* 0F  VOVVVV V        READ REVERSE(6) */
227         { 0x0F, T, "READ REVERSE(6)" },
228         /* 10  VM VVV          WRITE FILEMARKS(6) */
229         { 0x10, T, "WRITE FILEMARKS(6)" },
230         /* 10    O             SYNCHRONIZE BUFFER */
231         { 0x10, L, "SYNCHRONIZE BUFFER" },
232         /* 11  VMVVVV          SPACE(6) */
233         { 0x11, T, "SPACE(6)" },
234         /* 12  MMMMMMMMMMMMMM  INQUIRY */
235         { 0x12, ALL, "INQUIRY" },
236         /* 13  V VVVV */
237         /* 13   O              VERIFY(6) */
238         { 0x13, T, "VERIFY(6)" },
239         /* 14  VOOVVV          RECOVER BUFFERED DATA */
240         { 0x14, T | L, "RECOVER BUFFERED DATA" },
241         /* 15  OMO O OOOO OO   MODE SELECT(6) */
242         { 0x15, ALL & ~(P | R | B | F), "MODE SELECT(6)" },
243         /* 16  ZZMZO OOOZ O    RESERVE(6) */
244         { 0x16, ALL & ~(R | B | V | F | C), "RESERVE(6)" },
245         /* 16         Z        RESERVE ELEMENT(6) */
246         { 0x16, M, "RESERVE ELEMENT(6)" },
247         /* 17  ZZMZO OOOZ O    RELEASE(6) */
248         { 0x17, ALL & ~(R | B | V | F | C), "RELEASE(6)" },
249         /* 17         Z        RELEASE ELEMENT(6) */
250         { 0x17, M, "RELEASE ELEMENT(6)" },
251         /* 18  ZZZZOZO    Z    COPY */
252         { 0x18, D | T | L | P | W | R | O | K | S, "COPY" },
253         /* 19  VMVVVV          ERASE(6) */
254         { 0x19, T, "ERASE(6)" },
255         /* 1A  OMO O OOOO OO   MODE SENSE(6) */
256         { 0x1A, ALL & ~(P | R | B | F), "MODE SENSE(6)" },
257         /* 1B  O   OOO O MO O  START STOP UNIT */
258         { 0x1B, D | W | R | O | A | B | K | F, "START STOP UNIT" },
259         /* 1B   O          M   LOAD UNLOAD */
260         { 0x1B, T | V, "LOAD UNLOAD" },
261         /* 1B                  SCAN */
262         { 0x1B, S, "SCAN" },
263         /* 1B    O             STOP PRINT */
264         { 0x1B, L, "STOP PRINT" },
265         /* 1B         O        OPEN/CLOSE IMPORT/EXPORT ELEMENT */
266         { 0x1B, M, "OPEN/CLOSE IMPORT/EXPORT ELEMENT" },
267         /* 1C  OOOOO OOOM OOO  RECEIVE DIAGNOSTIC RESULTS */
268         { 0x1C, ALL & ~(R | B), "RECEIVE DIAGNOSTIC RESULTS" },
269         /* 1D  MMMMM MMOM MMM  SEND DIAGNOSTIC */
270         { 0x1D, ALL & ~(R | B), "SEND DIAGNOSTIC" },
271         /* 1E  OO  OOOO   O O  PREVENT ALLOW MEDIUM REMOVAL */
272         { 0x1E, D | T | W | R | O | M | K | F, "PREVENT ALLOW MEDIUM REMOVAL" },
273         /* 1F */
274         /* 20  V   VVV    V */
275         /* 21  V   VVV    V */
276         /* 22  V   VVV    V */
277         /* 23  V   V V    V */
278         /* 23       O          READ FORMAT CAPACITIES */
279         { 0x23, R, "READ FORMAT CAPACITIES" },
280         /* 24  V   VV          SET WINDOW */
281         { 0x24, S, "SET WINDOW" },
282         /* 25  M   M M   M     READ CAPACITY(10) */
283         { 0x25, D | W | O | B, "READ CAPACITY(10)" },
284         /* 25       O          READ CAPACITY */
285         { 0x25, R, "READ CAPACITY" },
286         /* 25             M    READ CARD CAPACITY */
287         { 0x25, K, "READ CARD CAPACITY" },
288         /* 25                  GET WINDOW */
289         { 0x25, S, "GET WINDOW" },
290         /* 26  V   VV */
291         /* 27  V   VV */
292         /* 28  M   MOM   MM    READ(10) */
293         { 0x28, D | W | R | O | B | K | S, "READ(10)" },
294         /* 28                  GET MESSAGE(10) */
295         { 0x28, C, "GET MESSAGE(10)" },
296         /* 29  V   VVO         READ GENERATION */
297         { 0x29, O, "READ GENERATION" },
298         /* 2A  O   MOM   MO    WRITE(10) */
299         { 0x2A, D | W | R | O | B | K, "WRITE(10)" },
300         /* 2A                  SEND(10) */
301         { 0x2A, S, "SEND(10)" },
302         /* 2A                  SEND MESSAGE(10) */
303         { 0x2A, C, "SEND MESSAGE(10)" },
304         /* 2B  Z   OOO    O    SEEK(10) */
305         { 0x2B, D | W | R | O | K, "SEEK(10)" },
306         /* 2B   O              LOCATE(10) */
307         { 0x2B, T, "LOCATE(10)" },
308         /* 2B         O        POSITION TO ELEMENT */
309         { 0x2B, M, "POSITION TO ELEMENT" },
310         /* 2C  V    OO         ERASE(10) */
311         { 0x2C, R | O, "ERASE(10)" },
312         /* 2D        O         READ UPDATED BLOCK */
313         { 0x2D, O, "READ UPDATED BLOCK" },
314         /* 2D  V */
315         /* 2E  O   OOO   MO    WRITE AND VERIFY(10) */
316         { 0x2E, D | W | R | O | B | K, "WRITE AND VERIFY(10)" },
317         /* 2F  O   OOO         VERIFY(10) */
318         { 0x2F, D | W | R | O, "VERIFY(10)" },
319         /* 30  Z   ZZZ         SEARCH DATA HIGH(10) */
320         { 0x30, D | W | R | O, "SEARCH DATA HIGH(10)" },
321         /* 31  Z   ZZZ         SEARCH DATA EQUAL(10) */
322         { 0x31, D | W | R | O, "SEARCH DATA EQUAL(10)" },
323         /* 31                  OBJECT POSITION */
324         { 0x31, S, "OBJECT POSITION" },
325         /* 32  Z   ZZZ         SEARCH DATA LOW(10) */
326         { 0x32, D | W | R | O, "SEARCH DATA LOW(10)" },
327         /* 33  Z   OZO         SET LIMITS(10) */
328         { 0x33, D | W | R | O, "SET LIMITS(10)" },
329         /* 34  O   O O    O    PRE-FETCH(10) */
330         { 0x34, D | W | O | K, "PRE-FETCH(10)" },
331         /* 34   M              READ POSITION */
332         { 0x34, T, "READ POSITION" },
333         /* 34                  GET DATA BUFFER STATUS */
334         { 0x34, S, "GET DATA BUFFER STATUS" },
335         /* 35  O   OOO   MO    SYNCHRONIZE CACHE(10) */
336         { 0x35, D | W | R | O | B | K, "SYNCHRONIZE CACHE(10)" },
337         /* 36  Z   O O    O    LOCK UNLOCK CACHE(10) */
338         { 0x36, D | W | O | K, "LOCK UNLOCK CACHE(10)" },
339         /* 37  O     O         READ DEFECT DATA(10) */
340         { 0x37, D | O, "READ DEFECT DATA(10)" },
341         /* 37         O        INITIALIZE ELEMENT STATUS WITH RANGE */
342         { 0x37, M, "INITIALIZE ELEMENT STATUS WITH RANGE" },
343         /* 38      O O    O    MEDIUM SCAN */
344         { 0x38, W | O | K, "MEDIUM SCAN" },
345         /* 39  ZZZZOZO    Z    COMPARE */
346         { 0x39, D | T | L | P | W | R | O | K | S, "COMPARE" },
347         /* 3A  ZZZZOZO    Z    COPY AND VERIFY */
348         { 0x3A, D | T | L | P | W | R | O | K | S, "COPY AND VERIFY" },
349         /* 3B  OOOOOOOOOOMOOO  WRITE BUFFER */
350         { 0x3B, ALL, "WRITE BUFFER" },
351         /* 3C  OOOOOOOOOO OOO  READ BUFFER */
352         { 0x3C, ALL & ~(B), "READ BUFFER" },
353         /* 3D        O         UPDATE BLOCK */
354         { 0x3D, O, "UPDATE BLOCK" },
355         /* 3E  O   O O         READ LONG(10) */
356         { 0x3E, D | W | O, "READ LONG(10)" },
357         /* 3F  O   O O         WRITE LONG(10) */
358         { 0x3F, D | W | O, "WRITE LONG(10)" },
359         /* 40  ZZZZOZOZ        CHANGE DEFINITION */
360         { 0x40, D | T | L | P | W | R | O | M | S | C, "CHANGE DEFINITION" },
361         /* 41  O               WRITE SAME(10) */
362         { 0x41, D, "WRITE SAME(10)" },
363         /* 42       O          READ SUB-CHANNEL */
364         { 0x42, R, "READ SUB-CHANNEL" },
365         /* 43       O          READ TOC/PMA/ATIP */
366         { 0x43, R, "READ TOC/PMA/ATIP" },
367         /* 44   M          M   REPORT DENSITY SUPPORT */
368         { 0x44, T | V, "REPORT DENSITY SUPPORT" },
369         /* 44                  READ HEADER */
370         /* 45       O          PLAY AUDIO(10) */
371         { 0x45, R, "PLAY AUDIO(10)" },
372         /* 46       M          GET CONFIGURATION */
373         { 0x46, R, "GET CONFIGURATION" },
374         /* 47       O          PLAY AUDIO MSF */
375         { 0x47, R, "PLAY AUDIO MSF" },
376         /* 48 */
377         /* 49 */
378         /* 4A       M          GET EVENT STATUS NOTIFICATION */
379         { 0x4A, R, "GET EVENT STATUS NOTIFICATION" },
380         /* 4B       O          PAUSE/RESUME */
381         { 0x4B, R, "PAUSE/RESUME" },
382         /* 4C  OOOOO OOOO OOO  LOG SELECT */
383         { 0x4C, ALL & ~(R | B), "LOG SELECT" },
384         /* 4D  OOOOO OOOO OMO  LOG SENSE */
385         { 0x4D, ALL & ~(R | B), "LOG SENSE" },
386         /* 4E       O          STOP PLAY/SCAN */
387         { 0x4E, R, "STOP PLAY/SCAN" },
388         /* 4F */
389         /* 50  O               XDWRITE(10) */
390         { 0x50, D, "XDWRITE(10)" },
391         /* 51  O               XPWRITE(10) */
392         { 0x51, D, "XPWRITE(10)" },
393         /* 51       O          READ DISC INFORMATION */
394         { 0x51, R, "READ DISC INFORMATION" },
395         /* 52  O               XDREAD(10) */
396         { 0x52, D, "XDREAD(10)" },
397         /* 52       O          READ TRACK INFORMATION */
398         { 0x52, R, "READ TRACK INFORMATION" },
399         /* 53       O          RESERVE TRACK */
400         { 0x53, R, "RESERVE TRACK" },
401         /* 54       O          SEND OPC INFORMATION */
402         { 0x54, R, "SEND OPC INFORMATION" },
403         /* 55  OOO OMOOOOMOMO  MODE SELECT(10) */
404         { 0x55, ALL & ~(P), "MODE SELECT(10)" },
405         /* 56  ZZMZO OOOZ      RESERVE(10) */
406         { 0x56, ALL & ~(R | B | K | V | F | C), "RESERVE(10)" },
407         /* 56         Z        RESERVE ELEMENT(10) */
408         { 0x56, M, "RESERVE ELEMENT(10)" },
409         /* 57  ZZMZO OOOZ      RELEASE(10) */
410         { 0x57, ALL & ~(R | B | K | V | F | C), "RELEASE(10)" },
411         /* 57         Z        RELEASE ELEMENT(10) */
412         { 0x57, M, "RELEASE ELEMENT(10)" },
413         /* 58       O          REPAIR TRACK */
414         { 0x58, R, "REPAIR TRACK" },
415         /* 59 */
416         /* 5A  OOO OMOOOOMOMO  MODE SENSE(10) */
417         { 0x5A, ALL & ~(P), "MODE SENSE(10)" },
418         /* 5B       O          CLOSE TRACK/SESSION */
419         { 0x5B, R, "CLOSE TRACK/SESSION" },
420         /* 5C       O          READ BUFFER CAPACITY */
421         { 0x5C, R, "READ BUFFER CAPACITY" },
422         /* 5D       O          SEND CUE SHEET */
423         { 0x5D, R, "SEND CUE SHEET" },
424         /* 5E  OOOOO OOOO   M  PERSISTENT RESERVE IN */
425         { 0x5E, ALL & ~(R | B | K | V | C), "PERSISTENT RESERVE IN" },
426         /* 5F  OOOOO OOOO   M  PERSISTENT RESERVE OUT */
427         { 0x5F, ALL & ~(R | B | K | V | C), "PERSISTENT RESERVE OUT" },
428         /* 7E  OO   O OOOO O   extended CDB */
429         { 0x7E, D | T | R | M | A | E | B | V, "extended CDB" },
430         /* 7F  O            M  variable length CDB (more than 16 bytes) */
431         { 0x7F, D | F, "variable length CDB (more than 16 bytes)" },
432         /* 80  Z               XDWRITE EXTENDED(16) */
433         { 0x80, D, "XDWRITE EXTENDED(16)" },
434         /* 80   M              WRITE FILEMARKS(16) */
435         { 0x80, T, "WRITE FILEMARKS(16)" },
436         /* 81  Z               REBUILD(16) */
437         { 0x81, D, "REBUILD(16)" },
438         /* 81   O              READ REVERSE(16) */
439         { 0x81, T, "READ REVERSE(16)" },
440         /* 82  Z               REGENERATE(16) */
441         { 0x82, D, "REGENERATE(16)" },
442         /* 83  OOOOO O    OO   EXTENDED COPY */
443         { 0x83, D | T | L | P | W | O | K | V, "EXTENDED COPY" },
444         /* 84  OOOOO O    OO   RECEIVE COPY RESULTS */
445         { 0x84, D | T | L | P | W | O | K | V, "RECEIVE COPY RESULTS" },
446         /* 85  O    O    O     ATA COMMAND PASS THROUGH(16) */
447         { 0x85, D | R | B, "ATA COMMAND PASS THROUGH(16)" },
448         /* 86  OO OO OOOOOOO   ACCESS CONTROL IN */
449         { 0x86, ALL & ~(L | R | F), "ACCESS CONTROL IN" },
450         /* 87  OO OO OOOOOOO   ACCESS CONTROL OUT */
451         { 0x87, ALL & ~(L | R | F), "ACCESS CONTROL OUT" },
452         /*
453          * XXX READ(16)/WRITE(16) were not listed for CD/DVE in op-num.txt
454          * but we had it since r1.40.  Do we really want them?
455          */
456         /* 88  MM  O O   O     READ(16) */
457         { 0x88, D | T | W | O | B, "READ(16)" },
458         /* 89 */
459         /* 8A  OM  O O   O     WRITE(16) */
460         { 0x8A, D | T | W | O | B, "WRITE(16)" },
461         /* 8B  O               ORWRITE */
462         { 0x8B, D, "ORWRITE" },
463         /* 8C  OO  O OO  O M   READ ATTRIBUTE */
464         { 0x8C, D | T | W | O | M | B | V, "READ ATTRIBUTE" },
465         /* 8D  OO  O OO  O O   WRITE ATTRIBUTE */
466         { 0x8D, D | T | W | O | M | B | V, "WRITE ATTRIBUTE" },
467         /* 8E  O   O O   O     WRITE AND VERIFY(16) */
468         { 0x8E, D | W | O | B, "WRITE AND VERIFY(16)" },
469         /* 8F  OO  O O   O     VERIFY(16) */
470         { 0x8F, D | T | W | O | B, "VERIFY(16)" },
471         /* 90  O   O O   O     PRE-FETCH(16) */
472         { 0x90, D | W | O | B, "PRE-FETCH(16)" },
473         /* 91  O   O O   O     SYNCHRONIZE CACHE(16) */
474         { 0x91, D | W | O | B, "SYNCHRONIZE CACHE(16)" },
475         /* 91   O              SPACE(16) */
476         { 0x91, T, "SPACE(16)" },
477         /* 92  Z   O O         LOCK UNLOCK CACHE(16) */
478         { 0x92, D | W | O, "LOCK UNLOCK CACHE(16)" },
479         /* 92   O              LOCATE(16) */
480         { 0x92, T, "LOCATE(16)" },
481         /* 93  O               WRITE SAME(16) */
482         { 0x93, D, "WRITE SAME(16)" },
483         /* 93   M              ERASE(16) */
484         { 0x93, T, "ERASE(16)" },
485         /* 94 [usage proposed by SCSI Socket Services project] */
486         /* 95 [usage proposed by SCSI Socket Services project] */
487         /* 96 [usage proposed by SCSI Socket Services project] */
488         /* 97 [usage proposed by SCSI Socket Services project] */
489         /* 98 */
490         /* 99 */
491         /* 9A */
492         /* 9B */
493         /* 9C */
494         /* 9D */
495         /* XXX KDM ALL for this?  op-num.txt defines it for none.. */
496         /* 9E                  SERVICE ACTION IN(16) */
497         { 0x9E, ALL, "SERVICE ACTION IN(16)" },
498         /* XXX KDM ALL for this?  op-num.txt defines it for ADC.. */
499         /* 9F              M   SERVICE ACTION OUT(16) */
500         { 0x9F, ALL, "SERVICE ACTION OUT(16)" },
501         /* A0  MMOOO OMMM OMO  REPORT LUNS */
502         { 0xA0, ALL & ~(R | B), "REPORT LUNS" },
503         /* A1       O          BLANK */
504         { 0xA1, R, "BLANK" },
505         /* A1  O         O     ATA COMMAND PASS THROUGH(12) */
506         { 0xA1, D | B, "ATA COMMAND PASS THROUGH(12)" },
507         /* A2  OO   O      O   SECURITY PROTOCOL IN */
508         { 0xA2, D | T | R | V, "SECURITY PROTOCOL IN" },
509         /* A3  OOO O OOMOOOM   MAINTENANCE (IN) */
510         { 0xA3, ALL & ~(P | R | F), "MAINTENANCE (IN)" },
511         /* A3       O          SEND KEY */
512         { 0xA3, R, "SEND KEY" },
513         /* A4  OOO O OOOOOOO   MAINTENANCE (OUT) */
514         { 0xA4, ALL & ~(P | R | F), "MAINTENANCE (OUT)" },
515         /* A4       O          REPORT KEY */
516         { 0xA4, R, "REPORT KEY" },
517         /* A5   O  O OM        MOVE MEDIUM */
518         { 0xA5, T | W | O | M, "MOVE MEDIUM" },
519         /* A5       O          PLAY AUDIO(12) */
520         { 0xA5, R, "PLAY AUDIO(12)" },
521         /* A6         O        EXCHANGE MEDIUM */
522         { 0xA6, M, "EXCHANGE MEDIUM" },
523         /* A6       O          LOAD/UNLOAD C/DVD */
524         { 0xA6, R, "LOAD/UNLOAD C/DVD" },
525         /* A7  ZZ  O O         MOVE MEDIUM ATTACHED */
526         { 0xA7, D | T | W | O, "MOVE MEDIUM ATTACHED" },
527         /* A7       O          SET READ AHEAD */
528         { 0xA7, R, "SET READ AHEAD" },
529         /* A8  O   OOO         READ(12) */
530         { 0xA8, D | W | R | O, "READ(12)" },
531         /* A8                  GET MESSAGE(12) */
532         { 0xA8, C, "GET MESSAGE(12)" },
533         /* A9              O   SERVICE ACTION OUT(12) */
534         { 0xA9, V, "SERVICE ACTION OUT(12)" },
535         /* AA  O   OOO         WRITE(12) */
536         { 0xAA, D | W | R | O, "WRITE(12)" },
537         /* AA                  SEND MESSAGE(12) */
538         { 0xAA, C, "SEND MESSAGE(12)" },
539         /* AB       O      O   SERVICE ACTION IN(12) */
540         { 0xAB, R | V, "SERVICE ACTION IN(12)" },
541         /* AC        O         ERASE(12) */
542         { 0xAC, O, "ERASE(12)" },
543         /* AC       O          GET PERFORMANCE */
544         { 0xAC, R, "GET PERFORMANCE" },
545         /* AD       O          READ DVD STRUCTURE */
546         { 0xAD, R, "READ DVD STRUCTURE" },
547         /* AE  O   O O         WRITE AND VERIFY(12) */
548         { 0xAE, D | W | O, "WRITE AND VERIFY(12)" },
549         /* AF  O   OZO         VERIFY(12) */
550         { 0xAF, D | W | R | O, "VERIFY(12)" },
551         /* B0      ZZZ         SEARCH DATA HIGH(12) */
552         { 0xB0, W | R | O, "SEARCH DATA HIGH(12)" },
553         /* B1      ZZZ         SEARCH DATA EQUAL(12) */
554         { 0xB1, W | R | O, "SEARCH DATA EQUAL(12)" },
555         /* B2      ZZZ         SEARCH DATA LOW(12) */
556         { 0xB2, W | R | O, "SEARCH DATA LOW(12)" },
557         /* B3  Z   OZO         SET LIMITS(12) */
558         { 0xB3, D | W | R | O, "SET LIMITS(12)" },
559         /* B4  ZZ  OZO         READ ELEMENT STATUS ATTACHED */
560         { 0xB4, D | T | W | R | O, "READ ELEMENT STATUS ATTACHED" },
561         /* B5  OO   O      O   SECURITY PROTOCOL OUT */
562         { 0xB5, D | T | R | V, "SECURITY PROTOCOL OUT" },
563         /* B5         O        REQUEST VOLUME ELEMENT ADDRESS */
564         { 0xB5, M, "REQUEST VOLUME ELEMENT ADDRESS" },
565         /* B6         O        SEND VOLUME TAG */
566         { 0xB6, M, "SEND VOLUME TAG" },
567         /* B6       O          SET STREAMING */
568         { 0xB6, R, "SET STREAMING" },
569         /* B7  O     O         READ DEFECT DATA(12) */
570         { 0xB7, D | O, "READ DEFECT DATA(12)" },
571         /* B8   O  OZOM        READ ELEMENT STATUS */
572         { 0xB8, T | W | R | O | M, "READ ELEMENT STATUS" },
573         /* B9       O          READ CD MSF */
574         { 0xB9, R, "READ CD MSF" },
575         /* BA  O   O OOMO      REDUNDANCY GROUP (IN) */
576         { 0xBA, D | W | O | M | A | E, "REDUNDANCY GROUP (IN)" },
577         /* BA       O          SCAN */
578         { 0xBA, R, "SCAN" },
579         /* BB  O   O OOOO      REDUNDANCY GROUP (OUT) */
580         { 0xBB, D | W | O | M | A | E, "REDUNDANCY GROUP (OUT)" },
581         /* BB       O          SET CD SPEED */
582         { 0xBB, R, "SET CD SPEED" },
583         /* BC  O   O OOMO      SPARE (IN) */
584         { 0xBC, D | W | O | M | A | E, "SPARE (IN)" },
585         /* BD  O   O OOOO      SPARE (OUT) */
586         { 0xBD, D | W | O | M | A | E, "SPARE (OUT)" },
587         /* BD       O          MECHANISM STATUS */
588         { 0xBD, R, "MECHANISM STATUS" },
589         /* BE  O   O OOMO      VOLUME SET (IN) */
590         { 0xBE, D | W | O | M | A | E, "VOLUME SET (IN)" },
591         /* BE       O          READ CD */
592         { 0xBE, R, "READ CD" },
593         /* BF  O   O OOOO      VOLUME SET (OUT) */
594         { 0xBF, D | W | O | M | A | E, "VOLUME SET (OUT)" },
595         /* BF       O          SEND DVD STRUCTURE */
596         { 0xBF, R, "SEND DVD STRUCTURE" }
597 };
598 
599 const char *
600 scsi_op_desc(u_int16_t opcode, struct scsi_inquiry_data *inq_data)
601 {
602         caddr_t match;
603         int i, j;
604         u_int32_t opmask;
605         u_int16_t pd_type;
606         int       num_ops[2];
607         struct op_table_entry *table[2];
608         int num_tables;
609 
610         pd_type = SID_TYPE(inq_data);
611 
612         match = cam_quirkmatch((caddr_t)inq_data,
613                                (caddr_t)scsi_op_quirk_table,
614                                sizeof(scsi_op_quirk_table)/
615                                sizeof(*scsi_op_quirk_table),
616                                sizeof(*scsi_op_quirk_table),
617                                scsi_inquiry_match);
618 
619         if (match != NULL) {
620                 table[0] = ((struct scsi_op_quirk_entry *)match)->op_table;
621                 num_ops[0] = ((struct scsi_op_quirk_entry *)match)->num_ops;
622                 table[1] = scsi_op_codes;
623                 num_ops[1] = sizeof(scsi_op_codes)/sizeof(scsi_op_codes[0]);
624                 num_tables = 2;
625         } else {
626                 /*      
627                  * If this is true, we have a vendor specific opcode that
628                  * wasn't covered in the quirk table.
629                  */
630                 if ((opcode > 0xBF) || ((opcode > 0x5F) && (opcode < 0x80)))
631                         return("Vendor Specific Command");
632 
633                 table[0] = scsi_op_codes;
634                 num_ops[0] = sizeof(scsi_op_codes)/sizeof(scsi_op_codes[0]);
635                 num_tables = 1;
636         }
637 
638         /* RBC is 'Simplified' Direct Access Device */
639         if (pd_type == T_RBC)
640                 pd_type = T_DIRECT;
641 
642         opmask = 1 << pd_type;
643 
644         for (j = 0; j < num_tables; j++) {
645                 for (i = 0;i < num_ops[j] && table[j][i].opcode <= opcode; i++){
646                         if ((table[j][i].opcode == opcode) 
647                          && ((table[j][i].opmask & opmask) != 0))
648                                 return(table[j][i].desc);
649                 }
650         }
651         
652         /*
653          * If we can't find a match for the command in the table, we just
654          * assume it's a vendor specifc command.
655          */
656         return("Vendor Specific Command");
657 
658 }
659 
660 #else /* SCSI_NO_OP_STRINGS */
661 
662 const char *
663 scsi_op_desc(u_int16_t opcode, struct scsi_inquiry_data *inq_data)
664 {
665         return("");
666 }
667 
668 #endif
669 
670 
671 #if !defined(SCSI_NO_SENSE_STRINGS)
672 #define SST(asc, ascq, action, desc) \
673         asc, ascq, action, desc
674 #else 
675 const char empty_string[] = "";
676 
677 #define SST(asc, ascq, action, desc) \
678         asc, ascq, action, empty_string
679 #endif 
680 
681 const struct sense_key_table_entry sense_key_table[] = 
682 {
683         { SSD_KEY_NO_SENSE, SS_NOP, "NO SENSE" },
684         { SSD_KEY_RECOVERED_ERROR, SS_NOP|SSQ_PRINT_SENSE, "RECOVERED ERROR" },
685         {
686           SSD_KEY_NOT_READY, SS_TUR|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY,
687           "NOT READY"
688         },
689         { SSD_KEY_MEDIUM_ERROR, SS_RDEF, "MEDIUM ERROR" },
690         { SSD_KEY_HARDWARE_ERROR, SS_RDEF, "HARDWARE FAILURE" },
691         { SSD_KEY_ILLEGAL_REQUEST, SS_FATAL|EINVAL, "ILLEGAL REQUEST" },
692         { SSD_KEY_UNIT_ATTENTION, SS_FATAL|ENXIO, "UNIT ATTENTION" },
693         { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" },
694         { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" },
695         { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" },
696         { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" },
697         { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" },
698         { SSD_KEY_EQUAL, SS_NOP, "EQUAL" },
699         { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" },
700         { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" },
701         { SSD_KEY_RESERVED, SS_FATAL|EIO, "RESERVED" }
702 };
703 
704 const int sense_key_table_size =
705     sizeof(sense_key_table)/sizeof(sense_key_table[0]);
706 
707 static struct asc_table_entry quantum_fireball_entries[] = {
708         { SST(0x04, 0x0b, SS_START | SSQ_DECREMENT_COUNT | ENXIO, 
709              "Logical unit not ready, initializing cmd. required") }
710 };
711 
712 static struct asc_table_entry sony_mo_entries[] = {
713         { SST(0x04, 0x00, SS_START | SSQ_DECREMENT_COUNT | ENXIO,
714              "Logical unit not ready, cause not reportable") }
715 };
716 
717 static struct scsi_sense_quirk_entry sense_quirk_table[] = {
718         {
719                 /*
720                  * XXX The Quantum Fireball ST and SE like to return 0x04 0x0b
721                  * when they really should return 0x04 0x02.
722                  */
723                 {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"},
724                 /*num_sense_keys*/0,
725                 sizeof(quantum_fireball_entries)/sizeof(struct asc_table_entry),
726                 /*sense key entries*/NULL,
727                 quantum_fireball_entries
728         },
729         {
730                 /*
731                  * This Sony MO drive likes to return 0x04, 0x00 when it
732                  * isn't spun up.
733                  */
734                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"},
735                 /*num_sense_keys*/0,
736                 sizeof(sony_mo_entries)/sizeof(struct asc_table_entry),
737                 /*sense key entries*/NULL,
738                 sony_mo_entries
739         }
740 };
741 
742 const int sense_quirk_table_size =
743     sizeof(sense_quirk_table)/sizeof(sense_quirk_table[0]);
744 
745 static struct asc_table_entry asc_table[] = {
746         /*
747          * From: http://www.t10.org/lists/asc-num.txt
748          * Modifications by Jung-uk Kim (jkim@FreeBSD.org)
749          */
750         /*
751          * File: ASC-NUM.TXT
752          *
753          * SCSI ASC/ASCQ Assignments
754          * Numeric Sorted Listing
755          * as of  7/29/08
756          *
757          * D - DIRECT ACCESS DEVICE (SBC-2)                   device column key
758          * .T - SEQUENTIAL ACCESS DEVICE (SSC)               -------------------
759          * . L - PRINTER DEVICE (SSC)                           blank = reserved
760          * .  P - PROCESSOR DEVICE (SPC)                     not blank = allowed
761          * .  .W - WRITE ONCE READ MULTIPLE DEVICE (SBC-2)
762          * .  . R - CD DEVICE (MMC)
763          * .  .  O - OPTICAL MEMORY DEVICE (SBC-2)
764          * .  .  .M - MEDIA CHANGER DEVICE (SMC)
765          * .  .  . A - STORAGE ARRAY DEVICE (SCC)
766          * .  .  .  E - ENCLOSURE SERVICES DEVICE (SES)
767          * .  .  .  .B - SIMPLIFIED DIRECT-ACCESS DEVICE (RBC)
768          * .  .  .  . K - OPTICAL CARD READER/WRITER DEVICE (OCRW)
769          * .  .  .  .  V - AUTOMATION/DRIVE INTERFACE (ADC)
770          * .  .  .  .  .F - OBJECT-BASED STORAGE (OSD)
771          * DTLPWROMAEBKVF
772          * ASC      ASCQ  Action
773          * Description
774          */
775         /* DTLPWROMAEBKVF */
776         { SST(0x00, 0x00, SS_NOP,
777             "No additional sense information") },
778         /*  T             */
779         { SST(0x00, 0x01, SS_RDEF,
780             "Filemark detected") },
781         /*  T             */
782         { SST(0x00, 0x02, SS_RDEF,
783             "End-of-partition/medium detected") },
784         /*  T             */
785         { SST(0x00, 0x03, SS_RDEF,
786             "Setmark detected") },
787         /*  T             */
788         { SST(0x00, 0x04, SS_RDEF,
789             "Beginning-of-partition/medium detected") },
790         /*  TL            */
791         { SST(0x00, 0x05, SS_RDEF,
792             "End-of-data detected") },
793         /* DTLPWROMAEBKVF */
794         { SST(0x00, 0x06, SS_RDEF,
795             "I/O process terminated") },
796         /*  T             */
797         { SST(0x00, 0x07, SS_RDEF,      /* XXX TBD */
798             "Programmable early warning detected") },
799         /*      R         */
800         { SST(0x00, 0x11, SS_FATAL | EBUSY,
801             "Audio play operation in progress") },
802         /*      R         */
803         { SST(0x00, 0x12, SS_NOP,
804             "Audio play operation paused") },
805         /*      R         */
806         { SST(0x00, 0x13, SS_NOP,
807             "Audio play operation successfully completed") },
808         /*      R         */
809         { SST(0x00, 0x14, SS_RDEF,
810             "Audio play operation stopped due to error") },
811         /*      R         */
812         { SST(0x00, 0x15, SS_NOP,
813             "No current audio status to return") },
814         /* DTLPWROMAEBKVF */
815         { SST(0x00, 0x16, SS_FATAL | EBUSY,
816             "Operation in progress") },
817         /* DTL WROMAEBKVF */
818         { SST(0x00, 0x17, SS_RDEF,
819             "Cleaning requested") },
820         /*  T             */
821         { SST(0x00, 0x18, SS_RDEF,      /* XXX TBD */
822             "Erase operation in progress") },
823         /*  T             */
824         { SST(0x00, 0x19, SS_RDEF,      /* XXX TBD */
825             "Locate operation in progress") },
826         /*  T             */
827         { SST(0x00, 0x1A, SS_RDEF,      /* XXX TBD */
828             "Rewind operation in progress") },
829         /*  T             */
830         { SST(0x00, 0x1B, SS_RDEF,      /* XXX TBD */
831             "Set capacity operation in progress") },
832         /*  T             */
833         { SST(0x00, 0x1C, SS_RDEF,      /* XXX TBD */
834             "Verify operation in progress") },
835         /* DT        B    */
836         { SST(0x00, 0x1D, SS_RDEF,      /* XXX TBD */
837             "ATA pass through information available") },
838         /* DT   R MAEBKV  */
839         { SST(0x00, 0x1E, SS_RDEF,      /* XXX TBD */
840             "Conflicting SA creation request") },
841         /* D   W O   BK   */
842         { SST(0x01, 0x00, SS_RDEF,
843             "No index/sector signal") },
844         /* D   WRO   BK   */
845         { SST(0x02, 0x00, SS_RDEF,
846             "No seek complete") },
847         /* DTL W O   BK   */
848         { SST(0x03, 0x00, SS_RDEF,
849             "Peripheral device write fault") },
850         /*  T             */
851         { SST(0x03, 0x01, SS_RDEF,
852             "No write current") },
853         /*  T             */
854         { SST(0x03, 0x02, SS_RDEF,
855             "Excessive write errors") },
856         /* DTLPWROMAEBKVF */
857         { SST(0x04, 0x00, SS_TUR | SSQ_MANY | SSQ_DECREMENT_COUNT | EIO,
858             "Logical unit not ready, cause not reportable") },
859         /* DTLPWROMAEBKVF */
860         { SST(0x04, 0x01, SS_TUR | SSQ_MANY | SSQ_DECREMENT_COUNT | EBUSY,
861             "Logical unit is in process of becoming ready") },
862         /* DTLPWROMAEBKVF */
863         { SST(0x04, 0x02, SS_START | SSQ_DECREMENT_COUNT | ENXIO,
864             "Logical unit not ready, initializing command required") },
865         /* DTLPWROMAEBKVF */
866         { SST(0x04, 0x03, SS_FATAL | ENXIO,
867             "Logical unit not ready, manual intervention required") },
868         /* DTL  RO   B    */
869         { SST(0x04, 0x04, SS_FATAL | EBUSY,
870             "Logical unit not ready, format in progress") },
871         /* DT  W O A BK F */
872         { SST(0x04, 0x05, SS_FATAL | EBUSY,
873             "Logical unit not ready, rebuild in progress") },
874         /* DT  W O A BK   */
875         { SST(0x04, 0x06, SS_FATAL | EBUSY,
876             "Logical unit not ready, recalculation in progress") },
877         /* DTLPWROMAEBKVF */
878         { SST(0x04, 0x07, SS_FATAL | EBUSY,
879             "Logical unit not ready, operation in progress") },
880         /*      R         */
881         { SST(0x04, 0x08, SS_FATAL | EBUSY,
882             "Logical unit not ready, long write in progress") },
883         /* DTLPWROMAEBKVF */
884         { SST(0x04, 0x09, SS_RDEF,      /* XXX TBD */
885             "Logical unit not ready, self-test in progress") },
886         /* DTLPWROMAEBKVF */
887         { SST(0x04, 0x0A, SS_RDEF,      /* XXX TBD */
888             "Logical unit not accessible, asymmetric access state transition")},
889         /* DTLPWROMAEBKVF */
890         { SST(0x04, 0x0B, SS_RDEF,      /* XXX TBD */
891             "Logical unit not accessible, target port in standby state") },
892         /* DTLPWROMAEBKVF */
893         { SST(0x04, 0x0C, SS_RDEF,      /* XXX TBD */
894             "Logical unit not accessible, target port in unavailable state") },
895         /*              F */
896         { SST(0x04, 0x0D, SS_RDEF,      /* XXX TBD */
897             "Logical unit not ready, structure check required") },
898         /* DT  WROM  B    */
899         { SST(0x04, 0x10, SS_RDEF,      /* XXX TBD */
900             "Logical unit not ready, auxiliary memory not accessible") },
901         /* DT  WRO AEB VF */
902         { SST(0x04, 0x11, SS_RDEF,      /* XXX TBD */
903             "Logical unit not ready, notify (enable spinup) required") },
904         /*        M    V  */
905         { SST(0x04, 0x12, SS_RDEF,      /* XXX TBD */
906             "Logical unit not ready, offline") },
907         /* DT   R MAEBKV  */
908         { SST(0x04, 0x13, SS_RDEF,      /* XXX TBD */
909             "Logical unit not ready, SA creation in progress") },
910         /* DTL WROMAEBKVF */
911         { SST(0x05, 0x00, SS_RDEF,
912             "Logical unit does not respond to selection") },
913         /* D   WROM  BK   */
914         { SST(0x06, 0x00,