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