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