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