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