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