spcs_s_impl.h revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SPCS_S_IMPL_H
#define _SPCS_S_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* The SPCS Unistat private implementation definitions
*
* Only modules spcs_s_u.c and spcs_s_k.c should be using this
*/
/*
* For Unistat, here are the definitions of the major and minor revisions:
*
* Bump major revision and zero minor revision if: Any change made to
* spcs_s_pinfo_t in terms of size, changed fields, etc, or any user
* functional change to spcs_s.h definitions that is not backwards
* compatible.
*
* Bump minor revision if: Any backwards compatible change to
* functionality but with no impact on interoperability between kernel and
* user level Unistat code having differing minor revs.
*
*/
#define SPCS_S_MAJOR_REV 1 /* Unistat major revision */
#define SPCS_S_MINOR_REV 1 /* Unistat minor revision */
/*
* This is the format of a unistat status code. It must overlay
* an int.
*/
#if defined(__sparc)
typedef struct {
/*
* If this flag is set the last supplemental item in idata is expected
* to be of type SU_BYTESTREAM and offset is a tdata index.
*/
unsigned char bytestream: 1;
/*
* count of items of supporting information references in idata
* to accompany this error status code spcs.h define SPCS_S_MAXSUPP
* must be 2 raised to the bit size of this field. Also don't forget
* to update the sprintf in spcs_s_string.
*/
unsigned char reserved: 4; /* reserved for future expansion */
unsigned char sup_count: 3;
unsigned char module: 8; /* module code (see below) */
unsigned short code: 16; /* status code number (>0) */
} spcs_s_code_t;
#elif defined(__i386) || (__amd64)
typedef struct {
/*
* count of items of supporting information references in idata
* to accompany this error status code spcs.h define SPCS_S_MAXSUPP
* must be 2 raised to the bit size of this field. Also don't forget
* to update the sprintf in spcs_s_string.
*/
unsigned short code: 16; /* status code number (>0) */
unsigned char module: 8; /* module code (see below) */
unsigned char sup_count: 3;
unsigned char reserved: 4; /* reserved for future expansion */
/*
* If this flag is set the last supplemental item in idata is expected
* to be of type SU_BYTESTREAM and offset is a tdata index.
*/
unsigned char bytestream: 1;
} spcs_s_code_t;
#else
#error "instruction set architecture error"
#endif
/*
* The types of supplemental data references
*/
typedef enum {SU_STRING, /* character string reference */
SU_BYTESTREAM, /* bytestream data reference */
SU_RES2,
SU_RES3} suenum;
/*
* Supplemental data references. These follow status codes that have
* nonzero sup_count fields. The supplemental data references can
* currently be either a string reference or a bytestream data reference.
* In both cases the reference simply contains an offset into the
* sdata array (string) or tdata array (bytestream). This struct must be
* the size of an int.
*/
#if defined(__sparc)
typedef struct {
suenum type: 3; /* the supplemental data type */
unsigned short reserved: 13; /* unused, reserved */
unsigned short offset: 16; /* the sudata array offset of the */
/* start of the supplemental data */
/* or the tdata array offset for */
/* bytestream data */
} spcs_s_sudata_t;
#elif defined(__i386) || (__amd64)
typedef struct {
unsigned short offset: 16; /* the sudata array offset of the */
/* start of the supplemental data */
/* or the tdata array offset for */
/* bytestream data */
unsigned short reserved: 13; /* unused, reserved */
suenum type: 3; /* the supplemental data type */
} spcs_s_sudata_t;
#else
#error "instruction set architecture error"
#endif
/*
* Although bytestream data pointers are only used in the kernel layer
* and are converted to offsets prior to unistat data being made available
* to userspace (i.e. this never comes back via an ioctl), it is critical
* to keep the unistat data structure spcs_s_pinfo_t a constant size
* whether or not we're using LP64 or a 32 bit model. So we put the
* pointer in a union with a long long so it is fixed at 64 bits in size.
*
* Prior to being transported through a pipe, unistat data containing
* tdata items (see below) must have its pointers eliminated. The pointers
* are simply nulled out and the actual bytestream data is sent out the
* pipe following the spcs_s_pinfo_t in the same order as its references
* in the sequential tdata elements.
*/
typedef union {
uchar_t *data; /* the pointer to the bytestream data */
long long _fix_the_size;
} _fixed_char_pointer_t;
/*
* The bytestream data descriptor in a tdata array element
*/
typedef struct {
uint32_t size; /* byte size of the bytestream data */
_fixed_char_pointer_t u_p; /* union containing pointer inside */
/* fixed length field */
} spcs_s_tdesc_t;
/*
* All the types that can occupy an idata array element.
*/
typedef union {
spcs_s_status_t s; /* as the public status type */
spcs_s_code_t f; /* as the internal status type */
spcs_s_sudata_t su; /* the supplemental data reference type */
int i; /* as integer: TEMPORARY */
} spcs_s_udata_t;
/*
* The number of idata array elements. This is the upper bound for the
* total status codes and supplemental data reference items that can be
* held by unistat at one time. It is IMPORTANT that this array be large
* enough to hold all the status and references for the worst case path
* through core software. This is currently trivial to do by inspection
* of the ioctl service code. However once unistat usage is deployed to
* the underlying layers of core software below the ioctl service call
* layer it may require special tools to validate this.
*/
#define SPCS_S_IDSIZE 16 /* size of idata array */
/*
* The number of sdata array elements. This is the upper bound for the
* total characters of string data added to the unistat structure as
* supplemental info. Same cautions as for SPCS_S_IDSIZE.
*/
#define SPCS_S_SDSIZE 512 /* size of sdata array */
/*
* The number of tdata array elements. This is the upper bound for the
* total bytestream data descriptors that can be held by unistat at one
* time. Same cautions as for SPCS_S_IDSIZE.
*/
#define SPCS_S_TDSIZE 2 /* size of tdata array */
/*
* The Unistat private data structure. This is pointed to by the
* public opaque pointer spcs_s_info_t and holds all the status codes
* and supplemental data references. String data is also stored here
* but the body of bytestream data is stored elsewhere (see below).
*
* If there is real concern about the overhead of ioctl copyouts they
* could be optimized such that only the scalars and the "used" elements
* of the idata, sdata and tdata arrays are moved. If this is done it is
* recommended that the scalars (i.e. major through spare) be moved into
* a structure to cut down on the chance of a coding error with manual
* size arithmetic.
*
* The major and minor revs are currently supperfulous since unistat and
* all of its clients are contained within the same private consolidation.
* There is an assertion to BLOW UP if mismatched major revisions are
* detected between the kernel and user layers. If the consolidation
* policies of core software are relaxed in the future the assertion must
* be replaced by code designed to do something intelligent if possible.
*
*/
#pragma pack()
typedef struct {
/* The next two fields must stay shorts and */
/* stay at the front and in this order */
/* "forever" */
short major; /* Major unistat revision */
short minor; /* Minor unistat revision */
/* this define should obviously never change */
#define SPCS_S_REVSIZE (sizeof (short) + sizeof (short))
short icount; /* Number of items currently stored in idata */
/* and the "next" index to store a new item */
/* into */
short scount; /* Number of items currently stored in sdata */
/* and the "next" index to store a new item */
/* into */
short tcount; /* Number of items currently stored in tdata */
/* and the "next" index to store a new item */
/* into */
short spare; /* Unused, reserved */
spcs_s_udata_t idata[SPCS_S_IDSIZE]; /* the status info and supp refs */
char sdata[SPCS_S_SDSIZE]; /* the supplemental string data pool. */
/* the supplemental bytestream data pool. */
spcs_s_tdesc_t tdata[SPCS_S_TDSIZE];
} spcs_s_pinfo_t;
/*
* Module codes. These can be in any order except that Solaris MUST BE
* FIRST.
*/
enum {SPCS_M_Solaris, /* Solaris module */
SPCS_M_SPCS, /* SPCS "module" (for codes that apply across */
/* all controller modules */
SPCS_M_DSW, /* InstantImage Module */
SPCS_M_SV, /* Storage Volume Module */
SPCS_M_RDC, /* Remote Dual Copy Module */
SPCS_M_SDBC, /* Storage Device Block Cache Module */
SPCS_M_STE, /* SCSI Target Emulation Module */
SPCS_M_SDCTL, /* Storage Device Control Module */
SPCS_M_MC, /* Memory Channel Module */
SPCS_M_SIMCKD, /* CKD Simulation (SIMCKD) Module */
SPCS_M_NVM}; /* Non-Volatile Memory Module */
#define SPCS_M_MAX SPCS_M_NVM /* Highest defined module code */
/*
* The SPCS general status values
*/
/* the module name spellings */
#define SPCS_M_NSOL "SOLARIS"
#define SPCS_M_NSPCS "SPCS"
#define SPCS_M_NDSW "II"
#define SPCS_M_NSV "SV"
#define SPCS_M_NRDC "SNDR"
#define SPCS_M_NSDBC "SDBC"
#define SPCS_M_NSTE "STE"
#define SPCS_M_NSDCTL "NSCTL"
#define SPCS_M_NMC "MC"
#define SPCS_M_NSIM "SIMCKD"
#define SPCS_M_NNVM "NVM"
/* limits */
#define SPCS_S_MAXKEY 256 /* max msg key length */
#define SPCS_S_MAXTEXT SPCS_S_MAXLINE /* max msg text length */
#define SPCS_S_MAXSIG 32 /* max format data signature length */
#define SPCS_S_MAXPRE 32 /* max module prefix length */
#define SPCS_S_MAXMODNAME 16 /* max module name length */
/* the module names in a lookup array */
#if !defined(_KERNEL)
static char *module_names[] = {SPCS_M_NSOL, SPCS_M_NSPCS, SPCS_M_NDSW,
SPCS_M_NSV, SPCS_M_NRDC, SPCS_M_NSDBC, SPCS_M_NSTE, SPCS_M_NSDCTL,
SPCS_M_NMC, SPCS_M_NSIM, SPCS_M_NNVM, NULL};
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SPCS_S_IMPL_H */