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_CACHING	0x08
195 #define	MODEPAGE_PDEVICE	0x09
196 #define	MODEPAGE_CTRL_MODE	0x0A
197 #define	MODEPAGE_POWER_COND	0x1A
198 #define	MODEPAGE_INFO_EXCPT	0x1C
199 
200 #define	MODEPAGE_ALLPAGES	0x3F
201 
202 /*
203  * Mode Select/Sense page structures (for all device types)
204  */
205 
206 /*
207  * Disconnect/Reconnect Page
208  */
209 
210 struct mode_disco_reco {
211 	struct	mode_page mode_page;	/* common mode page header */
212 	uchar_t	buffer_full_ratio;	/* write, how full before reconnect? */
213 	uchar_t	buffer_empty_ratio;	/* read, how full before reconnect? */
214 	ushort_t bus_inactivity_limit;	/* how much bus quiet time for BSY- */
215 	ushort_t disconect_time_limit;	/* min to remain disconnected */
216 	ushort_t connect_time_limit;	/* min to remain connected */
217 	ushort_t max_burst_size;	/* max data burst size */
218 #if defined(_BIT_FIELDS_LTOH)
219 	uchar_t		dtdc	: 3,	/* data transfer disconenct control */
220 			dimm	: 1,	/* disconnect immediate */
221 			fastat	: 1,	/* fair for status */
222 			fawrt	: 1,	/* fair for write */
223 			fard	: 1,	/* fair for read */
224 			emdp	: 1;	/* enable modify data pointers */
225 #elif defined(_BIT_FIELDS_HTOL)
226 	uchar_t		emdp	: 1,	/* enable modify data pointers */
227 			fard	: 1,	/* fair for read */
228 			fawrt	: 1,	/* fair for write */
229 			fastat	: 1,	/* fair for status */
230 			dimm	: 1,	/* disconnect immediate */
231 			dtdc	: 3;	/* data transfer disconenct control */
232 #else
233 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
234 #endif	/* _BIT_FIELDS_LTOH */
235 	uchar_t	reserved;
236 	ushort_t first_burst_sz;	/* first burst size */
237 };
238 
239 #define	DTDC_DATADONE	0x01
240 					/*
241 					 * Target may not disconnect once
242 					 * data transfer is started until
243 					 * all data successfully transferred.
244 					 */
245 
246 #define	DTDC_CMDDONE	0x03
247 					/*
248 					 * Target may not disconnect once
249 					 * data transfer is started until
250 					 * command completed.
251 					 */
252 /*
253  * Caching Page
254  */
255 
256 struct mode_caching {
257 	struct	mode_page mode_page;	/* common mode page header */
258 #if defined(_BIT_FIELDS_LTOH)
259 	uchar_t	rcd		: 1,	/* Read Cache Disable */
260 		mf		: 1,	/* Multiplication Factor */
261 		wce		: 1,	/* Write Cache Enable */
262 				: 5;	/* Reserved */
263 	uchar_t	write_ret_prio	: 4,	/* Write Retention Priority */
264 		dmd_rd_ret_prio	: 4;	/* Demand Read Retention Priority */
265 #elif defined(_BIT_FIELDS_HTOL)
266 	uchar_t			: 5,	/* Reserved */
267 		wce		: 1,	/* Write Cache Enable */
268 		mf		: 1,	/* Multiplication Factor */
269 		rcd		: 1;	/* Read Cache Disable */
270 	uchar_t	dmd_rd_ret_prio	: 4,	/* Demand Read Retention Priority */
271 		write_ret_prio	: 4;	/* Write Retention Priority */
272 #else
273 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
274 #endif	/* _BIT_FIELDS_LTOH */
275 	ushort_t pf_dsbl_trans_len;	/* Disable prefetch transfer length */
276 	ushort_t min_prefetch;		/* Minimum Prefetch */
277 	ushort_t max_prefetch;		/* Maximum Prefetch */
278 	ushort_t max_prefetch_ceiling;	/* Maximum Prefetch Ceiling */
279 };
280 
281 /*
282  * Peripheral Device Page
283  */
284 
285 struct mode_pdevice {
286 	struct	mode_page mode_page;	/* common mode page header */
287 	ushort_t if_ident;		/* interface identifier */
288 	uchar_t	reserved[4];		/* reserved */
289 	uchar_t	vendor_uniqe[1];	/* vendor unique data */
290 };
291 
292 #define	PDEV_SCSI	0x0000		/* scsi interface */
293 #define	PDEV_SMD	0x0001		/* SMD interface */
294 #define	PDEV_ESDI	0x0002		/* ESDI interface */
295 #define	PDEV_IPI2	0x0003		/* IPI-2 interface */
296 #define	PDEV_IPI3	0x0004		/* IPI-3 interface */
297 
298 /*
299  * Control Mode Page
300  *
301  * Note:	This structure is incompatible with previous SCSI
302  *		implementations. See <scsi/impl/mode.h> for an
303  *		alternative form of this structure. They can be
304  *		distinguished by the length of data returned
305  *		from a MODE SENSE command.
306  */
307 
308 #define	PAGELENGTH_MODE_CONTROL_SCSI3	0x0A
309 
310 struct mode_control_scsi3 {
311 	struct	mode_page mode_page;	/* common mode page header */
312 #if defined(_BIT_FIELDS_LTOH)
313 	uchar_t		rlec	: 1,	/* Report Log Exception bit */
314 			gltsd	: 1,	/* global logging target save disable */
315 			d_sense	: 1,	/* Use descriptor sense data (SPC-3) */
316 				: 5;
317 	uchar_t		qdisable: 1,	/* Queue disable */
318 			que_err	: 1,	/* Queue error */
319 				: 2,
320 			que_mod : 4;    /* Queue algorithm modifier */
321 	uchar_t		eanp	: 1,	/* Enable AEN permission */
322 			uaaenp  : 1,	/* Unit attention AEN permission */
323 			raenp   : 1,	/* Ready AEN permission */
324 				: 1,
325 			bybths	: 1,	/* By both RESET signal */
326 			byprtm	: 1,	/* By port message */
327 			rac	: 1,	/* report a check */
328 			eeca	: 1;	/* enable extended contingent */
329 					/* allegiance (only pre-SCSI-3) */
330 #elif defined(_BIT_FIELDS_HTOL)
331 	uchar_t			: 5,
332 			d_sense	: 1,	/* Use descriptor sense data (SPC-3) */
333 			gltsd	: 1,	/* global logging target save disable */
334 			rlec	: 1;	/* Report Log Exception bit */
335 	uchar_t		que_mod	: 4,	/* Queue algorithm modifier */
336 				: 2,
337 			que_err	: 1,	/* Queue error */
338 			qdisable: 1;	/* Queue disable */
339 	uchar_t		eeca	: 1,	/* enable extended contingent */
340 					/* allegiance (only pre-SCSI-3) */
341 			rac	: 1,	/* report a check */
342 			byprtm	: 1,	/* By port message */
343 			bybths	: 1,	/* By both RESET signal */
344 				: 1,
345 			raenp   : 1,	/* Ready AEN permission */
346 			uaaenp  : 1,	/* Unit attention AEN permission */
347 			eanp	: 1;	/* Enable AEN permission */
348 #else
349 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
350 #endif	/* _BIT_FIELDS_LTOH */
351 	uchar_t	reserved;
352 	ushort_t ready_aen_holdoff;	/* Ready AEN holdoff period */
353 	ushort_t busy_timeout;		/* Busy timeout period */
354 	uchar_t	reserved_2[2];
355 };
356 
357 #ifdef __lock_lint
358 _NOTE(SCHEME_PROTECTS_DATA("Unshared SCSI payload", \
359 	mode_control_scsi3))
360 #endif
361 
362 #define	CTRL_QMOD_RESTRICT	0x0
363 #define	CTRL_QMOD_UNRESTRICT	0x1
364 
365 /*
366  * Informational Exceptions Control Mode Page
367  */
368 
369 #define	PAGELENGTH_INFO_EXCPT	0x0A
370 
371 struct mode_info_excpt_page {
372 	struct	mode_page mode_page;	/* common mode page header */
373 #if defined(_BIT_FIELDS_LTOH)
374 	uchar_t		log_err	: 1;	/* log errors */
375 	uchar_t			: 1;	/* reserved */
376 	uchar_t		test	: 1;	/* create test failure */
377 	uchar_t		dexcpt	: 1;	/* disable exception */
378 	uchar_t		ewasc	: 1;	/* enable warning */
379 	uchar_t		ebf	: 1;	/* enable background function */
380 	uchar_t			: 1;	/* reserved */
381 	uchar_t		perf	: 1;	/* performance */
382 	uchar_t		mrie	: 4;	/* method of reporting info. excpts. */
383 	uchar_t			: 4;	/* reserved */
384 #elif defined(_BIT_FIELDS_HTOL)
385 	uchar_t		perf	: 1;	/* performance */
386 	uchar_t			: 1;	/* reserved */
387 	uchar_t		ebf	: 1;	/* enable background function */
388 	uchar_t		ewasc	: 1;	/* enable warning */
389 	uchar_t		dexcpt	: 1;	/* disable exception */
390 	uchar_t		test	: 1;	/* create test failure */
391 	uchar_t			: 1;	/* reserved */
392 	uchar_t		log_err	: 1;	/* log errors */
393 	uchar_t			: 4;	/* reserved */
394 	uchar_t		mrie	: 4;	/* method of reporting info. excpts. */
395 #else
396 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
397 #endif
398 	uchar_t	interval_timer[4];	/* interval timer */
399 	uchar_t	report_count[4];	/* report count */
400 };
401 
402 #define	MRIE_NO_REPORT		0x0
403 #define	MRIE_ASYNCH		0x1
404 #define	MRIE_UNIT_ATTN		0x2
405 #define	MRIE_COND_RECVD_ERR	0x3
406 #define	MRIE_UNCOND_RECVD_ERR	0x4
407 #define	MRIE_NO_SENSE		0x5
408 #define	MRIE_ONLY_ON_REQUEST	0x6
409 
410 struct mode_info_power_cond {
411 	struct mode_page mode_page;	/* common mode page header */
412 	uchar_t reserved;
413 #if defined(_BIT_FIELDS_LTOH)
414 	uchar_t standby	:1,	/* standby bit */
415 		idle	:1,	/* idle bit */
416 			:6;	/* reserved */
417 #elif defined(_BIT_FIELDS_HTOL)
418 	uchar_t		:6,	/* reserved */
419 		idle	:1,	/* idle bit */
420 		standby	:1;	/* standby bit */
421 #else
422 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
423 #endif
424 	uchar_t	idle_cond_timer_high;
425 	uchar_t idle_cond_timer_low;
426 	uchar_t standby_cond_timer[4];
427 };
428 
429 struct parameter_control {
430 #if defined(_BIT_FIELDS_LTOH)
431 	uchar_t fmt_link:2,	/* format and link bit */
432 		tmc	:2,	/* tmc bit */
433 		etc	:1,	/* etc bit */
434 		tsd	:1,	/* tsd bit */
435 		reserv	:1,	/* obsolete */
436 		du	:1;	/* du bit */
437 #elif defined(_BIT_FIELDS_HTOL)
438 	uchar_t	du	:1,	/* du bit */
439 		reserv	:1,	/* obsolete */
440 		tsd	:1,	/* tsd bit */
441 		etc	:1,	/* etc bit */
442 		tmc	:2,	/* tmc bit */
443 		fmt_link:2;	/* format and link bit */
444 #else
445 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
446 #endif
447 };
448 
449 struct start_stop_cycle_counter_log {
450 #if defined(_BIT_FIELDS_LTOH)
451 	uchar_t code	:6,	/* page code bit */
452 		spf	:1,	/* spf bit */
453 		ds	:1;	/* ds bit */
454 #elif defined(_BIT_FIELDS_HTOL)
455 	uchar_t	ds	:1,	/* ds bit */
456 		spf	:1,	/* spf bit */
457 		code	:6;	/* page code bit */
458 #else
459 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
460 #endif
461 	uchar_t			sub_page_code;
462 	uchar_t			page_len_high;
463 	uchar_t			page_len_low;
464 
465 	uchar_t			manufactor_date_high;
466 	uchar_t			manufactor_date_low;
467 	struct parameter_control param_1;
468 	uchar_t			param_len_1;
469 	uchar_t			year_manu[4];
470 	uchar_t			week_manu[2];
471 
472 	uchar_t			account_date_high;
473 	uchar_t			account_date_low;
474 	struct parameter_control param_2;
475 	uchar_t			param_len_2;
476 	uchar_t			year_account[4];
477 	uchar_t			week_account[2];
478 
479 	uchar_t			lifetime_code_high;
480 	uchar_t			lifetime_code_low;
481 	struct parameter_control param_3;
482 	uchar_t			param_len_3;
483 	uchar_t			cycle_lifetime[4];
484 
485 	uchar_t			cycle_code_high;
486 	uchar_t			cycle_code_low;
487 	struct parameter_control param_4;
488 	uchar_t			param_len_4;
489 	uchar_t			cycle_accumulated[4];
490 };
491 
492 
493 #ifdef	__cplusplus
494 }
495 #endif
496 
497 /*
498  * Include known generic device specific mode definitions and structures
499  */
500 
501 #include <sys/scsi/generic/dad_mode.h>
502 
503 /*
504  * Include implementation specific mode information
505  */
506 
507 #include <sys/scsi/impl/mode.h>
508 
509 #endif	/* _SYS_SCSI_GENERIC_MODE_H */
510