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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_SCSI_GENERIC_MODE_H 27 #define _SYS_SCSI_GENERIC_MODE_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /* 34 * 35 * Defines and Structures for SCSI Mode Sense/Select data - generic 36 * 37 */ 38 39 /* 40 * Structures and defines common for all device types 41 */ 42 43 /* 44 * Mode Sense/Select Header - Group 0 (6-byte). 45 * 46 * Mode Sense/Select data consists of a header, followed by zero or more 47 * block descriptors, followed by zero or more mode pages. 48 * 49 */ 50 51 struct mode_header { 52 uchar_t length; /* number of bytes following */ 53 uchar_t medium_type; /* device specific */ 54 uchar_t device_specific; /* device specific parameters */ 55 uchar_t bdesc_length; /* length of block descriptor(s), if any */ 56 }; 57 58 #define MODE_HEADER_LENGTH (sizeof (struct mode_header)) 59 60 /* 61 * Mode Sense/Select Header - Group 1 (10-bytes) 62 */ 63 64 struct mode_header_g1 { 65 ushort_t length; /* number of bytes following */ 66 uchar_t medium_type; /* device specific */ 67 uchar_t device_specific; /* device specific parameters */ 68 uchar_t reserved[2]; /* device specific parameters */ 69 ushort_t bdesc_length; /* len of block descriptor(s), if any */ 70 }; 71 72 #define MODE_HEADER_LENGTH_G1 (sizeof (struct mode_header_g1)) 73 74 /* 75 * Block Descriptor. Zero, one, or more may normally follow the mode header. 76 * 77 * The density code is device specific. 78 * 79 * The 24-bit value described by blks_{hi, mid, lo} describes the number of 80 * blocks which this block descriptor applies to. A value of zero means 81 * 'the rest of the blocks on the device'. 82 * 83 * The 24-bit value described by blksize_{hi, mid, lo} describes the blocksize 84 * (in bytes) applicable for this block descriptor. For Sequential Access 85 * devices, if this value is zero, the block size will be derived from 86 * the transfer length in I/O operations. 87 * 88 */ 89 90 struct block_descriptor { 91 uchar_t density_code; /* device specific */ 92 uchar_t blks_hi; /* hi */ 93 uchar_t blks_mid; /* mid */ 94 uchar_t blks_lo; /* low */ 95 uchar_t reserved; /* reserved */ 96 uchar_t blksize_hi; /* hi */ 97 uchar_t blksize_mid; /* mid */ 98 uchar_t blksize_lo; /* low */ 99 }; 100 101 #define MODE_BLK_DESC_LENGTH (sizeof (struct block_descriptor)) 102 #define MODE_PARAM_LENGTH (MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH) 103 104 /* 105 * Define a macro to take an address of a mode header to the address 106 * of the nth (0..n) block_descriptor, or NULL if there either aren't any 107 * block descriptors or the nth block descriptor doesn't exist. 108 */ 109 110 #define BLOCK_DESCRIPTOR_ADDR(mhdr, bdnum) \ 111 ((mhdr)->bdesc_length && ((unsigned)(bdnum)) < \ 112 ((mhdr)->bdesc_length/(sizeof (struct block_descriptor)))) ? \ 113 ((struct block_descriptor *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+ \ 114 ((bdnum) * sizeof (struct block_descriptor)))) : \ 115 ((struct block_descriptor *)0) 116 117 /* 118 * Mode page header. Zero or more Mode Pages follow either the block 119 * descriptors (if any), or the Mode Header. 120 * 121 * The 'ps' bit must be zero for mode select operations. 122 * 123 */ 124 125 struct mode_page { 126 #if defined(_BIT_FIELDS_LTOH) 127 uchar_t code :6, /* page code number */ 128 :1, /* reserved */ 129 ps :1; /* 'Parameter Saveable' bit */ 130 #elif defined(_BIT_FIELDS_HTOL) 131 uchar_t ps :1, /* 'Parameter Saveable' bit */ 132 :1, /* reserved */ 133 code :6; /* page code number */ 134 #else 135 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 136 #endif /* _BIT_FIELDS_LTOH */ 137 uchar_t length; /* length of bytes to follow */ 138 /* 139 * Mode Page specific data follows right after this... 140 */ 141 }; 142 143 /* 144 * Define a macro to retrieve the first mode page. Could be more 145 * general (for multiple mode pages). 146 */ 147 148 #define MODE_PAGE_ADDR(mhdr, type) \ 149 ((type *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+(mhdr)->bdesc_length)) 150 151 /* 152 * Page codes follow the following specification: 153 * 154 * Code Value(s) What 155 * ---------------------------------------------------------------------- 156 * 0x00 Vendor Unique (does not require page format) 157 * 158 * 0x02, 0x09, 0x0A pages for all Device Types 159 * 0x1A, 0x1C 160 * 161 * 0x01, 0x03-0x08, pages for specific Device Type 162 * 0x0B-0x19, 0x1B, 163 * 0x1D-0x1F 164 * 165 * 0x20-0x3E Vendor Unique (requires page format) 166 * 167 * 0x3F Return all pages (valid for Mode Sense only) 168 * 169 */ 170 171 /* 172 * Page codes and page length values (all device types) 173 */ 174 175 #define MODEPAGE_DISCO_RECO 0x02 176 #define MODEPAGE_CACHING 0x08 177 #define MODEPAGE_PDEVICE 0x09 178 #define MODEPAGE_CTRL_MODE 0x0A 179 #define MODEPAGE_POWER_COND 0x1A 180 #define MODEPAGE_INFO_EXCPT 0x1C 181 182 #define MODEPAGE_ALLPAGES 0x3F 183 184 /* 185 * Mode Select/Sense page structures (for all device types) 186 */ 187 188 /* 189 * Disconnect/Reconnect Page 190 */ 191 192 struct mode_disco_reco { 193 struct mode_page mode_page; /* common mode page header */ 194 uchar_t buffer_full_ratio; /* write, how full before reconnect? */ 195 uchar_t buffer_empty_ratio; /* read, how full before reconnect? */ 196 ushort_t bus_inactivity_limit; /* how much bus quiet time for BSY- */ 197 ushort_t disconect_time_limit; /* min to remain disconnected */ 198 ushort_t connect_time_limit; /* min to remain connected */ 199 ushort_t max_burst_size; /* max data burst size */ 200 #if defined(_BIT_FIELDS_LTOH) 201 uchar_t dtdc : 3, /* data transfer disconenct control */ 202 dimm : 1, /* disconnect immediate */ 203 fastat : 1, /* fair for status */ 204 fawrt : 1, /* fair for write */ 205 fard : 1, /* fair for read */ 206 emdp : 1; /* enable modify data pointers */ 207 #elif defined(_BIT_FIELDS_HTOL) 208 uchar_t emdp : 1, /* enable modify data pointers */ 209 fard : 1, /* fair for read */ 210 fawrt : 1, /* fair for write */ 211 fastat : 1, /* fair for status */ 212 dimm : 1, /* disconnect immediate */ 213 dtdc : 3; /* data transfer disconenct control */ 214 #else 215 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 216 #endif /* _BIT_FIELDS_LTOH */ 217 uchar_t reserved; 218 ushort_t first_burst_sz; /* first burst size */ 219 }; 220 221 #define DTDC_DATADONE 0x01 222 /* 223 * Target may not disconnect once 224 * data transfer is started until 225 * all data successfully transferred. 226 */ 227 228 #define DTDC_CMDDONE 0x03 229 /* 230 * Target may not disconnect once 231 * data transfer is started until 232 * command completed. 233 */ 234 /* 235 * Caching Page 236 */ 237 238 struct mode_caching { 239 struct mode_page mode_page; /* common mode page header */ 240 #if defined(_BIT_FIELDS_LTOH) 241 uchar_t rcd : 1, /* Read Cache Disable */ 242 mf : 1, /* Multiplication Factor */ 243 wce : 1, /* Write Cache Enable */ 244 : 5; /* Reserved */ 245 uchar_t write_ret_prio : 4, /* Write Retention Priority */ 246 dmd_rd_ret_prio : 4; /* Demand Read Retention Priority */ 247 #elif defined(_BIT_FIELDS_HTOL) 248 uchar_t : 5, /* Reserved */ 249 wce : 1, /* Write Cache Enable */ 250 mf : 1, /* Multiplication Factor */ 251 rcd : 1; /* Read Cache Disable */ 252 uchar_t dmd_rd_ret_prio : 4, /* Demand Read Retention Priority */ 253 write_ret_prio : 4; /* Write Retention Priority */ 254 #else 255 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 256 #endif /* _BIT_FIELDS_LTOH */ 257 ushort_t pf_dsbl_trans_len; /* Disable prefetch transfer length */ 258 ushort_t min_prefetch; /* Minimum Prefetch */ 259 ushort_t max_prefetch; /* Maximum Prefetch */ 260 ushort_t max_prefetch_ceiling; /* Maximum Prefetch Ceiling */ 261 }; 262 263 /* 264 * Peripheral Device Page 265 */ 266 267 struct mode_pdevice { 268 struct mode_page mode_page; /* common mode page header */ 269 ushort_t if_ident; /* interface identifier */ 270 uchar_t reserved[4]; /* reserved */ 271 uchar_t vendor_uniqe[1]; /* vendor unique data */ 272 }; 273 274 #define PDEV_SCSI 0x0000 /* scsi interface */ 275 #define PDEV_SMD 0x0001 /* SMD interface */ 276 #define PDEV_ESDI 0x0002 /* ESDI interface */ 277 #define PDEV_IPI2 0x0003 /* IPI-2 interface */ 278 #define PDEV_IPI3 0x0004 /* IPI-3 interface */ 279 280 /* 281 * Control Mode Page 282 * 283 * Note: This structure is incompatible with previous SCSI 284 * implementations. See <scsi/impl/mode.h> for an 285 * alternative form of this structure. They can be 286 * distinguished by the length of data returned 287 * from a MODE SENSE command. 288 */ 289 290 #define PAGELENGTH_MODE_CONTROL_SCSI3 0x0A 291 292 struct mode_control_scsi3 { 293 struct mode_page mode_page; /* common mode page header */ 294 #if defined(_BIT_FIELDS_LTOH) 295 uchar_t rlec : 1, /* Report Log Exception bit */ 296 gltsd : 1, /* global logging target save disable */ 297 d_sense : 1, /* Use descriptor sense data (SPC-3) */ 298 : 5; 299 uchar_t qdisable: 1, /* Queue disable */ 300 que_err : 1, /* Queue error */ 301 : 2, 302 que_mod : 4; /* Queue algorithm modifier */ 303 uchar_t eanp : 1, /* Enable AEN permission */ 304 uaaenp : 1, /* Unit attention AEN permission */ 305 raenp : 1, /* Ready AEN permission */ 306 : 1, 307 bybths : 1, /* By both RESET signal */ 308 byprtm : 1, /* By port message */ 309 rac : 1, /* report a check */ 310 eeca : 1; /* enable extended contingent */ 311 /* allegiance (only pre-SCSI-3) */ 312 #elif defined(_BIT_FIELDS_HTOL) 313 uchar_t : 5, 314 d_sense : 1, /* Use descriptor sense data (SPC-3) */ 315 gltsd : 1, /* global logging target save disable */ 316 rlec : 1; /* Report Log Exception bit */ 317 uchar_t que_mod : 4, /* Queue algorithm modifier */ 318 : 2, 319 que_err : 1, /* Queue error */ 320 qdisable: 1; /* Queue disable */ 321 uchar_t eeca : 1, /* enable extended contingent */ 322 /* allegiance (only pre-SCSI-3) */ 323 rac : 1, /* report a check */ 324 byprtm : 1, /* By port message */ 325 bybths : 1, /* By both RESET signal */ 326 : 1, 327 raenp : 1, /* Ready AEN permission */ 328 uaaenp : 1, /* Unit attention AEN permission */ 329 eanp : 1; /* Enable AEN permission */ 330 #else 331 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 332 #endif /* _BIT_FIELDS_LTOH */ 333 uchar_t reserved; 334 ushort_t ready_aen_holdoff; /* Ready AEN holdoff period */ 335 ushort_t busy_timeout; /* Busy timeout period */ 336 uchar_t reserved_2[2]; 337 }; 338 339 #ifdef __lock_lint 340 _NOTE(SCHEME_PROTECTS_DATA("Unshared SCSI payload", \ 341 mode_control_scsi3)) 342 #endif 343 344 #define CTRL_QMOD_RESTRICT 0x0 345 #define CTRL_QMOD_UNRESTRICT 0x1 346 347 /* 348 * Informational Exceptions Control Mode Page 349 */ 350 351 #define PAGELENGTH_INFO_EXCPT 0x0A 352 353 struct mode_info_excpt_page { 354 struct mode_page mode_page; /* common mode page header */ 355 #if defined(_BIT_FIELDS_LTOH) 356 uchar_t log_err : 1; /* log errors */ 357 uchar_t : 1; /* reserved */ 358 uchar_t test : 1; /* create test failure */ 359 uchar_t dexcpt : 1; /* disable exception */ 360 uchar_t ewasc : 1; /* enable warning */ 361 uchar_t ebf : 1; /* enable background function */ 362 uchar_t : 1; /* reserved */ 363 uchar_t perf : 1; /* performance */ 364 uchar_t mrie : 4; /* method of reporting info. excpts. */ 365 uchar_t : 4; /* reserved */ 366 #elif defined(_BIT_FIELDS_HTOL) 367 uchar_t perf : 1; /* performance */ 368 uchar_t : 1; /* reserved */ 369 uchar_t ebf : 1; /* enable background function */ 370 uchar_t ewasc : 1; /* enable warning */ 371 uchar_t dexcpt : 1; /* disable exception */ 372 uchar_t test : 1; /* create test failure */ 373 uchar_t : 1; /* reserved */ 374 uchar_t log_err : 1; /* log errors */ 375 uchar_t : 4; /* reserved */ 376 uchar_t mrie : 4; /* method of reporting info. excpts. */ 377 #else 378 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 379 #endif 380 uchar_t interval_timer[4]; /* interval timer */ 381 uchar_t report_count[4]; /* report count */ 382 }; 383 384 #define MRIE_NO_REPORT 0x0 385 #define MRIE_ASYNCH 0x1 386 #define MRIE_UNIT_ATTN 0x2 387 #define MRIE_COND_RECVD_ERR 0x3 388 #define MRIE_UNCOND_RECVD_ERR 0x4 389 #define MRIE_NO_SENSE 0x5 390 #define MRIE_ONLY_ON_REQUEST 0x6 391 392 struct mode_info_power_cond { 393 struct mode_page mode_page; /* common mode page header */ 394 uchar_t reserved; 395 #if defined(_BIT_FIELDS_LTOH) 396 uchar_t standby :1, /* standby bit */ 397 idle :1, /* idle bit */ 398 :6; /* reserved */ 399 #elif defined(_BIT_FIELDS_HTOL) 400 uchar_t :6, /* reserved */ 401 idle :1, /* idle bit */ 402 standby :1; /* standby bit */ 403 #else 404 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 405 #endif 406 uchar_t idle_cond_timer_high; 407 uchar_t idle_cond_timer_low; 408 uchar_t standby_cond_timer[4]; 409 }; 410 411 struct parameter_control { 412 #if defined(_BIT_FIELDS_LTOH) 413 uchar_t fmt_link:2, /* format and link bit */ 414 tmc :2, /* tmc bit */ 415 etc :1, /* etc bit */ 416 tsd :1, /* tsd bit */ 417 reserv :1, /* obsolete */ 418 du :1; /* du bit */ 419 #elif defined(_BIT_FIELDS_HTOL) 420 uchar_t du :1, /* du bit */ 421 reserv :1, /* obsolete */ 422 tsd :1, /* tsd bit */ 423 etc :1, /* etc bit */ 424 tmc :2, /* tmc bit */ 425 fmt_link:2; /* format and link bit */ 426 #else 427 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 428 #endif 429 }; 430 431 struct start_stop_cycle_counter_log { 432 #if defined(_BIT_FIELDS_LTOH) 433 uchar_t code :6, /* page code bit */ 434 spf :1, /* spf bit */ 435 ds :1; /* ds bit */ 436 #elif defined(_BIT_FIELDS_HTOL) 437 uchar_t ds :1, /* ds bit */ 438 spf :1, /* spf bit */ 439 code :6; /* page code bit */ 440 #else 441 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 442 #endif 443 uchar_t sub_page_code; 444 uchar_t page_len_high; 445 uchar_t page_len_low; 446 447 uchar_t manufactor_date_high; 448 uchar_t manufactor_date_low; 449 struct parameter_control param_1; 450 uchar_t param_len_1; 451 uchar_t year_manu[4]; 452 uchar_t week_manu[2]; 453 454 uchar_t account_date_high; 455 uchar_t account_date_low; 456 struct parameter_control param_2; 457 uchar_t param_len_2; 458 uchar_t year_account[4]; 459 uchar_t week_account[2]; 460 461 uchar_t lifetime_code_high; 462 uchar_t lifetime_code_low; 463 struct parameter_control param_3; 464 uchar_t param_len_3; 465 uchar_t cycle_lifetime[4]; 466 467 uchar_t cycle_code_high; 468 uchar_t cycle_code_low; 469 struct parameter_control param_4; 470 uchar_t param_len_4; 471 uchar_t cycle_accumulated[4]; 472 }; 473 474 475 #ifdef __cplusplus 476 } 477 #endif 478 479 /* 480 * Include known generic device specific mode definitions and structures 481 */ 482 483 #include <sys/scsi/generic/dad_mode.h> 484 485 /* 486 * Include implementation specific mode information 487 */ 488 489 #include <sys/scsi/impl/mode.h> 490 491 #endif /* _SYS_SCSI_GENERIC_MODE_H */ 492