xref: /dragonfly/sys/bus/cam/scsi/scsi_sa.h (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1 /*
2  * Structure and function declarations for the
3  * SCSI Sequential Access Peripheral driver for CAM.
4  *
5  * Copyright (c) 1999, 2000 Matthew Jacob
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions, and the following disclaimer,
13  *    without modification, immediately at the beginning of the file.
14  * 2. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD: src/sys/cam/scsi/scsi_sa.h,v 1.6.2.2 2001/01/12 02:50:39 steve Exp $
30  * $DragonFly: src/sys/bus/cam/scsi/scsi_sa.h,v 1.2 2003/06/17 04:28:19 dillon Exp $
31  */
32 
33 #ifndef   _SCSI_SCSI_SA_H
34 #define _SCSI_SCSI_SA_H 1
35 
36 #include <sys/cdefs.h>
37 
38 struct scsi_read_block_limits
39 {
40           u_int8_t opcode;
41           u_int8_t byte2;
42           u_int8_t unused[3];
43           u_int8_t control;
44 };
45 
46 struct scsi_read_block_limits_data
47 {
48           u_int8_t gran;
49 #define   RBL_GRAN_MASK       0x1F
50 #define RBL_GRAN(rblim) ((rblim)->gran & RBL_GRAN_MASK)
51           u_int8_t maximum[3];
52           u_int8_t minimum[2];
53 };
54 
55 struct scsi_sa_rw
56 {
57           u_int8_t opcode;
58         u_int8_t sli_fixed;
59 #define SAR_SLI               0x02
60 #define SARW_FIXED  0x01
61           u_int8_t length[3];
62         u_int8_t control;
63 };
64 
65 struct scsi_load_unload
66 {
67           u_int8_t opcode;
68         u_int8_t immediate;
69 #define SLU_IMMED   0x01
70           u_int8_t reserved[2];
71           u_int8_t eot_reten_load;
72 #define SLU_EOT               0x04
73 #define SLU_RETEN   0x02
74 #define SLU_LOAD    0x01
75         u_int8_t control;
76 };
77 
78 struct scsi_rewind
79 {
80           u_int8_t opcode;
81         u_int8_t immediate;
82 #define SREW_IMMED  0x01
83           u_int8_t reserved[3];
84         u_int8_t control;
85 };
86 
87 typedef enum {
88           SS_BLOCKS,
89           SS_FILEMARKS,
90           SS_SEQFILEMARKS,
91           SS_EOD,
92           SS_SETMARKS,
93           SS_SEQSETMARKS
94 } scsi_space_code;
95 
96 struct scsi_space
97 {
98           u_int8_t opcode;
99         u_int8_t code;
100 #define SREW_IMMED  0x01
101           u_int8_t count[3];
102         u_int8_t control;
103 };
104 
105 struct scsi_write_filemarks
106 {
107           u_int8_t opcode;
108         u_int8_t byte2;
109 #define SWFMRK_IMMED          0x01
110 #define SWFMRK_WSMK 0x02
111           u_int8_t num_marks[3];
112         u_int8_t control;
113 };
114 
115 /*
116  * Reserve and release unit have the same exact cdb format, but different
117  * opcodes.
118  */
119 struct scsi_reserve_release_unit
120 {
121           u_int8_t opcode;
122           u_int8_t lun_thirdparty;
123 #define SRRU_LUN_MASK         0xE0
124 #define SRRU_3RD_PARTY        0x10
125 #define SRRU_3RD_SHAMT        1
126 #define SRRU_3RD_MASK         0xE
127           u_int8_t reserved[3];
128           u_int8_t control;
129 };
130 
131 /*
132  * Erase a tape
133  */
134 struct scsi_erase
135 {
136           u_int8_t opcode;
137           u_int8_t lun_imm_long;
138 #define SE_LUN_MASK 0xE0
139 #define SE_LONG               0x1
140 #define SE_IMMED    0x2
141           u_int8_t reserved[3];
142           u_int8_t control;
143 };
144 
145 /*
146  * Dev specific mode page masks.
147  */
148 #define SMH_SA_WP             0x80
149 #define   SMH_SA_BUF_MODE_MASK          0x70
150 #define SMH_SA_BUF_MODE_NOBUF 0x00
151 #define SMH_SA_BUF_MODE_SIBUF 0x10      /* Single-Initiator buffering */
152 #define SMH_SA_BUF_MODE_MIBUF 0x20      /* Multi-Initiator buffering */
153 #define SMH_SA_SPEED_MASK     0x0F
154 #define SMH_SA_SPEED_DEFAULT  0x00
155 
156 /*
157  * Sequential-access specific mode page numbers.
158  */
159 #define SA_DEVICE_CONFIGURATION_PAGE    0x10
160 #define SA_MEDIUM_PARTITION_PAGE_1      0x11
161 #define SA_MEDIUM_PARTITION_PAGE_2      0x12
162 #define SA_MEDIUM_PARTITION_PAGE_3      0x13
163 #define SA_MEDIUM_PARTITION_PAGE_4      0x14
164 #define SA_DATA_COMPRESSION_PAGE        0x0f      /* SCSI-3 */
165 
166 /*
167  * Mode page definitions.
168  */
169 
170 /* See SCSI-II spec 9.3.3.1 */
171 struct scsi_dev_conf_page {
172           u_int8_t pagecode;  /* 0x10 */
173           u_int8_t pagelength;          /* 0x0e */
174           u_int8_t byte2;               /* CAP, CAF, Active Format */
175           u_int8_t active_partition;
176           u_int8_t wb_full_ratio;
177           u_int8_t rb_empty_ratio;
178           u_int8_t wrdelay_time[2];
179           u_int8_t byte8;
180 #define   SA_DBR                        0x80      /* data buffer recovery */
181 #define   SA_BIS                        0x40      /* block identifiers supported */
182 #define   SA_RSMK                       0x20      /* report setmarks */
183 #define   SA_AVC                        0x10      /* automatic velocity control */
184 #define   SA_SOCF_MASK                  0xc0      /* stop on consecutive formats */
185 #define   SA_RBO                        0x20      /* recover buffer order */
186 #define   SA_REW                        0x10      /* report early warning */
187           u_int8_t gap_size;
188           u_int8_t byte10;
189           u_int8_t ew_bufsize[3];
190           u_int8_t sel_comp_alg;
191 #define   SA_COMP_NONE                  0x00
192 #define   SA_COMP_DEFAULT               0x01
193           /* the following is 'reserved' in SCSI-2 but is defined in SSC-r22 */
194           u_int8_t extra_wp;
195 #define   SA_ASOC_WP                    0x04      /* Associated Write Protect */
196 #define   SA_PERS_WP                    0x02      /* Persistent Write Protect */
197 #define   SA_PERM_WP                    0x01      /* Permanent Write Protect */
198 };
199 
200 /* from SCSI-3: SSC-Rev10 (6/97) */
201 struct scsi_data_compression_page {
202           u_int8_t page_code; /* 0x0f */
203           u_int8_t page_length;         /* 0x0e */
204           u_int8_t dce_and_dcc;
205 #define SA_DCP_DCE            0x80      /* Data compression enable */
206 #define SA_DCP_DCC            0x40      /* Data compression capable */
207           u_int8_t dde_and_red;
208 #define SA_DCP_DDE            0x80      /* Data decompression enable */
209 #define SA_DCP_RED_MASK                 0x60      /* Report Exception on Decomp. */
210 #define SA_DCP_RED_SHAMT      5
211 #define SA_DCP_RED_0                    0x00
212 #define SA_DCP_RED_1                    0x20
213 #define SA_DCP_RED_2                    0x40
214           u_int8_t comp_algorithm[4];
215           u_int8_t decomp_algorithm[4];
216           u_int8_t reserved[4];
217 };
218 
219 typedef union {
220           struct { u_int8_t pagecode, pagelength; } hdr;
221           struct scsi_dev_conf_page dconf;
222           struct scsi_data_compression_page dcomp;
223 } sa_comp_t;
224 
225 struct scsi_tape_read_position {
226           u_int8_t opcode;              /* READ_POSITION */
227           u_int8_t byte1;                         /* set LSB to read hardware block pos */
228           u_int8_t reserved[8];
229 };
230 
231 struct scsi_tape_position_data          {         /* Short Form */
232           u_int8_t flags;
233 #define   SA_RPOS_BOP                   0x80      /* Beginning of Partition */
234 #define   SA_RPOS_EOP                   0x40      /* End of Partition */
235 #define   SA_RPOS_BCU                   0x20      /* Block Count Unknown (SCSI3) */
236 #define   SA_RPOS_BYCU                  0x10      /* Byte Count Unknown (SCSI3) */
237 #define   SA_RPOS_BPU                   0x04      /* Block Position Unknown */
238 #define   SA_RPOS_PERR                  0x02      /* Position Error (SCSI3) */
239 #define   SA_RPOS_UNCERTAIN   SA_RPOS_BPU
240           u_int8_t partition;
241           u_int8_t reserved[2];
242           u_int8_t firstblk[4];
243           u_int8_t lastblk[4];
244           u_int8_t reserved2;
245           u_int8_t nbufblk[3];
246           u_int8_t nbufbyte[4];
247 };
248 
249 struct scsi_tape_locate {
250           u_int8_t opcode;
251           u_int8_t byte1;
252 #define   SA_SPOS_IMMED                 0x01
253 #define   SA_SPOS_CP                    0x02
254 #define   SA_SPOS_BT                    0x04
255           u_int8_t reserved1;
256           u_int8_t blkaddr[4];
257           u_int8_t reserved2;
258           u_int8_t partition;
259           u_int8_t control;
260 };
261 
262 /*
263  * Opcodes
264  */
265 #define REWIND                          0x01
266 #define READ_BLOCK_LIMITS     0x05
267 #define SA_READ                         0x08
268 #define SA_WRITE              0x0A
269 #define WRITE_FILEMARKS                 0x10
270 #define SPACE                           0x11
271 #define RESERVE_UNIT                    0x16
272 #define RELEASE_UNIT                    0x17
273 #define ERASE                           0x19
274 #define LOAD_UNLOAD           0x1B
275 #define   LOCATE                        0x2B
276 #define   READ_POSITION                 0x34
277 
278 /*
279  * Tape specific density codes- only enough of them here to recognize
280  * some specific older units so we can choose 2FM@EOD or FIXED blocksize
281  * quirks.
282  */
283 #define SCSI_DENSITY_HALFINCH_800       0x01
284 #define SCSI_DENSITY_HALFINCH_1600      0x02
285 #define SCSI_DENSITY_HALFINCH_6250      0x03
286 #define SCSI_DENSITY_HALFINCH_6250C     0xC3      /* HP Compressed 6250 */
287 #define SCSI_DENSITY_QIC_11_4TRK        0x04
288 #define SCSI_DENSITY_QIC_11_9TRK        0x84      /* Vendor Unique Emulex */
289 #define SCSI_DENSITY_QIC_24             0x05
290 #define SCSI_DENSITY_HALFINCH_PE        0x06
291 #define SCSI_DENSITY_QIC_120            0x0f
292 #define SCSI_DENSITY_QIC_150            0x10
293 #define   SCSI_DENSITY_QIC_525_320      0x11
294 #define   SCSI_DENSITY_QIC_1320                   0x12
295 #define   SCSI_DENSITY_QIC_2GB                    0x22
296 #define   SCSI_DENSITY_QIC_4GB                    0x26
297 #define   SCSI_DENSITY_QIC_3080                   0x29
298 
299 __BEGIN_DECLS
300 void      scsi_read_block_limits(struct ccb_scsiio *, u_int32_t,
301                                      void (*cbfcnp)(struct cam_periph *, union ccb *),
302                                      u_int8_t, struct scsi_read_block_limits_data *,
303                                      u_int8_t , u_int32_t);
304 
305 void      scsi_sa_read_write(struct ccb_scsiio *csio, u_int32_t retries,
306                                  void (*cbfcnp)(struct cam_periph *, union ccb *),
307                                  u_int8_t tag_action, int readop, int sli,
308                                  int fixed, u_int32_t length, u_int8_t *data_ptr,
309                                  u_int32_t dxfer_len, u_int8_t sense_len,
310                                  u_int32_t timeout);
311 
312 void      scsi_rewind(struct ccb_scsiio *csio, u_int32_t retries,
313                         void (*cbfcnp)(struct cam_periph *, union ccb *),
314                         u_int8_t tag_action, int immediate, u_int8_t sense_len,
315                         u_int32_t timeout);
316 
317 void      scsi_space(struct ccb_scsiio *csio, u_int32_t retries,
318                        void (*cbfcnp)(struct cam_periph *, union ccb *),
319                        u_int8_t tag_action, scsi_space_code code,
320                        u_int32_t count, u_int8_t sense_len, u_int32_t timeout);
321 
322 void      scsi_load_unload(struct ccb_scsiio *csio, u_int32_t retries,
323                                void (*cbfcnp)(struct cam_periph *, union ccb *),
324                                u_int8_t tag_action, int immediate,   int eot,
325                                int reten, int load, u_int8_t sense_len,
326                                u_int32_t timeout);
327 
328 void      scsi_write_filemarks(struct ccb_scsiio *csio, u_int32_t retries,
329                                    void (*cbfcnp)(struct cam_periph *, union ccb *),
330                                    u_int8_t tag_action, int immediate, int setmark,
331                                    u_int32_t num_marks, u_int8_t sense_len,
332                                    u_int32_t timeout);
333 
334 void      scsi_reserve_release_unit(struct ccb_scsiio *csio, u_int32_t retries,
335                                           void (*cbfcnp)(struct cam_periph *,
336                                           union ccb *), u_int8_t tag_action,
337                                           int third_party, int third_party_id,
338                                           u_int8_t sense_len, u_int32_t timeout,
339                                           int reserve);
340 
341 void      scsi_erase(struct ccb_scsiio *csio, u_int32_t retries,
342                        void (*cbfcnp)(struct cam_periph *, union ccb *),
343                        u_int8_t tag_action, int immediate, int long_erase,
344                        u_int8_t sense_len, u_int32_t timeout);
345 
346 void      scsi_data_comp_page(struct scsi_data_compression_page *page,
347                                   u_int8_t dce, u_int8_t dde, u_int8_t red,
348                                   u_int32_t comp_algorithm,
349                                   u_int32_t decomp_algorithm);
350 
351 void      scsi_read_position(struct ccb_scsiio *csio, u_int32_t retries,
352                            void (*cbfcnp)(struct cam_periph *, union ccb *),
353                            u_int8_t tag_action, int hardsoft,
354                            struct scsi_tape_position_data *sbp,
355                            u_int8_t sense_len, u_int32_t timeout);
356 
357 void      scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries,
358                          void (*cbfcnp)(struct cam_periph *, union ccb *),
359                          u_int8_t tag_action, int hardsoft, u_int32_t blkno,
360                          u_int8_t sense_len, u_int32_t timeout);
361 __END_DECLS
362 
363 #endif /* _SCSI_SCSI_SA_H */
364