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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_SCSI_GENERIC_MODE_H 28 #define _SYS_SCSI_GENERIC_MODE_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * 38 * Defines and Structures for SCSI Mode Sense/Select data - generic 39 * 40 */ 41 42 /* 43 * Structures and defines common for all device types 44 */ 45 46 /* 47 * Mode Sense/Select Header - Group 0 (6-byte). 48 * 49 * Mode Sense/Select data consists of a header, followed by zero or more 50 * block descriptors, followed by zero or more mode pages. 51 * 52 */ 53 54 struct mode_header { 55 uchar_t length; /* number of bytes following */ 56 uchar_t medium_type; /* device specific */ 57 uchar_t device_specific; /* device specific parameters */ 58 uchar_t bdesc_length; /* length of block descriptor(s), if any */ 59 }; 60 61 #define MODE_HEADER_LENGTH (sizeof (struct mode_header)) 62 63 /* 64 * Mode Sense/Select Header - Group 1 (10-bytes) 65 */ 66 67 struct mode_header_g1 { 68 ushort_t length; /* number of bytes following */ 69 uchar_t medium_type; /* device specific */ 70 uchar_t device_specific; /* device specific parameters */ 71 uchar_t reserved[2]; /* device specific parameters */ 72 ushort_t bdesc_length; /* len of block descriptor(s), if any */ 73 }; 74 75 #define MODE_HEADER_LENGTH_G1 (sizeof (struct mode_header_g1)) 76 77 /* 78 * Block Descriptor. Zero, one, or more may normally follow the mode header. 79 * 80 * The density code is device specific. 81 * 82 * The 24-bit value described by blks_{hi, mid, lo} describes the number of 83 * blocks which this block descriptor applies to. A value of zero means 84 * 'the rest of the blocks on the device'. 85 * 86 * The 24-bit value described by blksize_{hi, mid, lo} describes the blocksize 87 * (in bytes) applicable for this block descriptor. For Sequential Access 88 * devices, if this value is zero, the block size will be derived from 89 * the transfer length in I/O operations. 90 * 91 */ 92 93 struct block_descriptor { 94 uchar_t density_code; /* device specific */ 95 uchar_t blks_hi; /* hi */ 96 uchar_t blks_mid; /* mid */ 97 uchar_t blks_lo; /* low */ 98 uchar_t reserved; /* reserved */ 99 uchar_t blksize_hi; /* hi */ 100 uchar_t blksize_mid; /* mid */ 101 uchar_t blksize_lo; /* low */ 102 }; 103 104 #define MODE_BLK_DESC_LENGTH (sizeof (struct block_descriptor)) 105 #define MODE_PARAM_LENGTH (MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH) 106 107 /* 108 * Define a macro to take an address of a mode header to the address 109 * of the nth (0..n) block_descriptor, or NULL if there either aren't any 110 * block descriptors or the nth block descriptor doesn't exist. 111 */ 112 113 #define BLOCK_DESCRIPTOR_ADDR(mhdr, bdnum) \ 114 ((mhdr)->bdesc_length && ((unsigned)(bdnum)) < \ 115 ((mhdr)->bdesc_length/(sizeof (struct block_descriptor)))) ? \ 116 ((struct block_descriptor *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+ \ 117 ((bdnum) * sizeof (struct block_descriptor)))) : \ 118 ((struct block_descriptor *)0) 119 120 /* 121 * Mode page header. Zero or more Mode Pages follow either the block 122 * descriptors (if any), or the Mode Header. 123 * 124 * The 'ps' bit must be zero for mode select operations. 125 * 126 */ 127 128 struct mode_page { 129 #if defined(_BIT_FIELDS_LTOH) 130 uchar_t code :6, /* page code number */ 131 :1, /* reserved */ 132 ps :1; /* 'Parameter Saveable' bit */ 133 #elif defined(_BIT_FIELDS_HTOL) 134 uchar_t ps :1, /* 'Parameter Saveable' bit */ 135 :1, /* reserved */ 136 code :6; /* page code number */ 137 #else 138 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 139 #endif /* _BIT_FIELDS_LTOH */ 140 uchar_t length; /* length of bytes to follow */ 141 /* 142 * Mode Page specific data follows right after this... 143 */ 144 }; 145 146 /* 147 * Define a macro to retrieve the first mode page. Could be more 148 * general (for multiple mode pages). 149 */ 150 151 #define MODE_PAGE_ADDR(mhdr, type) \ 152 ((type *)(((ulong_t)(mhdr))+MODE_HEADER_LENGTH+(mhdr)->bdesc_length)) 153 154 /* 155 * Page codes follow the following specification: 156 * 157 * Code Value(s) What 158 * ---------------------------------------------------------------------- 159 * 0x00 Vendor Unique (does not require page format) 160 * 161 * 0x02, 0x09, 0x0A pages for all Device Types 162 * 0x1A, 0x1C 163 * 164 * 0x01, 0x03-0x08, pages for specific Device Type 165 * 0x0B-0x19, 0x1B, 166 * 0x1D-0x1F 167 * 168 * 0x20-0x3E Vendor Unique (requires page format) 169 * 170 * 0x3F Return all pages (valid for Mode Sense only) 171 * 172 */ 173 174 /* 175 * Page codes and page length values (all device types) 176 */ 177 178 #define MODEPAGE_DISCO_RECO 0x02 179 #define MODEPAGE_CACHING 0x08 180 #define MODEPAGE_PDEVICE 0x09 181 #define MODEPAGE_CTRL_MODE 0x0A 182 #define MODEPAGE_POWER_COND 0x1A 183 #define MODEPAGE_INFO_EXCPT 0x1C 184 185 #define MODEPAGE_ALLPAGES 0x3F 186 187 /* 188 * Mode Select/Sense page structures (for all device types) 189 */ 190 191 /* 192 * Disconnect/Reconnect Page 193 */ 194 195 struct mode_disco_reco { 196 struct mode_page mode_page; /* common mode page header */ 197 uchar_t buffer_full_ratio; /* write, how full before reconnect? */ 198 uchar_t buffer_empty_ratio; /* read, how full before reconnect? */ 199 ushort_t bus_inactivity_limit; /* how much bus quiet time for BSY- */ 200 ushort_t disconect_time_limit; /* min to remain disconnected */ 201 ushort_t connect_time_limit; /* min to remain connected */ 202 ushort_t max_burst_size; /* max data burst size */ 203 #if defined(_BIT_FIELDS_LTOH) 204 uchar_t dtdc : 3, /* data transfer disconenct control */ 205 dimm : 1, /* disconnect immediate */ 206 fastat : 1, /* fair for status */ 207 fawrt : 1, /* fair for write */ 208 fard : 1, /* fair for read */ 209 emdp : 1; /* enable modify data pointers */ 210 #elif defined(_BIT_FIELDS_HTOL) 211 uchar_t emdp : 1, /* enable modify data pointers */ 212 fard : 1, /* fair for read */ 213 fawrt : 1, /* fair for write */ 214 fastat : 1, /* fair for status */ 215 dimm : 1, /* disconnect immediate */ 216 dtdc : 3; /* data transfer disconenct control */ 217 #else 218 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 219 #endif /* _BIT_FIELDS_LTOH */ 220 uchar_t reserved; 221 ushort_t first_burst_sz; /* first burst size */ 222 }; 223 224 #define DTDC_DATADONE 0x01 225 /* 226 * Target may not disconnect once 227 * data transfer is started until 228 * all data successfully transferred. 229 */ 230 231 #define DTDC_CMDDONE 0x03 232 /* 233 * Target may not disconnect once 234 * data transfer is started until 235 * command completed. 236 */ 237 /* 238 * Caching Page 239 */ 240 241 struct mode_caching { 242 struct mode_page mode_page; /* common mode page header */ 243 #if defined(_BIT_FIELDS_LTOH) 244 uchar_t rcd : 1, /* Read Cache Disable */ 245 mf : 1, /* Multiplication Factor */ 246 wce : 1, /* Write Cache Enable */ 247 : 5; /* Reserved */ 248 uchar_t write_ret_prio : 4, /* Write Retention Priority */ 249 dmd_rd_ret_prio : 4; /* Demand Read Retention Priority */ 250 #elif defined(_BIT_FIELDS_HTOL) 251 uchar_t : 5, /* Reserved */ 252 wce : 1, /* Write Cache Enable */ 253 mf : 1, /* Multiplication Factor */ 254 rcd : 1; /* Read Cache Disable */ 255 uchar_t dmd_rd_ret_prio : 4, /* Demand Read Retention Priority */ 256 write_ret_prio : 4; /* Write Retention Priority */ 257 #else 258 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 259 #endif /* _BIT_FIELDS_LTOH */ 260 ushort_t pf_dsbl_trans_len; /* Disable prefetch transfer length */ 261 ushort_t min_prefetch; /* Minimum Prefetch */ 262 ushort_t max_prefetch; /* Maximum Prefetch */ 263 ushort_t max_prefetch_ceiling; /* Maximum Prefetch Ceiling */ 264 }; 265 266 /* 267 * Peripheral Device Page 268 */ 269 270 struct mode_pdevice { 271 struct mode_page mode_page; /* common mode page header */ 272 ushort_t if_ident; /* interface identifier */ 273 uchar_t reserved[4]; /* reserved */ 274 uchar_t vendor_uniqe[1]; /* vendor unique data */ 275 }; 276 277 #define PDEV_SCSI 0x0000 /* scsi interface */ 278 #define PDEV_SMD 0x0001 /* SMD interface */ 279 #define PDEV_ESDI 0x0002 /* ESDI interface */ 280 #define PDEV_IPI2 0x0003 /* IPI-2 interface */ 281 #define PDEV_IPI3 0x0004 /* IPI-3 interface */ 282 283 /* 284 * Control Mode Page 285 * 286 * Note: This structure is incompatible with previous SCSI 287 * implementations. See <scsi/impl/mode.h> for an 288 * alternative form of this structure. They can be 289 * distinguished by the length of data returned 290 * from a MODE SENSE command. 291 */ 292 293 #define PAGELENGTH_MODE_CONTROL_SCSI3 0x0A 294 295 struct mode_control_scsi3 { 296 struct mode_page mode_page; /* common mode page header */ 297 #if defined(_BIT_FIELDS_LTOH) 298 uchar_t rlec : 1, /* Report Log Exception bit */ 299 gltsd : 1, /* global logging target save disable */ 300 d_sense : 1, /* Use descriptor sense data (SPC-3) */ 301 : 5; 302 uchar_t qdisable: 1, /* Queue disable */ 303 que_err : 1, /* Queue error */ 304 : 2, 305 que_mod : 4; /* Queue algorithm modifier */ 306 uchar_t eanp : 1, /* Enable AEN permission */ 307 uaaenp : 1, /* Unit attention AEN permission */ 308 raenp : 1, /* Ready AEN permission */ 309 : 1, 310 bybths : 1, /* By both RESET signal */ 311 byprtm : 1, /* By port message */ 312 rac : 1, /* report a check */ 313 eeca : 1; /* enable extended contingent */ 314 /* allegiance (only pre-SCSI-3) */ 315 #elif defined(_BIT_FIELDS_HTOL) 316 uchar_t : 5, 317 d_sense : 1, /* Use descriptor sense data (SPC-3) */ 318 gltsd : 1, /* global logging target save disable */ 319 rlec : 1; /* Report Log Exception bit */ 320 uchar_t que_mod : 4, /* Queue algorithm modifier */ 321 : 2, 322 que_err : 1, /* Queue error */ 323 qdisable: 1; /* Queue disable */ 324 uchar_t eeca : 1, /* enable extended contingent */ 325 /* allegiance (only pre-SCSI-3) */ 326 rac : 1, /* report a check */ 327 byprtm : 1, /* By port message */ 328 bybths : 1, /* By both RESET signal */ 329 : 1, 330 raenp : 1, /* Ready AEN permission */ 331 uaaenp : 1, /* Unit attention AEN permission */ 332 eanp : 1; /* Enable AEN permission */ 333 #else 334 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 335 #endif /* _BIT_FIELDS_LTOH */ 336 uchar_t reserved; 337 ushort_t ready_aen_holdoff; /* Ready AEN holdoff period */ 338 ushort_t busy_timeout; /* Busy timeout period */ 339 uchar_t reserved_2[2]; 340 }; 341 342 #define CTRL_QMOD_RESTRICT 0x0 343 #define CTRL_QMOD_UNRESTRICT 0x1 344 345 #ifdef __cplusplus 346 } 347 #endif 348 349 /* 350 * Include known generic device specific mode definitions and structures 351 */ 352 353 #include <sys/scsi/generic/dad_mode.h> 354 355 /* 356 * Include implementation specific mode information 357 */ 358 359 #include <sys/scsi/impl/mode.h> 360 361 #endif /* _SYS_SCSI_GENERIC_MODE_H */ 362