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