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