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