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 2006 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 #pragma ident "%Z%%M% %I% %E% SMI" 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 codes follow the following specification: 155 * 156 * Code Value(s) What 157 * ---------------------------------------------------------------------- 158 * 0x00 Vendor Unique (does not require page format) 159 * 160 * 0x02, 0x09, 0x0A pages for all Device Types 161 * 0x1A, 0x1C 162 * 163 * 0x01, 0x03-0x08, pages for specific Device Type 164 * 0x0B-0x19, 0x1B, 165 * 0x1D-0x1F 166 * 167 * 0x20-0x3E Vendor Unique (requires page format) 168 * 169 * 0x3F Return all pages (valid for Mode Sense only) 170 * 171 */ 172 173 /* 174 * Page codes and page length values (all device types) 175 */ 176 177 #define MODEPAGE_DISCO_RECO 0x02 178 #define MODEPAGE_CACHING 0x08 179 #define MODEPAGE_PDEVICE 0x09 180 #define MODEPAGE_CTRL_MODE 0x0A 181 #define MODEPAGE_POWER_COND 0x1A 182 #define MODEPAGE_INFO_EXCPT 0x1C 183 184 #define MODEPAGE_ALLPAGES 0x3F 185 186 /* 187 * Mode Select/Sense page structures (for all device types) 188 */ 189 190 /* 191 * Disconnect/Reconnect Page 192 */ 193 194 struct mode_disco_reco { 195 struct mode_page mode_page; /* common mode page header */ 196 uchar_t buffer_full_ratio; /* write, how full before reconnect? */ 197 uchar_t buffer_empty_ratio; /* read, how full before reconnect? */ 198 ushort_t bus_inactivity_limit; /* how much bus quiet time for BSY- */ 199 ushort_t disconect_time_limit; /* min to remain disconnected */ 200 ushort_t connect_time_limit; /* min to remain connected */ 201 ushort_t max_burst_size; /* max data burst size */ 202 #if defined(_BIT_FIELDS_LTOH) 203 uchar_t dtdc : 3, /* data transfer disconenct control */ 204 dimm : 1, /* disconnect immediate */ 205 fastat : 1, /* fair for status */ 206 fawrt : 1, /* fair for write */ 207 fard : 1, /* fair for read */ 208 emdp : 1; /* enable modify data pointers */ 209 #elif defined(_BIT_FIELDS_HTOL) 210 uchar_t emdp : 1, /* enable modify data pointers */ 211 fard : 1, /* fair for read */ 212 fawrt : 1, /* fair for write */ 213 fastat : 1, /* fair for status */ 214 dimm : 1, /* disconnect immediate */ 215 dtdc : 3; /* data transfer disconenct control */ 216 #else 217 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 218 #endif /* _BIT_FIELDS_LTOH */ 219 uchar_t reserved; 220 ushort_t first_burst_sz; /* first burst size */ 221 }; 222 223 #define DTDC_DATADONE 0x01 224 /* 225 * Target may not disconnect once 226 * data transfer is started until 227 * all data successfully transferred. 228 */ 229 230 #define DTDC_CMDDONE 0x03 231 /* 232 * Target may not disconnect once 233 * data transfer is started until 234 * command completed. 235 */ 236 /* 237 * Caching Page 238 */ 239 240 struct mode_caching { 241 struct mode_page mode_page; /* common mode page header */ 242 #if defined(_BIT_FIELDS_LTOH) 243 uchar_t rcd : 1, /* Read Cache Disable */ 244 mf : 1, /* Multiplication Factor */ 245 wce : 1, /* Write Cache Enable */ 246 : 5; /* Reserved */ 247 uchar_t write_ret_prio : 4, /* Write Retention Priority */ 248 dmd_rd_ret_prio : 4; /* Demand Read Retention Priority */ 249 #elif defined(_BIT_FIELDS_HTOL) 250 uchar_t : 5, /* Reserved */ 251 wce : 1, /* Write Cache Enable */ 252 mf : 1, /* Multiplication Factor */ 253 rcd : 1; /* Read Cache Disable */ 254 uchar_t dmd_rd_ret_prio : 4, /* Demand Read Retention Priority */ 255 write_ret_prio : 4; /* Write Retention Priority */ 256 #else 257 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 258 #endif /* _BIT_FIELDS_LTOH */ 259 ushort_t pf_dsbl_trans_len; /* Disable prefetch transfer length */ 260 ushort_t min_prefetch; /* Minimum Prefetch */ 261 ushort_t max_prefetch; /* Maximum Prefetch */ 262 ushort_t max_prefetch_ceiling; /* Maximum Prefetch Ceiling */ 263 }; 264 265 /* 266 * Peripheral Device Page 267 */ 268 269 struct mode_pdevice { 270 struct mode_page mode_page; /* common mode page header */ 271 ushort_t if_ident; /* interface identifier */ 272 uchar_t reserved[4]; /* reserved */ 273 uchar_t vendor_uniqe[1]; /* vendor unique data */ 274 }; 275 276 #define PDEV_SCSI 0x0000 /* scsi interface */ 277 #define PDEV_SMD 0x0001 /* SMD interface */ 278 #define PDEV_ESDI 0x0002 /* ESDI interface */ 279 #define PDEV_IPI2 0x0003 /* IPI-2 interface */ 280 #define PDEV_IPI3 0x0004 /* IPI-3 interface */ 281 282 /* 283 * Control Mode Page 284 * 285 * Note: This structure is incompatible with previous SCSI 286 * implementations. See <scsi/impl/mode.h> for an 287 * alternative form of this structure. They can be 288 * distinguished by the length of data returned 289 * from a MODE SENSE command. 290 */ 291 292 #define PAGELENGTH_MODE_CONTROL_SCSI3 0x0A 293 294 struct mode_control_scsi3 { 295 struct mode_page mode_page; /* common mode page header */ 296 #if defined(_BIT_FIELDS_LTOH) 297 uchar_t rlec : 1, /* Report Log Exception bit */ 298 gltsd : 1, /* global logging target save disable */ 299 d_sense : 1, /* Use descriptor sense data (SPC-3) */ 300 : 5; 301 uchar_t qdisable: 1, /* Queue disable */ 302 que_err : 1, /* Queue error */ 303 : 2, 304 que_mod : 4; /* Queue algorithm modifier */ 305 uchar_t eanp : 1, /* Enable AEN permission */ 306 uaaenp : 1, /* Unit attention AEN permission */ 307 raenp : 1, /* Ready AEN permission */ 308 : 1, 309 bybths : 1, /* By both RESET signal */ 310 byprtm : 1, /* By port message */ 311 rac : 1, /* report a check */ 312 eeca : 1; /* enable extended contingent */ 313 /* allegiance (only pre-SCSI-3) */ 314 #elif defined(_BIT_FIELDS_HTOL) 315 uchar_t : 5, 316 d_sense : 1, /* Use descriptor sense data (SPC-3) */ 317 gltsd : 1, /* global logging target save disable */ 318 rlec : 1; /* Report Log Exception bit */ 319 uchar_t que_mod : 4, /* Queue algorithm modifier */ 320 : 2, 321 que_err : 1, /* Queue error */ 322 qdisable: 1; /* Queue disable */ 323 uchar_t eeca : 1, /* enable extended contingent */ 324 /* allegiance (only pre-SCSI-3) */ 325 rac : 1, /* report a check */ 326 byprtm : 1, /* By port message */ 327 bybths : 1, /* By both RESET signal */ 328 : 1, 329 raenp : 1, /* Ready AEN permission */ 330 uaaenp : 1, /* Unit attention AEN permission */ 331 eanp : 1; /* Enable AEN permission */ 332 #else 333 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 334 #endif /* _BIT_FIELDS_LTOH */ 335 uchar_t reserved; 336 ushort_t ready_aen_holdoff; /* Ready AEN holdoff period */ 337 ushort_t busy_timeout; /* Busy timeout period */ 338 uchar_t reserved_2[2]; 339 }; 340 341 #ifdef __lock_lint 342 _NOTE(SCHEME_PROTECTS_DATA("Unshared SCSI payload", \ 343 mode_control_scsi3)) 344 #endif 345 346 #define CTRL_QMOD_RESTRICT 0x0 347 #define CTRL_QMOD_UNRESTRICT 0x1 348 349 /* 350 * Informational Exceptions Control Mode Page 351 */ 352 353 #define PAGELENGTH_INFO_EXCPT 0x0A 354 355 struct mode_info_excpt_page { 356 struct mode_page mode_page; /* common mode page header */ 357 #if defined(_BIT_FIELDS_LTOH) 358 uchar_t log_err : 1; /* log errors */ 359 uchar_t : 1; /* reserved */ 360 uchar_t test : 1; /* create test failure */ 361 uchar_t dexcpt : 1; /* disable exception */ 362 uchar_t ewasc : 1; /* enable warning */ 363 uchar_t ebf : 1; /* enable background function */ 364 uchar_t : 1; /* reserved */ 365 uchar_t perf : 1; /* performance */ 366 uchar_t mrie : 4; /* method of reporting info. excpts. */ 367 uchar_t : 4; /* reserved */ 368 #elif defined(_BIT_FIELDS_HTOL) 369 uchar_t perf : 1; /* performance */ 370 uchar_t : 1; /* reserved */ 371 uchar_t ebf : 1; /* enable background function */ 372 uchar_t ewasc : 1; /* enable warning */ 373 uchar_t dexcpt : 1; /* disable exception */ 374 uchar_t test : 1; /* create test failure */ 375 uchar_t : 1; /* reserved */ 376 uchar_t log_err : 1; /* log errors */ 377 uchar_t : 4; /* reserved */ 378 uchar_t mrie : 4; /* method of reporting info. excpts. */ 379 #else 380 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 381 #endif 382 uchar_t interval_timer[4]; /* interval timer */ 383 uchar_t report_count[4]; /* report count */ 384 }; 385 386 #define MRIE_NO_REPORT 0x0 387 #define MRIE_ASYNCH 0x1 388 #define MRIE_UNIT_ATTN 0x2 389 #define MRIE_COND_RECVD_ERR 0x3 390 #define MRIE_UNCOND_RECVD_ERR 0x4 391 #define MRIE_NO_SENSE 0x5 392 #define MRIE_ONLY_ON_REQUEST 0x6 393 394 #ifdef __cplusplus 395 } 396 #endif 397 398 /* 399 * Include known generic device specific mode definitions and structures 400 */ 401 402 #include <sys/scsi/generic/dad_mode.h> 403 404 /* 405 * Include implementation specific mode information 406 */ 407 408 #include <sys/scsi/impl/mode.h> 409 410 #endif /* _SYS_SCSI_GENERIC_MODE_H */ 411