Deleted Added
full compact
scsi_all.h (63171) scsi_all.h (64382)
1/*
2 * Largely written by Julian Elischer (julian@tfs.com)
3 * for TRW Financial Systems.
4 *
5 * TRW Financial Systems, in accordance with their agreement with Carnegie
6 * Mellon University, makes this software available to CMU to distribute
7 * or use in any manner that they see fit as long as this message is kept with
8 * the software. For this reason TFS also grants any other persons or
9 * organisations permission to use or modify this software.
10 *
11 * TFS supplies this software to be publicly redistributed
12 * on the understanding that TFS is not responsible for the correct
13 * functioning of this software in any circumstances.
14 *
15 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
16 *
1/*
2 * Largely written by Julian Elischer (julian@tfs.com)
3 * for TRW Financial Systems.
4 *
5 * TRW Financial Systems, in accordance with their agreement with Carnegie
6 * Mellon University, makes this software available to CMU to distribute
7 * or use in any manner that they see fit as long as this message is kept with
8 * the software. For this reason TFS also grants any other persons or
9 * organisations permission to use or modify this software.
10 *
11 * TFS supplies this software to be publicly redistributed
12 * on the understanding that TFS is not responsible for the correct
13 * functioning of this software in any circumstances.
14 *
15 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
16 *
17 * $FreeBSD: head/sys/cam/scsi/scsi_all.h 63171 2000-07-14 19:40:54Z mjacob $
17 * $FreeBSD: head/sys/cam/scsi/scsi_all.h 64382 2000-08-08 06:24:17Z kbyanc $
18 */
19
20/*
21 * SCSI general interface description
22 */
23
24#ifndef _SCSI_SCSI_ALL_H
25#define _SCSI_SCSI_ALL_H 1
26
27#include <sys/cdefs.h>
28
29#ifdef _KERNEL
30#include "opt_scsi.h"
31/*
32 * This is the number of seconds we wait for devices to settle after a SCSI
33 * bus reset.
34 */
35#ifndef SCSI_DELAY
36#define SCSI_DELAY 2000
37#endif
38/*
39 * If someone sets this to 0, we assume that they want the minimum
40 * allowable bus settle delay. All devices need _some_ sort of bus settle
41 * delay, so we'll set it to a minimum value of 100ms.
42 */
43#if (SCSI_DELAY == 0)
44#undef SCSI_DELAY
45#define SCSI_DELAY 100
46#endif
47
48/*
49 * Make sure the user isn't using seconds instead of milliseconds.
50 */
51#if (SCSI_DELAY < 100)
52#error "SCSI_DELAY is in milliseconds, not seconds! Please use a larger value"
53#endif
54#endif /* _KERNEL */
55
56/*
57 * SCSI command format
58 */
59
60/*
61 * Define dome bits that are in ALL (or a lot of) scsi commands
62 */
63#define SCSI_CTL_LINK 0x01
64#define SCSI_CTL_FLAG 0x02
65#define SCSI_CTL_VENDOR 0xC0
66#define SCSI_CMD_LUN 0xA0 /* these two should not be needed */
67#define SCSI_CMD_LUN_SHIFT 5 /* LUN in the cmd is no longer SCSI */
68
69#define SCSI_MAX_CDBLEN 16 /*
70 * 16 byte commands are in the
71 * SCSI-3 spec
72 */
73#if defined(CAM_MAX_CDBLEN) && (CAM_MAX_CDBLEN < SCSI_MAX_CDBLEN)
74#error "CAM_MAX_CDBLEN cannot be less than SCSI_MAX_CDBLEN"
75#endif
76
77/* 6byte CDBs special case 0 length to be 256 */
78#define SCSI_CDB6_LEN(len) ((len) == 0 ? 256 : len)
79
80/*
81 * This type defines actions to be taken when a particular sense code is
82 * received. Right now, these flags are only defined to take up 16 bits,
83 * but can be expanded in the future if necessary.
84 */
85typedef enum {
86 SS_NOP = 0x000000, /* Do nothing */
87 SS_RETRY = 0x010000, /* Retry the command */
88 SS_FAIL = 0x020000, /* Bail out */
89 SS_START = 0x030000, /* Send a Start Unit command to the device,
90 * then retry the original command.
91 */
92 SS_TUR = 0x040000, /* Send a Test Unit Ready command to the
93 * device, then retry the original command.
94 */
95 SS_MANUAL = 0x050000, /*
96 * This error must be handled manually,
97 * i.e. the code must look at the asc and
98 * ascq values and determine the proper
99 * course of action.
100 */
101 SS_TURSTART = 0x060000, /*
102 * Send a Test Unit Ready command to the
103 * device, and if that fails, send a start
104 * unit.
105 */
106 SS_MASK = 0xff0000
107} scsi_sense_action;
108
109typedef enum {
110 SSQ_NONE = 0x0000,
111 SSQ_DECREMENT_COUNT = 0x0100, /* Decrement the retry count */
112 SSQ_MANY = 0x0200, /* send lots of recovery commands */
113 SSQ_RANGE = 0x0400, /*
114 * Yes, this is a hack. Basically,
115 * if this flag is set then it
116 * represents an ascq range. The
117 * "correct" way to implement the
118 * ranges might be to add a special
119 * field to the sense code table,
120 * but that would take up a lot of
121 * additional space. This solution
122 * isn't as elegant, but is more
123 * space efficient.
124 */
125 SSQ_PRINT_SENSE = 0x0800,
126 SSQ_MASK = 0xff00
127} scsi_sense_action_qualifier;
128
129/* Mask for error status values */
130#define SS_ERRMASK 0xff
131
132/* The default error action */
133#define SS_DEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO
134
135/* Default error action, without an error return value */
136#define SS_NEDEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE
137
138/* Default error action, without sense printing or an error return value */
139#define SS_NEPDEF SS_RETRY|SSQ_DECREMENT_COUNT
140
141struct scsi_generic
142{
143 u_int8_t opcode;
144 u_int8_t bytes[11];
145};
146
147struct scsi_request_sense
148{
149 u_int8_t opcode;
150 u_int8_t byte2;
151 u_int8_t unused[2];
152 u_int8_t length;
153 u_int8_t control;
154};
155
156struct scsi_test_unit_ready
157{
158 u_int8_t opcode;
159 u_int8_t byte2;
160 u_int8_t unused[3];
161 u_int8_t control;
162};
163
164struct scsi_send_diag
165{
166 u_int8_t opcode;
167 u_int8_t byte2;
168#define SSD_UOL 0x01
169#define SSD_DOL 0x02
170#define SSD_SELFTEST 0x04
171#define SSD_PF 0x10
172 u_int8_t unused[1];
173 u_int8_t paramlen[2];
174 u_int8_t control;
175};
176
177struct scsi_sense
178{
179 u_int8_t opcode;
180 u_int8_t byte2;
181 u_int8_t unused[2];
182 u_int8_t length;
183 u_int8_t control;
184};
185
186struct scsi_inquiry
187{
188 u_int8_t opcode;
189 u_int8_t byte2;
190#define SI_EVPD 0x01
191 u_int8_t page_code;
192 u_int8_t reserved;
193 u_int8_t length;
194 u_int8_t control;
195};
196
197struct scsi_mode_sense_6
198{
199 u_int8_t opcode;
200 u_int8_t byte2;
201#define SMS_DBD 0x08
202 u_int8_t page;
203#define SMS_PAGE_CODE 0x3F
204#define SMS_VENDOR_SPECIFIC_PAGE 0x00
205#define SMS_DISCONNECT_RECONNECT_PAGE 0x02
206#define SMS_PERIPHERAL_DEVICE_PAGE 0x09
207#define SMS_CONTROL_MODE_PAGE 0x0A
208#define SMS_ALL_PAGES_PAGE 0x3F
209#define SMS_PAGE_CTRL_MASK 0xC0
210#define SMS_PAGE_CTRL_CURRENT 0x00
211#define SMS_PAGE_CTRL_CHANGEABLE 0x40
212#define SMS_PAGE_CTRL_DEFAULT 0x80
213#define SMS_PAGE_CTRL_SAVED 0xC0
214 u_int8_t unused;
215 u_int8_t length;
216 u_int8_t control;
217};
218
219struct scsi_mode_sense_10
220{
221 u_int8_t opcode;
222 u_int8_t byte2; /* same bits as small version */
223 u_int8_t page; /* same bits as small version */
224 u_int8_t unused[4];
225 u_int8_t length[2];
226 u_int8_t control;
227};
228
229struct scsi_mode_select_6
230{
231 u_int8_t opcode;
232 u_int8_t byte2;
233#define SMS_SP 0x01
234#define SMS_PF 0x10
235 u_int8_t unused[2];
236 u_int8_t length;
237 u_int8_t control;
238};
239
240struct scsi_mode_select_10
241{
242 u_int8_t opcode;
243 u_int8_t byte2; /* same bits as small version */
244 u_int8_t unused[5];
245 u_int8_t length[2];
246 u_int8_t control;
247};
248
249/*
250 * When sending a mode select to a tape drive, the medium type must be 0.
251 */
252struct scsi_mode_hdr_6
253{
254 u_int8_t datalen;
255 u_int8_t medium_type;
256 u_int8_t dev_specific;
257 u_int8_t block_descr_len;
258};
259
260struct scsi_mode_hdr_10
261{
262 u_int8_t datalen[2];
263 u_int8_t medium_type;
264 u_int8_t dev_specific;
265 u_int8_t reserved[2];
266 u_int8_t block_descr_len[2];
267};
268
269struct scsi_mode_block_descr
270{
271 u_int8_t density_code;
272 u_int8_t num_blocks[3];
273 u_int8_t reserved;
274 u_int8_t block_len[3];
275};
276
277struct scsi_control_page {
278 u_int8_t page_code;
279 u_int8_t page_length;
280 u_int8_t rlec;
281#define SCB_RLEC 0x01 /*Report Log Exception Cond*/
282 u_int8_t queue_flags;
283#define SCP_QUEUE_ALG_MASK 0xF0
284#define SCP_QUEUE_ALG_RESTRICTED 0x00
285#define SCP_QUEUE_ALG_UNRESTRICTED 0x10
286#define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/
287#define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/
288 u_int8_t eca_and_aen;
289#define SCP_EECA 0x80 /*Enable Extended CA*/
290#define SCP_RAENP 0x04 /*Ready AEN Permission*/
291#define SCP_UAAENP 0x02 /*UA AEN Permission*/
292#define SCP_EAENP 0x01 /*Error AEN Permission*/
293 u_int8_t reserved;
294 u_int8_t aen_holdoff_period[2];
295};
296
297struct scsi_reserve
298{
299 u_int8_t opcode;
300 u_int8_t byte2;
301 u_int8_t unused[2];
302 u_int8_t length;
303 u_int8_t control;
304};
305
306struct scsi_release
307{
308 u_int8_t opcode;
309 u_int8_t byte2;
310 u_int8_t unused[2];
311 u_int8_t length;
312 u_int8_t control;
313};
314
315struct scsi_prevent
316{
317 u_int8_t opcode;
318 u_int8_t byte2;
319 u_int8_t unused[2];
320 u_int8_t how;
321 u_int8_t control;
322};
323#define PR_PREVENT 0x01
324#define PR_ALLOW 0x00
325
326struct scsi_sync_cache
327{
328 u_int8_t opcode;
329 u_int8_t byte2;
330 u_int8_t begin_lba[4];
331 u_int8_t reserved;
332 u_int8_t lb_count[2];
333 u_int8_t control;
334};
335
336
337struct scsi_changedef
338{
339 u_int8_t opcode;
340 u_int8_t byte2;
341 u_int8_t unused1;
342 u_int8_t how;
343 u_int8_t unused[4];
344 u_int8_t datalen;
345 u_int8_t control;
346};
347
348struct scsi_read_buffer
349{
350 u_int8_t opcode;
351 u_int8_t byte2;
352#define RWB_MODE 0x07
353#define RWB_MODE_HDR_DATA 0x00
354#define RWB_MODE_DATA 0x02
355#define RWB_MODE_DOWNLOAD 0x04
356#define RWB_MODE_DOWNLOAD_SAVE 0x05
357 u_int8_t buffer_id;
358 u_int8_t offset[3];
359 u_int8_t length[3];
360 u_int8_t control;
361};
362
363struct scsi_write_buffer
364{
365 u_int8_t opcode;
366 u_int8_t byte2;
367 u_int8_t buffer_id;
368 u_int8_t offset[3];
369 u_int8_t length[3];
370 u_int8_t control;
371};
372
373struct scsi_rw_6
374{
375 u_int8_t opcode;
376 u_int8_t addr[3];
377/* only 5 bits are valid in the MSB address byte */
378#define SRW_TOPADDR 0x1F
379 u_int8_t length;
380 u_int8_t control;
381};
382
383struct scsi_rw_10
384{
385 u_int8_t opcode;
386#define SRW10_RELADDR 0x01
387#define SRW10_FUA 0x08
388#define SRW10_DPO 0x10
389 u_int8_t byte2;
390 u_int8_t addr[4];
391 u_int8_t reserved;
392 u_int8_t length[2];
393 u_int8_t control;
394};
395
396struct scsi_rw_12
397{
398 u_int8_t opcode;
399#define SRW12_RELADDR 0x01
400#define SRW12_FUA 0x08
401#define SRW12_DPO 0x10
402 u_int8_t byte2;
403 u_int8_t addr[4];
404 u_int8_t reserved;
405 u_int8_t length[4];
406 u_int8_t control;
407};
408
409struct scsi_start_stop_unit
410{
411 u_int8_t opcode;
412 u_int8_t byte2;
413#define SSS_IMMED 0x01
414 u_int8_t reserved[2];
415 u_int8_t how;
416#define SSS_START 0x01
417#define SSS_LOEJ 0x02
418 u_int8_t control;
419};
420
421#define SC_SCSI_1 0x01
422#define SC_SCSI_2 0x03
423
424/*
425 * Opcodes
426 */
427
428#define TEST_UNIT_READY 0x00
429#define REQUEST_SENSE 0x03
430#define READ_6 0x08
431#define WRITE_6 0x0a
432#define INQUIRY 0x12
433#define MODE_SELECT_6 0x15
434#define MODE_SENSE_6 0x1a
435#define START_STOP_UNIT 0x1b
436#define START_STOP 0x1b
437#define RESERVE 0x16
438#define RELEASE 0x17
439#define RECEIVE_DIAGNOSTIC 0x1c
440#define SEND_DIAGNOSTIC 0x1d
441#define PREVENT_ALLOW 0x1e
442#define READ_CAPACITY 0x25
443#define READ_10 0x28
444#define WRITE_10 0x2a
445#define POSITION_TO_ELEMENT 0x2b
446#define SYNCHRONIZE_CACHE 0x35
447#define WRITE_BUFFER 0x3b
448#define READ_BUFFER 0x3c
449#define CHANGE_DEFINITION 0x40
450#define MODE_SELECT_10 0x55
451#define MODE_SENSE_10 0x5A
452#define MOVE_MEDIUM 0xa5
453#define READ_12 0xa8
454#define WRITE_12 0xaa
455#define READ_ELEMENT_STATUS 0xb8
456
457
458/*
459 * Device Types
460 */
461#define T_DIRECT 0x00
462#define T_SEQUENTIAL 0x01
463#define T_PRINTER 0x02
464#define T_PROCESSOR 0x03
465#define T_WORM 0x04
466#define T_CDROM 0x05
467#define T_SCANNER 0x06
468#define T_OPTICAL 0x07
469#define T_CHANGER 0x08
470#define T_COMM 0x09
471#define T_ASC0 0x0a
472#define T_ASC1 0x0b
473#define T_STORARRAY 0x0c
474#define T_ENCLOSURE 0x0d
475#define T_RBC 0x0e
476#define T_OCRW 0x0f
477#define T_NODEVICE 0x1F
478#define T_ANY 0xFF /* Used in Quirk table matches */
479
480#define T_REMOV 1
481#define T_FIXED 0
482
483/*
484 * This length is the initial inquiry length used by the probe code, as
485 * well as the legnth necessary for scsi_print_inquiry() to function
486 * correctly. If either use requires a different length in the future,
487 * the two values should be de-coupled.
488 */
489#define SHORT_INQUIRY_LENGTH 36
490
491struct scsi_inquiry_data
492{
493 u_int8_t device;
494#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f)
495#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5)
496#define SID_QUAL_LU_CONNECTED 0x00 /* The specified peripheral device
497 * type is currently connected to
498 * logical unit. If the target cannot
499 * determine whether or not a physical
500 * device is currently connected, it
501 * shall also use this peripheral
502 * qualifier when returning the INQUIRY
503 * data. This peripheral qualifier
504 * does not mean that the device is
505 * ready for access by the initiator.
506 */
507#define SID_QUAL_LU_OFFLINE 0x01 /* The target is capable of supporting
508 * the specified peripheral device type
509 * on this logical unit; however, the
510 * physical device is not currently
511 * connected to this logical unit.
512 */
513#define SID_QUAL_RSVD 0x02
514#define SID_QUAL_BAD_LU 0x03 /* The target is not capable of
515 * supporting a physical device on
516 * this logical unit. For this
517 * peripheral qualifier the peripheral
518 * device type shall be set to 1Fh to
519 * provide compatibility with previous
520 * versions of SCSI. All other
521 * peripheral device type values are
522 * reserved for this peripheral
523 * qualifier.
524 */
525#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0)
526 u_int8_t dev_qual2;
527#define SID_QUAL2 0x7F
528#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0)
529 u_int8_t version;
530#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07)
531#define SCSI_REV_0 0
532#define SCSI_REV_CCS 1
533#define SCSI_REV_2 2
534#define SCSI_REV_3 3
535#define SCSI_REV_SPC2 4
536
537#define SID_ECMA 0x38
538#define SID_ISO 0xC0
539 u_int8_t response_format;
540#define SID_AENC 0x80
541#define SID_TrmIOP 0x40
542 u_int8_t additional_length;
543 u_int8_t reserved[2];
544 u_int8_t flags;
545#define SID_SftRe 0x01
546#define SID_CmdQue 0x02
547#define SID_Linked 0x08
548#define SID_Sync 0x10
549#define SID_WBus16 0x20
550#define SID_WBus32 0x40
551#define SID_RelAdr 0x80
552#define SID_VENDOR_SIZE 8
553 char vendor[SID_VENDOR_SIZE];
554#define SID_PRODUCT_SIZE 16
555 char product[SID_PRODUCT_SIZE];
556#define SID_REVISION_SIZE 4
557 char revision[SID_REVISION_SIZE];
558 /*
559 * The following fields were taken from SCSI Primary Commands - 2
560 * (SPC-2) Revision 14, Dated 11 November 1999
561 */
562#define SID_VENDOR_SPECIFIC_0_SIZE 20
563 u_int8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE];
564 /*
565 * An extension of SCSI Parallel Specific Values
566 */
567#define SID_SPI_IUS 0x01
568#define SID_SPI_QAS 0x02
569#define SID_SPI_CLOCK_ST 0x00
570#define SID_SPI_CLOCK_DT 0x04
571#define SID_SPI_CLOCK_DT_ST 0x0C
572 u_int8_t spi3data;
573 u_int8_t reserved2;
574 /*
575 * Version Descriptors, stored 2 byte values.
576 */
577 u_int8_t version1[2];
578 u_int8_t version2[2];
579 u_int8_t version3[2];
580 u_int8_t version4[2];
581 u_int8_t version5[2];
582 u_int8_t version6[2];
583 u_int8_t version7[2];
584 u_int8_t version8[2];
585
586 u_int8_t reserved3[22];
587
588#define SID_VENDOR_SPECIFIC_1_SIZE 160
589 u_int8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE];
590};
591
592struct scsi_vpd_unit_serial_number
593{
594 u_int8_t device;
595 u_int8_t page_code;
596#define SVPD_UNIT_SERIAL_NUMBER 0x80
597 u_int8_t reserved;
598 u_int8_t length; /* serial number length */
599#define SVPD_SERIAL_NUM_SIZE 251
600 u_int8_t serial_num[SVPD_SERIAL_NUM_SIZE];
601};
602
603struct scsi_read_capacity
604{
605 u_int8_t opcode;
606 u_int8_t byte2;
607 u_int8_t addr[4];
608 u_int8_t unused[3];
609 u_int8_t control;
610};
611
612struct scsi_read_capacity_data
613{
614 u_int8_t addr[4];
615 u_int8_t length[4];
616};
617
618struct scsi_sense_data
619{
620 u_int8_t error_code;
621#define SSD_ERRCODE 0x7F
622#define SSD_CURRENT_ERROR 0x70
623#define SSD_DEFERRED_ERROR 0x71
624#define SSD_ERRCODE_VALID 0x80
625 u_int8_t segment;
626 u_int8_t flags;
627#define SSD_KEY 0x0F
628#define SSD_KEY_NO_SENSE 0x00
629#define SSD_KEY_RECOVERED_ERROR 0x01
630#define SSD_KEY_NOT_READY 0x02
631#define SSD_KEY_MEDIUM_ERROR 0x03
632#define SSD_KEY_HARDWARE_ERROR 0x04
633#define SSD_KEY_ILLEGAL_REQUEST 0x05
634#define SSD_KEY_UNIT_ATTENTION 0x06
635#define SSD_KEY_DATA_PROTECT 0x07
636#define SSD_KEY_BLANK_CHECK 0x08
637#define SSD_KEY_Vendor_Specific 0x09
638#define SSD_KEY_COPY_ABORTED 0x0a
639#define SSD_KEY_ABORTED_COMMAND 0x0b
640#define SSD_KEY_EQUAL 0x0c
641#define SSD_KEY_VOLUME_OVERFLOW 0x0d
642#define SSD_KEY_MISCOMPARE 0x0e
643#define SSD_KEY_RESERVED 0x0f
644#define SSD_ILI 0x20
645#define SSD_EOM 0x40
646#define SSD_FILEMARK 0x80
647 u_int8_t info[4];
648 u_int8_t extra_len;
649 u_int8_t cmd_spec_info[4];
650 u_int8_t add_sense_code;
651 u_int8_t add_sense_code_qual;
652 u_int8_t fru;
653 u_int8_t sense_key_spec[3];
654#define SSD_SCS_VALID 0x80
655#define SSD_FIELDPTR_CMD 0x40
656#define SSD_BITPTR_VALID 0x08
657#define SSD_BITPTR_VALUE 0x07
658#define SSD_MIN_SIZE 18
659 u_int8_t extra_bytes[14];
660#define SSD_FULL_SIZE sizeof(struct scsi_sense_data)
661};
662
663struct scsi_mode_header_6
664{
665 u_int8_t data_length; /* Sense data length */
666 u_int8_t medium_type;
667 u_int8_t dev_spec;
668 u_int8_t blk_desc_len;
669};
670
671struct scsi_mode_header_10
672{
673 u_int8_t data_length[2];/* Sense data length */
674 u_int8_t medium_type;
675 u_int8_t dev_spec;
676 u_int8_t unused[2];
677 u_int8_t blk_desc_len[2];
678};
679
18 */
19
20/*
21 * SCSI general interface description
22 */
23
24#ifndef _SCSI_SCSI_ALL_H
25#define _SCSI_SCSI_ALL_H 1
26
27#include <sys/cdefs.h>
28
29#ifdef _KERNEL
30#include "opt_scsi.h"
31/*
32 * This is the number of seconds we wait for devices to settle after a SCSI
33 * bus reset.
34 */
35#ifndef SCSI_DELAY
36#define SCSI_DELAY 2000
37#endif
38/*
39 * If someone sets this to 0, we assume that they want the minimum
40 * allowable bus settle delay. All devices need _some_ sort of bus settle
41 * delay, so we'll set it to a minimum value of 100ms.
42 */
43#if (SCSI_DELAY == 0)
44#undef SCSI_DELAY
45#define SCSI_DELAY 100
46#endif
47
48/*
49 * Make sure the user isn't using seconds instead of milliseconds.
50 */
51#if (SCSI_DELAY < 100)
52#error "SCSI_DELAY is in milliseconds, not seconds! Please use a larger value"
53#endif
54#endif /* _KERNEL */
55
56/*
57 * SCSI command format
58 */
59
60/*
61 * Define dome bits that are in ALL (or a lot of) scsi commands
62 */
63#define SCSI_CTL_LINK 0x01
64#define SCSI_CTL_FLAG 0x02
65#define SCSI_CTL_VENDOR 0xC0
66#define SCSI_CMD_LUN 0xA0 /* these two should not be needed */
67#define SCSI_CMD_LUN_SHIFT 5 /* LUN in the cmd is no longer SCSI */
68
69#define SCSI_MAX_CDBLEN 16 /*
70 * 16 byte commands are in the
71 * SCSI-3 spec
72 */
73#if defined(CAM_MAX_CDBLEN) && (CAM_MAX_CDBLEN < SCSI_MAX_CDBLEN)
74#error "CAM_MAX_CDBLEN cannot be less than SCSI_MAX_CDBLEN"
75#endif
76
77/* 6byte CDBs special case 0 length to be 256 */
78#define SCSI_CDB6_LEN(len) ((len) == 0 ? 256 : len)
79
80/*
81 * This type defines actions to be taken when a particular sense code is
82 * received. Right now, these flags are only defined to take up 16 bits,
83 * but can be expanded in the future if necessary.
84 */
85typedef enum {
86 SS_NOP = 0x000000, /* Do nothing */
87 SS_RETRY = 0x010000, /* Retry the command */
88 SS_FAIL = 0x020000, /* Bail out */
89 SS_START = 0x030000, /* Send a Start Unit command to the device,
90 * then retry the original command.
91 */
92 SS_TUR = 0x040000, /* Send a Test Unit Ready command to the
93 * device, then retry the original command.
94 */
95 SS_MANUAL = 0x050000, /*
96 * This error must be handled manually,
97 * i.e. the code must look at the asc and
98 * ascq values and determine the proper
99 * course of action.
100 */
101 SS_TURSTART = 0x060000, /*
102 * Send a Test Unit Ready command to the
103 * device, and if that fails, send a start
104 * unit.
105 */
106 SS_MASK = 0xff0000
107} scsi_sense_action;
108
109typedef enum {
110 SSQ_NONE = 0x0000,
111 SSQ_DECREMENT_COUNT = 0x0100, /* Decrement the retry count */
112 SSQ_MANY = 0x0200, /* send lots of recovery commands */
113 SSQ_RANGE = 0x0400, /*
114 * Yes, this is a hack. Basically,
115 * if this flag is set then it
116 * represents an ascq range. The
117 * "correct" way to implement the
118 * ranges might be to add a special
119 * field to the sense code table,
120 * but that would take up a lot of
121 * additional space. This solution
122 * isn't as elegant, but is more
123 * space efficient.
124 */
125 SSQ_PRINT_SENSE = 0x0800,
126 SSQ_MASK = 0xff00
127} scsi_sense_action_qualifier;
128
129/* Mask for error status values */
130#define SS_ERRMASK 0xff
131
132/* The default error action */
133#define SS_DEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO
134
135/* Default error action, without an error return value */
136#define SS_NEDEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE
137
138/* Default error action, without sense printing or an error return value */
139#define SS_NEPDEF SS_RETRY|SSQ_DECREMENT_COUNT
140
141struct scsi_generic
142{
143 u_int8_t opcode;
144 u_int8_t bytes[11];
145};
146
147struct scsi_request_sense
148{
149 u_int8_t opcode;
150 u_int8_t byte2;
151 u_int8_t unused[2];
152 u_int8_t length;
153 u_int8_t control;
154};
155
156struct scsi_test_unit_ready
157{
158 u_int8_t opcode;
159 u_int8_t byte2;
160 u_int8_t unused[3];
161 u_int8_t control;
162};
163
164struct scsi_send_diag
165{
166 u_int8_t opcode;
167 u_int8_t byte2;
168#define SSD_UOL 0x01
169#define SSD_DOL 0x02
170#define SSD_SELFTEST 0x04
171#define SSD_PF 0x10
172 u_int8_t unused[1];
173 u_int8_t paramlen[2];
174 u_int8_t control;
175};
176
177struct scsi_sense
178{
179 u_int8_t opcode;
180 u_int8_t byte2;
181 u_int8_t unused[2];
182 u_int8_t length;
183 u_int8_t control;
184};
185
186struct scsi_inquiry
187{
188 u_int8_t opcode;
189 u_int8_t byte2;
190#define SI_EVPD 0x01
191 u_int8_t page_code;
192 u_int8_t reserved;
193 u_int8_t length;
194 u_int8_t control;
195};
196
197struct scsi_mode_sense_6
198{
199 u_int8_t opcode;
200 u_int8_t byte2;
201#define SMS_DBD 0x08
202 u_int8_t page;
203#define SMS_PAGE_CODE 0x3F
204#define SMS_VENDOR_SPECIFIC_PAGE 0x00
205#define SMS_DISCONNECT_RECONNECT_PAGE 0x02
206#define SMS_PERIPHERAL_DEVICE_PAGE 0x09
207#define SMS_CONTROL_MODE_PAGE 0x0A
208#define SMS_ALL_PAGES_PAGE 0x3F
209#define SMS_PAGE_CTRL_MASK 0xC0
210#define SMS_PAGE_CTRL_CURRENT 0x00
211#define SMS_PAGE_CTRL_CHANGEABLE 0x40
212#define SMS_PAGE_CTRL_DEFAULT 0x80
213#define SMS_PAGE_CTRL_SAVED 0xC0
214 u_int8_t unused;
215 u_int8_t length;
216 u_int8_t control;
217};
218
219struct scsi_mode_sense_10
220{
221 u_int8_t opcode;
222 u_int8_t byte2; /* same bits as small version */
223 u_int8_t page; /* same bits as small version */
224 u_int8_t unused[4];
225 u_int8_t length[2];
226 u_int8_t control;
227};
228
229struct scsi_mode_select_6
230{
231 u_int8_t opcode;
232 u_int8_t byte2;
233#define SMS_SP 0x01
234#define SMS_PF 0x10
235 u_int8_t unused[2];
236 u_int8_t length;
237 u_int8_t control;
238};
239
240struct scsi_mode_select_10
241{
242 u_int8_t opcode;
243 u_int8_t byte2; /* same bits as small version */
244 u_int8_t unused[5];
245 u_int8_t length[2];
246 u_int8_t control;
247};
248
249/*
250 * When sending a mode select to a tape drive, the medium type must be 0.
251 */
252struct scsi_mode_hdr_6
253{
254 u_int8_t datalen;
255 u_int8_t medium_type;
256 u_int8_t dev_specific;
257 u_int8_t block_descr_len;
258};
259
260struct scsi_mode_hdr_10
261{
262 u_int8_t datalen[2];
263 u_int8_t medium_type;
264 u_int8_t dev_specific;
265 u_int8_t reserved[2];
266 u_int8_t block_descr_len[2];
267};
268
269struct scsi_mode_block_descr
270{
271 u_int8_t density_code;
272 u_int8_t num_blocks[3];
273 u_int8_t reserved;
274 u_int8_t block_len[3];
275};
276
277struct scsi_control_page {
278 u_int8_t page_code;
279 u_int8_t page_length;
280 u_int8_t rlec;
281#define SCB_RLEC 0x01 /*Report Log Exception Cond*/
282 u_int8_t queue_flags;
283#define SCP_QUEUE_ALG_MASK 0xF0
284#define SCP_QUEUE_ALG_RESTRICTED 0x00
285#define SCP_QUEUE_ALG_UNRESTRICTED 0x10
286#define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/
287#define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/
288 u_int8_t eca_and_aen;
289#define SCP_EECA 0x80 /*Enable Extended CA*/
290#define SCP_RAENP 0x04 /*Ready AEN Permission*/
291#define SCP_UAAENP 0x02 /*UA AEN Permission*/
292#define SCP_EAENP 0x01 /*Error AEN Permission*/
293 u_int8_t reserved;
294 u_int8_t aen_holdoff_period[2];
295};
296
297struct scsi_reserve
298{
299 u_int8_t opcode;
300 u_int8_t byte2;
301 u_int8_t unused[2];
302 u_int8_t length;
303 u_int8_t control;
304};
305
306struct scsi_release
307{
308 u_int8_t opcode;
309 u_int8_t byte2;
310 u_int8_t unused[2];
311 u_int8_t length;
312 u_int8_t control;
313};
314
315struct scsi_prevent
316{
317 u_int8_t opcode;
318 u_int8_t byte2;
319 u_int8_t unused[2];
320 u_int8_t how;
321 u_int8_t control;
322};
323#define PR_PREVENT 0x01
324#define PR_ALLOW 0x00
325
326struct scsi_sync_cache
327{
328 u_int8_t opcode;
329 u_int8_t byte2;
330 u_int8_t begin_lba[4];
331 u_int8_t reserved;
332 u_int8_t lb_count[2];
333 u_int8_t control;
334};
335
336
337struct scsi_changedef
338{
339 u_int8_t opcode;
340 u_int8_t byte2;
341 u_int8_t unused1;
342 u_int8_t how;
343 u_int8_t unused[4];
344 u_int8_t datalen;
345 u_int8_t control;
346};
347
348struct scsi_read_buffer
349{
350 u_int8_t opcode;
351 u_int8_t byte2;
352#define RWB_MODE 0x07
353#define RWB_MODE_HDR_DATA 0x00
354#define RWB_MODE_DATA 0x02
355#define RWB_MODE_DOWNLOAD 0x04
356#define RWB_MODE_DOWNLOAD_SAVE 0x05
357 u_int8_t buffer_id;
358 u_int8_t offset[3];
359 u_int8_t length[3];
360 u_int8_t control;
361};
362
363struct scsi_write_buffer
364{
365 u_int8_t opcode;
366 u_int8_t byte2;
367 u_int8_t buffer_id;
368 u_int8_t offset[3];
369 u_int8_t length[3];
370 u_int8_t control;
371};
372
373struct scsi_rw_6
374{
375 u_int8_t opcode;
376 u_int8_t addr[3];
377/* only 5 bits are valid in the MSB address byte */
378#define SRW_TOPADDR 0x1F
379 u_int8_t length;
380 u_int8_t control;
381};
382
383struct scsi_rw_10
384{
385 u_int8_t opcode;
386#define SRW10_RELADDR 0x01
387#define SRW10_FUA 0x08
388#define SRW10_DPO 0x10
389 u_int8_t byte2;
390 u_int8_t addr[4];
391 u_int8_t reserved;
392 u_int8_t length[2];
393 u_int8_t control;
394};
395
396struct scsi_rw_12
397{
398 u_int8_t opcode;
399#define SRW12_RELADDR 0x01
400#define SRW12_FUA 0x08
401#define SRW12_DPO 0x10
402 u_int8_t byte2;
403 u_int8_t addr[4];
404 u_int8_t reserved;
405 u_int8_t length[4];
406 u_int8_t control;
407};
408
409struct scsi_start_stop_unit
410{
411 u_int8_t opcode;
412 u_int8_t byte2;
413#define SSS_IMMED 0x01
414 u_int8_t reserved[2];
415 u_int8_t how;
416#define SSS_START 0x01
417#define SSS_LOEJ 0x02
418 u_int8_t control;
419};
420
421#define SC_SCSI_1 0x01
422#define SC_SCSI_2 0x03
423
424/*
425 * Opcodes
426 */
427
428#define TEST_UNIT_READY 0x00
429#define REQUEST_SENSE 0x03
430#define READ_6 0x08
431#define WRITE_6 0x0a
432#define INQUIRY 0x12
433#define MODE_SELECT_6 0x15
434#define MODE_SENSE_6 0x1a
435#define START_STOP_UNIT 0x1b
436#define START_STOP 0x1b
437#define RESERVE 0x16
438#define RELEASE 0x17
439#define RECEIVE_DIAGNOSTIC 0x1c
440#define SEND_DIAGNOSTIC 0x1d
441#define PREVENT_ALLOW 0x1e
442#define READ_CAPACITY 0x25
443#define READ_10 0x28
444#define WRITE_10 0x2a
445#define POSITION_TO_ELEMENT 0x2b
446#define SYNCHRONIZE_CACHE 0x35
447#define WRITE_BUFFER 0x3b
448#define READ_BUFFER 0x3c
449#define CHANGE_DEFINITION 0x40
450#define MODE_SELECT_10 0x55
451#define MODE_SENSE_10 0x5A
452#define MOVE_MEDIUM 0xa5
453#define READ_12 0xa8
454#define WRITE_12 0xaa
455#define READ_ELEMENT_STATUS 0xb8
456
457
458/*
459 * Device Types
460 */
461#define T_DIRECT 0x00
462#define T_SEQUENTIAL 0x01
463#define T_PRINTER 0x02
464#define T_PROCESSOR 0x03
465#define T_WORM 0x04
466#define T_CDROM 0x05
467#define T_SCANNER 0x06
468#define T_OPTICAL 0x07
469#define T_CHANGER 0x08
470#define T_COMM 0x09
471#define T_ASC0 0x0a
472#define T_ASC1 0x0b
473#define T_STORARRAY 0x0c
474#define T_ENCLOSURE 0x0d
475#define T_RBC 0x0e
476#define T_OCRW 0x0f
477#define T_NODEVICE 0x1F
478#define T_ANY 0xFF /* Used in Quirk table matches */
479
480#define T_REMOV 1
481#define T_FIXED 0
482
483/*
484 * This length is the initial inquiry length used by the probe code, as
485 * well as the legnth necessary for scsi_print_inquiry() to function
486 * correctly. If either use requires a different length in the future,
487 * the two values should be de-coupled.
488 */
489#define SHORT_INQUIRY_LENGTH 36
490
491struct scsi_inquiry_data
492{
493 u_int8_t device;
494#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f)
495#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5)
496#define SID_QUAL_LU_CONNECTED 0x00 /* The specified peripheral device
497 * type is currently connected to
498 * logical unit. If the target cannot
499 * determine whether or not a physical
500 * device is currently connected, it
501 * shall also use this peripheral
502 * qualifier when returning the INQUIRY
503 * data. This peripheral qualifier
504 * does not mean that the device is
505 * ready for access by the initiator.
506 */
507#define SID_QUAL_LU_OFFLINE 0x01 /* The target is capable of supporting
508 * the specified peripheral device type
509 * on this logical unit; however, the
510 * physical device is not currently
511 * connected to this logical unit.
512 */
513#define SID_QUAL_RSVD 0x02
514#define SID_QUAL_BAD_LU 0x03 /* The target is not capable of
515 * supporting a physical device on
516 * this logical unit. For this
517 * peripheral qualifier the peripheral
518 * device type shall be set to 1Fh to
519 * provide compatibility with previous
520 * versions of SCSI. All other
521 * peripheral device type values are
522 * reserved for this peripheral
523 * qualifier.
524 */
525#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0)
526 u_int8_t dev_qual2;
527#define SID_QUAL2 0x7F
528#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0)
529 u_int8_t version;
530#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07)
531#define SCSI_REV_0 0
532#define SCSI_REV_CCS 1
533#define SCSI_REV_2 2
534#define SCSI_REV_3 3
535#define SCSI_REV_SPC2 4
536
537#define SID_ECMA 0x38
538#define SID_ISO 0xC0
539 u_int8_t response_format;
540#define SID_AENC 0x80
541#define SID_TrmIOP 0x40
542 u_int8_t additional_length;
543 u_int8_t reserved[2];
544 u_int8_t flags;
545#define SID_SftRe 0x01
546#define SID_CmdQue 0x02
547#define SID_Linked 0x08
548#define SID_Sync 0x10
549#define SID_WBus16 0x20
550#define SID_WBus32 0x40
551#define SID_RelAdr 0x80
552#define SID_VENDOR_SIZE 8
553 char vendor[SID_VENDOR_SIZE];
554#define SID_PRODUCT_SIZE 16
555 char product[SID_PRODUCT_SIZE];
556#define SID_REVISION_SIZE 4
557 char revision[SID_REVISION_SIZE];
558 /*
559 * The following fields were taken from SCSI Primary Commands - 2
560 * (SPC-2) Revision 14, Dated 11 November 1999
561 */
562#define SID_VENDOR_SPECIFIC_0_SIZE 20
563 u_int8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE];
564 /*
565 * An extension of SCSI Parallel Specific Values
566 */
567#define SID_SPI_IUS 0x01
568#define SID_SPI_QAS 0x02
569#define SID_SPI_CLOCK_ST 0x00
570#define SID_SPI_CLOCK_DT 0x04
571#define SID_SPI_CLOCK_DT_ST 0x0C
572 u_int8_t spi3data;
573 u_int8_t reserved2;
574 /*
575 * Version Descriptors, stored 2 byte values.
576 */
577 u_int8_t version1[2];
578 u_int8_t version2[2];
579 u_int8_t version3[2];
580 u_int8_t version4[2];
581 u_int8_t version5[2];
582 u_int8_t version6[2];
583 u_int8_t version7[2];
584 u_int8_t version8[2];
585
586 u_int8_t reserved3[22];
587
588#define SID_VENDOR_SPECIFIC_1_SIZE 160
589 u_int8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE];
590};
591
592struct scsi_vpd_unit_serial_number
593{
594 u_int8_t device;
595 u_int8_t page_code;
596#define SVPD_UNIT_SERIAL_NUMBER 0x80
597 u_int8_t reserved;
598 u_int8_t length; /* serial number length */
599#define SVPD_SERIAL_NUM_SIZE 251
600 u_int8_t serial_num[SVPD_SERIAL_NUM_SIZE];
601};
602
603struct scsi_read_capacity
604{
605 u_int8_t opcode;
606 u_int8_t byte2;
607 u_int8_t addr[4];
608 u_int8_t unused[3];
609 u_int8_t control;
610};
611
612struct scsi_read_capacity_data
613{
614 u_int8_t addr[4];
615 u_int8_t length[4];
616};
617
618struct scsi_sense_data
619{
620 u_int8_t error_code;
621#define SSD_ERRCODE 0x7F
622#define SSD_CURRENT_ERROR 0x70
623#define SSD_DEFERRED_ERROR 0x71
624#define SSD_ERRCODE_VALID 0x80
625 u_int8_t segment;
626 u_int8_t flags;
627#define SSD_KEY 0x0F
628#define SSD_KEY_NO_SENSE 0x00
629#define SSD_KEY_RECOVERED_ERROR 0x01
630#define SSD_KEY_NOT_READY 0x02
631#define SSD_KEY_MEDIUM_ERROR 0x03
632#define SSD_KEY_HARDWARE_ERROR 0x04
633#define SSD_KEY_ILLEGAL_REQUEST 0x05
634#define SSD_KEY_UNIT_ATTENTION 0x06
635#define SSD_KEY_DATA_PROTECT 0x07
636#define SSD_KEY_BLANK_CHECK 0x08
637#define SSD_KEY_Vendor_Specific 0x09
638#define SSD_KEY_COPY_ABORTED 0x0a
639#define SSD_KEY_ABORTED_COMMAND 0x0b
640#define SSD_KEY_EQUAL 0x0c
641#define SSD_KEY_VOLUME_OVERFLOW 0x0d
642#define SSD_KEY_MISCOMPARE 0x0e
643#define SSD_KEY_RESERVED 0x0f
644#define SSD_ILI 0x20
645#define SSD_EOM 0x40
646#define SSD_FILEMARK 0x80
647 u_int8_t info[4];
648 u_int8_t extra_len;
649 u_int8_t cmd_spec_info[4];
650 u_int8_t add_sense_code;
651 u_int8_t add_sense_code_qual;
652 u_int8_t fru;
653 u_int8_t sense_key_spec[3];
654#define SSD_SCS_VALID 0x80
655#define SSD_FIELDPTR_CMD 0x40
656#define SSD_BITPTR_VALID 0x08
657#define SSD_BITPTR_VALUE 0x07
658#define SSD_MIN_SIZE 18
659 u_int8_t extra_bytes[14];
660#define SSD_FULL_SIZE sizeof(struct scsi_sense_data)
661};
662
663struct scsi_mode_header_6
664{
665 u_int8_t data_length; /* Sense data length */
666 u_int8_t medium_type;
667 u_int8_t dev_spec;
668 u_int8_t blk_desc_len;
669};
670
671struct scsi_mode_header_10
672{
673 u_int8_t data_length[2];/* Sense data length */
674 u_int8_t medium_type;
675 u_int8_t dev_spec;
676 u_int8_t unused[2];
677 u_int8_t blk_desc_len[2];
678};
679
680struct scsi_mode_blk_desc
680struct scsi_mode_page_header
681{
681{
682 u_int8_t page_code;
683 u_int8_t page_length;
684};
685
686struct scsi_mode_blk_desc
687{
682 u_int8_t density;
683 u_int8_t nblocks[3];
684 u_int8_t reserved;
685 u_int8_t blklen[3];
686};
687
688#define SCSI_DEFAULT_DENSITY 0x00 /* use 'default' density */
689#define SCSI_SAME_DENSITY 0x7f /* use 'same' density- >= SCSI-2 only */
690/*
691 * Status Byte
692 */
693#define SCSI_STATUS_OK 0x00
694#define SCSI_STATUS_CHECK_COND 0x02
695#define SCSI_STATUS_COND_MET 0x04
696#define SCSI_STATUS_BUSY 0x08
697#define SCSI_STATUS_INTERMED 0x10
698#define SCSI_STATUS_INTERMED_COND_MET 0x14
699#define SCSI_STATUS_RESERV_CONFLICT 0x18
700#define SCSI_STATUS_CMD_TERMINATED 0x22
701#define SCSI_STATUS_QUEUE_FULL 0x28
702
703struct scsi_inquiry_pattern {
704 u_int8_t type;
705 u_int8_t media_type;
706#define SIP_MEDIA_REMOVABLE 0x01
707#define SIP_MEDIA_FIXED 0x02
708 const char *vendor;
709 const char *product;
710 const char *revision;
711};
712
713struct scsi_static_inquiry_pattern {
714 u_int8_t type;
715 u_int8_t media_type;
716 char vendor[SID_VENDOR_SIZE+1];
717 char product[SID_PRODUCT_SIZE+1];
718 char revision[SID_REVISION_SIZE+1];
719};
720
721struct scsi_sense_quirk_entry {
722 struct scsi_inquiry_pattern inq_pat;
723 int num_ascs;
724 struct asc_table_entry *asc_info;
725};
726
727struct asc_table_entry {
728 u_int8_t asc;
729 u_int8_t ascq;
730 u_int32_t action;
731#if !defined(SCSI_NO_SENSE_STRINGS)
732 const char *desc;
733#endif
734};
735
736struct op_table_entry {
737 u_int8_t opcode;
738 u_int16_t opmask;
739 const char *desc;
740};
741
742struct scsi_op_quirk_entry {
743 struct scsi_inquiry_pattern inq_pat;
744 int num_ops;
745 struct op_table_entry *op_table;
746};
747
748
749struct ccb_scsiio;
750struct cam_periph;
751union ccb;
752#ifndef _KERNEL
753struct cam_device;
754#endif
755
756extern const char *scsi_sense_key_text[];
757
758__BEGIN_DECLS
759const char * scsi_sense_desc(int asc, int ascq,
760 struct scsi_inquiry_data *inq_data);
761scsi_sense_action scsi_error_action(int asc, int ascq,
762 struct scsi_inquiry_data *inq_data);
763#ifdef _KERNEL
764void scsi_sense_print(struct ccb_scsiio *csio);
765int scsi_interpret_sense(union ccb *ccb,
766 u_int32_t sense_flags,
767 u_int32_t *relsim_flags,
768 u_int32_t *reduction,
769 u_int32_t *timeout,
770 scsi_sense_action error_action);
771#else
772char * scsi_sense_string(struct cam_device *device,
773 struct ccb_scsiio *csio,
774 char *str, int str_len);
775void scsi_sense_print(struct cam_device *device,
776 struct ccb_scsiio *csio, FILE *ofile);
777int scsi_interpret_sense(struct cam_device *device,
778 union ccb *ccb,
779 u_int32_t sense_flags,
780 u_int32_t *relsim_flags,
781 u_int32_t *reduction,
782 u_int32_t *timeout,
783 scsi_sense_action error_action);
784#endif /* _KERNEL */
785
786#define SF_RETRY_UA 0x01
787#define SF_NO_PRINT 0x02
788#define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */
789#define SF_PRINT_ALWAYS 0x08
790#define SF_RETRY_SELTO 0x10 /* Retry selection timeouts */
791
792
793const char * scsi_op_desc(u_int16_t opcode,
794 struct scsi_inquiry_data *inq_data);
795char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
796 size_t len);
797
798void scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
799
800u_int scsi_calc_syncsrate(u_int period_factor);
801u_int scsi_calc_syncparam(u_int period);
802
803void scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
804 void (*cbfcnp)(struct cam_periph *,
805 union ccb *),
806 u_int8_t tag_action,
807 u_int8_t sense_len, u_int32_t timeout);
808
809void scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries,
810 void (*cbfcnp)(struct cam_periph *,
811 union ccb *),
812 void *data_ptr, u_int8_t dxfer_len,
813 u_int8_t tag_action, u_int8_t sense_len,
814 u_int32_t timeout);
815
816void scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries,
817 void (*cbfcnp)(struct cam_periph *, union ccb *),
818 u_int8_t tag_action, u_int8_t *inq_buf,
819 u_int32_t inq_len, int evpd, u_int8_t page_code,
820 u_int8_t sense_len, u_int32_t timeout);
821
822void scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
823 void (*cbfcnp)(struct cam_periph *,
824 union ccb *),
825 u_int8_t tag_action, int dbd,
826 u_int8_t page_code, u_int8_t page,
827 u_int8_t *param_buf, u_int32_t param_len,
828 u_int8_t sense_len, u_int32_t timeout);
829
830void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
831 void (*cbfcnp)(struct cam_periph *,
832 union ccb *),
833 u_int8_t tag_action, int scsi_page_fmt,
834 int save_pages, u_int8_t *param_buf,
835 u_int32_t param_len, u_int8_t sense_len,
836 u_int32_t timeout);
837
838void scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries,
839 void (*cbfcnp)(struct cam_periph *,
840 union ccb *), u_int8_t tag_action,
841 struct scsi_read_capacity_data *rcap_buf,
842 u_int8_t sense_len, u_int32_t timeout);
843
844void scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries,
845 void (*cbfcnp)(struct cam_periph *, union ccb *),
846 u_int8_t tag_action, u_int8_t action,
847 u_int8_t sense_len, u_int32_t timeout);
848
849void scsi_synchronize_cache(struct ccb_scsiio *csio,
850 u_int32_t retries,
851 void (*cbfcnp)(struct cam_periph *,
852 union ccb *), u_int8_t tag_action,
853 u_int32_t begin_lba, u_int16_t lb_count,
854 u_int8_t sense_len, u_int32_t timeout);
855
856void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
857 void (*cbfcnp)(struct cam_periph *, union ccb *),
858 u_int8_t tag_action, int readop, u_int8_t byte2,
859 int minimum_cmd_size, u_int32_t lba,
860 u_int32_t block_count, u_int8_t *data_ptr,
861 u_int32_t dxfer_len, u_int8_t sense_len,
862 u_int32_t timeout);
863
864void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
865 void (*cbfcnp)(struct cam_periph *, union ccb *),
866 u_int8_t tag_action, int start, int load_eject,
867 int immediate, u_int8_t sense_len, u_int32_t timeout);
868
869int scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry);
870int scsi_static_inquiry_match(caddr_t inqbuffer,
871 caddr_t table_entry);
872
873static __inline void scsi_extract_sense(struct scsi_sense_data *sense,
874 int *error_code, int *sense_key,
875 int *asc, int *ascq);
876static __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes);
877static __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes);
878static __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes);
879static __inline u_int32_t scsi_2btoul(u_int8_t *bytes);
880static __inline u_int32_t scsi_3btoul(u_int8_t *bytes);
881static __inline int32_t scsi_3btol(u_int8_t *bytes);
882static __inline u_int32_t scsi_4btoul(u_int8_t *bytes);
883static __inline void *find_mode_page_6(struct scsi_mode_header_6 *mode_header);
884static __inline void *find_mode_page_10(struct scsi_mode_header_10 *mode_header);
885
886static __inline void scsi_extract_sense(struct scsi_sense_data *sense,
887 int *error_code, int *sense_key,
888 int *asc, int *ascq)
889{
890 *error_code = sense->error_code & SSD_ERRCODE;
891 *sense_key = sense->flags & SSD_KEY;
892 *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0;
893 *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0;
894}
895
896static __inline void
897scsi_ulto2b(u_int32_t val, u_int8_t *bytes)
898{
899
900 bytes[0] = (val >> 8) & 0xff;
901 bytes[1] = val & 0xff;
902}
903
904static __inline void
905scsi_ulto3b(u_int32_t val, u_int8_t *bytes)
906{
907
908 bytes[0] = (val >> 16) & 0xff;
909 bytes[1] = (val >> 8) & 0xff;
910 bytes[2] = val & 0xff;
911}
912
913static __inline void
914scsi_ulto4b(u_int32_t val, u_int8_t *bytes)
915{
916
917 bytes[0] = (val >> 24) & 0xff;
918 bytes[1] = (val >> 16) & 0xff;
919 bytes[2] = (val >> 8) & 0xff;
920 bytes[3] = val & 0xff;
921}
922
923static __inline u_int32_t
924scsi_2btoul(u_int8_t *bytes)
925{
926 u_int32_t rv;
927
928 rv = (bytes[0] << 8) |
929 bytes[1];
930 return (rv);
931}
932
933static __inline u_int32_t
934scsi_3btoul(u_int8_t *bytes)
935{
936 u_int32_t rv;
937
938 rv = (bytes[0] << 16) |
939 (bytes[1] << 8) |
940 bytes[2];
941 return (rv);
942}
943
944static __inline int32_t
945scsi_3btol(u_int8_t *bytes)
946{
947 u_int32_t rc = scsi_3btoul(bytes);
948
949 if (rc & 0x00800000)
950 rc |= 0xff000000;
951
952 return (int32_t) rc;
953}
954
955static __inline u_int32_t
956scsi_4btoul(u_int8_t *bytes)
957{
958 u_int32_t rv;
959
960 rv = (bytes[0] << 24) |
961 (bytes[1] << 16) |
962 (bytes[2] << 8) |
963 bytes[3];
964 return (rv);
965}
966
967/*
968 * Given the pointer to a returned mode sense buffer, return a pointer to
969 * the start of the first mode page.
970 */
971static __inline void *
972find_mode_page_6(struct scsi_mode_header_6 *mode_header)
973{
974 void *page_start;
975
976 page_start = (void *)((u_int8_t *)&mode_header[1] +
977 mode_header->blk_desc_len);
978
979 return(page_start);
980}
981
982static __inline void *
983find_mode_page_10(struct scsi_mode_header_10 *mode_header)
984{
985 void *page_start;
986
987 page_start = (void *)((u_int8_t *)&mode_header[1] +
988 scsi_2btoul(mode_header->blk_desc_len));
989
990 return(page_start);
991}
992
993__END_DECLS
994
995#endif /*_SCSI_SCSI_ALL_H*/
688 u_int8_t density;
689 u_int8_t nblocks[3];
690 u_int8_t reserved;
691 u_int8_t blklen[3];
692};
693
694#define SCSI_DEFAULT_DENSITY 0x00 /* use 'default' density */
695#define SCSI_SAME_DENSITY 0x7f /* use 'same' density- >= SCSI-2 only */
696/*
697 * Status Byte
698 */
699#define SCSI_STATUS_OK 0x00
700#define SCSI_STATUS_CHECK_COND 0x02
701#define SCSI_STATUS_COND_MET 0x04
702#define SCSI_STATUS_BUSY 0x08
703#define SCSI_STATUS_INTERMED 0x10
704#define SCSI_STATUS_INTERMED_COND_MET 0x14
705#define SCSI_STATUS_RESERV_CONFLICT 0x18
706#define SCSI_STATUS_CMD_TERMINATED 0x22
707#define SCSI_STATUS_QUEUE_FULL 0x28
708
709struct scsi_inquiry_pattern {
710 u_int8_t type;
711 u_int8_t media_type;
712#define SIP_MEDIA_REMOVABLE 0x01
713#define SIP_MEDIA_FIXED 0x02
714 const char *vendor;
715 const char *product;
716 const char *revision;
717};
718
719struct scsi_static_inquiry_pattern {
720 u_int8_t type;
721 u_int8_t media_type;
722 char vendor[SID_VENDOR_SIZE+1];
723 char product[SID_PRODUCT_SIZE+1];
724 char revision[SID_REVISION_SIZE+1];
725};
726
727struct scsi_sense_quirk_entry {
728 struct scsi_inquiry_pattern inq_pat;
729 int num_ascs;
730 struct asc_table_entry *asc_info;
731};
732
733struct asc_table_entry {
734 u_int8_t asc;
735 u_int8_t ascq;
736 u_int32_t action;
737#if !defined(SCSI_NO_SENSE_STRINGS)
738 const char *desc;
739#endif
740};
741
742struct op_table_entry {
743 u_int8_t opcode;
744 u_int16_t opmask;
745 const char *desc;
746};
747
748struct scsi_op_quirk_entry {
749 struct scsi_inquiry_pattern inq_pat;
750 int num_ops;
751 struct op_table_entry *op_table;
752};
753
754
755struct ccb_scsiio;
756struct cam_periph;
757union ccb;
758#ifndef _KERNEL
759struct cam_device;
760#endif
761
762extern const char *scsi_sense_key_text[];
763
764__BEGIN_DECLS
765const char * scsi_sense_desc(int asc, int ascq,
766 struct scsi_inquiry_data *inq_data);
767scsi_sense_action scsi_error_action(int asc, int ascq,
768 struct scsi_inquiry_data *inq_data);
769#ifdef _KERNEL
770void scsi_sense_print(struct ccb_scsiio *csio);
771int scsi_interpret_sense(union ccb *ccb,
772 u_int32_t sense_flags,
773 u_int32_t *relsim_flags,
774 u_int32_t *reduction,
775 u_int32_t *timeout,
776 scsi_sense_action error_action);
777#else
778char * scsi_sense_string(struct cam_device *device,
779 struct ccb_scsiio *csio,
780 char *str, int str_len);
781void scsi_sense_print(struct cam_device *device,
782 struct ccb_scsiio *csio, FILE *ofile);
783int scsi_interpret_sense(struct cam_device *device,
784 union ccb *ccb,
785 u_int32_t sense_flags,
786 u_int32_t *relsim_flags,
787 u_int32_t *reduction,
788 u_int32_t *timeout,
789 scsi_sense_action error_action);
790#endif /* _KERNEL */
791
792#define SF_RETRY_UA 0x01
793#define SF_NO_PRINT 0x02
794#define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */
795#define SF_PRINT_ALWAYS 0x08
796#define SF_RETRY_SELTO 0x10 /* Retry selection timeouts */
797
798
799const char * scsi_op_desc(u_int16_t opcode,
800 struct scsi_inquiry_data *inq_data);
801char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
802 size_t len);
803
804void scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
805
806u_int scsi_calc_syncsrate(u_int period_factor);
807u_int scsi_calc_syncparam(u_int period);
808
809void scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
810 void (*cbfcnp)(struct cam_periph *,
811 union ccb *),
812 u_int8_t tag_action,
813 u_int8_t sense_len, u_int32_t timeout);
814
815void scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries,
816 void (*cbfcnp)(struct cam_periph *,
817 union ccb *),
818 void *data_ptr, u_int8_t dxfer_len,
819 u_int8_t tag_action, u_int8_t sense_len,
820 u_int32_t timeout);
821
822void scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries,
823 void (*cbfcnp)(struct cam_periph *, union ccb *),
824 u_int8_t tag_action, u_int8_t *inq_buf,
825 u_int32_t inq_len, int evpd, u_int8_t page_code,
826 u_int8_t sense_len, u_int32_t timeout);
827
828void scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
829 void (*cbfcnp)(struct cam_periph *,
830 union ccb *),
831 u_int8_t tag_action, int dbd,
832 u_int8_t page_code, u_int8_t page,
833 u_int8_t *param_buf, u_int32_t param_len,
834 u_int8_t sense_len, u_int32_t timeout);
835
836void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
837 void (*cbfcnp)(struct cam_periph *,
838 union ccb *),
839 u_int8_t tag_action, int scsi_page_fmt,
840 int save_pages, u_int8_t *param_buf,
841 u_int32_t param_len, u_int8_t sense_len,
842 u_int32_t timeout);
843
844void scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries,
845 void (*cbfcnp)(struct cam_periph *,
846 union ccb *), u_int8_t tag_action,
847 struct scsi_read_capacity_data *rcap_buf,
848 u_int8_t sense_len, u_int32_t timeout);
849
850void scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries,
851 void (*cbfcnp)(struct cam_periph *, union ccb *),
852 u_int8_t tag_action, u_int8_t action,
853 u_int8_t sense_len, u_int32_t timeout);
854
855void scsi_synchronize_cache(struct ccb_scsiio *csio,
856 u_int32_t retries,
857 void (*cbfcnp)(struct cam_periph *,
858 union ccb *), u_int8_t tag_action,
859 u_int32_t begin_lba, u_int16_t lb_count,
860 u_int8_t sense_len, u_int32_t timeout);
861
862void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
863 void (*cbfcnp)(struct cam_periph *, union ccb *),
864 u_int8_t tag_action, int readop, u_int8_t byte2,
865 int minimum_cmd_size, u_int32_t lba,
866 u_int32_t block_count, u_int8_t *data_ptr,
867 u_int32_t dxfer_len, u_int8_t sense_len,
868 u_int32_t timeout);
869
870void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
871 void (*cbfcnp)(struct cam_periph *, union ccb *),
872 u_int8_t tag_action, int start, int load_eject,
873 int immediate, u_int8_t sense_len, u_int32_t timeout);
874
875int scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry);
876int scsi_static_inquiry_match(caddr_t inqbuffer,
877 caddr_t table_entry);
878
879static __inline void scsi_extract_sense(struct scsi_sense_data *sense,
880 int *error_code, int *sense_key,
881 int *asc, int *ascq);
882static __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes);
883static __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes);
884static __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes);
885static __inline u_int32_t scsi_2btoul(u_int8_t *bytes);
886static __inline u_int32_t scsi_3btoul(u_int8_t *bytes);
887static __inline int32_t scsi_3btol(u_int8_t *bytes);
888static __inline u_int32_t scsi_4btoul(u_int8_t *bytes);
889static __inline void *find_mode_page_6(struct scsi_mode_header_6 *mode_header);
890static __inline void *find_mode_page_10(struct scsi_mode_header_10 *mode_header);
891
892static __inline void scsi_extract_sense(struct scsi_sense_data *sense,
893 int *error_code, int *sense_key,
894 int *asc, int *ascq)
895{
896 *error_code = sense->error_code & SSD_ERRCODE;
897 *sense_key = sense->flags & SSD_KEY;
898 *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0;
899 *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0;
900}
901
902static __inline void
903scsi_ulto2b(u_int32_t val, u_int8_t *bytes)
904{
905
906 bytes[0] = (val >> 8) & 0xff;
907 bytes[1] = val & 0xff;
908}
909
910static __inline void
911scsi_ulto3b(u_int32_t val, u_int8_t *bytes)
912{
913
914 bytes[0] = (val >> 16) & 0xff;
915 bytes[1] = (val >> 8) & 0xff;
916 bytes[2] = val & 0xff;
917}
918
919static __inline void
920scsi_ulto4b(u_int32_t val, u_int8_t *bytes)
921{
922
923 bytes[0] = (val >> 24) & 0xff;
924 bytes[1] = (val >> 16) & 0xff;
925 bytes[2] = (val >> 8) & 0xff;
926 bytes[3] = val & 0xff;
927}
928
929static __inline u_int32_t
930scsi_2btoul(u_int8_t *bytes)
931{
932 u_int32_t rv;
933
934 rv = (bytes[0] << 8) |
935 bytes[1];
936 return (rv);
937}
938
939static __inline u_int32_t
940scsi_3btoul(u_int8_t *bytes)
941{
942 u_int32_t rv;
943
944 rv = (bytes[0] << 16) |
945 (bytes[1] << 8) |
946 bytes[2];
947 return (rv);
948}
949
950static __inline int32_t
951scsi_3btol(u_int8_t *bytes)
952{
953 u_int32_t rc = scsi_3btoul(bytes);
954
955 if (rc & 0x00800000)
956 rc |= 0xff000000;
957
958 return (int32_t) rc;
959}
960
961static __inline u_int32_t
962scsi_4btoul(u_int8_t *bytes)
963{
964 u_int32_t rv;
965
966 rv = (bytes[0] << 24) |
967 (bytes[1] << 16) |
968 (bytes[2] << 8) |
969 bytes[3];
970 return (rv);
971}
972
973/*
974 * Given the pointer to a returned mode sense buffer, return a pointer to
975 * the start of the first mode page.
976 */
977static __inline void *
978find_mode_page_6(struct scsi_mode_header_6 *mode_header)
979{
980 void *page_start;
981
982 page_start = (void *)((u_int8_t *)&mode_header[1] +
983 mode_header->blk_desc_len);
984
985 return(page_start);
986}
987
988static __inline void *
989find_mode_page_10(struct scsi_mode_header_10 *mode_header)
990{
991 void *page_start;
992
993 page_start = (void *)((u_int8_t *)&mode_header[1] +
994 scsi_2btoul(mode_header->blk_desc_len));
995
996 return(page_start);
997}
998
999__END_DECLS
1000
1001#endif /*_SCSI_SCSI_ALL_H*/