1 /* $OpenBSD: scsi_disk.h,v 1.35 2015/06/07 19:13:27 krw Exp $ */ 2 /* $NetBSD: scsi_disk.h,v 1.10 1996/07/05 16:19:05 christos Exp $ */ 3 4 /* 5 * SCSI interface description 6 */ 7 8 /* 9 * Some lines of this file come from a file of the name "scsi.h" 10 * distributed by OSF as part of mach2.5, 11 * so the following disclaimer has been kept. 12 * 13 * Copyright 1990 by Open Software Foundation, 14 * Grenoble, FRANCE 15 * 16 * All Rights Reserved 17 * 18 * Permission to use, copy, modify, and distribute this software and 19 * its documentation for any purpose and without fee is hereby granted, 20 * provided that the above copyright notice appears in all copies and 21 * that both the copyright notice and this permission notice appear in 22 * supporting documentation, and that the name of OSF or Open Software 23 * Foundation not be used in advertising or publicity pertaining to 24 * distribution of the software without specific, written prior 25 * permission. 26 * 27 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 28 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, 29 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 30 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 31 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 32 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 33 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 34 */ 35 36 /* 37 * Largely written by Julian Elischer (julian@tfs.com) 38 * for TRW Financial Systems. 39 * 40 * TRW Financial Systems, in accordance with their agreement with Carnegie 41 * Mellon University, makes this software available to CMU to distribute 42 * or use in any manner that they see fit as long as this message is kept with 43 * the software. For this reason TFS also grants any other persons or 44 * organisations permission to use or modify this software. 45 * 46 * TFS supplies this software to be publicly redistributed 47 * on the understanding that TFS is not responsible for the correct 48 * functioning of this software in any circumstances. 49 * 50 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 51 */ 52 53 /* 54 * SCSI command format 55 */ 56 57 #ifndef _SCSI_SCSI_DISK_H 58 #define _SCSI_SCSI_DISK_H 1 59 60 /* 61 * XXX Is this also used by ATAPI? 62 */ 63 #define FORMAT_UNIT 0x04 64 struct scsi_format_unit { 65 u_int8_t opcode; 66 u_int8_t flags; 67 #define SFU_DLF_MASK 0x07 68 #define SFU_CMPLST 0x08 69 #define SFU_FMTDATA 0x10 70 u_int8_t vendor_specific; 71 u_int8_t interleave[2]; 72 u_int8_t control; 73 }; 74 75 /* 76 * If the FmtData bit is set, a FORMAT UNIT parameter list is transferred 77 * to the target during the DATA OUT phase. The parameter list includes 78 * 79 * Defect list header 80 * Initialization pattern descriptor (if any) 81 * Defect descriptor(s) (if any) 82 */ 83 84 struct scsi_format_unit_defect_list_header { 85 u_int8_t reserved; 86 u_int8_t flags; 87 #define DLH_VS 0x01 /* vendor specific */ 88 #define DLH_IMMED 0x02 /* immediate return */ 89 #define DLH_DSP 0x04 /* disable saving parameters */ 90 #define DLH_IP 0x08 /* initialization pattern */ 91 #define DLH_STPF 0x10 /* stop format */ 92 #define DLH_DCRT 0x20 /* disable certification */ 93 #define DLH_DPRY 0x40 /* disable primary */ 94 #define DLH_FOV 0x80 /* format options valid */ 95 u_int8_t defect_lst_len[2]; 96 }; 97 98 /* 99 * See Table 117 of the SCSI-2 specification for a description of 100 * the IP modifier. 101 */ 102 struct scsi_initialization_pattern_descriptor { 103 u_int8_t ip_modifier; 104 u_int8_t pattern_type; 105 #define IP_TYPE_DEFAULT 0x01 106 #define IP_TYPE_REPEAT 0x01 107 /* 0x02 -> 0x7f: reserved */ 108 /* 0x80 -> 0xff: vendor-specific */ 109 u_int8_t pattern_length[2]; 110 #if 0 111 u_int8_t pattern[...]; 112 #endif 113 }; 114 115 /* 116 * Defect desciptors. These are used as the defect lists in the FORMAT UNIT 117 * and READ DEFECT DATA commands, and as the translate page of the 118 * SEND DIAGNOSTIC and RECEIVE DIAGNOSTIC RESULTS commands. 119 */ 120 121 /* Block format */ 122 struct scsi_defect_descriptor_bf { 123 u_int8_t block_address[4]; 124 }; 125 126 /* Bytes from index format */ 127 struct scsi_defect_descriptor_bfif { 128 u_int8_t cylinder[2]; 129 u_int8_t head; 130 u_int8_t bytes_from_index[2]; 131 }; 132 133 /* Physical sector format */ 134 struct scsi_defect_descriptor_psf { 135 u_int8_t cylinder[2]; 136 u_int8_t head; 137 u_int8_t sector[2]; 138 }; 139 140 141 struct scsi_reassign_blocks { 142 u_int8_t opcode; 143 u_int8_t byte2; 144 u_int8_t unused[3]; 145 u_int8_t control; 146 }; 147 148 /* 149 * XXX Is this also used by ATAPI? 150 */ 151 #define REZERO_UNIT 0x01 152 struct scsi_rezero_unit { 153 u_int8_t opcode; 154 u_int8_t byte2; 155 u_int8_t reserved[3]; 156 u_int8_t control; 157 }; 158 159 struct scsi_rw { 160 u_int8_t opcode; 161 u_int8_t addr[3]; 162 #define SRW_TOPADDR 0x1F /* only 5 bits here */ 163 u_int8_t length; 164 u_int8_t control; 165 }; 166 167 struct scsi_rw_big { 168 u_int8_t opcode; 169 u_int8_t byte2; 170 #define SRWB_RELADDR 0x01 171 u_int8_t addr[4]; 172 u_int8_t reserved; 173 u_int8_t length[2]; 174 u_int8_t control; 175 }; 176 177 struct scsi_rw_12 { 178 u_int8_t opcode; 179 u_int8_t byte2; 180 u_int8_t addr[4]; 181 u_int8_t length[4]; 182 u_int8_t reserved; 183 u_int8_t control; 184 }; 185 186 struct scsi_rw_16 { 187 u_int8_t opcode; 188 u_int8_t byte2; 189 u_int8_t addr[8]; 190 u_int8_t length[4]; 191 u_int8_t reserved; 192 u_int8_t control; 193 }; 194 195 struct scsi_write_same_10 { 196 u_int8_t opcode; 197 u_int8_t flags; 198 #define WRITE_SAME_F_LBDATA (1 << 1) 199 #define WRITE_SAME_F_PBDATA (1 << 2) 200 u_int8_t lba[4]; 201 u_int8_t group_number; 202 u_int8_t length[2]; 203 u_int8_t control; 204 }; 205 206 struct scsi_write_same_16 { 207 u_int8_t opcode; 208 u_int8_t flags; 209 /* includes WRITE SAME 10 flags */ 210 #define WRITE_SAME_F_UNMAP (1 << 3) 211 #define WRITE_SAME_F_ANCHOR (1 << 4) 212 u_int8_t lba[8]; 213 u_int8_t length[4]; 214 u_int8_t group_number; 215 u_int8_t control; 216 }; 217 218 struct scsi_unmap { 219 u_int8_t opcode; 220 u_int8_t anchor; 221 u_int8_t _reserved[4]; 222 u_int8_t group_number; 223 u_int8_t list_len[2]; 224 u_int8_t control; 225 }; 226 227 struct scsi_unmap_data { 228 u_int8_t data_length[2]; 229 u_int8_t desc_length[2]; 230 u_int8_t _reserved[4]; 231 232 /* followed by struct scsi_unmap_desc */ 233 }; 234 235 struct scsi_unmap_desc { 236 u_int8_t logical_addr[8]; 237 u_int8_t logical_blocks[4]; 238 u_int8_t _reserved[4]; 239 }; 240 241 struct scsi_read_capacity { 242 u_int8_t opcode; 243 u_int8_t byte2; 244 u_int8_t addr[4]; 245 u_int8_t unused[3]; 246 u_int8_t control; 247 }; 248 249 struct scsi_read_capacity_16 { 250 u_int8_t opcode; 251 u_int8_t byte2; 252 #define SRC16_SERVICE_ACTION 0x10 253 u_int8_t addr[8]; 254 u_int8_t length[4]; 255 u_int8_t reserved; 256 u_int8_t control; 257 }; 258 259 struct scsi_start_stop { 260 u_int8_t opcode; 261 u_int8_t byte2; 262 u_int8_t unused[2]; 263 u_int8_t how; 264 #define SSS_STOP 0x00 265 #define SSS_START 0x01 266 #define SSS_LOEJ 0x02 267 u_int8_t control; 268 }; 269 270 271 /* 272 * XXX Does ATAPI have an equivalent? 273 */ 274 struct scsi_synchronize_cache { 275 u_int8_t opcode; 276 u_int8_t flags; 277 #define SSC_RELADR 0x01 278 #define SSC_IMMED 0x02 279 u_int8_t addr[4]; 280 u_int8_t reserved; 281 u_int8_t length[2]; 282 u_int8_t control; 283 }; 284 285 286 287 /* 288 * Disk specific opcodes 289 */ 290 #define REASSIGN_BLOCKS 0x07 291 #define READ_COMMAND 0x08 292 #define WRITE_COMMAND 0x0a 293 #define READ_CAPACITY 0x25 294 #define READ_CAPACITY_16 0x9e 295 #define READ_BIG 0x28 296 #define WRITE_BIG 0x2a 297 #define READ_12 0xa8 298 #define WRITE_12 0xaa 299 #define READ_16 0x88 300 #define WRITE_16 0x8a 301 #define SYNCHRONIZE_CACHE 0x35 302 #define WRITE_SAME_10 0x41 303 #define WRITE_SAME_16 0x93 304 #define UNMAP 0x42 305 306 307 struct scsi_read_cap_data { 308 u_int8_t addr[4]; 309 u_int8_t length[4]; 310 }; 311 312 struct scsi_read_cap_data_16 { 313 u_int8_t addr[8]; 314 u_int8_t length[4]; 315 u_int8_t p_type_prot; 316 u_int8_t logical_per_phys; 317 u_int8_t lowest_aligned[2]; 318 #define READ_CAP_16_TPE 0x8000 319 #define READ_CAP_16_TPRZ 0x4000 320 u_int8_t reserved[16]; 321 }; 322 323 struct scsi_reassign_blocks_data { 324 u_int8_t reserved[2]; 325 u_int8_t length[2]; 326 struct { 327 u_int8_t dlbaddr[4]; 328 } defect_descriptor[1]; 329 }; 330 331 /* Only the lower 6 bits of the pg_code field are used for page #. */ 332 #define DISK_PGCODE(pg, n) ((pg) != NULL) && (((pg)->pg_code & 0x3f) == n) 333 #define PAGE_DISK_FORMAT 3 334 #define PAGE_RIGID_GEOMETRY 4 335 #define PAGE_FLEX_GEOMETRY 5 336 #define PAGE_REDUCED_GEOMETRY 6 337 #define PAGE_CACHING_MODE 8 338 339 struct page_disk_format { 340 u_int8_t pg_code; /* page code (should be 3) */ 341 u_int8_t pg_length; /* page length (should be 0x16) */ 342 u_int8_t trk_z[2]; /* tracks per zone */ 343 u_int8_t alt_sec[2]; /* alternate sectors per zone */ 344 u_int8_t alt_trk_z[2]; /* alternate tracks per zone */ 345 u_int8_t alt_trk_v[2]; /* alternate tracks per volume */ 346 u_int8_t ph_sec_t[2]; /* physical sectors per track */ 347 u_int8_t bytes_s[2]; /* bytes per sector */ 348 u_int8_t interleave[2]; /* interleave */ 349 u_int8_t trk_skew[2]; /* track skew factor */ 350 u_int8_t cyl_skew[2]; /* cylinder skew */ 351 u_int8_t flags; /* various */ 352 #define DISK_FMT_SURF 0x10 353 #define DISK_FMT_RMB 0x20 354 #define DISK_FMT_HSEC 0x40 355 #define DISK_FMT_SSEC 0x80 356 u_int8_t reserved1; 357 u_int8_t reserved2; 358 u_int8_t reserved3; 359 }; 360 361 struct page_rigid_geometry { 362 u_int8_t pg_code; /* page code (should be 4) */ 363 u_int8_t pg_length; /* page length (should be 0x12 or 0x16) */ 364 u_int8_t ncyl[3]; /* number of cylinders */ 365 u_int8_t nheads; /* number of heads */ 366 u_int8_t st_cyl_wp[3]; /* starting cyl., write precomp */ 367 u_int8_t st_cyl_rwc[3]; /* starting cyl., red. write cur */ 368 u_int8_t driv_step[2]; /* drive step rate */ 369 u_int8_t land_zone[3]; /* landing zone cylinder */ 370 u_int8_t sp_sync_ctl; /* spindle synch control */ 371 #define SPINDLE_SYNCH_MASK 0x03 /* mask of valid bits */ 372 #define SPINDLE_SYNCH_NONE 0x00 /* synch disabled or not supported */ 373 #define SPINDLE_SYNCH_SLAVE 0x01 /* disk is a slave */ 374 #define SPINDLE_SYNCH_MASTER 0x02 /* disk is a master */ 375 #define SPINDLE_SYNCH_MCONTROL 0x03 /* disk is a master control */ 376 u_int8_t rot_offset; /* rotational offset (for spindle synch) */ 377 u_int8_t reserved1; 378 u_int8_t rpm[2]; /* media rotation speed */ 379 u_int8_t reserved2; 380 u_int8_t reserved3; 381 }; 382 383 struct page_flex_geometry { 384 u_int8_t pg_code; /* page code (should be 5) */ 385 u_int8_t pg_length; /* page length (should be 0x1a or 0x1e) */ 386 u_int8_t xfr_rate[2]; 387 u_int8_t nheads; /* number of heads */ 388 u_int8_t ph_sec_tr; /* physical sectors per track */ 389 u_int8_t bytes_s[2]; /* bytes per sector */ 390 u_int8_t ncyl[2]; /* number of cylinders */ 391 u_int8_t st_cyl_wp[2]; /* start cyl., write precomp */ 392 u_int8_t st_cyl_rwc[2]; /* start cyl., red. write cur */ 393 u_int8_t driv_step[2]; /* drive step rate */ 394 u_int8_t driv_step_w; /* drive step pulse width */ 395 u_int8_t head_settle[2];/* head settle delay */ 396 u_int8_t motor_on; /* motor on delay */ 397 u_int8_t motor_off; /* motor off delay */ 398 u_int8_t flags; /* various flags */ 399 #define MOTOR_ON 0x20 /* motor on (pin 16)? */ 400 #define START_AT_SECTOR_1 0x40 /* start at sector 1 */ 401 #define READY_VALID 0x20 /* RDY (pin 34) valid */ 402 u_int8_t step_p_cyl; /* step pulses per cylinder */ 403 u_int8_t write_pre; /* write precompensation */ 404 u_int8_t head_load; /* head load delay */ 405 u_int8_t head_unload; /* head unload delay */ 406 u_int8_t pin_34_2; /* pin 34 (6) pin 2 (7/11) definition */ 407 u_int8_t pin_4_1; /* pin 4 (8/9) pin 1 (13) definition */ 408 u_int8_t rpm[2]; /* media rotation speed */ 409 u_int8_t reserved1; 410 u_int8_t reserved2; 411 }; 412 413 struct page_reduced_geometry { 414 u_int8_t pg_code; /* page code (should be 6) */ 415 u_int8_t pg_length; /* page length (should be 0x0B) */ 416 u_int8_t wcd; /* bit 0 = write cache disable */ 417 u_int8_t bytes_s[2]; /* bytes per sector */ 418 u_int8_t sectors[5]; /* total number of sectors */ 419 u_int8_t pow_perf; /* power/performance level */ 420 u_int8_t flags; /* various */ 421 #define LOCK_DISABLED 0x1 422 #define FORMAT_DISABLED 0x2 423 #define WRITE_DISABLED 0x4 424 #define READ_DISABLED 0x8 425 u_int8_t reserved; 426 }; 427 428 struct page_caching_mode { 429 u_int8_t pg_code; /* page code (should be 8) */ 430 u_int8_t pg_length; /* page length (should be 0x12) */ 431 u_int8_t flags; 432 #define PG_CACHE_FL_RCD (1<<0) 433 #define PG_CACHE_FL_MF (1<<1) 434 #define PG_CACHE_FL_WCE (1<<2) 435 #define PG_CACHE_FL_SIZE (1<<3) 436 #define PG_CACHE_FL_DISC (1<<4) 437 #define PG_CACHE_FL_CAP (1<<5) 438 #define PG_CACHE_FL_ABPF (1<<6) 439 #define PG_CACHE_FL_IC (1<<7) 440 u_int8_t priority; 441 #define PG_CACHE_PRI_DEMAND(_f) ((_f) & 0x0f) 442 #define PG_CACHE_PRI_WRITE(_f) (((_f) >> 4) & 0x0f) 443 u_int8_t dis_prefetch_tl[2]; 444 u_int8_t min_prefetch[2]; 445 u_int8_t max_prefetch[2]; 446 u_int8_t max_prefetch_ceil[2]; 447 }; 448 449 #define SI_PG_DISK_LIMITS 0xb0 /* block limits */ 450 #define SI_PG_DISK_INFO 0xb1 /* device charateristics */ 451 #define SI_PG_DISK_THIN 0xb2 /* thin provisioning */ 452 453 struct scsi_vpd_disk_limits { 454 struct scsi_vpd_hdr hdr; 455 #define SI_PG_DISK_LIMITS_LEN 0x10 456 #define SI_PG_DISK_LIMITS_LEN_THIN 0x3c 457 458 u_int8_t _reserved1[1]; 459 u_int8_t max_comp_wr_len; 460 u_int8_t optimal_xfer_granularity[2]; 461 462 u_int8_t max_xfer_len[4]; 463 464 u_int8_t optimal_xfer[4]; 465 466 u_int8_t max_xd_prefetch_len[4]; 467 468 u_int8_t max_unmap_lba_count[4]; 469 470 u_int8_t max_unmap_desc_count[4]; 471 472 u_int8_t optimal_unmap_granularity[4]; 473 474 u_int8_t unmap_granularity_align[4]; 475 #define SI_PG_DISK_LIMITS_UGAVALID (1U << 31) 476 477 u_int8_t _reserved2[28]; 478 }; 479 480 struct scsi_vpd_disk_info { 481 struct scsi_vpd_hdr hdr; 482 u_int8_t rpm[2]; 483 #define VPD_DISK_INFO_RPM_UNDEF 0x0000 484 #define VPD_DISK_INFO_RPM_NONE 0x0001 485 u_int8_t _reserved1[1]; 486 u_int8_t form_factor; 487 #define VPD_DISK_INFO_FORM_MASK 0xf 488 #define VPD_DISK_INFO_FORM_UNDEF 0x0 489 #define VPD_DISK_INFO_FORM_5_25 0x1 490 #define VPD_DISK_INFO_FORM_3_5 0x2 491 #define VPD_DISK_INFO_FORM_2_5 0x3 492 #define VPD_DISK_INFO_FORM_1_8 0x4 493 #define VPD_DISK_INFO_FORM_LT_1_8 0x5 494 u_int8_t _reserved2[56]; 495 }; 496 497 struct scsi_vpd_disk_thin { 498 struct scsi_vpd_hdr hdr; 499 500 u_int8_t threshold_exponent; 501 u_int8_t flags; 502 #define VPD_DISK_THIN_DP (1 << 0) /* descriptor present */ 503 #define VPD_DISK_THIN_ANC_SUP (0x7 << 1) 504 #define VPD_DISK_THIN_ANC_SUP_NO (0x0 << 1) 505 #define VPD_DISK_THIN_ANC_SUP_YES (0x1 << 1) 506 #define VPD_DISK_THIN_TPWS (1 << 6) /* WRITE SAME 16 */ 507 #define VPD_DISK_THIN_TPU (1 << 7) /* UNMAP */ 508 u_int8_t _reserved1[2]; 509 510 /* followed by a designation descriptor if DP is set */ 511 }; 512 513 #endif /* _SCSI_SCSI_DISK_H */ 514