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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SPCS_S_IMPL_H 27 #define _SPCS_S_IMPL_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /* 34 * The SPCS Unistat private implementation definitions 35 * 36 * Only modules spcs_s_u.c and spcs_s_k.c should be using this 37 */ 38 39 /* 40 * For Unistat, here are the definitions of the major and minor revisions: 41 * 42 * Bump major revision and zero minor revision if: Any change made to 43 * spcs_s_pinfo_t in terms of size, changed fields, etc, or any user 44 * functional change to spcs_s.h definitions that is not backwards 45 * compatible. 46 * 47 * Bump minor revision if: Any backwards compatible change to 48 * functionality but with no impact on interoperability between kernel and 49 * user level Unistat code having differing minor revs. 50 * 51 */ 52 53 #define SPCS_S_MAJOR_REV 1 /* Unistat major revision */ 54 #define SPCS_S_MINOR_REV 1 /* Unistat minor revision */ 55 /* 56 * This is the format of a unistat status code. It must overlay 57 * an int. 58 */ 59 #if defined(__sparc) 60 typedef struct { 61 /* 62 * If this flag is set the last supplemental item in idata is expected 63 * to be of type SU_BYTESTREAM and offset is a tdata index. 64 */ 65 unsigned char bytestream: 1; 66 /* 67 * count of items of supporting information references in idata 68 * to accompany this error status code spcs.h define SPCS_S_MAXSUPP 69 * must be 2 raised to the bit size of this field. Also don't forget 70 * to update the sprintf in spcs_s_string. 71 */ 72 unsigned char reserved: 4; /* reserved for future expansion */ 73 unsigned char sup_count: 3; 74 unsigned char module: 8; /* module code (see below) */ 75 unsigned short code: 16; /* status code number (>0) */ 76 } spcs_s_code_t; 77 #elif defined(__i386) || (__amd64) 78 typedef struct { 79 /* 80 * count of items of supporting information references in idata 81 * to accompany this error status code spcs.h define SPCS_S_MAXSUPP 82 * must be 2 raised to the bit size of this field. Also don't forget 83 * to update the sprintf in spcs_s_string. 84 */ 85 unsigned short code: 16; /* status code number (>0) */ 86 unsigned char module: 8; /* module code (see below) */ 87 unsigned char sup_count: 3; 88 unsigned char reserved: 4; /* reserved for future expansion */ 89 /* 90 * If this flag is set the last supplemental item in idata is expected 91 * to be of type SU_BYTESTREAM and offset is a tdata index. 92 */ 93 unsigned char bytestream: 1; 94 } spcs_s_code_t; 95 #else 96 #error "instruction set architecture error" 97 #endif 98 99 /* 100 * The types of supplemental data references 101 */ 102 103 typedef enum {SU_STRING, /* character string reference */ 104 SU_BYTESTREAM, /* bytestream data reference */ 105 SU_RES2, 106 SU_RES3} suenum; 107 /* 108 * Supplemental data references. These follow status codes that have 109 * nonzero sup_count fields. The supplemental data references can 110 * currently be either a string reference or a bytestream data reference. 111 * In both cases the reference simply contains an offset into the 112 * sdata array (string) or tdata array (bytestream). This struct must be 113 * the size of an int. 114 */ 115 116 #if defined(__sparc) 117 typedef struct { 118 suenum type: 3; /* the supplemental data type */ 119 unsigned short reserved: 13; /* unused, reserved */ 120 unsigned short offset: 16; /* the sudata array offset of the */ 121 /* start of the supplemental data */ 122 /* or the tdata array offset for */ 123 /* bytestream data */ 124 } spcs_s_sudata_t; 125 #elif defined(__i386) || (__amd64) 126 typedef struct { 127 unsigned short offset: 16; /* the sudata array offset of the */ 128 /* start of the supplemental data */ 129 /* or the tdata array offset for */ 130 /* bytestream data */ 131 unsigned short reserved: 13; /* unused, reserved */ 132 suenum type: 3; /* the supplemental data type */ 133 } spcs_s_sudata_t; 134 #else 135 #error "instruction set architecture error" 136 #endif 137 138 /* 139 * Although bytestream data pointers are only used in the kernel layer 140 * and are converted to offsets prior to unistat data being made available 141 * to userspace (i.e. this never comes back via an ioctl), it is critical 142 * to keep the unistat data structure spcs_s_pinfo_t a constant size 143 * whether or not we're using LP64 or a 32 bit model. So we put the 144 * pointer in a union with a long long so it is fixed at 64 bits in size. 145 * 146 * Prior to being transported through a pipe, unistat data containing 147 * tdata items (see below) must have its pointers eliminated. The pointers 148 * are simply nulled out and the actual bytestream data is sent out the 149 * pipe following the spcs_s_pinfo_t in the same order as its references 150 * in the sequential tdata elements. 151 */ 152 153 typedef union { 154 uchar_t *data; /* the pointer to the bytestream data */ 155 long long _fix_the_size; 156 } _fixed_char_pointer_t; 157 158 /* 159 * The bytestream data descriptor in a tdata array element 160 */ 161 162 typedef struct { 163 uint32_t size; /* byte size of the bytestream data */ 164 _fixed_char_pointer_t u_p; /* union containing pointer inside */ 165 /* fixed length field */ 166 } spcs_s_tdesc_t; 167 168 /* 169 * All the types that can occupy an idata array element. 170 */ 171 172 typedef union { 173 spcs_s_status_t s; /* as the public status type */ 174 spcs_s_code_t f; /* as the internal status type */ 175 spcs_s_sudata_t su; /* the supplemental data reference type */ 176 int i; /* as integer: TEMPORARY */ 177 } spcs_s_udata_t; 178 179 /* 180 * The number of idata array elements. This is the upper bound for the 181 * total status codes and supplemental data reference items that can be 182 * held by unistat at one time. It is IMPORTANT that this array be large 183 * enough to hold all the status and references for the worst case path 184 * through core software. This is currently trivial to do by inspection 185 * of the ioctl service code. However once unistat usage is deployed to 186 * the underlying layers of core software below the ioctl service call 187 * layer it may require special tools to validate this. 188 */ 189 190 #define SPCS_S_IDSIZE 16 /* size of idata array */ 191 /* 192 * The number of sdata array elements. This is the upper bound for the 193 * total characters of string data added to the unistat structure as 194 * supplemental info. Same cautions as for SPCS_S_IDSIZE. 195 */ 196 197 #define SPCS_S_SDSIZE 512 /* size of sdata array */ 198 /* 199 * The number of tdata array elements. This is the upper bound for the 200 * total bytestream data descriptors that can be held by unistat at one 201 * time. Same cautions as for SPCS_S_IDSIZE. 202 */ 203 204 #define SPCS_S_TDSIZE 2 /* size of tdata array */ 205 206 /* 207 * The Unistat private data structure. This is pointed to by the 208 * public opaque pointer spcs_s_info_t and holds all the status codes 209 * and supplemental data references. String data is also stored here 210 * but the body of bytestream data is stored elsewhere (see below). 211 * 212 * If there is real concern about the overhead of ioctl copyouts they 213 * could be optimized such that only the scalars and the "used" elements 214 * of the idata, sdata and tdata arrays are moved. If this is done it is 215 * recommended that the scalars (i.e. major through spare) be moved into 216 * a structure to cut down on the chance of a coding error with manual 217 * size arithmetic. 218 * 219 * The major and minor revs are currently supperfulous since unistat and 220 * all of its clients are contained within the same private consolidation. 221 * There is an assertion to BLOW UP if mismatched major revisions are 222 * detected between the kernel and user layers. If the consolidation 223 * policies of core software are relaxed in the future the assertion must 224 * be replaced by code designed to do something intelligent if possible. 225 * 226 */ 227 228 #pragma pack() 229 typedef struct { 230 /* The next two fields must stay shorts and */ 231 /* stay at the front and in this order */ 232 /* "forever" */ 233 short major; /* Major unistat revision */ 234 short minor; /* Minor unistat revision */ 235 /* this define should obviously never change */ 236 #define SPCS_S_REVSIZE (sizeof (short) + sizeof (short)) 237 short icount; /* Number of items currently stored in idata */ 238 /* and the "next" index to store a new item */ 239 /* into */ 240 short scount; /* Number of items currently stored in sdata */ 241 /* and the "next" index to store a new item */ 242 /* into */ 243 short tcount; /* Number of items currently stored in tdata */ 244 /* and the "next" index to store a new item */ 245 /* into */ 246 short spare; /* Unused, reserved */ 247 spcs_s_udata_t idata[SPCS_S_IDSIZE]; /* the status info and supp refs */ 248 char sdata[SPCS_S_SDSIZE]; /* the supplemental string data pool. */ 249 /* the supplemental bytestream data pool. */ 250 spcs_s_tdesc_t tdata[SPCS_S_TDSIZE]; 251 } spcs_s_pinfo_t; 252 253 /* 254 * Module codes. These can be in any order except that Solaris MUST BE 255 * FIRST. 256 */ 257 258 enum {SPCS_M_Solaris, /* Solaris module */ 259 SPCS_M_SPCS, /* SPCS "module" (for codes that apply across */ 260 /* all controller modules */ 261 SPCS_M_DSW, /* InstantImage Module */ 262 SPCS_M_SV, /* Storage Volume Module */ 263 SPCS_M_RDC, /* Remote Dual Copy Module */ 264 SPCS_M_SDBC, /* Storage Device Block Cache Module */ 265 SPCS_M_STE, /* SCSI Target Emulation Module */ 266 SPCS_M_SDCTL, /* Storage Device Control Module */ 267 SPCS_M_MC, /* Memory Channel Module */ 268 SPCS_M_SIMCKD, /* CKD Simulation (SIMCKD) Module */ 269 SPCS_M_NVM}; /* Non-Volatile Memory Module */ 270 271 #define SPCS_M_MAX SPCS_M_NVM /* Highest defined module code */ 272 273 /* 274 * The SPCS general status values 275 */ 276 277 /* the module name spellings */ 278 279 #define SPCS_M_NSOL "SOLARIS" 280 #define SPCS_M_NSPCS "SPCS" 281 #define SPCS_M_NDSW "II" 282 #define SPCS_M_NSV "SV" 283 #define SPCS_M_NRDC "SNDR" 284 #define SPCS_M_NSDBC "SDBC" 285 #define SPCS_M_NSTE "STE" 286 #define SPCS_M_NSDCTL "NSCTL" 287 #define SPCS_M_NMC "MC" 288 #define SPCS_M_NSIM "SIMCKD" 289 #define SPCS_M_NNVM "NVM" 290 291 /* limits */ 292 293 #define SPCS_S_MAXKEY 256 /* max msg key length */ 294 #define SPCS_S_MAXTEXT SPCS_S_MAXLINE /* max msg text length */ 295 #define SPCS_S_MAXSIG 32 /* max format data signature length */ 296 #define SPCS_S_MAXPRE 32 /* max module prefix length */ 297 #define SPCS_S_MAXMODNAME 16 /* max module name length */ 298 299 /* the module names in a lookup array */ 300 #if !defined(_KERNEL) 301 static char *module_names[] = {SPCS_M_NSOL, SPCS_M_NSPCS, SPCS_M_NDSW, 302 SPCS_M_NSV, SPCS_M_NRDC, SPCS_M_NSDBC, SPCS_M_NSTE, SPCS_M_NSDCTL, 303 SPCS_M_NMC, SPCS_M_NSIM, SPCS_M_NNVM, NULL}; 304 #endif 305 306 #ifdef __cplusplus 307 } 308 #endif 309 310 #endif /* _SPCS_S_IMPL_H */ 311