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