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