1139743Simp/*-
270946Ssteve * Structure and function declarations for the
339213Sgibbs * SCSI Sequential Access Peripheral driver for CAM.
439213Sgibbs *
568116Smjacob * Copyright (c) 1999, 2000 Matthew Jacob
639213Sgibbs * All rights reserved.
739213Sgibbs *
839213Sgibbs * Redistribution and use in source and binary forms, with or without
939213Sgibbs * modification, are permitted provided that the following conditions
1039213Sgibbs * are met:
1139213Sgibbs * 1. Redistributions of source code must retain the above copyright
1239213Sgibbs *    notice, this list of conditions, and the following disclaimer,
1339213Sgibbs *    without modification, immediately at the beginning of the file.
1439213Sgibbs * 2. The name of the author may not be used to endorse or promote products
1539213Sgibbs *    derived from this software without specific prior written permission.
1639213Sgibbs *
1739213Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1839213Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1939213Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2039213Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2139213Sgibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2239213Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2339213Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2439213Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2539213Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2639213Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2739213Sgibbs * SUCH DAMAGE.
2839213Sgibbs *
2950477Speter * $FreeBSD$
3039213Sgibbs */
3139213Sgibbs
3239213Sgibbs#ifndef	_SCSI_SCSI_SA_H
3339213Sgibbs#define _SCSI_SCSI_SA_H 1
3439213Sgibbs
3539213Sgibbs#include <sys/cdefs.h>
3639213Sgibbs
3739213Sgibbsstruct scsi_read_block_limits
3839213Sgibbs{
3939213Sgibbs	u_int8_t opcode;
4039213Sgibbs	u_int8_t byte2;
4139213Sgibbs	u_int8_t unused[3];
4239213Sgibbs	u_int8_t control;
4339213Sgibbs};
4439213Sgibbs
4539213Sgibbsstruct scsi_read_block_limits_data
4639213Sgibbs{
4739213Sgibbs	u_int8_t gran;
4839213Sgibbs#define	RBL_GRAN_MASK	0x1F
4939213Sgibbs#define RBL_GRAN(rblim) ((rblim)->gran & RBL_GRAN_MASK)
5039213Sgibbs	u_int8_t maximum[3];
5139213Sgibbs	u_int8_t minimum[2];
5239213Sgibbs};
5339213Sgibbs
5439213Sgibbsstruct scsi_sa_rw
5539213Sgibbs{
5639213Sgibbs	u_int8_t opcode;
5739213Sgibbs        u_int8_t sli_fixed;
5839213Sgibbs#define SAR_SLI		0x02
5939213Sgibbs#define SARW_FIXED	0x01
6039213Sgibbs	u_int8_t length[3];
6139213Sgibbs        u_int8_t control;
6239213Sgibbs};
6339213Sgibbs
6439213Sgibbsstruct scsi_load_unload
6539213Sgibbs{
6639213Sgibbs	u_int8_t opcode;
6739213Sgibbs        u_int8_t immediate;
6839213Sgibbs#define SLU_IMMED	0x01
6939213Sgibbs	u_int8_t reserved[2];
7039213Sgibbs	u_int8_t eot_reten_load;
7139213Sgibbs#define SLU_EOT		0x04
7239213Sgibbs#define SLU_RETEN	0x02
7339213Sgibbs#define SLU_LOAD	0x01
7439213Sgibbs        u_int8_t control;
7539213Sgibbs};
7639213Sgibbs
7739213Sgibbsstruct scsi_rewind
7839213Sgibbs{
7939213Sgibbs	u_int8_t opcode;
8039213Sgibbs        u_int8_t immediate;
8139213Sgibbs#define SREW_IMMED	0x01
8239213Sgibbs	u_int8_t reserved[3];
8339213Sgibbs        u_int8_t control;
8439213Sgibbs};
8539213Sgibbs
8639213Sgibbstypedef enum {
8739213Sgibbs	SS_BLOCKS,
8839213Sgibbs	SS_FILEMARKS,
8939213Sgibbs	SS_SEQFILEMARKS,
9039213Sgibbs	SS_EOD,
9139213Sgibbs	SS_SETMARKS,
9239213Sgibbs	SS_SEQSETMARKS
9339213Sgibbs} scsi_space_code;
9439213Sgibbs
9539213Sgibbsstruct scsi_space
9639213Sgibbs{
9739213Sgibbs	u_int8_t opcode;
9839213Sgibbs        u_int8_t code;
9939213Sgibbs#define SREW_IMMED	0x01
10039213Sgibbs	u_int8_t count[3];
10139213Sgibbs        u_int8_t control;
10239213Sgibbs};
10339213Sgibbs
10439213Sgibbsstruct scsi_write_filemarks
10539213Sgibbs{
10639213Sgibbs	u_int8_t opcode;
10739213Sgibbs        u_int8_t byte2;
10839213Sgibbs#define SWFMRK_IMMED	0x01
10939213Sgibbs#define SWFMRK_WSMK	0x02
11039213Sgibbs	u_int8_t num_marks[3];
11139213Sgibbs        u_int8_t control;
11239213Sgibbs};
11339213Sgibbs
11439213Sgibbs/*
11539213Sgibbs * Reserve and release unit have the same exact cdb format, but different
11639213Sgibbs * opcodes.
11739213Sgibbs */
11839213Sgibbsstruct scsi_reserve_release_unit
11939213Sgibbs{
12039213Sgibbs	u_int8_t opcode;
12139213Sgibbs	u_int8_t lun_thirdparty;
12239213Sgibbs#define SRRU_LUN_MASK	0xE0
12339213Sgibbs#define SRRU_3RD_PARTY	0x10
12439213Sgibbs#define SRRU_3RD_SHAMT	1
12539213Sgibbs#define SRRU_3RD_MASK	0xE
12639213Sgibbs	u_int8_t reserved[3];
12739213Sgibbs	u_int8_t control;
12839213Sgibbs};
12939213Sgibbs
13039213Sgibbs/*
13139213Sgibbs * Erase a tape
13239213Sgibbs */
13339213Sgibbsstruct scsi_erase
13439213Sgibbs{
13539213Sgibbs	u_int8_t opcode;
13639213Sgibbs	u_int8_t lun_imm_long;
13739213Sgibbs#define SE_LUN_MASK	0xE0
13839213Sgibbs#define SE_LONG		0x1
13939213Sgibbs#define SE_IMMED	0x2
14039213Sgibbs	u_int8_t reserved[3];
14139213Sgibbs	u_int8_t control;
14239213Sgibbs};
14339213Sgibbs
14439213Sgibbs/*
14539213Sgibbs * Dev specific mode page masks.
14639213Sgibbs */
14739213Sgibbs#define SMH_SA_WP		0x80
14839213Sgibbs#define	SMH_SA_BUF_MODE_MASK	0x70
14939213Sgibbs#define SMH_SA_BUF_MODE_NOBUF	0x00
15039213Sgibbs#define SMH_SA_BUF_MODE_SIBUF	0x10	/* Single-Initiator buffering */
15139213Sgibbs#define SMH_SA_BUF_MODE_MIBUF	0x20	/* Multi-Initiator buffering */
15239213Sgibbs#define SMH_SA_SPEED_MASK	0x0F
15339213Sgibbs#define SMH_SA_SPEED_DEFAULT	0x00
15439213Sgibbs
15539213Sgibbs/*
15639213Sgibbs * Sequential-access specific mode page numbers.
15739213Sgibbs */
15839213Sgibbs#define SA_DEVICE_CONFIGURATION_PAGE	0x10
15939213Sgibbs#define SA_MEDIUM_PARTITION_PAGE_1	0x11
16039213Sgibbs#define SA_MEDIUM_PARTITION_PAGE_2	0x12
16139213Sgibbs#define SA_MEDIUM_PARTITION_PAGE_3	0x13
16239213Sgibbs#define SA_MEDIUM_PARTITION_PAGE_4	0x14
16346950Smjacob#define SA_DATA_COMPRESSION_PAGE	0x0f	/* SCSI-3 */
16439213Sgibbs
16539213Sgibbs/*
16639213Sgibbs * Mode page definitions.
16739213Sgibbs */
16839213Sgibbs
16946950Smjacob/* See SCSI-II spec 9.3.3.1 */
17046950Smjacobstruct scsi_dev_conf_page {
17146950Smjacob	u_int8_t pagecode;	/* 0x10 */
17246950Smjacob	u_int8_t pagelength;	/* 0x0e */
17368114Smjacob	u_int8_t byte2;		/* CAP, CAF, Active Format */
17446950Smjacob	u_int8_t active_partition;
17546950Smjacob	u_int8_t wb_full_ratio;
17646950Smjacob	u_int8_t rb_empty_ratio;
17746950Smjacob	u_int8_t wrdelay_time[2];
17846950Smjacob	u_int8_t byte8;
17946950Smjacob#define	SA_DBR			0x80	/* data buffer recovery */
18046950Smjacob#define	SA_BIS			0x40	/* block identifiers supported */
18146950Smjacob#define	SA_RSMK			0x20	/* report setmarks */
18246950Smjacob#define	SA_AVC			0x10	/* automatic velocity control */
18346950Smjacob#define	SA_SOCF_MASK		0xc0	/* stop on consecutive formats */
18446950Smjacob#define	SA_RBO			0x20	/* recover buffer order */
18546950Smjacob#define	SA_REW			0x10	/* report early warning */
18646950Smjacob	u_int8_t gap_size;
18746950Smjacob	u_int8_t byte10;
18846950Smjacob	u_int8_t ew_bufsize[3];
18946950Smjacob	u_int8_t sel_comp_alg;
19046950Smjacob#define	SA_COMP_NONE		0x00
19146950Smjacob#define	SA_COMP_DEFAULT		0x01
19268114Smjacob	/* the following is 'reserved' in SCSI-2 but is defined in SSC-r22 */
19368114Smjacob	u_int8_t extra_wp;
19468114Smjacob#define	SA_ASOC_WP		0x04	/* Associated Write Protect */
19568114Smjacob#define	SA_PERS_WP		0x02	/* Persistent Write Protect */
19668114Smjacob#define	SA_PERM_WP		0x01	/* Permanent Write Protect */
19746950Smjacob};
19846950Smjacob
19946950Smjacob/* from SCSI-3: SSC-Rev10 (6/97) */
20039213Sgibbsstruct scsi_data_compression_page {
20146950Smjacob	u_int8_t page_code;	/* 0x0f */
20268114Smjacob	u_int8_t page_length;	/* 0x0e */
20368114Smjacob	u_int8_t dce_and_dcc;
20439213Sgibbs#define SA_DCP_DCE		0x80 	/* Data compression enable */
20539213Sgibbs#define SA_DCP_DCC		0x40	/* Data compression capable */
20668114Smjacob	u_int8_t dde_and_red;
20739213Sgibbs#define SA_DCP_DDE		0x80	/* Data decompression enable */
20839213Sgibbs#define SA_DCP_RED_MASK		0x60	/* Report Exception on Decomp. */
20939213Sgibbs#define SA_DCP_RED_SHAMT	5
21039213Sgibbs#define SA_DCP_RED_0		0x00
21139213Sgibbs#define SA_DCP_RED_1		0x20
21239213Sgibbs#define SA_DCP_RED_2		0x40
21339213Sgibbs	u_int8_t comp_algorithm[4];
21439213Sgibbs	u_int8_t decomp_algorithm[4];
21539213Sgibbs	u_int8_t reserved[4];
21639213Sgibbs};
21739213Sgibbs
21846950Smjacobtypedef union {
21946950Smjacob	struct { u_int8_t pagecode, pagelength; } hdr;
22046950Smjacob	struct scsi_dev_conf_page dconf;
22146950Smjacob	struct scsi_data_compression_page dcomp;
22246950Smjacob} sa_comp_t;
22346950Smjacob
22441917Smjacobstruct scsi_tape_read_position {
22541917Smjacob	u_int8_t opcode;		/* READ_POSITION */
22641917Smjacob	u_int8_t byte1;			/* set LSB to read hardware block pos */
22741917Smjacob	u_int8_t reserved[8];
22841917Smjacob};
22941917Smjacob
23041917Smjacobstruct scsi_tape_position_data	{	/* Short Form */
23141917Smjacob	u_int8_t flags;
23241917Smjacob#define	SA_RPOS_BOP		0x80	/* Beginning of Partition */
23341917Smjacob#define	SA_RPOS_EOP		0x40	/* End of Partition */
23441917Smjacob#define	SA_RPOS_BCU		0x20	/* Block Count Unknown (SCSI3) */
23541917Smjacob#define	SA_RPOS_BYCU		0x10	/* Byte Count Unknown (SCSI3) */
23641917Smjacob#define	SA_RPOS_BPU		0x04	/* Block Position Unknown */
23741917Smjacob#define	SA_RPOS_PERR		0x02	/* Position Error (SCSI3) */
23841917Smjacob#define	SA_RPOS_UNCERTAIN	SA_RPOS_BPU
23941917Smjacob	u_int8_t partition;
24041917Smjacob	u_int8_t reserved[2];
24141917Smjacob	u_int8_t firstblk[4];
24241917Smjacob	u_int8_t lastblk[4];
24341917Smjacob	u_int8_t reserved2;
24441917Smjacob	u_int8_t nbufblk[3];
24541917Smjacob	u_int8_t nbufbyte[4];
24641917Smjacob};
24741917Smjacob
24841917Smjacobstruct scsi_tape_locate {
24941917Smjacob	u_int8_t opcode;
25041917Smjacob	u_int8_t byte1;
25141917Smjacob#define	SA_SPOS_IMMED		0x01
25241917Smjacob#define	SA_SPOS_CP		0x02
25341917Smjacob#define	SA_SPOS_BT		0x04
25441917Smjacob	u_int8_t reserved1;
25541917Smjacob	u_int8_t blkaddr[4];
25641917Smjacob	u_int8_t reserved2;
25741917Smjacob	u_int8_t partition;
25841917Smjacob	u_int8_t control;
25941917Smjacob};
26041917Smjacob
26139213Sgibbs/*
26239213Sgibbs * Opcodes
26339213Sgibbs */
26439213Sgibbs#define REWIND			0x01
26539213Sgibbs#define READ_BLOCK_LIMITS	0x05
26639213Sgibbs#define SA_READ			0x08
26739213Sgibbs#define SA_WRITE		0x0A
26839213Sgibbs#define WRITE_FILEMARKS		0x10
26939213Sgibbs#define SPACE			0x11
27039213Sgibbs#define RESERVE_UNIT		0x16
27139213Sgibbs#define RELEASE_UNIT		0x17
27239213Sgibbs#define ERASE			0x19
27339213Sgibbs#define LOAD_UNLOAD		0x1B
27441917Smjacob#define	LOCATE			0x2B
27541917Smjacob#define	READ_POSITION		0x34
27639213Sgibbs
27741907Smjacob/*
27841907Smjacob * Tape specific density codes- only enough of them here to recognize
27941907Smjacob * some specific older units so we can choose 2FM@EOD or FIXED blocksize
28041907Smjacob * quirks.
28141907Smjacob */
28241907Smjacob#define SCSI_DENSITY_HALFINCH_800	0x01
28341907Smjacob#define SCSI_DENSITY_HALFINCH_1600	0x02
28441907Smjacob#define SCSI_DENSITY_HALFINCH_6250	0x03
28541907Smjacob#define SCSI_DENSITY_HALFINCH_6250C	0xC3	/* HP Compressed 6250 */
28641907Smjacob#define SCSI_DENSITY_QIC_11_4TRK	0x04
28741907Smjacob#define SCSI_DENSITY_QIC_11_9TRK	0x84	/* Vendor Unique Emulex */
28841907Smjacob#define SCSI_DENSITY_QIC_24		0x05
28941907Smjacob#define SCSI_DENSITY_HALFINCH_PE	0x06
29041907Smjacob#define SCSI_DENSITY_QIC_120		0x0f
29141907Smjacob#define SCSI_DENSITY_QIC_150		0x10
29243635Smjacob#define	SCSI_DENSITY_QIC_525_320	0x11
29343635Smjacob#define	SCSI_DENSITY_QIC_1320		0x12
29446950Smjacob#define	SCSI_DENSITY_QIC_2GB		0x22
29546950Smjacob#define	SCSI_DENSITY_QIC_4GB		0x26
29643635Smjacob#define	SCSI_DENSITY_QIC_3080		0x29
29741907Smjacob
29839213Sgibbs__BEGIN_DECLS
29939213Sgibbsvoid	scsi_read_block_limits(struct ccb_scsiio *, u_int32_t,
30039213Sgibbs			       void (*cbfcnp)(struct cam_periph *, union ccb *),
30139213Sgibbs			       u_int8_t, struct scsi_read_block_limits_data *,
30239213Sgibbs			       u_int8_t , u_int32_t);
30339213Sgibbs
30439213Sgibbsvoid	scsi_sa_read_write(struct ccb_scsiio *csio, u_int32_t retries,
30539213Sgibbs			   void (*cbfcnp)(struct cam_periph *, union ccb *),
30639213Sgibbs			   u_int8_t tag_action, int readop, int sli,
30739213Sgibbs			   int fixed, u_int32_t length, u_int8_t *data_ptr,
30839213Sgibbs			   u_int32_t dxfer_len, u_int8_t sense_len,
30939213Sgibbs			   u_int32_t timeout);
31039213Sgibbs
31139213Sgibbsvoid	scsi_rewind(struct ccb_scsiio *csio, u_int32_t retries,
31239213Sgibbs		    void (*cbfcnp)(struct cam_periph *, union ccb *),
31339213Sgibbs		    u_int8_t tag_action, int immediate, u_int8_t sense_len,
31439213Sgibbs		    u_int32_t timeout);
31539213Sgibbs
31639213Sgibbsvoid	scsi_space(struct ccb_scsiio *csio, u_int32_t retries,
31739213Sgibbs		   void (*cbfcnp)(struct cam_periph *, union ccb *),
31839213Sgibbs		   u_int8_t tag_action, scsi_space_code code,
31939213Sgibbs		   u_int32_t count, u_int8_t sense_len, u_int32_t timeout);
32039213Sgibbs
32139213Sgibbsvoid	scsi_load_unload(struct ccb_scsiio *csio, u_int32_t retries,
32239213Sgibbs			 void (*cbfcnp)(struct cam_periph *, union ccb *),
32339213Sgibbs			 u_int8_t tag_action, int immediate,   int eot,
32439213Sgibbs			 int reten, int load, u_int8_t sense_len,
32539213Sgibbs			 u_int32_t timeout);
32639213Sgibbs
32739213Sgibbsvoid	scsi_write_filemarks(struct ccb_scsiio *csio, u_int32_t retries,
32839213Sgibbs			     void (*cbfcnp)(struct cam_periph *, union ccb *),
32939213Sgibbs			     u_int8_t tag_action, int immediate, int setmark,
33039213Sgibbs			     u_int32_t num_marks, u_int8_t sense_len,
33139213Sgibbs			     u_int32_t timeout);
33239213Sgibbs
33339213Sgibbsvoid	scsi_reserve_release_unit(struct ccb_scsiio *csio, u_int32_t retries,
33439213Sgibbs				  void (*cbfcnp)(struct cam_periph *,
33539213Sgibbs				  union ccb *), u_int8_t tag_action,
33639213Sgibbs				  int third_party, int third_party_id,
33739213Sgibbs				  u_int8_t sense_len, u_int32_t timeout,
33839213Sgibbs				  int reserve);
33939213Sgibbs
34039213Sgibbsvoid	scsi_erase(struct ccb_scsiio *csio, u_int32_t retries,
34139213Sgibbs		   void (*cbfcnp)(struct cam_periph *, union ccb *),
34239213Sgibbs		   u_int8_t tag_action, int immediate, int long_erase,
34339213Sgibbs		   u_int8_t sense_len, u_int32_t timeout);
34439213Sgibbs
34539213Sgibbsvoid	scsi_data_comp_page(struct scsi_data_compression_page *page,
34639213Sgibbs			    u_int8_t dce, u_int8_t dde, u_int8_t red,
34739213Sgibbs			    u_int32_t comp_algorithm,
34839213Sgibbs			    u_int32_t decomp_algorithm);
34941917Smjacob
35041917Smjacobvoid	scsi_read_position(struct ccb_scsiio *csio, u_int32_t retries,
35141917Smjacob                           void (*cbfcnp)(struct cam_periph *, union ccb *),
35241917Smjacob                           u_int8_t tag_action, int hardsoft,
35341917Smjacob                           struct scsi_tape_position_data *sbp,
35441917Smjacob                           u_int8_t sense_len, u_int32_t timeout);
35541917Smjacob
35641917Smjacobvoid	scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries,
35741917Smjacob                         void (*cbfcnp)(struct cam_periph *, union ccb *),
35841917Smjacob                         u_int8_t tag_action, int hardsoft, u_int32_t blkno,
35941917Smjacob                         u_int8_t sense_len, u_int32_t timeout);
36039213Sgibbs__END_DECLS
36139213Sgibbs
36239213Sgibbs#endif /* _SCSI_SCSI_SA_H */
363