xref: /illumos-gate/usr/src/uts/common/sys/scsi/generic/mode.h (revision fa4a3e77edc40df6d92e8da6fc4961d275e9896d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  * Copyright 2017 Nexenta Systems, Inc.
26  */
27 
28 #ifndef	_SYS_SCSI_GENERIC_MODE_H
29 #define	_SYS_SCSI_GENERIC_MODE_H
30 
31 #ifdef	__cplusplus
32 extern "C" {
33 #endif
34 
35 /*
36  *
37  * Defines and Structures for SCSI Mode Sense/Select data - generic
38  *
39  */
40 
41 /*
42  * Structures and defines common for all device types
43  */
44 
45 /*
46  * Mode Sense/Select Header - Group 0 (6-byte).
47  *
48  * Mode Sense/Select data consists of a header, followed by zero or more
49  * block descriptors, followed by zero or more mode pages.
50  *
51  */
52 
53 struct mode_header {
54 	uchar_t length;		/* number of bytes following */
55 	uchar_t medium_type;	/* device specific */
56 	uchar_t device_specific;	/* device specific parameters */
57 	uchar_t bdesc_length;	/* length of block descriptor(s), if any */
58 };
59 
60 #define	MODE_HEADER_LENGTH	(sizeof (struct mode_header))
61 
62 /*
63  * Mode Sense/Select Header - Group 1 (10-bytes)
64  */
65 
66 struct mode_header_g1 {
67 	ushort_t	length;		/* number of bytes following */
68 	uchar_t		medium_type;	/* device specific */
69 	uchar_t		device_specific;	/* device specific parameters */
70 	uchar_t		reserved[2];	/* device specific parameters */
71 	ushort_t	bdesc_length;	/* len of block descriptor(s), if any */
72 };
73 
74 #define	MODE_HEADER_LENGTH_G1	(sizeof (struct mode_header_g1))
75 
76 /*
77  * Block Descriptor. Zero, one, or more may normally follow the mode header.
78  *
79  * The density code is device specific.
80  *
81  * The 24-bit value described by blks_{hi, mid, lo} describes the number of
82  * blocks which this block descriptor applies to. A value of zero means
83  * 'the rest of the blocks on the device'.
84  *
85  * The 24-bit value described by blksize_{hi, mid, lo} describes the blocksize
86  * (in bytes) applicable for this block descriptor. For Sequential Access
87  * devices, if this value is zero, the block size will be derived from
88  * the transfer length in I/O operations.
89  *
90  */
91 
92 struct block_descriptor {
93 	uchar_t density_code;	/* device specific */
94 	uchar_t blks_hi;	/* hi  */
95 	uchar_t blks_mid;	/* mid */
96 	uchar_t blks_lo;	/* low */
97 	uchar_t reserved;	/* reserved */
98 	uchar_t blksize_hi;	/* hi  */
99 	uchar_t blksize_mid;	/* mid */
100 	uchar_t blksize_lo;	/* low */
101 };
102 
103 #define	MODE_BLK_DESC_LENGTH	(sizeof (struct block_descriptor))
104 #define	MODE_PARAM_LENGTH 	(MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH)
105 
106 /*
107  * Define a macro to take an address of a mode header to the address
108  * of the nth (0..n) block_descriptor, or NULL if there either aren't any
109  * block descriptors or the nth block descriptor doesn't exist.
110  */
111 
112 #define	BLOCK_DESCRIPTOR_ADDR(mhdr, bdnum) \
113 	((mhdr)->bdesc_length && ((unsigned)(bdnum)) < \
114 	((mhdr)->bdesc_length/(sizeof (struct block_descriptor)))) ? \
115 	((struct block_descriptor *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+ \
116 	((bdnum) * sizeof (struct block_descriptor)))) : \
117 	((struct block_descriptor *)0)
118 
119 /*
120  * Mode page header. Zero or more Mode Pages follow either the block
121  * descriptors (if any), or the Mode Header.
122  *
123  * The 'ps' bit must be zero for mode select operations.
124  *
125  */
126 
127 struct mode_page {
128 #if defined(_BIT_FIELDS_LTOH)
129 	uchar_t	code	:6,	/* page code number */
130 			:1,	/* reserved */
131 		ps	:1;	/* 'Parameter Saveable' bit */
132 #elif defined(_BIT_FIELDS_HTOL)
133 	uchar_t	ps	:1,	/* 'Parameter Saveable' bit */
134 			:1,	/* reserved */
135 		code	:6;	/* page code number */
136 #else
137 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
138 #endif	/* _BIT_FIELDS_LTOH */
139 	uchar_t	length;		/* length of bytes to follow */
140 	/*
141 	 * Mode Page specific data follows right after this...
142 	 */
143 };
144 
145 /*
146  * Define a macro to retrieve the first mode page. Could be more
147  * general (for multiple mode pages).
148  */
149 
150 #define	MODE_PAGE_ADDR(mhdr, type)	\
151 	((type *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+(mhdr)->bdesc_length))
152 
153 /*
154  * Page Control field (bits 7 and 6) follows the following specification:
155  *
156  * 	Value			Meaning
157  * 	----------------------------------------------------------------------
158  * 	00b			current values
159  * 	01b			changeable values
160  * 	10b			default values
161  * 	11b			saved values
162  */
163 
164 #define	MODEPAGE_CURRENT	0x00
165 #define	MODEPAGE_CHANGEABLE	0x40
166 #define	MODEPAGE_DEFAULT	0x80
167 #define	MODEPAGE_SAVED		0xC0
168 
169 /*
170  * Page codes follow the following specification:
171  *
172  *	Code Value(s)		What
173  *	----------------------------------------------------------------------
174  *	0x00			Vendor Unique (does not require page format)
175  *
176  *	0x02, 0x09, 0x0A	pages for all Device Types
177  *	0x1A, 0x1C
178  *
179  *	0x01, 0x03-0x08,	pages for specific Device Type
180  *	0x0B-0x19, 0x1B,
181  *	0x1D-0x1F
182  *
183  *	0x20-0x3E		Vendor Unique (requires page format)
184  *
185  *	0x3F			Return all pages (valid for Mode Sense only)
186  *
187  */
188 
189 /*
190  * Page codes and page length values (all device types)
191  */
192 
193 #define	MODEPAGE_DISCO_RECO	0x02
194 #define	MODEPAGE_FORMAT		0x03
195 #define	MODEPAGE_GEOMETRY	0x04
196 #define	MODEPAGE_CACHING	0x08
197 #define	MODEPAGE_PDEVICE	0x09
198 #define	MODEPAGE_CTRL_MODE	0x0A
199 #define	MODEPAGE_POWER_COND	0x1A
200 #define	MODEPAGE_INFO_EXCPT	0x1C
201 
202 #define	MODEPAGE_ALLPAGES	0x3F
203 
204 /*
205  * Mode Select/Sense page structures (for all device types)
206  */
207 
208 /*
209  * Disconnect/Reconnect Page
210  */
211 
212 struct mode_disco_reco {
213 	struct	mode_page mode_page;	/* common mode page header */
214 	uchar_t	buffer_full_ratio;	/* write, how full before reconnect? */
215 	uchar_t	buffer_empty_ratio;	/* read, how full before reconnect? */
216 	ushort_t bus_inactivity_limit;	/* how much bus quiet time for BSY- */
217 	ushort_t disconect_time_limit;	/* min to remain disconnected */
218 	ushort_t connect_time_limit;	/* min to remain connected */
219 	ushort_t max_burst_size;	/* max data burst size */
220 #if defined(_BIT_FIELDS_LTOH)
221 	uchar_t		dtdc	: 3,	/* data transfer disconenct control */
222 			dimm	: 1,	/* disconnect immediate */
223 			fastat	: 1,	/* fair for status */
224 			fawrt	: 1,	/* fair for write */
225 			fard	: 1,	/* fair for read */
226 			emdp	: 1;	/* enable modify data pointers */
227 #elif defined(_BIT_FIELDS_HTOL)
228 	uchar_t		emdp	: 1,	/* enable modify data pointers */
229 			fard	: 1,	/* fair for read */
230 			fawrt	: 1,	/* fair for write */
231 			fastat	: 1,	/* fair for status */
232 			dimm	: 1,	/* disconnect immediate */
233 			dtdc	: 3;	/* data transfer disconenct control */
234 #else
235 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
236 #endif	/* _BIT_FIELDS_LTOH */
237 	uchar_t	reserved;
238 	ushort_t first_burst_sz;	/* first burst size */
239 };
240 
241 #define	DTDC_DATADONE	0x01
242 					/*
243 					 * Target may not disconnect once
244 					 * data transfer is started until
245 					 * all data successfully transferred.
246 					 */
247 
248 #define	DTDC_CMDDONE	0x03
249 					/*
250 					 * Target may not disconnect once
251 					 * data transfer is started until
252 					 * command completed.
253 					 */
254 /*
255  * Caching Page
256  */
257 
258 struct mode_caching {
259 	struct	mode_page mode_page;	/* common mode page header */
260 #if defined(_BIT_FIELDS_LTOH)
261 	uchar_t	rcd		: 1,	/* Read Cache Disable */
262 		mf		: 1,	/* Multiplication Factor */
263 		wce		: 1,	/* Write Cache Enable */
264 				: 5;	/* Reserved */
265 	uchar_t	write_ret_prio	: 4,	/* Write Retention Priority */
266 		dmd_rd_ret_prio	: 4;	/* Demand Read Retention Priority */
267 #elif defined(_BIT_FIELDS_HTOL)
268 	uchar_t			: 5,	/* Reserved */
269 		wce		: 1,	/* Write Cache Enable */
270 		mf		: 1,	/* Multiplication Factor */
271 		rcd		: 1;	/* Read Cache Disable */
272 	uchar_t	dmd_rd_ret_prio	: 4,	/* Demand Read Retention Priority */
273 		write_ret_prio	: 4;	/* Write Retention Priority */
274 #else
275 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
276 #endif	/* _BIT_FIELDS_LTOH */
277 	ushort_t pf_dsbl_trans_len;	/* Disable prefetch transfer length */
278 	ushort_t min_prefetch;		/* Minimum Prefetch */
279 	ushort_t max_prefetch;		/* Maximum Prefetch */
280 	ushort_t max_prefetch_ceiling;	/* Maximum Prefetch Ceiling */
281 };
282 
283 /*
284  * Peripheral Device Page
285  */
286 
287 struct mode_pdevice {
288 	struct	mode_page mode_page;	/* common mode page header */
289 	ushort_t if_ident;		/* interface identifier */
290 	uchar_t	reserved[4];		/* reserved */
291 	uchar_t	vendor_uniqe[1];	/* vendor unique data */
292 };
293 
294 #define	PDEV_SCSI	0x0000		/* scsi interface */
295 #define	PDEV_SMD	0x0001		/* SMD interface */
296 #define	PDEV_ESDI	0x0002		/* ESDI interface */
297 #define	PDEV_IPI2	0x0003		/* IPI-2 interface */
298 #define	PDEV_IPI3	0x0004		/* IPI-3 interface */
299 
300 /*
301  * Control Mode Page
302  *
303  * Note:	This structure is incompatible with previous SCSI
304  *		implementations. See <scsi/impl/mode.h> for an
305  *		alternative form of this structure. They can be
306  *		distinguished by the length of data returned
307  *		from a MODE SENSE command.
308  */
309 
310 #define	PAGELENGTH_MODE_CONTROL_SCSI3	0x0A
311 
312 struct mode_control_scsi3 {
313 	struct	mode_page mode_page;	/* common mode page header */
314 #if defined(_BIT_FIELDS_LTOH)
315 	uchar_t		rlec	: 1,	/* Report Log Exception bit */
316 			gltsd	: 1,	/* global logging target save disable */
317 			d_sense	: 1,	/* Use descriptor sense data (SPC-3) */
318 				: 5;
319 	uchar_t		qdisable: 1,	/* Queue disable */
320 			que_err	: 1,	/* Queue error */
321 				: 2,
322 			que_mod : 4;    /* Queue algorithm modifier */
323 	uchar_t		eanp	: 1,	/* Enable AEN permission */
324 			uaaenp  : 1,	/* Unit attention AEN permission */
325 			raenp   : 1,	/* Ready AEN permission */
326 				: 1,
327 			bybths	: 1,	/* By both RESET signal */
328 			byprtm	: 1,	/* By port message */
329 			rac	: 1,	/* report a check */
330 			eeca	: 1;	/* enable extended contingent */
331 					/* allegiance (only pre-SCSI-3) */
332 #elif defined(_BIT_FIELDS_HTOL)
333 	uchar_t			: 5,
334 			d_sense	: 1,	/* Use descriptor sense data (SPC-3) */
335 			gltsd	: 1,	/* global logging target save disable */
336 			rlec	: 1;	/* Report Log Exception bit */
337 	uchar_t		que_mod	: 4,	/* Queue algorithm modifier */
338 				: 2,
339 			que_err	: 1,	/* Queue error */
340 			qdisable: 1;	/* Queue disable */
341 	uchar_t		eeca	: 1,	/* enable extended contingent */
342 					/* allegiance (only pre-SCSI-3) */
343 			rac	: 1,	/* report a check */
344 			byprtm	: 1,	/* By port message */
345 			bybths	: 1,	/* By both RESET signal */
346 				: 1,
347 			raenp   : 1,	/* Ready AEN permission */
348 			uaaenp  : 1,	/* Unit attention AEN permission */
349 			eanp	: 1;	/* Enable AEN permission */
350 #else
351 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
352 #endif	/* _BIT_FIELDS_LTOH */
353 	uchar_t	reserved;
354 	ushort_t ready_aen_holdoff;	/* Ready AEN holdoff period */
355 	ushort_t busy_timeout;		/* Busy timeout period */
356 	uchar_t	reserved_2[2];
357 };
358 
359 #ifdef __lock_lint
360 _NOTE(SCHEME_PROTECTS_DATA("Unshared SCSI payload", \
361 	mode_control_scsi3))
362 #endif
363 
364 #define	CTRL_QMOD_RESTRICT	0x0
365 #define	CTRL_QMOD_UNRESTRICT	0x1
366 
367 /*
368  * Informational Exceptions Control Mode Page
369  */
370 
371 #define	PAGELENGTH_INFO_EXCPT	0x0A
372 
373 struct mode_info_excpt_page {
374 	struct	mode_page mode_page;	/* common mode page header */
375 #if defined(_BIT_FIELDS_LTOH)
376 	uchar_t		log_err	: 1;	/* log errors */
377 	uchar_t			: 1;	/* reserved */
378 	uchar_t		test	: 1;	/* create test failure */
379 	uchar_t		dexcpt	: 1;	/* disable exception */
380 	uchar_t		ewasc	: 1;	/* enable warning */
381 	uchar_t		ebf	: 1;	/* enable background function */
382 	uchar_t			: 1;	/* reserved */
383 	uchar_t		perf	: 1;	/* performance */
384 	uchar_t		mrie	: 4;	/* method of reporting info. excpts. */
385 	uchar_t			: 4;	/* reserved */
386 #elif defined(_BIT_FIELDS_HTOL)
387 	uchar_t		perf	: 1;	/* performance */
388 	uchar_t			: 1;	/* reserved */
389 	uchar_t		ebf	: 1;	/* enable background function */
390 	uchar_t		ewasc	: 1;	/* enable warning */
391 	uchar_t		dexcpt	: 1;	/* disable exception */
392 	uchar_t		test	: 1;	/* create test failure */
393 	uchar_t			: 1;	/* reserved */
394 	uchar_t		log_err	: 1;	/* log errors */
395 	uchar_t			: 4;	/* reserved */
396 	uchar_t		mrie	: 4;	/* method of reporting info. excpts. */
397 #else
398 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
399 #endif
400 	uchar_t	interval_timer[4];	/* interval timer */
401 	uchar_t	report_count[4];	/* report count */
402 };
403 
404 #define	MRIE_NO_REPORT		0x0
405 #define	MRIE_ASYNCH		0x1
406 #define	MRIE_UNIT_ATTN		0x2
407 #define	MRIE_COND_RECVD_ERR	0x3
408 #define	MRIE_UNCOND_RECVD_ERR	0x4
409 #define	MRIE_NO_SENSE		0x5
410 #define	MRIE_ONLY_ON_REQUEST	0x6
411 
412 struct mode_info_power_cond {
413 	struct mode_page mode_page;	/* common mode page header */
414 	uchar_t reserved;
415 #if defined(_BIT_FIELDS_LTOH)
416 	uchar_t standby	:1,	/* standby bit */
417 		idle	:1,	/* idle bit */
418 			:6;	/* reserved */
419 #elif defined(_BIT_FIELDS_HTOL)
420 	uchar_t		:6,	/* reserved */
421 		idle	:1,	/* idle bit */
422 		standby	:1;	/* standby bit */
423 #else
424 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
425 #endif
426 	uchar_t	idle_cond_timer_high;
427 	uchar_t idle_cond_timer_low;
428 	uchar_t standby_cond_timer[4];
429 };
430 
431 struct parameter_control {
432 #if defined(_BIT_FIELDS_LTOH)
433 	uchar_t fmt_link:2,	/* format and link bit */
434 		tmc	:2,	/* tmc bit */
435 		etc	:1,	/* etc bit */
436 		tsd	:1,	/* tsd bit */
437 		reserv	:1,	/* obsolete */
438 		du	:1;	/* du bit */
439 #elif defined(_BIT_FIELDS_HTOL)
440 	uchar_t	du	:1,	/* du bit */
441 		reserv	:1,	/* obsolete */
442 		tsd	:1,	/* tsd bit */
443 		etc	:1,	/* etc bit */
444 		tmc	:2,	/* tmc bit */
445 		fmt_link:2;	/* format and link bit */
446 #else
447 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
448 #endif
449 };
450 
451 struct start_stop_cycle_counter_log {
452 #if defined(_BIT_FIELDS_LTOH)
453 	uchar_t code	:6,	/* page code bit */
454 		spf	:1,	/* spf bit */
455 		ds	:1;	/* ds bit */
456 #elif defined(_BIT_FIELDS_HTOL)
457 	uchar_t	ds	:1,	/* ds bit */
458 		spf	:1,	/* spf bit */
459 		code	:6;	/* page code bit */
460 #else
461 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
462 #endif
463 	uchar_t			sub_page_code;
464 	uchar_t			page_len_high;
465 	uchar_t			page_len_low;
466 
467 	uchar_t			manufactor_date_high;
468 	uchar_t			manufactor_date_low;
469 	struct parameter_control param_1;
470 	uchar_t			param_len_1;
471 	uchar_t			year_manu[4];
472 	uchar_t			week_manu[2];
473 
474 	uchar_t			account_date_high;
475 	uchar_t			account_date_low;
476 	struct parameter_control param_2;
477 	uchar_t			param_len_2;
478 	uchar_t			year_account[4];
479 	uchar_t			week_account[2];
480 
481 	uchar_t			lifetime_code_high;
482 	uchar_t			lifetime_code_low;
483 	struct parameter_control param_3;
484 	uchar_t			param_len_3;
485 	uchar_t			cycle_lifetime[4];
486 
487 	uchar_t			cycle_code_high;
488 	uchar_t			cycle_code_low;
489 	struct parameter_control param_4;
490 	uchar_t			param_len_4;
491 	uchar_t			cycle_accumulated[4];
492 };
493 
494 
495 #ifdef	__cplusplus
496 }
497 #endif
498 
499 /*
500  * Include known generic device specific mode definitions and structures
501  */
502 
503 #include <sys/scsi/generic/dad_mode.h>
504 
505 /*
506  * Include implementation specific mode information
507  */
508 
509 #include <sys/scsi/impl/mode.h>
510 
511 #endif	/* _SYS_SCSI_GENERIC_MODE_H */
512