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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_SCSI_GENERIC_MODE_H
28 #define	_SYS_SCSI_GENERIC_MODE_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37  *
38  * Defines and Structures for SCSI Mode Sense/Select data - generic
39  *
40  */
41 
42 /*
43  * Structures and defines common for all device types
44  */
45 
46 /*
47  * Mode Sense/Select Header - Group 0 (6-byte).
48  *
49  * Mode Sense/Select data consists of a header, followed by zero or more
50  * block descriptors, followed by zero or more mode pages.
51  *
52  */
53 
54 struct mode_header {
55 	uchar_t length;		/* number of bytes following */
56 	uchar_t medium_type;	/* device specific */
57 	uchar_t device_specific;	/* device specific parameters */
58 	uchar_t bdesc_length;	/* length of block descriptor(s), if any */
59 };
60 
61 #define	MODE_HEADER_LENGTH	(sizeof (struct mode_header))
62 
63 /*
64  * Mode Sense/Select Header - Group 1 (10-bytes)
65  */
66 
67 struct mode_header_g1 {
68 	ushort_t	length;		/* number of bytes following */
69 	uchar_t		medium_type;	/* device specific */
70 	uchar_t		device_specific;	/* device specific parameters */
71 	uchar_t		reserved[2];	/* device specific parameters */
72 	ushort_t	bdesc_length;	/* len of block descriptor(s), if any */
73 };
74 
75 #define	MODE_HEADER_LENGTH_G1	(sizeof (struct mode_header_g1))
76 
77 /*
78  * Block Descriptor. Zero, one, or more may normally follow the mode header.
79  *
80  * The density code is device specific.
81  *
82  * The 24-bit value described by blks_{hi, mid, lo} describes the number of
83  * blocks which this block descriptor applies to. A value of zero means
84  * 'the rest of the blocks on the device'.
85  *
86  * The 24-bit value described by blksize_{hi, mid, lo} describes the blocksize
87  * (in bytes) applicable for this block descriptor. For Sequential Access
88  * devices, if this value is zero, the block size will be derived from
89  * the transfer length in I/O operations.
90  *
91  */
92 
93 struct block_descriptor {
94 	uchar_t density_code;	/* device specific */
95 	uchar_t blks_hi;	/* hi  */
96 	uchar_t blks_mid;	/* mid */
97 	uchar_t blks_lo;	/* low */
98 	uchar_t reserved;	/* reserved */
99 	uchar_t blksize_hi;	/* hi  */
100 	uchar_t blksize_mid;	/* mid */
101 	uchar_t blksize_lo;	/* low */
102 };
103 
104 #define	MODE_BLK_DESC_LENGTH	(sizeof (struct block_descriptor))
105 #define	MODE_PARAM_LENGTH 	(MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH)
106 
107 /*
108  * Define a macro to take an address of a mode header to the address
109  * of the nth (0..n) block_descriptor, or NULL if there either aren't any
110  * block descriptors or the nth block descriptor doesn't exist.
111  */
112 
113 #define	BLOCK_DESCRIPTOR_ADDR(mhdr, bdnum) \
114 	((mhdr)->bdesc_length && ((unsigned)(bdnum)) < \
115 	((mhdr)->bdesc_length/(sizeof (struct block_descriptor)))) ? \
116 	((struct block_descriptor *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+ \
117 	((bdnum) * sizeof (struct block_descriptor)))) : \
118 	((struct block_descriptor *)0)
119 
120 /*
121  * Mode page header. Zero or more Mode Pages follow either the block
122  * descriptors (if any), or the Mode Header.
123  *
124  * The 'ps' bit must be zero for mode select operations.
125  *
126  */
127 
128 struct mode_page {
129 #if defined(_BIT_FIELDS_LTOH)
130 	uchar_t	code	:6,	/* page code number */
131 			:1,	/* reserved */
132 		ps	:1;	/* 'Parameter Saveable' bit */
133 #elif defined(_BIT_FIELDS_HTOL)
134 	uchar_t	ps	:1,	/* 'Parameter Saveable' bit */
135 			:1,	/* reserved */
136 		code	:6;	/* page code number */
137 #else
138 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
139 #endif	/* _BIT_FIELDS_LTOH */
140 	uchar_t	length;		/* length of bytes to follow */
141 	/*
142 	 * Mode Page specific data follows right after this...
143 	 */
144 };
145 
146 /*
147  * Define a macro to retrieve the first mode page. Could be more
148  * general (for multiple mode pages).
149  */
150 
151 #define	MODE_PAGE_ADDR(mhdr, type)	\
152 	((type *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+(mhdr)->bdesc_length))
153 
154 /*
155  * Page codes follow the following specification:
156  *
157  *	Code Value(s)		What
158  *	----------------------------------------------------------------------
159  *	0x00			Vendor Unique (does not require page format)
160  *
161  *	0x02, 0x09, 0x0A	pages for all Device Types
162  *	0x1A, 0x1C
163  *
164  *	0x01, 0x03-0x08,	pages for specific Device Type
165  *	0x0B-0x19, 0x1B,
166  *	0x1D-0x1F
167  *
168  *	0x20-0x3E		Vendor Unique (requires page format)
169  *
170  *	0x3F			Return all pages (valid for Mode Sense only)
171  *
172  */
173 
174 /*
175  * Page codes and page length values (all device types)
176  */
177 
178 #define	MODEPAGE_DISCO_RECO	0x02
179 #define	MODEPAGE_CACHING	0x08
180 #define	MODEPAGE_PDEVICE	0x09
181 #define	MODEPAGE_CTRL_MODE	0x0A
182 #define	MODEPAGE_POWER_COND	0x1A
183 #define	MODEPAGE_INFO_EXCPT	0x1C
184 
185 #define	MODEPAGE_ALLPAGES	0x3F
186 
187 /*
188  * Mode Select/Sense page structures (for all device types)
189  */
190 
191 /*
192  * Disconnect/Reconnect Page
193  */
194 
195 struct mode_disco_reco {
196 	struct	mode_page mode_page;	/* common mode page header */
197 	uchar_t	buffer_full_ratio;	/* write, how full before reconnect? */
198 	uchar_t	buffer_empty_ratio;	/* read, how full before reconnect? */
199 	ushort_t bus_inactivity_limit;	/* how much bus quiet time for BSY- */
200 	ushort_t disconect_time_limit;	/* min to remain disconnected */
201 	ushort_t connect_time_limit;	/* min to remain connected */
202 	ushort_t max_burst_size;	/* max data burst size */
203 #if defined(_BIT_FIELDS_LTOH)
204 	uchar_t		dtdc	: 3,	/* data transfer disconenct control */
205 			dimm	: 1,	/* disconnect immediate */
206 			fastat	: 1,	/* fair for status */
207 			fawrt	: 1,	/* fair for write */
208 			fard	: 1,	/* fair for read */
209 			emdp	: 1;	/* enable modify data pointers */
210 #elif defined(_BIT_FIELDS_HTOL)
211 	uchar_t		emdp	: 1,	/* enable modify data pointers */
212 			fard	: 1,	/* fair for read */
213 			fawrt	: 1,	/* fair for write */
214 			fastat	: 1,	/* fair for status */
215 			dimm	: 1,	/* disconnect immediate */
216 			dtdc	: 3;	/* data transfer disconenct control */
217 #else
218 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
219 #endif	/* _BIT_FIELDS_LTOH */
220 	uchar_t	reserved;
221 	ushort_t first_burst_sz;	/* first burst size */
222 };
223 
224 #define	DTDC_DATADONE	0x01
225 					/*
226 					 * Target may not disconnect once
227 					 * data transfer is started until
228 					 * all data successfully transferred.
229 					 */
230 
231 #define	DTDC_CMDDONE	0x03
232 					/*
233 					 * Target may not disconnect once
234 					 * data transfer is started until
235 					 * command completed.
236 					 */
237 /*
238  * Caching Page
239  */
240 
241 struct mode_caching {
242 	struct	mode_page mode_page;	/* common mode page header */
243 #if defined(_BIT_FIELDS_LTOH)
244 	uchar_t	rcd		: 1,	/* Read Cache Disable */
245 		mf		: 1,	/* Multiplication Factor */
246 		wce		: 1,	/* Write Cache Enable */
247 				: 5;	/* Reserved */
248 	uchar_t	write_ret_prio	: 4,	/* Write Retention Priority */
249 		dmd_rd_ret_prio	: 4;	/* Demand Read Retention Priority */
250 #elif defined(_BIT_FIELDS_HTOL)
251 	uchar_t			: 5,	/* Reserved */
252 		wce		: 1,	/* Write Cache Enable */
253 		mf		: 1,	/* Multiplication Factor */
254 		rcd		: 1;	/* Read Cache Disable */
255 	uchar_t	dmd_rd_ret_prio	: 4,	/* Demand Read Retention Priority */
256 		write_ret_prio	: 4;	/* Write Retention Priority */
257 #else
258 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
259 #endif	/* _BIT_FIELDS_LTOH */
260 	ushort_t pf_dsbl_trans_len;	/* Disable prefetch transfer length */
261 	ushort_t min_prefetch;		/* Minimum Prefetch */
262 	ushort_t max_prefetch;		/* Maximum Prefetch */
263 	ushort_t max_prefetch_ceiling;	/* Maximum Prefetch Ceiling */
264 };
265 
266 /*
267  * Peripheral Device Page
268  */
269 
270 struct mode_pdevice {
271 	struct	mode_page mode_page;	/* common mode page header */
272 	ushort_t if_ident;		/* interface identifier */
273 	uchar_t	reserved[4];		/* reserved */
274 	uchar_t	vendor_uniqe[1];	/* vendor unique data */
275 };
276 
277 #define	PDEV_SCSI	0x0000		/* scsi interface */
278 #define	PDEV_SMD	0x0001		/* SMD interface */
279 #define	PDEV_ESDI	0x0002		/* ESDI interface */
280 #define	PDEV_IPI2	0x0003		/* IPI-2 interface */
281 #define	PDEV_IPI3	0x0004		/* IPI-3 interface */
282 
283 /*
284  * Control Mode Page
285  *
286  * Note:	This structure is incompatible with previous SCSI
287  *		implementations. See <scsi/impl/mode.h> for an
288  *		alternative form of this structure. They can be
289  *		distinguished by the length of data returned
290  *		from a MODE SENSE command.
291  */
292 
293 #define	PAGELENGTH_MODE_CONTROL_SCSI3	0x0A
294 
295 struct mode_control_scsi3 {
296 	struct	mode_page mode_page;	/* common mode page header */
297 #if defined(_BIT_FIELDS_LTOH)
298 	uchar_t		rlec	: 1,	/* Report Log Exception bit */
299 			gltsd	: 1,	/* global logging target save disable */
300 			d_sense	: 1,	/* Use descriptor sense data (SPC-3) */
301 				: 5;
302 	uchar_t		qdisable: 1,	/* Queue disable */
303 			que_err	: 1,	/* Queue error */
304 				: 2,
305 			que_mod : 4;    /* Queue algorithm modifier */
306 	uchar_t		eanp	: 1,	/* Enable AEN permission */
307 			uaaenp  : 1,	/* Unit attention AEN permission */
308 			raenp   : 1,	/* Ready AEN permission */
309 				: 1,
310 			bybths	: 1,	/* By both RESET signal */
311 			byprtm	: 1,	/* By port message */
312 			rac	: 1,	/* report a check */
313 			eeca	: 1;	/* enable extended contingent */
314 					/* allegiance (only pre-SCSI-3) */
315 #elif defined(_BIT_FIELDS_HTOL)
316 	uchar_t			: 5,
317 			d_sense	: 1,	/* Use descriptor sense data (SPC-3) */
318 			gltsd	: 1,	/* global logging target save disable */
319 			rlec	: 1;	/* Report Log Exception bit */
320 	uchar_t		que_mod	: 4,	/* Queue algorithm modifier */
321 				: 2,
322 			que_err	: 1,	/* Queue error */
323 			qdisable: 1;	/* Queue disable */
324 	uchar_t		eeca	: 1,	/* enable extended contingent */
325 					/* allegiance (only pre-SCSI-3) */
326 			rac	: 1,	/* report a check */
327 			byprtm	: 1,	/* By port message */
328 			bybths	: 1,	/* By both RESET signal */
329 				: 1,
330 			raenp   : 1,	/* Ready AEN permission */
331 			uaaenp  : 1,	/* Unit attention AEN permission */
332 			eanp	: 1;	/* Enable AEN permission */
333 #else
334 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
335 #endif	/* _BIT_FIELDS_LTOH */
336 	uchar_t	reserved;
337 	ushort_t ready_aen_holdoff;	/* Ready AEN holdoff period */
338 	ushort_t busy_timeout;		/* Busy timeout period */
339 	uchar_t	reserved_2[2];
340 };
341 
342 #define	CTRL_QMOD_RESTRICT	0x0
343 #define	CTRL_QMOD_UNRESTRICT	0x1
344 
345 #ifdef	__cplusplus
346 }
347 #endif
348 
349 /*
350  * Include known generic device specific mode definitions and structures
351  */
352 
353 #include <sys/scsi/generic/dad_mode.h>
354 
355 /*
356  * Include implementation specific mode information
357  */
358 
359 #include <sys/scsi/impl/mode.h>
360 
361 #endif	/* _SYS_SCSI_GENERIC_MODE_H */
362