root/usr/src/uts/sun4u/lw8/sys/sgenv_impl.h
/*
 * 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 2006 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_SGENV_IMPL_H
#define _SYS_SGENV_IMPL_H

#pragma ident   "%Z%%M% %I%     %E% SMI"

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * sgenv_impl.h - Serengeti Environmental Driver
 *
 * This header file contains the private environmental definitions for
 * the Serengeti platform. (used only by sgenv driver)
 *
 */

/* get the public definitions */
#include <sys/sgenv.h>

/* named field of keyswitch kstat */
#define POSITION_KSTAT_NAME     "position"

/* Mailbox message sub-types */
#define SG_GET_ENV_HPU_KEYS     0x4000
#define SG_GET_ENV_CONSTANTS    0x4004
#define SG_GET_ENV_VOLATILES    0x4002
#define SG_GET_ENV_THRESHOLDS   0x4003

/*
 * Max time sgenv waits for mailbox to respond before
 * it decides to timeout. (measured in seconds)
 */
#define SGENV_DEFAULT_MAX_MBOX_WAIT_TIME        30

#define SGENV_MAX_SENSORS_PER_KEY       27      /* from design doc (3.1.4) */
#define SGENV_MAX_HPUS_PER_DOMAIN       24
#define SGENV_MAX_HPU_KEYS              (SSM_MAX_INSTANCES * \
                                                SGENV_MAX_HPUS_PER_DOMAIN)
#define SGENV_MAX_SENSORS               (SGENV_MAX_SENSORS_PER_KEY * \
                                                SGENV_MAX_HPU_KEYS)

#define SGENV_NO_NODE_EXISTS            0x0
#define SGENV_NODE_TYPE_DS              0x3FF

#define SGENV_POLL_THREAD       0x1     /* cache update called from kstat */
#define SGENV_INTERRUPT_THREAD  0x2     /* cache update called from softint */

#define BOARD_CACHE             0x1
#define ENV_CACHE               0x2

/*
 * Event Publisher definitions for sysevent.
 */
#define EP_SGENV        SUNW_KERN_PUB SGENV_DRV_NAME

/*
 * Event definitions
 */
#define MAX_TAG_ID_STR_LEN              100

#define HPU_ENTRY(value_macro)  {       \
        value_macro,    \
        value_macro ## _STR,    \
        value_macro ## _ID      \
}

#define PART_VALUE(value_macro) {       \
        value_macro,    \
        value_macro ## _STR     \
}

#define TYPE_VALUE(value_macro, scale) {        \
        value_macro,    \
        value_macro ## _STR,    \
        value_macro ## _UNITS,  \
        scale   \
}

typedef struct hpu_value {
        unsigned        value;
        const char      *name;
        const char      *IDstr;

} hpu_value_t;

typedef struct part_value {
        unsigned        value;
        const char      *name;
} part_value_t;

typedef struct type_value {
        unsigned        value;
        const char      *name;
        const char      *units;
        uint32_t        scale;

} type_value_t;


/*
 * SGENV soft state structure.
 */
typedef struct sgenv_soft_state {
        int                     instance;       /* instance number */
        dev_info_t              *dip;           /* dev_info structure */
        kstat_t                 *keyswitch_ksp;
        kstat_t                 *env_info_ksp;
        kstat_t                 *board_info_ksp;

} sgenv_soft_state_t;


/*
 * Environmental Info Structures.
 */
typedef int32_t envresp_key_t;

typedef struct envresp_constants {
        sensor_id_t     id; /* sd_id */
        sensor_data_t   lo; /* sd_lo */
        sensor_data_t   hi; /* sd_hi */
        /* no padding required, 3x4-bytes in total length */

} envresp_constants_t;

typedef struct envresp_volatiles {
        sensor_status_t info;   /* sd_infostamp */
        sensor_data_t   value;  /* sd_value */
        int32_t         _pad;   /* pad to 2x8-bytes */

} envresp_volatiles_t;

typedef struct envresp_thresholds {
        sensor_data_t   lo_warn; /* sd_lo_warn */
        sensor_data_t   hi_warn; /* sd_hi_warn */
        /* no padding required, 2x4-bytes in total length */

} envresp_thresholds_t;


/*
 * functions local to this driver.
 */
static int      sgenv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
static int      sgenv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);

static int      sgenv_add_kstats(sgenv_soft_state_t *softsp);
static void     sgenv_remove_kstats(sgenv_soft_state_t *softsp);

static int      sgenv_create_cache_update_threads(void);
static int      sgenv_remove_cache_update_threads(void);
static void     sgenv_indicate_cache_update_needed(int cache);

static int      sgenv_keyswitch_kstat_update(kstat_t *ksp, int rw);

static void     sgenv_init_env_cache(void);
static void     sgenv_update_env_cache(void);
static int      sgenv_env_info_kstat_update(kstat_t *ksp, int rw);
static int      sgenv_env_info_kstat_snapshot(kstat_t *ksp, void *buf, int rw);
static int      sgenv_get_env_info_data(void);
static int      sgenv_get_hpu_keys(envresp_key_t *new, int *status);
static int      sgenv_get_env_data(envresp_key_t key, int key_posn,
                                        uint16_t flag, int *status);
static int      sgenv_handle_env_data_error(int err, int status, int key_posn,
                                        envresp_key_t key, char *str);
static void     sgenv_mbox_error_msg(char *str, int err, int status);
static void     sgenv_destroy_env_cache(void);
static void     sgenv_clear_env_cache_entry(int key_posn);
static int      sgenv_create_env_cache_entry(int key_posn);
static void     sgenv_set_sensor_status(env_sensor_t *sensor);
static void     sgenv_update_env_kstat_size(kstat_t *ksp);

static void     sgenv_init_board_cache(void);
static void     sgenv_update_board_cache(void);
static int      sgenv_board_info_kstat_update(kstat_t *ksp, int rw);
static int      sgenv_board_info_kstat_snapshot(kstat_t *ksp,
                                        void *buf, int rw);
static int      sgenv_get_board_info_data(void);
static void     sgenv_set_valid_node_positions(uint_t *node_present);

static int      sgenv_process_threshold_event(env_sensor_t sensor);
static void     sgenv_tagid_to_string(sensor_id_t id, char *str);
static int      sgenv_add_intr_handlers(void);
static int      sgenv_remove_intr_handlers(void);
static uint_t   sgenv_keyswitch_handler(char *);
static uint_t   sgenv_env_data_handler(char *);
static uint_t   sgenv_fan_status_handler(char *);
static uint_t   sgenv_dr_event_handler(char *);
static uint_t   sgenv_check_sensor_thresholds(void);
static const char       *sgenv_get_hpu_id_str(uint_t hpu_type);
static const char       *sgenv_get_part_str(uint_t sensor_part);
static const char       *sgenv_get_type_str(uint_t sensor_type);


/*
 * Debug stuff
 */
#ifdef DEBUG
extern uint_t   sgenv_debug;

#define SGENV_DEBUG_NONE        0x00
#define SGENV_DEBUG_POLL        0x01
#define SGENV_DEBUG_EVENT       0x02
#define SGENV_DEBUG_CACHE       0x04
#define SGENV_DEBUG_MSG         0x08
#define SGENV_DEBUG_THREAD      0x10
#define SGENV_DEBUG_ALL         0xFF

#define DCMN_ERR_S(v, s)        static fn_t (v) = (s)

#define DCMN_ERR        cmn_err
#define DCMN_ERR_EVENT  if (sgenv_debug & SGENV_DEBUG_EVENT)    DCMN_ERR
#define DCMN_ERR_CACHE  if (sgenv_debug & SGENV_DEBUG_CACHE)    DCMN_ERR
#define DCMN_ERR_THREAD if (sgenv_debug & SGENV_DEBUG_THREAD)   DCMN_ERR

#define SGENV_PRINT_MBOX_MSG(x, str)    \
        DCMN_ERR(CE_CONT, "Mbox msg info: %s", str);    \
        DCMN_ERR(CE_CONT, "\ttype = 0x%x,", x->msg_type.type);     \
        DCMN_ERR(CE_CONT, "\tsub_type = 0x%x\n", x->msg_type.sub_type);    \
        DCMN_ERR(CE_CONT, "\tstatus = 0x%x\n", x->msg_status);     \
        DCMN_ERR(CE_CONT, "\tlen = %d\n", x->msg_len);   \
        DCMN_ERR(CE_CONT, "\tbytes = %d\n", x->msg_bytes);       \
        DCMN_ERR(CE_CONT, "\tdata[0] = %d\n", x->msg_data[0]);       \
        DCMN_ERR(CE_CONT, "\tdata[1] = %d\n", x->msg_data[1]);

#define SGENV_PRINT_ENV_INFO(x) \
        DCMN_ERR(CE_CONT, "Tag=%lx, Val=%d, Lo=%d, LoW=%d, HiW=%d, Hi=%d, " \
                        "Inf=%llx St=%x PSt=%x",  \
                x.sd_id.tag_id, x.sd_value, \
                x.sd_lo, x.sd_lo_warn, x.sd_hi_warn, x.sd_hi, x.sd_infostamp, \
                SG_GET_SENSOR_STATUS(x.sd_status), \
                SG_GET_PREV_SENSOR_STATUS(x.sd_status));

#define SGENV_PRINT_POLL_INFO(x) \
                if (sgenv_debug & SGENV_DEBUG_POLL)     SGENV_PRINT_ENV_INFO(x)

#else
#define DCMN_ERR_S(v, s)        fn_t (v) = ""

#define _DCMN_ERR               cmn_err
#define DCMN_ERR                if (0) _DCMN_ERR
#define DCMN_ERR_EVENT          if (0) _DCMN_ERR
#define DCMN_ERR_CACHE          if (0) _DCMN_ERR
#define DCMN_ERR_THREAD         if (0) _DCMN_ERR
#define SGENV_PRINT_MBOX_MSG
#define SGENV_PRINT_ENV_INFO
#define SGENV_PRINT_POLL_INFO
#endif

#ifdef  __cplusplus
}
#endif

#endif  /* _SYS_SGENV_IMPL_H */