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 */