TRIM support
[dragonfly.git] / sys / bus / cam / scsi / scsi_all.h
CommitLineData
984263bc
MD
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 *
3a33d431
PA
17 * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.31 2008/08/07 17:25:05 jkim Exp $
18 * $DragonFly: src/sys/bus/cam/scsi/scsi_all.h,v 1.15 2008/08/23 22:27:27 pavalos Exp $
984263bc
MD
19 */
20
21/*
22 * SCSI general interface description
23 */
24
25#ifndef _SCSI_SCSI_ALL_H
26#define _SCSI_SCSI_ALL_H 1
27
03d6a592 28#ifndef _SYS_CDEFS_H_
984263bc 29#include <sys/cdefs.h>
03d6a592
MD
30#endif
31#if !defined(_KERNEL) && !defined(_STDIO_H_)
32#include <stdio.h> /* FILE for userland protos */
33#endif
984263bc
MD
34
35#ifdef _KERNEL
984263bc 36/*
3a33d431 37 * This is the number of milliseconds we wait for devices to settle after a SCSI
984263bc
MD
38 * bus reset.
39 */
cf66c265 40extern int scsi_delay;
984263bc
MD
41#endif /* _KERNEL */
42
43/*
44 * SCSI command format
45 */
46
47/*
48 * Define dome bits that are in ALL (or a lot of) scsi commands
49 */
50#define SCSI_CTL_LINK 0x01
51#define SCSI_CTL_FLAG 0x02
52#define SCSI_CTL_VENDOR 0xC0
53#define SCSI_CMD_LUN 0xA0 /* these two should not be needed */
54#define SCSI_CMD_LUN_SHIFT 5 /* LUN in the cmd is no longer SCSI */
55
56#define SCSI_MAX_CDBLEN 16 /*
57 * 16 byte commands are in the
58 * SCSI-3 spec
59 */
60#if defined(CAM_MAX_CDBLEN) && (CAM_MAX_CDBLEN < SCSI_MAX_CDBLEN)
61#error "CAM_MAX_CDBLEN cannot be less than SCSI_MAX_CDBLEN"
62#endif
63
64/* 6byte CDBs special case 0 length to be 256 */
65#define SCSI_CDB6_LEN(len) ((len) == 0 ? 256 : len)
66
67/*
68 * This type defines actions to be taken when a particular sense code is
69 * received. Right now, these flags are only defined to take up 16 bits,
70 * but can be expanded in the future if necessary.
71 */
72typedef enum {
73 SS_NOP = 0x000000, /* Do nothing */
74 SS_RETRY = 0x010000, /* Retry the command */
75 SS_FAIL = 0x020000, /* Bail out */
76 SS_START = 0x030000, /* Send a Start Unit command to the device,
77 * then retry the original command.
78 */
79 SS_TUR = 0x040000, /* Send a Test Unit Ready command to the
80 * device, then retry the original command.
81 */
b05e84c9
PA
82 SS_REQSENSE = 0x050000, /* Send a RequestSense command to the
83 * device, then retry the original command.
984263bc
MD
84 */
85 SS_MASK = 0xff0000
86} scsi_sense_action;
87
88typedef enum {
89 SSQ_NONE = 0x0000,
90 SSQ_DECREMENT_COUNT = 0x0100, /* Decrement the retry count */
91 SSQ_MANY = 0x0200, /* send lots of recovery commands */
92 SSQ_RANGE = 0x0400, /*
b05e84c9
PA
93 * This table entry represents the
94 * end of a range of ASCQs that
95 * have identical error actions
96 * and text.
984263bc
MD
97 */
98 SSQ_PRINT_SENSE = 0x0800,
99 SSQ_MASK = 0xff00
100} scsi_sense_action_qualifier;
101
102/* Mask for error status values */
103#define SS_ERRMASK 0xff
104
b05e84c9
PA
105/* The default, retyable, error action */
106#define SS_RDEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO
984263bc 107
b05e84c9
PA
108/* The retyable, error action, with table specified error code */
109#define SS_RET SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE
984263bc 110
b05e84c9
PA
111/* Fatal error action, with table specified error code */
112#define SS_FATAL SS_FAIL|SSQ_PRINT_SENSE
984263bc
MD
113
114struct scsi_generic
115{
116 u_int8_t opcode;
117 u_int8_t bytes[11];
118};
119
120struct scsi_request_sense
121{
122 u_int8_t opcode;
123 u_int8_t byte2;
124 u_int8_t unused[2];
125 u_int8_t length;
126 u_int8_t control;
127};
128
129struct scsi_test_unit_ready
130{
131 u_int8_t opcode;
132 u_int8_t byte2;
133 u_int8_t unused[3];
134 u_int8_t control;
135};
136
137struct scsi_send_diag
138{
139 u_int8_t opcode;
140 u_int8_t byte2;
141#define SSD_UOL 0x01
142#define SSD_DOL 0x02
143#define SSD_SELFTEST 0x04
144#define SSD_PF 0x10
145 u_int8_t unused[1];
146 u_int8_t paramlen[2];
147 u_int8_t control;
148};
149
150struct scsi_sense
151{
152 u_int8_t opcode;
153 u_int8_t byte2;
154 u_int8_t unused[2];
155 u_int8_t length;
156 u_int8_t control;
157};
158
159struct scsi_inquiry
160{
161 u_int8_t opcode;
162 u_int8_t byte2;
163#define SI_EVPD 0x01
164 u_int8_t page_code;
165 u_int8_t reserved;
166 u_int8_t length;
167 u_int8_t control;
168};
169
170struct scsi_mode_sense_6
171{
172 u_int8_t opcode;
173 u_int8_t byte2;
174#define SMS_DBD 0x08
175 u_int8_t page;
176#define SMS_PAGE_CODE 0x3F
177#define SMS_VENDOR_SPECIFIC_PAGE 0x00
178#define SMS_DISCONNECT_RECONNECT_PAGE 0x02
1c8b7a9a 179#define SMS_CACHE_PAGE 0x08
984263bc
MD
180#define SMS_PERIPHERAL_DEVICE_PAGE 0x09
181#define SMS_CONTROL_MODE_PAGE 0x0A
1c8b7a9a
PA
182#define SMS_PROTO_SPECIFIC_PAGE 0x19
183#define SMS_INFO_EXCEPTIONS_PAGE 0x1C
984263bc
MD
184#define SMS_ALL_PAGES_PAGE 0x3F
185#define SMS_PAGE_CTRL_MASK 0xC0
186#define SMS_PAGE_CTRL_CURRENT 0x00
187#define SMS_PAGE_CTRL_CHANGEABLE 0x40
188#define SMS_PAGE_CTRL_DEFAULT 0x80
189#define SMS_PAGE_CTRL_SAVED 0xC0
190 u_int8_t unused;
191 u_int8_t length;
192 u_int8_t control;
193};
194
195struct scsi_mode_sense_10
196{
197 u_int8_t opcode;
198 u_int8_t byte2; /* same bits as small version */
199 u_int8_t page; /* same bits as small version */
200 u_int8_t unused[4];
201 u_int8_t length[2];
202 u_int8_t control;
203};
204
205struct scsi_mode_select_6
206{
207 u_int8_t opcode;
208 u_int8_t byte2;
209#define SMS_SP 0x01
210#define SMS_PF 0x10
211 u_int8_t unused[2];
212 u_int8_t length;
213 u_int8_t control;
214};
215
216struct scsi_mode_select_10
217{
218 u_int8_t opcode;
219 u_int8_t byte2; /* same bits as small version */
220 u_int8_t unused[5];
221 u_int8_t length[2];
222 u_int8_t control;
223};
224
225/*
226 * When sending a mode select to a tape drive, the medium type must be 0.
227 */
228struct scsi_mode_hdr_6
229{
230 u_int8_t datalen;
231 u_int8_t medium_type;
232 u_int8_t dev_specific;
233 u_int8_t block_descr_len;
234};
235
236struct scsi_mode_hdr_10
237{
238 u_int8_t datalen[2];
239 u_int8_t medium_type;
240 u_int8_t dev_specific;
241 u_int8_t reserved[2];
242 u_int8_t block_descr_len[2];
243};
244
245struct scsi_mode_block_descr
246{
247 u_int8_t density_code;
248 u_int8_t num_blocks[3];
249 u_int8_t reserved;
250 u_int8_t block_len[3];
251};
252
f46fe720
PA
253struct scsi_log_sense
254{
255 u_int8_t opcode;
256 u_int8_t byte2;
257#define SLS_SP 0x01
258#define SLS_PPC 0x02
259 u_int8_t page;
260#define SLS_PAGE_CODE 0x3F
261#define SLS_ALL_PAGES_PAGE 0x00
262#define SLS_OVERRUN_PAGE 0x01
263#define SLS_ERROR_WRITE_PAGE 0x02
264#define SLS_ERROR_READ_PAGE 0x03
265#define SLS_ERROR_READREVERSE_PAGE 0x04
266#define SLS_ERROR_VERIFY_PAGE 0x05
267#define SLS_ERROR_NONMEDIUM_PAGE 0x06
268#define SLS_ERROR_LASTN_PAGE 0x07
1c8b7a9a
PA
269#define SLS_SELF_TEST_PAGE 0x10
270#define SLS_IE_PAGE 0x2f
f46fe720
PA
271#define SLS_PAGE_CTRL_MASK 0xC0
272#define SLS_PAGE_CTRL_THRESHOLD 0x00
273#define SLS_PAGE_CTRL_CUMULATIVE 0x40
274#define SLS_PAGE_CTRL_THRESH_DEFAULT 0x80
275#define SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0
276 u_int8_t reserved[2];
277 u_int8_t paramptr[2];
278 u_int8_t length[2];
279 u_int8_t control;
280};
281
282struct scsi_log_select
283{
284 u_int8_t opcode;
285 u_int8_t byte2;
286/* SLS_SP 0x01 */
287#define SLS_PCR 0x02
288 u_int8_t page;
289/* SLS_PAGE_CTRL_MASK 0xC0 */
290/* SLS_PAGE_CTRL_THRESHOLD 0x00 */
291/* SLS_PAGE_CTRL_CUMULATIVE 0x40 */
292/* SLS_PAGE_CTRL_THRESH_DEFAULT 0x80 */
293/* SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0 */
294 u_int8_t reserved[4];
295 u_int8_t length[2];
296 u_int8_t control;
297};
298
299struct scsi_log_header
300{
301 u_int8_t page;
302 u_int8_t reserved;
303 u_int8_t datalen[2];
304};
305
306struct scsi_log_param_header {
307 u_int8_t param_code[2];
308 u_int8_t param_control;
309#define SLP_LP 0x01
310#define SLP_LBIN 0x02
311#define SLP_TMC_MASK 0x0C
312#define SLP_TMC_ALWAYS 0x00
313#define SLP_TMC_EQUAL 0x04
314#define SLP_TMC_NOTEQUAL 0x08
315#define SLP_TMC_GREATER 0x0C
316#define SLP_ETC 0x10
317#define SLP_TSD 0x20
318#define SLP_DS 0x40
319#define SLP_DU 0x80
320 u_int8_t param_len;
321};
322
984263bc
MD
323struct scsi_control_page {
324 u_int8_t page_code;
325 u_int8_t page_length;
326 u_int8_t rlec;
327#define SCB_RLEC 0x01 /*Report Log Exception Cond*/
328 u_int8_t queue_flags;
329#define SCP_QUEUE_ALG_MASK 0xF0
330#define SCP_QUEUE_ALG_RESTRICTED 0x00
331#define SCP_QUEUE_ALG_UNRESTRICTED 0x10
332#define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/
333#define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/
334 u_int8_t eca_and_aen;
335#define SCP_EECA 0x80 /*Enable Extended CA*/
336#define SCP_RAENP 0x04 /*Ready AEN Permission*/
337#define SCP_UAAENP 0x02 /*UA AEN Permission*/
338#define SCP_EAENP 0x01 /*Error AEN Permission*/
339 u_int8_t reserved;
340 u_int8_t aen_holdoff_period[2];
341};
342
1c8b7a9a
PA
343struct scsi_cache_page {
344 u_int8_t page_code;
345#define SCHP_PAGE_SAVABLE 0x80 /* Page is savable */
346 u_int8_t page_length;
347 u_int8_t cache_flags;
348#define SCHP_FLAGS_WCE 0x04 /* Write Cache Enable */
349#define SCHP_FLAGS_MF 0x02 /* Multiplication factor */
350#define SCHP_FLAGS_RCD 0x01 /* Read Cache Disable */
351 u_int8_t rw_cache_policy;
352 u_int8_t dis_prefetch[2];
353 u_int8_t min_prefetch[2];
354 u_int8_t max_prefetch[2];
355 u_int8_t max_prefetch_ceil[2];
356};
357
358struct scsi_info_exceptions_page {
359 u_int8_t page_code;
360#define SIEP_PAGE_SAVABLE 0x80 /* Page is savable */
361 u_int8_t page_length;
362 u_int8_t info_flags;
363#define SIEP_FLAGS_PERF 0x80
364#define SIEP_FLAGS_EBF 0x20
365#define SIEP_FLAGS_EWASC 0x10
366#define SIEP_FLAGS_DEXCPT 0x08
367#define SIEP_FLAGS_TEST 0x04
368#define SIEP_FLAGS_EBACKERR 0x02
369#define SIEP_FLAGS_LOGERR 0x01
370 u_int8_t mrie;
371 u_int8_t interval_timer[4];
372 u_int8_t report_count[4];
373};
374
375struct scsi_proto_specific_page {
376 u_int8_t page_code;
377#define SPSP_PAGE_SAVABLE 0x80 /* Page is savable */
378 u_int8_t page_length;
379 u_int8_t protocol;
380#define SPSP_PROTO_FC 0x00
381#define SPSP_PROTO_SPI 0x01
382#define SPSP_PROTO_SSA 0x02
383#define SPSP_PROTO_1394 0x03
384#define SPSP_PROTO_RDMA 0x04
385#define SPSP_PROTO_ISCSI 0x05
386#define SPSP_PROTO_SAS 0x06
387#define SPSP_PROTO_ADT 0x07
388#define SPSP_PROTO_ATA 0x08
389#define SPSP_PROTO_NONE 0x0f
390};
391
984263bc
MD
392struct scsi_reserve
393{
394 u_int8_t opcode;
395 u_int8_t byte2;
396 u_int8_t unused[2];
397 u_int8_t length;
398 u_int8_t control;
399};
400
401struct scsi_release
402{
403 u_int8_t opcode;
404 u_int8_t byte2;
405 u_int8_t unused[2];
406 u_int8_t length;
407 u_int8_t control;
408};
409
410struct scsi_prevent
411{
412 u_int8_t opcode;
413 u_int8_t byte2;
414 u_int8_t unused[2];
415 u_int8_t how;
416 u_int8_t control;
417};
418#define PR_PREVENT 0x01
419#define PR_ALLOW 0x00
420
421struct scsi_sync_cache
422{
423 u_int8_t opcode;
424 u_int8_t byte2;
425 u_int8_t begin_lba[4];
426 u_int8_t reserved;
427 u_int8_t lb_count[2];
428 u_int8_t control;
429};
430
431
432struct scsi_changedef
433{
434 u_int8_t opcode;
435 u_int8_t byte2;
436 u_int8_t unused1;
437 u_int8_t how;
438 u_int8_t unused[4];
439 u_int8_t datalen;
440 u_int8_t control;
441};
442
443struct scsi_read_buffer
444{
445 u_int8_t opcode;
446 u_int8_t byte2;
447#define RWB_MODE 0x07
448#define RWB_MODE_HDR_DATA 0x00
449#define RWB_MODE_DATA 0x02
450#define RWB_MODE_DOWNLOAD 0x04
451#define RWB_MODE_DOWNLOAD_SAVE 0x05
452 u_int8_t buffer_id;
453 u_int8_t offset[3];
454 u_int8_t length[3];
455 u_int8_t control;
456};
457
458struct scsi_write_buffer
459{
460 u_int8_t opcode;
461 u_int8_t byte2;
462 u_int8_t buffer_id;
463 u_int8_t offset[3];
464 u_int8_t length[3];
465 u_int8_t control;
466};
467
468struct scsi_rw_6
469{
470 u_int8_t opcode;
471 u_int8_t addr[3];
472/* only 5 bits are valid in the MSB address byte */
473#define SRW_TOPADDR 0x1F
474 u_int8_t length;
475 u_int8_t control;
476};
477
478struct scsi_rw_10
479{
480 u_int8_t opcode;
481#define SRW10_RELADDR 0x01
bdd58e03
MD
482/* EBP defined for WRITE(10) only */
483#define SRW10_EBP 0x04
984263bc
MD
484#define SRW10_FUA 0x08
485#define SRW10_DPO 0x10
486 u_int8_t byte2;
487 u_int8_t addr[4];
488 u_int8_t reserved;
489 u_int8_t length[2];
490 u_int8_t control;
491};
492
493struct scsi_rw_12
494{
495 u_int8_t opcode;
496#define SRW12_RELADDR 0x01
497#define SRW12_FUA 0x08
498#define SRW12_DPO 0x10
499 u_int8_t byte2;
500 u_int8_t addr[4];
501 u_int8_t length[4];
502 u_int8_t reserved;
503 u_int8_t control;
504};
505
bdd58e03
MD
506struct scsi_rw_16
507{
508 u_int8_t opcode;
509#define SRW16_RELADDR 0x01
510#define SRW16_FUA 0x08
511#define SRW16_DPO 0x10
512 u_int8_t byte2;
513 u_int8_t addr[8];
514 u_int8_t length[4];
515 u_int8_t reserved;
516 u_int8_t control;
517};
518
519
984263bc
MD
520struct scsi_start_stop_unit
521{
522 u_int8_t opcode;
523 u_int8_t byte2;
524#define SSS_IMMED 0x01
525 u_int8_t reserved[2];
526 u_int8_t how;
527#define SSS_START 0x01
528#define SSS_LOEJ 0x02
529 u_int8_t control;
530};
531
1c8b7a9a
PA
532struct ata_pass_12 {
533 u_int8_t opcode;
534 u_int8_t protocol;
535#define AP_MULTI 0xe0
536 u_int8_t flags;
537#define AP_T_LEN 0x03
538#define AP_BB 0x04
539#define AP_T_DIR 0x08
540#define AP_CK_COND 0x20
541#define AP_OFFLINE 0x60
542 u_int8_t features;
543 u_int8_t sector_count;
544 u_int8_t lba_low;
545 u_int8_t lba_mid;
546 u_int8_t lba_high;
547 u_int8_t device;
548 u_int8_t command;
549 u_int8_t reserved;
550 u_int8_t control;
551};
552
553struct ata_pass_16 {
554 u_int8_t opcode;
555 u_int8_t protocol;
556#define AP_EXTEND 0x01
557 u_int8_t flags;
558 u_int8_t features_ext;
559 u_int8_t features;
560 u_int8_t sector_count_ext;
561 u_int8_t sector_count;
562 u_int8_t lba_low_ext;
563 u_int8_t lba_low;
564 u_int8_t lba_mid_ext;
565 u_int8_t lba_mid;
566 u_int8_t lba_high_ext;
567 u_int8_t lba_high;
568 u_int8_t device;
569 u_int8_t command;
570 u_int8_t control;
571};
572
984263bc
MD
573#define SC_SCSI_1 0x01
574#define SC_SCSI_2 0x03
575
576/*
577 * Opcodes
578 */
579
580#define TEST_UNIT_READY 0x00
581#define REQUEST_SENSE 0x03
582#define READ_6 0x08
583#define WRITE_6 0x0a
584#define INQUIRY 0x12
585#define MODE_SELECT_6 0x15
586#define MODE_SENSE_6 0x1a
587#define START_STOP_UNIT 0x1b
588#define START_STOP 0x1b
589#define RESERVE 0x16
590#define RELEASE 0x17
591#define RECEIVE_DIAGNOSTIC 0x1c
592#define SEND_DIAGNOSTIC 0x1d
593#define PREVENT_ALLOW 0x1e
594#define READ_CAPACITY 0x25
595#define READ_10 0x28
596#define WRITE_10 0x2a
597#define POSITION_TO_ELEMENT 0x2b
598#define SYNCHRONIZE_CACHE 0x35
1c8b7a9a 599#define READ_DEFECT_DATA_10 0x37
984263bc
MD
600#define WRITE_BUFFER 0x3b
601#define READ_BUFFER 0x3c
602#define CHANGE_DEFINITION 0x40
e0fb398b 603#define TRIM 0x42
f46fe720
PA
604#define LOG_SELECT 0x4c
605#define LOG_SENSE 0x4d
984263bc 606#define MODE_SELECT_10 0x55
1c8b7a9a
PA
607#define MODE_SENSE_10 0x5a
608#define ATA_PASS_16 0x85
bdd58e03
MD
609#define READ_16 0x88
610#define WRITE_16 0x8a
0b0362e1 611#define READ_CAPACITY_16 0x9e
bdd58e03 612#define SERVICE_ACTION_IN 0x9e
3026f14f 613#define REPORT_LUNS 0xa0
1c8b7a9a 614#define ATA_PASS_12 0xa1
984263bc
MD
615#define MOVE_MEDIUM 0xa5
616#define READ_12 0xa8
617#define WRITE_12 0xaa
618#define READ_ELEMENT_STATUS 0xb8
619
984263bc
MD
620/*
621 * Device Types
622 */
3a33d431
PA
623#define T_DIRECT 0x00
624#define T_SEQUENTIAL 0x01
625#define T_PRINTER 0x02
626#define T_PROCESSOR 0x03
627#define T_WORM 0x04
628#define T_CDROM 0x05
629#define T_SCANNER 0x06
630#define T_OPTICAL 0x07
631#define T_CHANGER 0x08
632#define T_COMM 0x09
633#define T_ASC0 0x0a
634#define T_ASC1 0x0b
984263bc
MD
635#define T_STORARRAY 0x0c
636#define T_ENCLOSURE 0x0d
637#define T_RBC 0x0e
638#define T_OCRW 0x0f
3a33d431
PA
639#define T_OSD 0x11
640#define T_ADC 0x12
641#define T_NODEVICE 0x1f
642#define T_ANY 0xff /* Used in Quirk table matches */
984263bc
MD
643
644#define T_REMOV 1
645#define T_FIXED 0
646
647/*
648 * This length is the initial inquiry length used by the probe code, as
649 * well as the legnth necessary for scsi_print_inquiry() to function
650 * correctly. If either use requires a different length in the future,
651 * the two values should be de-coupled.
652 */
653#define SHORT_INQUIRY_LENGTH 36
654
655struct scsi_inquiry_data
656{
657 u_int8_t device;
658#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f)
659#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5)
b05e84c9
PA
660#define SID_QUAL_LU_CONNECTED 0x00 /*
661 * The specified peripheral device
984263bc
MD
662 * type is currently connected to
663 * logical unit. If the target cannot
664 * determine whether or not a physical
665 * device is currently connected, it
666 * shall also use this peripheral
667 * qualifier when returning the INQUIRY
668 * data. This peripheral qualifier
669 * does not mean that the device is
670 * ready for access by the initiator.
671 */
b05e84c9
PA
672#define SID_QUAL_LU_OFFLINE 0x01 /*
673 * The target is capable of supporting
984263bc
MD
674 * the specified peripheral device type
675 * on this logical unit; however, the
676 * physical device is not currently
677 * connected to this logical unit.
678 */
679#define SID_QUAL_RSVD 0x02
b05e84c9
PA
680#define SID_QUAL_BAD_LU 0x03 /*
681 * The target is not capable of
984263bc
MD
682 * supporting a physical device on
683 * this logical unit. For this
684 * peripheral qualifier the peripheral
685 * device type shall be set to 1Fh to
686 * provide compatibility with previous
687 * versions of SCSI. All other
688 * peripheral device type values are
689 * reserved for this peripheral
690 * qualifier.
691 */
692#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0)
693 u_int8_t dev_qual2;
694#define SID_QUAL2 0x7F
695#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0)
696 u_int8_t version;
697#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07)
698#define SCSI_REV_0 0
699#define SCSI_REV_CCS 1
700#define SCSI_REV_2 2
b05e84c9 701#define SCSI_REV_SPC 3
984263bc 702#define SCSI_REV_SPC2 4
0b0362e1 703#define SCSI_REV_SPC3 5
984263bc
MD
704
705#define SID_ECMA 0x38
706#define SID_ISO 0xC0
707 u_int8_t response_format;
708#define SID_AENC 0x80
709#define SID_TrmIOP 0x40
710 u_int8_t additional_length;
1c8b7a9a
PA
711#define SID_ADDITIONAL_LENGTH(iqd) \
712 ((iqd)->additional_length + \
713 offsetof(struct scsi_inquiry_data, additional_length) + 1)
9d4fe89a
PA
714 u_int8_t reserved;
715 u_int8_t spc2_flags;
716#define SPC2_SID_MChngr 0x08
717#define SPC2_SID_MultiP 0x10
718#define SPC2_SID_EncServ 0x40
719#define SPC2_SID_BQueue 0x80
720
721#define INQ_DATA_TQ_ENABLED(iqd) \
722 ((SID_ANSI_REV(iqd) < SCSI_REV_SPC2)? ((iqd)->flags & SID_CmdQue) : \
723 (((iqd)->flags & SID_CmdQue) && !((iqd)->spc2_flags & SPC2_SID_BQueue)) || \
724 (!((iqd)->flags & SID_CmdQue) && ((iqd)->spc2_flags & SPC2_SID_BQueue)))
725
726
984263bc
MD
727 u_int8_t flags;
728#define SID_SftRe 0x01
729#define SID_CmdQue 0x02
730#define SID_Linked 0x08
731#define SID_Sync 0x10
732#define SID_WBus16 0x20
733#define SID_WBus32 0x40
734#define SID_RelAdr 0x80
735#define SID_VENDOR_SIZE 8
736 char vendor[SID_VENDOR_SIZE];
737#define SID_PRODUCT_SIZE 16
738 char product[SID_PRODUCT_SIZE];
739#define SID_REVISION_SIZE 4
740 char revision[SID_REVISION_SIZE];
741 /*
742 * The following fields were taken from SCSI Primary Commands - 2
743 * (SPC-2) Revision 14, Dated 11 November 1999
744 */
745#define SID_VENDOR_SPECIFIC_0_SIZE 20
746 u_int8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE];
747 /*
748 * An extension of SCSI Parallel Specific Values
749 */
750#define SID_SPI_IUS 0x01
751#define SID_SPI_QAS 0x02
752#define SID_SPI_CLOCK_ST 0x00
753#define SID_SPI_CLOCK_DT 0x04
754#define SID_SPI_CLOCK_DT_ST 0x0C
b05e84c9 755#define SID_SPI_MASK 0x0F
984263bc
MD
756 u_int8_t spi3data;
757 u_int8_t reserved2;
758 /*
759 * Version Descriptors, stored 2 byte values.
760 */
761 u_int8_t version1[2];
762 u_int8_t version2[2];
763 u_int8_t version3[2];
764 u_int8_t version4[2];
765 u_int8_t version5[2];
766 u_int8_t version6[2];
767 u_int8_t version7[2];
768 u_int8_t version8[2];
769
770 u_int8_t reserved3[22];
771
772#define SID_VENDOR_SPECIFIC_1_SIZE 160
773 u_int8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE];
774};
775
1c8b7a9a
PA
776struct scsi_vpd_supported_page_list
777{
778 u_int8_t device;
779 u_int8_t page_code;
780#define SVPD_SUPPORTED_PAGE_LIST 0x00
781 u_int8_t reserved;
782 u_int8_t length; /* number of VPD entries */
783#define SVPD_SUPPORTED_PAGES_SIZE 251
784 u_int8_t list[SVPD_SUPPORTED_PAGES_SIZE];
785};
786
984263bc
MD
787struct scsi_vpd_unit_serial_number
788{
789 u_int8_t device;
790 u_int8_t page_code;
791#define SVPD_UNIT_SERIAL_NUMBER 0x80
792 u_int8_t reserved;
793 u_int8_t length; /* serial number length */
794#define SVPD_SERIAL_NUM_SIZE 251
795 u_int8_t serial_num[SVPD_SERIAL_NUM_SIZE];
796};
797
0b0362e1
MD
798struct scsi_vpd_unit_devid
799{
800 u_int8_t device;
801 u_int8_t page_code;
802#define SVPD_UNIT_DEVID 0x83
803 u_int8_t reserved;
804 u_int8_t length;
805 /* extended by variable array of scsi_vpd_devid_hdr */
806};
807
808struct scsi_vpd_devid_hdr {
809 u_int8_t pi_code;
810#define VPD_DEVID_PI(_f) (((_f) >> 4) & 0xf0)
811#define VPD_DEVID_CODE(_f) (((_f) >> 0) & 0x0f)
812#define VPD_DEVID_CODE_BINARY 0x1
813#define VPD_DEVID_CODE_ASCII 0x2
814#define VPD_DEVID_CODE_UTF8 0x3
815 u_int8_t flags;
816#define VPD_DEVID_PIV 0x80
817#define VPD_DEVID_ASSOC(_f) ((_f) & 0x30)
818#define VPD_DEVID_ASSOC_LU 0x00
819#define VPD_DEVID_ASSOC_PORT 0x10
820#define VPD_DEVID_ASSOC_TARG 0x20
821#define VPD_DEVID_TYPE(_f) ((_f) & 0x0f)
822#define VPD_DEVID_TYPE_VENDOR 0x0
823#define VPD_DEVID_TYPE_T10 0x1
824#define VPD_DEVID_TYPE_EUI64 0x2
825#define VPD_DEVID_TYPE_NAA 0x3
826#define VPD_DEVID_TYPE_RELATIVE 0x4
827#define VPD_DEVID_TYPE_PORT 0x5
828#define VPD_DEVID_TYPE_LU 0x6
829#define VPD_DEVID_TYPE_MD5 0x7
830#define VPD_DEVID_TYPE_NAME 0x8
831 u_int8_t reserved;
832 u_int8_t len;
833};
834
984263bc
MD
835struct scsi_read_capacity
836{
837 u_int8_t opcode;
838 u_int8_t byte2;
839 u_int8_t addr[4];
840 u_int8_t unused[3];
841 u_int8_t control;
842};
843
bdd58e03
MD
844struct scsi_read_capacity_16
845{
846 uint8_t opcode;
847#define SRC16_SERVICE_ACTION 0x10
848 uint8_t service_action;
849 uint8_t addr[8];
850 uint8_t alloc_len[4];
851#define SRC16_PMI 0x01
852#define SRC16_RELADR 0x02
853 uint8_t reladr;
854 uint8_t control;
855};
856
984263bc
MD
857struct scsi_read_capacity_data
858{
859 u_int8_t addr[4];
860 u_int8_t length[4];
861};
862
0b0362e1 863struct scsi_read_capacity_data_16
bdd58e03
MD
864{
865 uint8_t addr[8];
866 uint8_t length[4];
0b0362e1
MD
867 u_int8_t p_type_prot;
868 u_int8_t logical_per_phys;
869 u_int8_t lowest_aligned[2];
870 u_int8_t reserved[16];
bdd58e03
MD
871};
872
3026f14f
PA
873struct scsi_report_luns
874{
d4226324
PA
875 uint8_t opcode;
876 uint8_t reserved1;
877#define RPL_REPORT_DEFAULT 0x00
878#define RPL_REPORT_WELLKNOWN 0x01
879#define RPL_REPORT_ALL 0x02
880 uint8_t select_report;
881 uint8_t reserved2[3];
882 uint8_t length[4];
883 uint8_t reserved3;
884 uint8_t control;
3026f14f
PA
885};
886
887struct scsi_report_luns_data {
888 u_int8_t length[4]; /* length of LUN inventory, in bytes */
889 u_int8_t reserved[4]; /* unused */
890 /*
891 * LUN inventory- we only support the type zero form for now.
892 */
893 struct {
894 u_int8_t lundata[8];
d4226324 895 } luns[0];
3026f14f 896};
d4226324
PA
897#define RPL_LUNDATA_PERIPH_BUS_MASK 0x3f
898#define RPL_LUNDATA_FLAT_LUN_MASK 0x3f
899#define RPL_LUNDATA_LUN_TARG_MASK 0x3f
900#define RPL_LUNDATA_LUN_BUS_MASK 0xe0
901#define RPL_LUNDATA_LUN_LUN_MASK 0x1f
902#define RPL_LUNDATA_EXT_LEN_MASK 0x30
903#define RPL_LUNDATA_EXT_EAM_MASK 0x0f
904#define RPL_LUNDATA_EXT_EAM_WK 0x01
905#define RPL_LUNDATA_EXT_EAM_NOT_SPEC 0x0f
3026f14f 906#define RPL_LUNDATA_ATYP_MASK 0xc0 /* MBZ for type 0 lun */
d4226324
PA
907#define RPL_LUNDATA_ATYP_PERIPH 0x00
908#define RPL_LUNDATA_ATYP_FLAT 0x40
909#define RPL_LUNDATA_ATYP_LUN 0x80
910#define RPL_LUNDATA_ATYP_EXTLUN 0xc0
3026f14f 911
984263bc
MD
912struct scsi_sense_data
913{
914 u_int8_t error_code;
915#define SSD_ERRCODE 0x7F
916#define SSD_CURRENT_ERROR 0x70
917#define SSD_DEFERRED_ERROR 0x71
918#define SSD_ERRCODE_VALID 0x80
919 u_int8_t segment;
920 u_int8_t flags;
921#define SSD_KEY 0x0F
922#define SSD_KEY_NO_SENSE 0x00
923#define SSD_KEY_RECOVERED_ERROR 0x01
924#define SSD_KEY_NOT_READY 0x02
925#define SSD_KEY_MEDIUM_ERROR 0x03
926#define SSD_KEY_HARDWARE_ERROR 0x04
927#define SSD_KEY_ILLEGAL_REQUEST 0x05
928#define SSD_KEY_UNIT_ATTENTION 0x06
929#define SSD_KEY_DATA_PROTECT 0x07
930#define SSD_KEY_BLANK_CHECK 0x08
931#define SSD_KEY_Vendor_Specific 0x09
932#define SSD_KEY_COPY_ABORTED 0x0a
933#define SSD_KEY_ABORTED_COMMAND 0x0b
934#define SSD_KEY_EQUAL 0x0c
935#define SSD_KEY_VOLUME_OVERFLOW 0x0d
936#define SSD_KEY_MISCOMPARE 0x0e
937#define SSD_KEY_RESERVED 0x0f
938#define SSD_ILI 0x20
939#define SSD_EOM 0x40
940#define SSD_FILEMARK 0x80
941 u_int8_t info[4];
942 u_int8_t extra_len;
943 u_int8_t cmd_spec_info[4];
944 u_int8_t add_sense_code;
945 u_int8_t add_sense_code_qual;
946 u_int8_t fru;
947 u_int8_t sense_key_spec[3];
948#define SSD_SCS_VALID 0x80
949#define SSD_FIELDPTR_CMD 0x40
950#define SSD_BITPTR_VALID 0x08
951#define SSD_BITPTR_VALUE 0x07
952#define SSD_MIN_SIZE 18
953 u_int8_t extra_bytes[14];
954#define SSD_FULL_SIZE sizeof(struct scsi_sense_data)
955};
956
957struct scsi_mode_header_6
958{
959 u_int8_t data_length; /* Sense data length */
960 u_int8_t medium_type;
961 u_int8_t dev_spec;
962 u_int8_t blk_desc_len;
963};
964
965struct scsi_mode_header_10
966{
967 u_int8_t data_length[2];/* Sense data length */
968 u_int8_t medium_type;
969 u_int8_t dev_spec;
970 u_int8_t unused[2];
971 u_int8_t blk_desc_len[2];
972};
973
974struct scsi_mode_page_header
975{
976 u_int8_t page_code;
977 u_int8_t page_length;
978};
979
980struct scsi_mode_blk_desc
981{
982 u_int8_t density;
983 u_int8_t nblocks[3];
984 u_int8_t reserved;
985 u_int8_t blklen[3];
986};
987
988#define SCSI_DEFAULT_DENSITY 0x00 /* use 'default' density */
989#define SCSI_SAME_DENSITY 0x7f /* use 'same' density- >= SCSI-2 only */
3026f14f
PA
990
991
984263bc
MD
992/*
993 * Status Byte
994 */
995#define SCSI_STATUS_OK 0x00
996#define SCSI_STATUS_CHECK_COND 0x02
997#define SCSI_STATUS_COND_MET 0x04
998#define SCSI_STATUS_BUSY 0x08
999#define SCSI_STATUS_INTERMED 0x10
1000#define SCSI_STATUS_INTERMED_COND_MET 0x14
1001#define SCSI_STATUS_RESERV_CONFLICT 0x18
b05e84c9 1002#define SCSI_STATUS_CMD_TERMINATED 0x22 /* Obsolete in SAM-2 */
984263bc 1003#define SCSI_STATUS_QUEUE_FULL 0x28
b05e84c9
PA
1004#define SCSI_STATUS_ACA_ACTIVE 0x30
1005#define SCSI_STATUS_TASK_ABORTED 0x40
984263bc
MD
1006
1007struct scsi_inquiry_pattern {
1008 u_int8_t type;
1009 u_int8_t media_type;
1010#define SIP_MEDIA_REMOVABLE 0x01
1011#define SIP_MEDIA_FIXED 0x02
1012 const char *vendor;
1013 const char *product;
1014 const char *revision;
1015};
1016
1017struct scsi_static_inquiry_pattern {
1018 u_int8_t type;
1019 u_int8_t media_type;
1020 char vendor[SID_VENDOR_SIZE+1];
1021 char product[SID_PRODUCT_SIZE+1];
1022 char revision[SID_REVISION_SIZE+1];
1023};
1024
1025struct scsi_sense_quirk_entry {
1026 struct scsi_inquiry_pattern inq_pat;
b05e84c9 1027 int num_sense_keys;
984263bc 1028 int num_ascs;
b05e84c9 1029 struct sense_key_table_entry *sense_key_info;
984263bc
MD
1030 struct asc_table_entry *asc_info;
1031};
1032
b05e84c9
PA
1033struct sense_key_table_entry {
1034 u_int8_t sense_key;
1035 u_int32_t action;
1036 const char *desc;
1037};
1038
984263bc
MD
1039struct asc_table_entry {
1040 u_int8_t asc;
1041 u_int8_t ascq;
1042 u_int32_t action;
984263bc 1043 const char *desc;
984263bc
MD
1044};
1045
1046struct op_table_entry {
1047 u_int8_t opcode;
3a33d431 1048 u_int32_t opmask;
984263bc
MD
1049 const char *desc;
1050};
1051
1052struct scsi_op_quirk_entry {
1053 struct scsi_inquiry_pattern inq_pat;
1054 int num_ops;
1055 struct op_table_entry *op_table;
1056};
1057
b05e84c9
PA
1058typedef enum {
1059 SSS_FLAG_NONE = 0x00,
1060 SSS_FLAG_PRINT_COMMAND = 0x01
1061} scsi_sense_string_flags;
984263bc 1062
0b0362e1
MD
1063typedef union scsi_cdb {
1064 struct scsi_generic generic;
1065 struct scsi_sense sense;
1066 struct scsi_test_unit_ready test_unit_ready;
1067 struct scsi_send_diag send_diag;
1068 struct scsi_inquiry inquiry;
1069 struct scsi_mode_sense_6 mode_sense_6;
1070 struct scsi_mode_sense_10 mode_sense_10;
1071 struct scsi_mode_select_6 mode_select_6;
1072 struct scsi_mode_select_10 mode_select_10;
1073 struct scsi_log_sense log_sense;
1074 struct scsi_log_select log_select;
1075 struct scsi_reserve reserve;
1076 struct scsi_release release;
1077 struct scsi_prevent prevent;
1078 struct scsi_sync_cache sync_cache;
1079 struct scsi_changedef changedef;
1080 struct scsi_read_buffer read_buffer;
1081 struct scsi_write_buffer write_buffer;
1082 struct scsi_rw_6 rw_6;
1083 struct scsi_rw_10 rw_10;
1084 struct scsi_rw_12 rw_12;
1085 struct scsi_rw_16 rw_16;
1086 struct scsi_start_stop_unit start_stop_unit;
1087 struct ata_pass_12 ata_pass_12;
1088 struct ata_pass_16 ata_pass_16;
1089 struct scsi_read_capacity read_capacity;
1090 struct scsi_read_capacity_16 read_capacity_16;
1091 struct scsi_report_luns report_luns;
1092} *scsi_cdb_t;
1093
1094typedef union scsi_data {
1095 struct scsi_mode_hdr_6 mode_hdr_6;
1096 struct scsi_mode_hdr_10 mode_hdr_10;
1097 struct scsi_mode_block_descr mode_block_descr;
1098 struct scsi_log_header log_header;
1099 struct scsi_log_param_header log_param_header;
1100 struct scsi_control_page control_page;
1101 struct scsi_cache_page cache_page;
1102 struct scsi_info_exceptions_page info_exceptions_page;
1103 struct scsi_proto_specific_page proto_specific_page;
1104 struct scsi_inquiry_data inquiry_data;
1105 struct scsi_vpd_supported_page_list vpd_supported_page_list;
1106 struct scsi_vpd_unit_serial_number vpd_unit_serial_number;
1107 struct scsi_vpd_unit_devid vpd_unit_devid;
1108 struct scsi_read_capacity_data read_capacity_data;
1109 struct scsi_read_capacity_data_16 read_capacity_data_16;
1110 struct scsi_report_luns_data report_luns_data;
1111 struct scsi_sense_data sense_data;
1112 struct scsi_mode_header_6 mode_header_6;
1113 struct scsi_mode_header_10 mode_header_10;
1114 struct scsi_mode_page_header mode_page_header;
1115 struct scsi_mode_blk_desc mode_blk_desc;
1116 struct scsi_inquiry_pattern inquiry_pattern;
1117 struct scsi_static_inquiry_pattern static_inquiry_pattern;
1118} *scsi_data_t;
1119
984263bc
MD
1120struct ccb_scsiio;
1121struct cam_periph;
1122union ccb;
1123#ifndef _KERNEL
1124struct cam_device;
1125#endif
1126
1127extern const char *scsi_sense_key_text[];
1128
b05e84c9
PA
1129struct sbuf;
1130
984263bc 1131__BEGIN_DECLS
b05e84c9
PA
1132void scsi_sense_desc(int sense_key, int asc, int ascq,
1133 struct scsi_inquiry_data *inq_data,
1134 const char **sense_key_desc, const char **asc_desc);
1135scsi_sense_action scsi_error_action(struct ccb_scsiio* csio,
1136 struct scsi_inquiry_data *inq_data,
1137 u_int32_t sense_flags);
1138const char * scsi_status_string(struct ccb_scsiio *csio);
984263bc 1139#ifdef _KERNEL
b05e84c9
PA
1140int scsi_command_string(struct ccb_scsiio *csio, struct sbuf *sb);
1141int scsi_sense_sbuf(struct ccb_scsiio *csio, struct sbuf *sb,
1142 scsi_sense_string_flags flags);
1143char * scsi_sense_string(struct ccb_scsiio *csio,
1144 char *str, int str_len);
984263bc
MD
1145void scsi_sense_print(struct ccb_scsiio *csio);
1146int scsi_interpret_sense(union ccb *ccb,
1147 u_int32_t sense_flags,
1148 u_int32_t *relsim_flags,
1149 u_int32_t *reduction,
1150 u_int32_t *timeout,
1151 scsi_sense_action error_action);
1152#else
b05e84c9
PA
1153int scsi_command_string(struct cam_device *device,
1154 struct ccb_scsiio *csio, struct sbuf *sb);
1155int scsi_sense_sbuf(struct cam_device *device,
1156 struct ccb_scsiio *csio, struct sbuf *sb,
1157 scsi_sense_string_flags flags);
984263bc
MD
1158char * scsi_sense_string(struct cam_device *device,
1159 struct ccb_scsiio *csio,
1160 char *str, int str_len);
1161void scsi_sense_print(struct cam_device *device,
1162 struct ccb_scsiio *csio, FILE *ofile);
1163int scsi_interpret_sense(struct cam_device *device,
1164 union ccb *ccb,
1165 u_int32_t sense_flags,
1166 u_int32_t *relsim_flags,
1167 u_int32_t *reduction,
1168 u_int32_t *timeout,
1169 scsi_sense_action error_action);
1170#endif /* _KERNEL */
1171
1172#define SF_RETRY_UA 0x01
1173#define SF_NO_PRINT 0x02
1174#define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */
1175#define SF_PRINT_ALWAYS 0x08
984263bc
MD
1176
1177
1178const char * scsi_op_desc(u_int16_t opcode,
1179 struct scsi_inquiry_data *inq_data);
1180char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
1181 size_t len);
1182
1183void scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
1184
1185u_int scsi_calc_syncsrate(u_int period_factor);
1186u_int scsi_calc_syncparam(u_int period);
1187
1188void scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
1189 void (*cbfcnp)(struct cam_periph *,
1190 union ccb *),
1191 u_int8_t tag_action,
1192 u_int8_t sense_len, u_int32_t timeout);
1193
1194void scsi_request_sense(struct ccb_scsiio *csio, u_int32_t retries,
1195 void (*cbfcnp)(struct cam_periph *,
1196 union ccb *),
1197 void *data_ptr, u_int8_t dxfer_len,
1198 u_int8_t tag_action, u_int8_t sense_len,
1199 u_int32_t timeout);
1200
6f540908 1201#ifndef CAM_NO_SCSI_INQUIRY /* hack for cdparanoia */
984263bc
MD
1202void scsi_inquiry(struct ccb_scsiio *csio, u_int32_t retries,
1203 void (*cbfcnp)(struct cam_periph *, union ccb *),
1204 u_int8_t tag_action, u_int8_t *inq_buf,
1205 u_int32_t inq_len, int evpd, u_int8_t page_code,
1206 u_int8_t sense_len, u_int32_t timeout);
6f540908 1207#endif
984263bc
MD
1208
1209void scsi_mode_sense(struct ccb_scsiio *csio, u_int32_t retries,
1210 void (*cbfcnp)(struct cam_periph *,
1211 union ccb *),
1212 u_int8_t tag_action, int dbd,
1213 u_int8_t page_code, u_int8_t page,
1214 u_int8_t *param_buf, u_int32_t param_len,
1215 u_int8_t sense_len, u_int32_t timeout);
62ade751
MD
1216void scsi_mode_sense_len(struct ccb_scsiio *csio, u_int32_t retries,
1217 void (*cbfcnp)(struct cam_periph *,
1218 union ccb *),
1219 u_int8_t tag_action, int dbd,
1220 u_int8_t page_code, u_int8_t page,
1221 u_int8_t *param_buf, u_int32_t param_len,
1222 int minimum_cmd_size, u_int8_t sense_len,
1223 u_int32_t timeout);
984263bc
MD
1224
1225void scsi_mode_select(struct ccb_scsiio *csio, u_int32_t retries,
1226 void (*cbfcnp)(struct cam_periph *,
1227 union ccb *),
1228 u_int8_t tag_action, int scsi_page_fmt,
1229 int save_pages, u_int8_t *param_buf,
1230 u_int32_t param_len, u_int8_t sense_len,
1231 u_int32_t timeout);
1232
62ade751
MD
1233void scsi_mode_select_len(struct ccb_scsiio *csio, u_int32_t retries,
1234 void (*cbfcnp)(struct cam_periph *,
1235 union ccb *),
1236 u_int8_t tag_action, int scsi_page_fmt,
1237 int save_pages, u_int8_t *param_buf,
1238 u_int32_t param_len, int minimum_cmd_size,
1239 u_int8_t sense_len, u_int32_t timeout);
1240
f46fe720
PA
1241void scsi_log_sense(struct ccb_scsiio *csio, u_int32_t retries,
1242 void (*cbfcnp)(struct cam_periph *, union ccb *),
1243 u_int8_t tag_action, u_int8_t page_code,
1244 u_int8_t page, int save_pages, int ppc,
1245 u_int32_t paramptr, u_int8_t *param_buf,
1246 u_int32_t param_len, u_int8_t sense_len,
1247 u_int32_t timeout);
1248
1249void scsi_log_select(struct ccb_scsiio *csio, u_int32_t retries,
1250 void (*cbfcnp)(struct cam_periph *,
1251 union ccb *), u_int8_t tag_action,
1252 u_int8_t page_code, int save_pages,
1253 int pc_reset, u_int8_t *param_buf,
1254 u_int32_t param_len, u_int8_t sense_len,
1255 u_int32_t timeout);
1256
3026f14f
PA
1257void scsi_prevent(struct ccb_scsiio *csio, u_int32_t retries,
1258 void (*cbfcnp)(struct cam_periph *, union ccb *),
1259 u_int8_t tag_action, u_int8_t action,
1260 u_int8_t sense_len, u_int32_t timeout);
1261
984263bc
MD
1262void scsi_read_capacity(struct ccb_scsiio *csio, u_int32_t retries,
1263 void (*cbfcnp)(struct cam_periph *,
1264 union ccb *), u_int8_t tag_action,
3026f14f 1265 struct scsi_read_capacity_data *,
984263bc 1266 u_int8_t sense_len, u_int32_t timeout);
bdd58e03
MD
1267void scsi_read_capacity_16(struct ccb_scsiio *csio, uint32_t retries,
1268 void (*cbfcnp)(struct cam_periph *,
1269 union ccb *), uint8_t tag_action,
1270 uint64_t lba, int reladr, int pmi,
0b0362e1 1271 struct scsi_read_capacity_data_16
bdd58e03
MD
1272 *rcap_buf, uint8_t sense_len,
1273 uint32_t timeout);
984263bc 1274
3026f14f 1275void scsi_report_luns(struct ccb_scsiio *csio, u_int32_t retries,
d4226324
PA
1276 void (*cbfcnp)(struct cam_periph *,
1277 union ccb *), u_int8_t tag_action,
1278 u_int8_t select_report,
1279 struct scsi_report_luns_data *rpl_buf,
1280 u_int32_t alloc_len, u_int8_t sense_len,
1281 u_int32_t timeout);
984263bc
MD
1282
1283void scsi_synchronize_cache(struct ccb_scsiio *csio,
1284 u_int32_t retries,
1285 void (*cbfcnp)(struct cam_periph *,
1286 union ccb *), u_int8_t tag_action,
1287 u_int32_t begin_lba, u_int16_t lb_count,
1288 u_int8_t sense_len, u_int32_t timeout);
1289
1290void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
1291 void (*cbfcnp)(struct cam_periph *, union ccb *),
1292 u_int8_t tag_action, int readop, u_int8_t byte2,
e0fc5693 1293 int minimum_cmd_size, u_int64_t lba,
984263bc
MD
1294 u_int32_t block_count, u_int8_t *data_ptr,
1295 u_int32_t dxfer_len, u_int8_t sense_len,
1296 u_int32_t timeout);
1297
1298void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
1299 void (*cbfcnp)(struct cam_periph *, union ccb *),
1300 u_int8_t tag_action, int start, int load_eject,
1301 int immediate, u_int8_t sense_len, u_int32_t timeout);
1302
1303int scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry);
1304int scsi_static_inquiry_match(caddr_t inqbuffer,
1305 caddr_t table_entry);
1306
1307static __inline void scsi_extract_sense(struct scsi_sense_data *sense,
1308 int *error_code, int *sense_key,
1309 int *asc, int *ascq);
1310static __inline void scsi_ulto2b(u_int32_t val, u_int8_t *bytes);
1311static __inline void scsi_ulto3b(u_int32_t val, u_int8_t *bytes);
1312static __inline void scsi_ulto4b(u_int32_t val, u_int8_t *bytes);
bdd58e03 1313static __inline void scsi_u64to8b(u_int64_t val, u_int8_t *bytes);
984263bc
MD
1314static __inline u_int32_t scsi_2btoul(u_int8_t *bytes);
1315static __inline u_int32_t scsi_3btoul(u_int8_t *bytes);
1316static __inline int32_t scsi_3btol(u_int8_t *bytes);
1317static __inline u_int32_t scsi_4btoul(u_int8_t *bytes);
bdd58e03 1318static __inline u_int64_t scsi_8btou64(u_int8_t *bytes);
984263bc
MD
1319static __inline void *find_mode_page_6(struct scsi_mode_header_6 *mode_header);
1320static __inline void *find_mode_page_10(struct scsi_mode_header_10 *mode_header);
1321
0e224b5d
SW
1322static __inline void
1323scsi_extract_sense(struct scsi_sense_data *sense, int *error_code,
1324 int *sense_key, int *asc, int *ascq)
984263bc
MD
1325{
1326 *error_code = sense->error_code & SSD_ERRCODE;
1327 *sense_key = sense->flags & SSD_KEY;
1328 *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0;
1329 *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0;
1330}
1331
1332static __inline void
1333scsi_ulto2b(u_int32_t val, u_int8_t *bytes)
1334{
1335
1336 bytes[0] = (val >> 8) & 0xff;
1337 bytes[1] = val & 0xff;
1338}
1339
1340static __inline void
1341scsi_ulto3b(u_int32_t val, u_int8_t *bytes)
1342{
1343
1344 bytes[0] = (val >> 16) & 0xff;
1345 bytes[1] = (val >> 8) & 0xff;
1346 bytes[2] = val & 0xff;
1347}
1348
1349static __inline void
1350scsi_ulto4b(u_int32_t val, u_int8_t *bytes)
1351{
1352
1353 bytes[0] = (val >> 24) & 0xff;
1354 bytes[1] = (val >> 16) & 0xff;
1355 bytes[2] = (val >> 8) & 0xff;
1356 bytes[3] = val & 0xff;
1357}
1358
bdd58e03
MD
1359static __inline void
1360scsi_u64to8b(u_int64_t val, u_int8_t *bytes)
1361{
1362 bytes[0] = (val >> 56) & 0xff;
1363 bytes[1] = (val >> 48) & 0xff;
1364 bytes[2] = (val >> 40) & 0xff;
1365 bytes[3] = (val >> 32) & 0xff;
1366 bytes[4] = (val >> 24) & 0xff;
1367 bytes[5] = (val >> 16) & 0xff;
1368 bytes[6] = (val >> 8) & 0xff;
1369 bytes[7] = val & 0xff;
1370}
1371
984263bc
MD
1372static __inline u_int32_t
1373scsi_2btoul(u_int8_t *bytes)
1374{
1375 u_int32_t rv;
1376
1377 rv = (bytes[0] << 8) |
1378 bytes[1];
1379 return (rv);
1380}
1381
bdd58e03
MD
1382static __inline uint64_t
1383scsi_8btou64(uint8_t *bytes)
1384{
1385 uint64_t rv;
1386
1387 rv = (((uint64_t)bytes[0]) << 56) |
1388 (((uint64_t)bytes[1]) << 48) |
1389 (((uint64_t)bytes[2]) << 40) |
1390 (((uint64_t)bytes[3]) << 32) |
1391 (((uint64_t)bytes[4]) << 24) |
1392 (((uint64_t)bytes[5]) << 16) |
1393 (((uint64_t)bytes[6]) << 8) |
1394 bytes[7];
1395 return (rv);
1396}
1397
984263bc
MD
1398static __inline u_int32_t
1399scsi_3btoul(u_int8_t *bytes)
1400{
1401 u_int32_t rv;
1402
1403 rv = (bytes[0] << 16) |
1404 (bytes[1] << 8) |
1405 bytes[2];
1406 return (rv);
1407}
1408
1409static __inline int32_t
1410scsi_3btol(u_int8_t *bytes)
1411{
1412 u_int32_t rc = scsi_3btoul(bytes);
1413
1414 if (rc & 0x00800000)
1415 rc |= 0xff000000;
1416
1417 return (int32_t) rc;
1418}
1419
1420static __inline u_int32_t
1421scsi_4btoul(u_int8_t *bytes)
1422{
1423 u_int32_t rv;
1424
1425 rv = (bytes[0] << 24) |
1426 (bytes[1] << 16) |
1427 (bytes[2] << 8) |
1428 bytes[3];
1429 return (rv);
1430}
1431
1432/*
1433 * Given the pointer to a returned mode sense buffer, return a pointer to
1434 * the start of the first mode page.
1435 */
1436static __inline void *
1437find_mode_page_6(struct scsi_mode_header_6 *mode_header)
1438{
1439 void *page_start;
1440
1441 page_start = (void *)((u_int8_t *)&mode_header[1] +
1442 mode_header->blk_desc_len);
1443
1444 return(page_start);
1445}
1446
1447static __inline void *
1448find_mode_page_10(struct scsi_mode_header_10 *mode_header)
1449{
1450 void *page_start;
1451
1452 page_start = (void *)((u_int8_t *)&mode_header[1] +
1453 scsi_2btoul(mode_header->blk_desc_len));
1454
1455 return(page_start);
1456}
1457
1458__END_DECLS
1459
1460#endif /*_SCSI_SCSI_ALL_H*/