| 1 | /* |
| 2 | * Structures and definitions for SCSI commands to Direct Access Devices |
| 3 | */ |
| 4 | |
| 5 | /*- |
| 6 | * Some lines of this file come from a file of the name "scsi.h" |
| 7 | * distributed by OSF as part of mach2.5, |
| 8 | * so the following disclaimer has been kept. |
| 9 | * |
| 10 | * Copyright 1990 by Open Software Foundation, |
| 11 | * Grenoble, FRANCE |
| 12 | * |
| 13 | * 		All Rights Reserved |
| 14 | * |
| 15 | * Permission to use, copy, modify, and distribute this software and |
| 16 | * its documentation for any purpose and without fee is hereby granted, |
| 17 | * provided that the above copyright notice appears in all copies and |
| 18 | * that both the copyright notice and this permission notice appear in |
| 19 | * supporting documentation, and that the name of OSF or Open Software |
| 20 | * Foundation not be used in advertising or publicity pertaining to |
| 21 | * distribution of the software without specific, written prior |
| 22 | * permission. |
| 23 | * |
| 24 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE |
| 25 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, |
| 26 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR |
| 27 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
| 28 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, |
| 29 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
| 30 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 31 | */ |
| 32 | |
| 33 | /*- |
| 34 | * Largely written by Julian Elischer (julian@tfs.com) |
| 35 | * for TRW Financial Systems. |
| 36 | * |
| 37 | * TRW Financial Systems, in accordance with their agreement with Carnegie |
| 38 | * Mellon University, makes this software available to CMU to distribute |
| 39 | * or use in any manner that they see fit as long as this message is kept with |
| 40 | * the software. For this reason TFS also grants any other persons or |
| 41 | * organisations permission to use or modify this software. |
| 42 | * |
| 43 | * TFS supplies this software to be publicly redistributed |
| 44 | * on the understanding that TFS is not responsible for the correct |
| 45 | * functioning of this software in any circumstances. |
| 46 | * |
| 47 | * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 |
| 48 | */ |
| 49 | |
| 50 | #ifndef	_SCSI_SCSI_DA_H |
| 51 | #define _SCSI_SCSI_DA_H 1 |
| 52 | |
| 53 | |
| 54 | struct scsi_rezero_unit |
| 55 | { |
| 56 | 	uint8_t opcode; |
| 57 | #define SRZU_LUN_MASK 0xE0 |
| 58 | 	uint8_t byte2; |
| 59 | 	uint8_t reserved[3]; |
| 60 | 	uint8_t control; |
| 61 | }; |
| 62 | |
| 63 | /* |
| 64 | * NOTE: The lower three bits of byte2 of the format CDB are the same as |
| 65 | * the lower three bits of byte2 of the read defect data CDB, below. |
| 66 | */ |
| 67 | struct scsi_format_unit |
| 68 | { |
| 69 | 	uint8_t opcode; |
| 70 | 	uint8_t byte2; |
| 71 | #define FU_FORMAT_MASK	SRDD10_DLIST_FORMAT_MASK |
| 72 | #define FU_BLOCK_FORMAT	SRDD10_BLOCK_FORMAT |
| 73 | #define FU_BFI_FORMAT	SRDD10_BYTES_FROM_INDEX_FORMAT |
| 74 | #define FU_PHYS_FORMAT	SRDD10_PHYSICAL_SECTOR_FORMAT |
| 75 | #define FU_CMPLST	0x08 |
| 76 | #define FU_FMT_DATA	0x10 |
| 77 | 	uint8_t vendor_specific; |
| 78 | 	uint8_t interleave[2]; |
| 79 | 	uint8_t control; |
| 80 | }; |
| 81 | |
| 82 | struct scsi_reassign_blocks |
| 83 | { |
| 84 | 	uint8_t opcode; |
| 85 | 	uint8_t byte2; |
| 86 | 	uint8_t unused[3]; |
| 87 | 	uint8_t control; |
| 88 | }; |
| 89 | |
| 90 | struct scsi_read_defect_data_10 |
| 91 | { |
| 92 | 	uint8_t opcode; |
| 93 | 	uint8_t byte2; |
| 94 | #define SRDD10_GLIST 0x08 |
| 95 | #define SRDD10_PLIST 0x10 |
| 96 | #define SRDD10_DLIST_FORMAT_MASK 0x07 |
| 97 | #define SRDD10_BLOCK_FORMAT 0x00 |
| 98 | #define SRDD10_EXT_BFI_FORMAT 	 0x01 |
| 99 | #define SRDD10_EXT_PHYS_FORMAT 	 0x02 |
| 100 | #define SRDD10_LONG_BLOCK_FORMAT 0x03 |
| 101 | #define SRDD10_BYTES_FROM_INDEX_FORMAT 0x04 |
| 102 | #define SRDD10_PHYSICAL_SECTOR_FORMAT 0x05 |
| 103 | #define SRDD10_VENDOR_FORMAT	 0x06 |
| 104 | 	uint8_t format; |
| 105 | 	uint8_t reserved[4]; |
| 106 | 	uint8_t alloc_length[2]; |
| 107 | #define	SRDD10_MAX_LENGTH		0xffff |
| 108 | 	uint8_t control; |
| 109 | }; |
| 110 | |
| 111 | struct scsi_sanitize |
| 112 | { |
| 113 | 	uint8_t opcode; |
| 114 | 	uint8_t byte2; |
| 115 | #define SSZ_SERVICE_ACTION_OVERWRITE 0x01 |
| 116 | #define SSZ_SERVICE_ACTION_BLOCK_ERASE 0x02 |
| 117 | #define SSZ_SERVICE_ACTION_CRYPTO_ERASE 0x03 |
| 118 | #define SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE 0x1F |
| 119 | #define SSZ_UNRESTRICTED_EXIT 0x20 |
| 120 | #define SSZ_IMMED 0x80 |
| 121 | 	uint8_t reserved[5]; |
| 122 | 	uint8_t length[2]; |
| 123 | 	uint8_t control; |
| 124 | }; |
| 125 | |
| 126 | struct scsi_sanitize_parameter_list |
| 127 | { |
| 128 | 	uint8_t byte1; |
| 129 | #define SSZPL_INVERT 0x80 |
| 130 | 	uint8_t reserved; |
| 131 | 	uint8_t length[2]; |
| 132 | 	/* Variable length initialization pattern. */ |
| 133 | #define SSZPL_MAX_PATTERN_LENGTH 65535 |
| 134 | }; |
| 135 | |
| 136 | struct scsi_read_defect_data_12 |
| 137 | { |
| 138 | 	uint8_t opcode; |
| 139 | #define SRDD12_GLIST 0x08 |
| 140 | #define SRDD12_PLIST 0x10 |
| 141 | #define SRDD12_DLIST_FORMAT_MASK 0x07 |
| 142 | #define SRDD12_BLOCK_FORMAT SRDD10_BLOCK_FORMAT |
| 143 | #define SRDD12_BYTES_FROM_INDEX_FORMAT SRDD10_BYTES_FROM_INDEX_FORMAT |
| 144 | #define SRDD12_PHYSICAL_SECTOR_FORMAT SRDD10_PHYSICAL_SECTOR_FORMAT |
| 145 | 	uint8_t format; |
| 146 | 	uint8_t address_descriptor_index[4]; |
| 147 | 	uint8_t alloc_length[4]; |
| 148 | #define	SRDD12_MAX_LENGTH		0xffffffff |
| 149 | 	uint8_t reserved; |
| 150 | 	uint8_t control; |
| 151 | }; |
| 152 | |
| 153 | struct scsi_zbc_out |
| 154 | { |
| 155 | 	uint8_t opcode; |
| 156 | 	uint8_t service_action; |
| 157 | #define	ZBC_OUT_SA_CLOSE	0x01 |
| 158 | #define	ZBC_OUT_SA_FINISH	0x02 |
| 159 | #define	ZBC_OUT_SA_OPEN		0x03 |
| 160 | #define	ZBC_OUT_SA_RWP		0x04 |
| 161 | 	uint8_t zone_id[8]; |
| 162 | 	uint8_t reserved[4]; |
| 163 | 	uint8_t zone_flags; |
| 164 | #define	ZBC_OUT_ALL		0x01 |
| 165 | 	uint8_t control; |
| 166 | }; |
| 167 | |
| 168 | struct scsi_zbc_in |
| 169 | { |
| 170 | 	uint8_t opcode; |
| 171 | 	uint8_t service_action; |
| 172 | #define	ZBC_IN_SA_REPORT_ZONES	0x00 |
| 173 | 	uint8_t zone_start_lba[8]; |
| 174 | 	uint8_t length[4]; |
| 175 | 	uint8_t zone_options; |
| 176 | #define	ZBC_IN_PARTIAL		0x80 |
| 177 | #define	ZBC_IN_REP_ALL_ZONES	0x00 |
| 178 | #define	ZBC_IN_REP_EMPTY	0x01 |
| 179 | #define	ZBC_IN_REP_IMP_OPEN	0x02 |
| 180 | #define	ZBC_IN_REP_EXP_OPEN	0x03 |
| 181 | #define	ZBC_IN_REP_CLOSED	0x04 |
| 182 | #define	ZBC_IN_REP_FULL		0x05 |
| 183 | #define	ZBC_IN_REP_READONLY	0x06 |
| 184 | #define	ZBC_IN_REP_OFFLINE	0x07 |
| 185 | #define	ZBC_IN_REP_RESET	0x10 |
| 186 | #define	ZBC_IN_REP_NON_SEQ	0x11 |
| 187 | #define	ZBC_IN_REP_NON_WP	0x3f |
| 188 | #define	ZBC_IN_REP_MASK		0x3f |
| 189 | 	uint8_t control; |
| 190 | }; |
| 191 | |
| 192 | struct scsi_report_zones_desc { |
| 193 | 	uint8_t zone_type; |
| 194 | #define	SRZ_TYPE_CONVENTIONAL	0x01 |
| 195 | #define	SRZ_TYPE_SEQ_REQUIRED	0x02 |
| 196 | #define	SRZ_TYPE_SEQ_PREFERRED	0x03 |
| 197 | #define	SRZ_TYPE_MASK		0x0f |
| 198 | 	uint8_t zone_flags; |
| 199 | #define	SRZ_ZONE_COND_SHIFT	4 |
| 200 | #define	SRZ_ZONE_COND_MASK	0xf0 |
| 201 | #define	SRZ_ZONE_COND_NWP	0x00 |
| 202 | #define	SRZ_ZONE_COND_EMPTY	0x10 |
| 203 | #define	SRZ_ZONE_COND_IMP_OPEN	0x20 |
| 204 | #define	SRZ_ZONE_COND_EXP_OPEN	0x30 |
| 205 | #define	SRZ_ZONE_COND_CLOSED	0x40 |
| 206 | #define	SRZ_ZONE_COND_READONLY	0xd0 |
| 207 | #define	SRZ_ZONE_COND_FULL	0xe0 |
| 208 | #define	SRZ_ZONE_COND_OFFLINE	0xf0 |
| 209 | #define	SRZ_ZONE_NON_SEQ	0x02 |
| 210 | #define	SRZ_ZONE_RESET		0x01 |
| 211 | 	uint8_t reserved[6]; |
| 212 | 	uint8_t zone_length[8]; |
| 213 | 	uint8_t zone_start_lba[8]; |
| 214 | 	uint8_t write_pointer_lba[8]; |
| 215 | 	uint8_t reserved2[32]; |
| 216 | }; |
| 217 | |
| 218 | struct scsi_report_zones_hdr { |
| 219 | 	uint8_t length[4]; |
| 220 | 	uint8_t byte4; |
| 221 | #define	SRZ_SAME_ALL_DIFFERENT	 0x00 /* Lengths and types vary */ |
| 222 | #define	SRZ_SAME_ALL_SAME	 0x01 /* Lengths and types the same */ |
| 223 | #define	SRZ_SAME_LAST_DIFFERENT	 0x02 /* Types same, last length varies */ |
| 224 | #define SRZ_SAME_TYPES_DIFFERENT 0x03 /* Types vary, length the same */ |
| 225 | #define	SRZ_SAME_MASK		 0x0f |
| 226 | 	uint8_t reserved[3]; |
| 227 | 	uint8_t maximum_lba[8]; |
| 228 | 	uint8_t reserved2[48]; |
| 229 | 	struct scsi_report_zones_desc desc_list[]; |
| 230 | }; |
| 231 | |
| 232 | /* |
| 233 | * Opcodes |
| 234 | */ |
| 235 | #define REZERO_UNIT		0x01 |
| 236 | #define FORMAT_UNIT		0x04 |
| 237 | #define	REASSIGN_BLOCKS		0x07 |
| 238 | #define MODE_SELECT		0x15 |
| 239 | #define MODE_SENSE		0x1a |
| 240 | #define	READ_FORMAT_CAPACITIES	0x23 |
| 241 | #define	WRITE_AND_VERIFY	0x2e |
| 242 | #define	VERIFY			0x2f |
| 243 | #define READ_DEFECT_DATA_10	0x37 |
| 244 | #define SANITIZE		0x48 |
| 245 | #define	ZBC_OUT			0x94 |
| 246 | #define	ZBC_IN			0x95 |
| 247 | #define READ_DEFECT_DATA_12	0xb7 |
| 248 | |
| 249 | struct format_defect_list_header |
| 250 | { |
| 251 | 	uint8_t reserved; |
| 252 | 	uint8_t byte2; |
| 253 | #define FU_DLH_VS	0x01 |
| 254 | #define FU_DLH_IMMED	0x02 |
| 255 | #define FU_DLH_DSP	0x04 |
| 256 | #define FU_DLH_IP	0x08 |
| 257 | #define FU_DLH_STPF	0x10 |
| 258 | #define FU_DLH_DCRT	0x20 |
| 259 | #define FU_DLH_DPRY	0x40 |
| 260 | #define FU_DLH_FOV	0x80 |
| 261 | 	uint8_t defect_list_length[2]; |
| 262 | }; |
| 263 | |
| 264 | struct format_ipat_descriptor |
| 265 | { |
| 266 | 	uint8_t byte1; |
| 267 | #define	FU_INIT_NO_HDR		0x00 |
| 268 | #define FU_INIT_LBA_MSB		0x40 |
| 269 | #define FU_INIT_LBA_EACH	0x80 |
| 270 | #define FU_INIT_SI		0x20 |
| 271 | 	uint8_t pattern_type; |
| 272 | #define FU_INIT_PAT_DEFAULT	0x00 |
| 273 | #define FU_INIT_PAT_REPEAT	0x01 |
| 274 | 	uint8_t pat_length[2]; |
| 275 | }; |
| 276 | |
| 277 | struct scsi_read_format_capacities |
| 278 | { |
| 279 | 	uint8_t	opcode;		/* READ_FORMAT_CAPACITIES */ |
| 280 | 	uint8_t	byte2; |
| 281 | #define	SRFC_LUN_MASK	0xE0 |
| 282 | 	uint8_t	reserved0[5]; |
| 283 | 	uint8_t	alloc_length[2]; |
| 284 | 	uint8_t	reserved1[3]; |
| 285 | }; |
| 286 | |
| 287 | struct scsi_verify_10 |
| 288 | { |
| 289 | 	uint8_t	opcode;		/* VERIFY(10) */ |
| 290 | 	uint8_t	byte2; |
| 291 | #define	SVFY_LUN_MASK	0xE0 |
| 292 | #define	SVFY_RELADR	0x01 |
| 293 | #define	SVFY_BYTCHK	0x02 |
| 294 | #define	SVFY_DPO	0x10 |
| 295 | 	uint8_t	addr[4];	/* LBA to begin verification at */ |
| 296 | 	uint8_t	group; |
| 297 | 	uint8_t	length[2];		/* number of blocks to verify */ |
| 298 | 	uint8_t	control; |
| 299 | }; |
| 300 | |
| 301 | struct scsi_verify_12 |
| 302 | { |
| 303 | 	uint8_t	opcode;		/* VERIFY(12) */ |
| 304 | 	uint8_t	byte2; |
| 305 | 	uint8_t	addr[4];	/* LBA to begin verification at */ |
| 306 | 	uint8_t	length[4];		/* number of blocks to verify */ |
| 307 | 	uint8_t	group; |
| 308 | 	uint8_t	control; |
| 309 | }; |
| 310 | |
| 311 | struct scsi_verify_16 |
| 312 | { |
| 313 | 	uint8_t	opcode;		/* VERIFY(16) */ |
| 314 | 	uint8_t	byte2; |
| 315 | 	uint8_t	addr[8];	/* LBA to begin verification at */ |
| 316 | 	uint8_t	length[4];		/* number of blocks to verify */ |
| 317 | 	uint8_t	group; |
| 318 | 	uint8_t	control; |
| 319 | }; |
| 320 | |
| 321 | struct scsi_compare_and_write |
| 322 | { |
| 323 | 	uint8_t	opcode;		/* COMPARE AND WRITE */ |
| 324 | 	uint8_t	byte2; |
| 325 | 	uint8_t	addr[8];	/* LBA to begin verification at */ |
| 326 | 	uint8_t	reserved[3]; |
| 327 | 	uint8_t	length;		/* number of blocks */ |
| 328 | 	uint8_t	group; |
| 329 | 	uint8_t	control; |
| 330 | }; |
| 331 | |
| 332 | struct scsi_write_and_verify |
| 333 | { |
| 334 | 	uint8_t	opcode;		/* WRITE_AND_VERIFY */ |
| 335 | 	uint8_t	byte2; |
| 336 | #define	SWVY_LUN_MASK	0xE0 |
| 337 | #define	SWVY_RELADR	0x01 |
| 338 | #define	SWVY_BYTECHK	0x02 |
| 339 | #define	SWVY_DPO	0x10 |
| 340 | 	uint8_t	addr[4];	/* LBA to begin verification at */ |
| 341 | 	uint8_t	reserved0[1]; |
| 342 | 	uint8_t	len[2];		/* number of blocks to write and verify */ |
| 343 | 	uint8_t	reserved1[3]; |
| 344 | }; |
| 345 | |
| 346 | /* |
| 347 | * Replies to READ_FORMAT_CAPACITIES look like this: |
| 348 | * |
| 349 | * struct format_capacity_list_header |
| 350 | * struct format_capacity_descriptor[1..n] |
| 351 | * |
| 352 | * These are similar, but not totally identical to, the |
| 353 | * defect list used to format a rigid disk. |
| 354 | * |
| 355 | * The appropriate csio_decode() format string looks like this: |
| 356 | * "{} *i3 {Len} i1 {Blocks} i4 {} *b6 {Code} b2 {Blocklen} i3" |
| 357 | * |
| 358 | * If the capacity_list_length is greater than |
| 359 | * sizeof(struct format_capacity_descriptor), then there are |
| 360 | * additional format capacity descriptors available which |
| 361 | * denote which format(s) the drive can handle. |
| 362 | * |
| 363 | * (Source: USB Mass Storage UFI Specification) |
| 364 | */ |
| 365 | |
| 366 | struct format_capacity_list_header { |
| 367 | 	uint8_t	unused[3]; |
| 368 | 	uint8_t	capacity_list_length; |
| 369 | }; |
| 370 | |
| 371 | struct format_capacity_descriptor { |
| 372 | 	uint8_t	nblocks[4];	/* total number of LBAs */ |
| 373 | 	uint8_t	byte4;		/* only present in max/cur descriptor */ |
| 374 | #define FCD_CODE_MASK	0x03	/* mask for code field above */ |
| 375 | #define FCD_UNFORMATTED	0x01	/* unformatted media present, |
| 376 | 				 * maximum capacity returned */ |
| 377 | #define FCD_FORMATTED	0x02	/* formatted media present, |
| 378 | 				 * current capacity returned */ |
| 379 | #define FCD_NOMEDIA	0x03	/* no media present, |
| 380 | 				 * maximum device capacity returned */ |
| 381 | 	uint8_t	block_length[3];	/* length of an LBA in bytes */ |
| 382 | }; |
| 383 | |
| 384 | struct scsi_reassign_blocks_data |
| 385 | { |
| 386 | 	uint8_t reserved[2]; |
| 387 | 	uint8_t length[2]; |
| 388 | 	struct { |
| 389 | 		uint8_t dlbaddr[4];	/* defect logical block address */ |
| 390 | 	} defect_descriptor[1]; |
| 391 | }; |
| 392 | |
| 393 | /* |
| 394 | * This is the list header for the READ DEFECT DATA(10) command above. |
| 395 | * It may be a bit wrong to append the 10 at the end of the data structure, |
| 396 | * since it's only 4 bytes but it does tie it to the 10 byte command. |
| 397 | */ |
| 398 | struct scsi_read_defect_data_hdr_10 |
| 399 | { |
| 400 | 	uint8_t reserved; |
| 401 | #define SRDDH10_GLIST 0x08 |
| 402 | #define SRDDH10_PLIST 0x10 |
| 403 | #define SRDDH10_DLIST_FORMAT_MASK 0x07 |
| 404 | #define SRDDH10_BLOCK_FORMAT 0x00 |
| 405 | #define SRDDH10_BYTES_FROM_INDEX_FORMAT 0x04 |
| 406 | #define SRDDH10_PHYSICAL_SECTOR_FORMAT 0x05 |
| 407 | 	uint8_t format; |
| 408 | 	uint8_t length[2]; |
| 409 | #define	SRDDH10_MAX_LENGTH	SRDD10_MAX_LENGTH -			 \ |
| 410 | 				sizeof(struct scsi_read_defect_data_hdr_10) |
| 411 | }; |
| 412 | |
| 413 | struct scsi_defect_desc_block |
| 414 | { |
| 415 | 	uint8_t address[4]; |
| 416 | }; |
| 417 | |
| 418 | struct scsi_defect_desc_long_block |
| 419 | { |
| 420 | 	uint8_t address[8]; |
| 421 | }; |
| 422 | |
| 423 | struct scsi_defect_desc_bytes_from_index |
| 424 | { |
| 425 | 	uint8_t cylinder[3]; |
| 426 | 	uint8_t head; |
| 427 | #define	SDD_EXT_BFI_MADS		0x80000000 |
| 428 | #define	SDD_EXT_BFI_FLAG_MASK		0xf0000000 |
| 429 | #define	SDD_EXT_BFI_ENTIRE_TRACK	0x0fffffff |
| 430 | 	uint8_t bytes_from_index[4]; |
| 431 | }; |
| 432 | |
| 433 | struct scsi_defect_desc_phys_sector |
| 434 | { |
| 435 | 	uint8_t cylinder[3]; |
| 436 | 	uint8_t head; |
| 437 | #define	SDD_EXT_PHYS_MADS		0x80000000 |
| 438 | #define	SDD_EXT_PHYS_FLAG_MASK		0xf0000000 |
| 439 | #define	SDD_EXT_PHYS_ENTIRE_TRACK	0x0fffffff |
| 440 | 	uint8_t sector[4]; |
| 441 | }; |
| 442 | |
| 443 | struct scsi_read_defect_data_hdr_12 |
| 444 | { |
| 445 | 	uint8_t reserved; |
| 446 | #define SRDDH12_GLIST 0x08 |
| 447 | #define SRDDH12_PLIST 0x10 |
| 448 | #define SRDDH12_DLIST_FORMAT_MASK 0x07 |
| 449 | #define SRDDH12_BLOCK_FORMAT 0x00 |
| 450 | #define SRDDH12_BYTES_FROM_INDEX_FORMAT 0x04 |
| 451 | #define SRDDH12_PHYSICAL_SECTOR_FORMAT 0x05 |
| 452 | 	uint8_t format; |
| 453 | 	uint8_t generation[2]; |
| 454 | 	uint8_t length[4]; |
| 455 | #define	SRDDH12_MAX_LENGTH	SRDD12_MAX_LENGTH -			 \ |
| 456 | 				sizeof(struct scsi_read_defect_data_hdr_12) |
| 457 | }; |
| 458 | |
| 459 | union	disk_pages /* this is the structure copied from osf */ |
| 460 | { |
| 461 | 	struct format_device_page { |
| 462 | 		uint8_t pg_code;	/* page code (should be 3)	 */ |
| 463 | #define	SMS_FORMAT_DEVICE_PAGE	0x03	/* only 6 bits valid */ |
| 464 | 		uint8_t pg_length;	/* page length (should be 0x16)	 */ |
| 465 | #define	SMS_FORMAT_DEVICE_PLEN	0x16 |
| 466 | 		uint8_t trk_z_1;	/* tracks per zone (MSB)	 */ |
| 467 | 		uint8_t trk_z_0;	/* tracks per zone (LSB)	 */ |
| 468 | 		uint8_t alt_sec_1;	/* alternate sectors per zone (MSB) */ |
| 469 | 		uint8_t alt_sec_0;	/* alternate sectors per zone (LSB) */ |
| 470 | 		uint8_t alt_trk_z_1;	/* alternate tracks per zone (MSB) */ |
| 471 | 		uint8_t alt_trk_z_0;	/* alternate tracks per zone (LSB) */ |
| 472 | 		uint8_t alt_trk_v_1;	/* alternate tracks per volume (MSB) */ |
| 473 | 		uint8_t alt_trk_v_0;	/* alternate tracks per volume (LSB) */ |
| 474 | 		uint8_t ph_sec_t_1;	/* physical sectors per track (MSB) */ |
| 475 | 		uint8_t ph_sec_t_0;	/* physical sectors per track (LSB) */ |
| 476 | 		uint8_t bytes_s_1;	/* bytes per sector (MSB)	 */ |
| 477 | 		uint8_t bytes_s_0;	/* bytes per sector (LSB)	 */ |
| 478 | 		uint8_t interleave_1;	/* interleave (MSB)		 */ |
| 479 | 		uint8_t interleave_0;	/* interleave (LSB)		 */ |
| 480 | 		uint8_t trk_skew_1;	/* track skew factor (MSB)	 */ |
| 481 | 		uint8_t trk_skew_0;	/* track skew factor (LSB)	 */ |
| 482 | 		uint8_t cyl_skew_1;	/* cylinder skew (MSB)		 */ |
| 483 | 		uint8_t cyl_skew_0;	/* cylinder skew (LSB)		 */ |
| 484 | 		uint8_t flags;		/* various */ |
| 485 | #define			DISK_FMT_SURF	0x10 |
| 486 | #define	 		DISK_FMT_RMB	0x20 |
| 487 | #define			DISK_FMT_HSEC	0x40 |
| 488 | #define			DISK_FMT_SSEC	0x80 |
| 489 | 		uint8_t reserved21; |
| 490 | 		uint8_t reserved22; |
| 491 | 		uint8_t reserved23; |
| 492 | 	} format_device; |
| 493 | 	struct rigid_geometry_page { |
| 494 | 		uint8_t pg_code;	/* page code (should be 4)	 */ |
| 495 | #define SMS_RIGID_GEOMETRY_PAGE 0x04 |
| 496 | 		uint8_t pg_length;	/* page length (should be 0x16)	 */ |
| 497 | #define SMS_RIGID_GEOMETRY_PLEN 0x16		 |
| 498 | 		uint8_t ncyl_2;	/* number of cylinders (MSB)	 */ |
| 499 | 		uint8_t ncyl_1;	/* number of cylinders 		 */ |
| 500 | 		uint8_t ncyl_0;	/* number of cylinders (LSB)	 */ |
| 501 | 		uint8_t nheads;	/* number of heads 		 */ |
| 502 | 		uint8_t st_cyl_wp_2;	/* starting cyl., write precomp (MSB) */ |
| 503 | 		uint8_t st_cyl_wp_1;	/* starting cyl., write precomp	 */ |
| 504 | 		uint8_t st_cyl_wp_0;	/* starting cyl., write precomp (LSB) */ |
| 505 | 		uint8_t st_cyl_rwc_2;	/* starting cyl., red. write cur (MSB)*/ |
| 506 | 		uint8_t st_cyl_rwc_1;	/* starting cyl., red. write cur */ |
| 507 | 		uint8_t st_cyl_rwc_0;	/* starting cyl., red. write cur (LSB)*/ |
| 508 | 		uint8_t driv_step_1;	/* drive step rate (MSB)	 */ |
| 509 | 		uint8_t driv_step_0;	/* drive step rate (LSB)	 */ |
| 510 | 		uint8_t land_zone_2;	/* landing zone cylinder (MSB)	 */ |
| 511 | 		uint8_t land_zone_1;	/* landing zone cylinder 	 */ |
| 512 | 		uint8_t land_zone_0;	/* landing zone cylinder (LSB)	 */ |
| 513 | 		uint8_t rpl;		/* rotational position locking (2 bits) */ |
| 514 | 		uint8_t rot_offset;	/* rotational offset */ |
| 515 | 		uint8_t reserved19; |
| 516 | 		uint8_t medium_rot_rate_1; /* medium rotation rate (RPM) (MSB) */ |
| 517 | 		uint8_t medium_rot_rate_0; /* medium rotation rate (RPM) (LSB) */ |
| 518 | 		uint8_t reserved22; |
| 519 | 		uint8_t reserved23; |
| 520 | 	} rigid_geometry; |
| 521 | 	struct flexible_disk_page { |
| 522 | 		uint8_t pg_code;	/* page code (should be 5)	 */ |
| 523 | #define SMS_FLEXIBLE_GEOMETRY_PAGE 0x05 |
| 524 | 		uint8_t pg_length;	/* page length (should be 0x1E)	 */ |
| 525 | #define SMS_FLEXIBLE_GEOMETRY_PLEN 0x1E |
| 526 | 		uint8_t xfr_rate_1;	/* transfer rate (MSB)		 */ |
| 527 | 		uint8_t xfr_rate_0;	/* transfer rate (LSB)		 */ |
| 528 | 		uint8_t nheads;	/* number of heads 		 */ |
| 529 | 		uint8_t sec_per_track;	/* Sectors per track		 */ |
| 530 | 		uint8_t bytes_s_1;	/* bytes per sector (MSB)	 */ |
| 531 | 		uint8_t bytes_s_0;	/* bytes per sector (LSB)	 */ |
| 532 | 		uint8_t ncyl_1;	/* number of cylinders (MSB)	 */ |
| 533 | 		uint8_t ncyl_0;	/* number of cylinders (LSB)	 */ |
| 534 | 		uint8_t st_cyl_wp_1;	/* starting cyl., write precomp (MSB) */ |
| 535 | 		uint8_t st_cyl_wp_0;	/* starting cyl., write precomp (LSB) */ |
| 536 | 		uint8_t st_cyl_rwc_1;	/* starting cyl., red. write cur (MSB)*/ |
| 537 | 		uint8_t st_cyl_rwc_0;	/* starting cyl., red. write cur (LSB)*/		 |
| 538 | 		uint8_t driv_step_1;	/* drive step rate (MSB)	 */ |
| 539 | 		uint8_t driv_step_0;	/* drive step rate (LSB)	 */ |
| 540 | 		uint8_t driv_step_pw;	/* drive step pulse width	 */ |
| 541 | 		uint8_t head_stl_del_1;/* Head settle delay (MSB)	 */ |
| 542 | 		uint8_t head_stl_del_0;/* Head settle delay (LSB)	 */ |
| 543 | 		uint8_t motor_on_del;	/* Motor on delay		 */ |
| 544 | 		uint8_t motor_off_del;	/* Motor off delay		 */ |
| 545 | 		uint8_t trdy_ssn_mo;	/* XXX ??? */ |
| 546 | 		uint8_t spc;		/* XXX ??? */ |
| 547 | 		uint8_t write_comp;	/* Write compensation */ |
| 548 | 		uint8_t head_load_del; /* Head load delay */ |
| 549 | 		uint8_t head_uload_del;/* Head un-load delay */ |
| 550 | 		uint8_t pin32_pin2; |
| 551 | 		uint8_t pin4_pint1; |
| 552 | 		uint8_t medium_rot_rate_1; /* medium rotation rate (RPM) (MSB) */ |
| 553 | 		uint8_t medium_rot_rate_0; /* medium rotation rate (RPM) (LSB) */		 |
| 554 | 		uint8_t reserved30; |
| 555 | 		uint8_t reserved31; |
| 556 | 	} flexible_disk;	 |
| 557 | }; |
| 558 | |
| 559 | /* |
| 560 | * XXX KDM |
| 561 | * Here for CTL compatibility, reconcile this. |
| 562 | */ |
| 563 | struct scsi_format_page { |
| 564 | 	uint8_t page_code; |
| 565 | 	uint8_t page_length; |
| 566 | 	uint8_t tracks_per_zone[2]; |
| 567 | 	uint8_t alt_sectors_per_zone[2]; |
| 568 | 	uint8_t alt_tracks_per_zone[2]; |
| 569 | 	uint8_t alt_tracks_per_lun[2]; |
| 570 | 	uint8_t sectors_per_track[2]; |
| 571 | 	uint8_t bytes_per_sector[2]; |
| 572 | 	uint8_t interleave[2]; |
| 573 | 	uint8_t track_skew[2]; |
| 574 | 	uint8_t cylinder_skew[2]; |
| 575 | 	uint8_t flags; |
| 576 | #define	SFP_SSEC	0x80 |
| 577 | #define	SFP_HSEC	0x40 |
| 578 | #define	SFP_RMB		0x20 |
| 579 | #define	SFP_SURF	0x10 |
| 580 | 	uint8_t reserved[3]; |
| 581 | }; |
| 582 | |
| 583 | /* |
| 584 | * XXX KDM |
| 585 | * Here for CTL compatibility, reconcile this. |
| 586 | */ |
| 587 | struct scsi_rigid_disk_page { |
| 588 | 	uint8_t page_code; |
| 589 | #define	SMS_RIGID_DISK_PAGE		0x04 |
| 590 | 	uint8_t page_length; |
| 591 | 	uint8_t cylinders[3]; |
| 592 | 	uint8_t heads; |
| 593 | 	uint8_t start_write_precomp[3]; |
| 594 | 	uint8_t start_reduced_current[3]; |
| 595 | 	uint8_t step_rate[2]; |
| 596 | 	uint8_t landing_zone_cylinder[3]; |
| 597 | 	uint8_t rpl; |
| 598 | #define	SRDP_RPL_DISABLED	0x00 |
| 599 | #define	SRDP_RPL_SLAVE		0x01 |
| 600 | #define	SRDP_RPL_MASTER		0x02 |
| 601 | #define	SRDP_RPL_MASTER_CONTROL	0x03 |
| 602 | 	uint8_t rotational_offset; |
| 603 | 	uint8_t reserved1; |
| 604 | 	uint8_t rotation_rate[2]; |
| 605 | 	uint8_t reserved2[2]; |
| 606 | }; |
| 607 | |
| 608 | struct scsi_da_rw_recovery_page { |
| 609 | 	uint8_t page_code; |
| 610 | #define SMS_RW_ERROR_RECOVERY_PAGE	0x01 |
| 611 | 	uint8_t page_length; |
| 612 | 	uint8_t byte3; |
| 613 | #define SMS_RWER_AWRE			0x80 |
| 614 | #define SMS_RWER_ARRE			0x40 |
| 615 | #define SMS_RWER_TB			0x20 |
| 616 | #define SMS_RWER_RC			0x10 |
| 617 | #define SMS_RWER_EER			0x08 |
| 618 | #define SMS_RWER_PER			0x04 |
| 619 | #define SMS_RWER_DTE			0x02 |
| 620 | #define SMS_RWER_DCR			0x01 |
| 621 | 	uint8_t read_retry_count; |
| 622 | 	uint8_t correction_span; |
| 623 | 	uint8_t head_offset_count; |
| 624 | 	uint8_t data_strobe_offset_cnt; |
| 625 | 	uint8_t byte8; |
| 626 | #define SMS_RWER_LBPERE			0x80 |
| 627 | 	uint8_t write_retry_count; |
| 628 | 	uint8_t reserved2; |
| 629 | 	uint8_t recovery_time_limit[2]; |
| 630 | }; |
| 631 | |
| 632 | struct scsi_da_verify_recovery_page { |
| 633 | 	uint8_t page_code; |
| 634 | #define SMS_VERIFY_ERROR_RECOVERY_PAGE	0x07 |
| 635 | 	uint8_t page_length; |
| 636 | 	uint8_t byte3; |
| 637 | #define SMS_VER_EER			0x08 |
| 638 | #define SMS_VER_PER			0x04 |
| 639 | #define SMS_VER_DTE			0x02 |
| 640 | #define SMS_VER_DCR			0x01 |
| 641 | 	uint8_t read_retry_count; |
| 642 | 	uint8_t reserved[6]; |
| 643 | 	uint8_t recovery_time_limit[2]; |
| 644 | }; |
| 645 | |
| 646 | __BEGIN_DECLS |
| 647 | /* |
| 648 | * XXX These are only left out of the kernel build to silence warnings. If, |
| 649 | * for some reason these functions are used in the kernel, the ifdefs should |
| 650 | * be moved so they are included both in the kernel and userland. |
| 651 | */ |
| 652 | #ifndef _KERNEL |
| 653 | void scsi_format_unit(struct ccb_scsiio *csio, uint32_t retries, |
| 654 | 		 void (*cbfcnp)(struct cam_periph *, union ccb *), |
| 655 | 		 uint8_t tag_action, uint8_t byte2, uint16_t ileave, |
| 656 | 		 uint8_t *data_ptr, uint32_t dxfer_len, |
| 657 | 		 uint8_t sense_len, uint32_t timeout); |
| 658 | |
| 659 | void scsi_read_defects(struct ccb_scsiio *csio, uint32_t retries, |
| 660 | 		 void (*cbfcnp)(struct cam_periph *, union ccb *), |
| 661 | 		 uint8_t tag_action, uint8_t list_format, |
| 662 | 		 uint32_t addr_desc_index, uint8_t *data_ptr, |
| 663 | 		 uint32_t dxfer_len, int minimum_cmd_size, |
| 664 | 		 uint8_t sense_len, uint32_t timeout); |
| 665 | |
| 666 | void scsi_sanitize(struct ccb_scsiio *csio, uint32_t retries, |
| 667 | 		 void (*cbfcnp)(struct cam_periph *, union ccb *), |
| 668 | 		 uint8_t tag_action, uint8_t byte2, uint16_t control, |
| 669 | 		 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t sense_len, |
| 670 | 		 uint32_t timeout); |
| 671 | |
| 672 | #endif /* !_KERNEL */ |
| 673 | |
| 674 | void scsi_zbc_out(struct ccb_scsiio *csio, uint32_t retries, |
| 675 | 		 void (*cbfcnp)(struct cam_periph *, union ccb *), |
| 676 | 		 uint8_t tag_action, uint8_t service_action, uint64_t zone_id, |
| 677 | 		 uint8_t zone_flags, uint8_t *data_ptr, uint32_t dxfer_len, |
| 678 | 		 uint8_t sense_len, uint32_t timeout); |
| 679 | |
| 680 | void scsi_zbc_in(struct ccb_scsiio *csio, uint32_t retries, |
| 681 | 		 void (*cbfcnp)(struct cam_periph *, union ccb *), |
| 682 | 		 uint8_t tag_action, uint8_t service_action, |
| 683 | 		 uint64_t zone_start_lba, uint8_t zone_options, |
| 684 | 		 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t sense_len, |
| 685 | 		 uint32_t timeout); |
| 686 | |
| 687 | int scsi_ata_zac_mgmt_out(struct ccb_scsiio *csio, uint32_t retries, |
| 688 | 			 void (*cbfcnp)(struct cam_periph *, union ccb *), |
| 689 | 			 uint8_t tag_action, int use_ncq, |
| 690 | 			 uint8_t zm_action, uint64_t zone_id, |
| 691 | 			 uint8_t zone_flags, uint8_t *data_ptr, |
| 692 | 			 uint32_t dxfer_len, uint8_t *cdb_storage, |
| 693 | 			 size_t cdb_storage_len, uint8_t sense_len, |
| 694 | 			 uint32_t timeout); |
| 695 | |
| 696 | int scsi_ata_zac_mgmt_in(struct ccb_scsiio *csio, uint32_t retries, |
| 697 | 			 void (*cbfcnp)(struct cam_periph *, union ccb *), |
| 698 | 			 uint8_t tag_action, int use_ncq, |
| 699 | 			 uint8_t zm_action, uint64_t zone_id, |
| 700 | 			 uint8_t zone_flags, uint8_t *data_ptr, |
| 701 | 			 uint32_t dxfer_len, uint8_t *cdb_storage, |
| 702 | 			 size_t cdb_storage_len, uint8_t sense_len, |
| 703 | 			 uint32_t timeout); |
| 704 | |
| 705 | __END_DECLS |
| 706 | |
| 707 | #endif /* _SCSI_SCSI_DA_H */ |