/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
* 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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* These routines in this file are used to interact with SMC driver to
* read and write FRUID data
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <stdarg.h>
#include <synch.h>
#include <thread.h>
#include <fcntl.h>
#include <syslog.h>
#include <stropts.h>
#include <poll.h>
#include <smclib.h>
#include "fru_access_impl.h"
/* IPMI fru spec Storage definition version 1.0, rev 1.1 */
/* type encoding */
/* for ascii conversion */
/* IPMI commands */
typedef struct {
extern void get_fru_data_info(int, int, format_t *);
/*
* Routine to read FRUID information from BMC
*/
static int
{
return (-1);
}
POLL_TIMEOUT) != SMC_SUCCESS) {
return (-1);
}
/* check the completion code */
return (-1);
}
return (0);
}
/*
* Routine to read FRUID information from other boards
*/
static int
{
int ipmi = 0;
return (-1);
}
/* figure out if onboard access or ipmb access */
ipmi = 0;
} else {
ipmi = 1;
}
switch (ipmi) {
case 0: /* on board info (local i2c) */
/* data field for request */
} else {
}
/* make a call to smc library to send cmd */
POLL_TIMEOUT) != SMC_SUCCESS) {
return (-1);
}
return (-1);
}
return (0);
default:
/* data for request packet */
} else {
}
POLL_TIMEOUT) != SMC_SUCCESS) {
return (-1);
}
/* check the completion code */
return (-1);
}
/* check the size */
return (-1);
}
return (0);
}
}
/*
* routine to read the IPMI common header field
*/
static int
{
int ret = 0;
format);
if (ret < 0) {
return (-1);
}
/* version check */
return (-1);
}
return (0);
}
/*
* Read the values of each field based on FORMAT
*/
/* ARGSUSED */
static int
{
if (ret < 0) {
return (-1);
}
if (data[0] == AREA_TERMINATION_INDICATOR) {
return (0);
}
if (len <= 0) {
return (0);
}
if (ret < 0) {
return (-1);
}
switch (encode_type) {
case SIX_BITASCII_TYPE:
return (-1);
}
break;
case BCDPLUS_TYPE:
return (-1);
}
break;
case BINARY_TYPE:
case UNICODE_TYPE:
default:
return (-1);
}
return (len);
}
static int
{
int bd_area_len = 0;
/* read version, length, lang code, mfg. time */
if (ret < 0) {
return (-1);
}
/* version check */
return (-1);
}
/* byte 2 is lang code */
mfg_time[0] = 0x0;
/* fill the timestamp into manr */
if (bd_area_len < BD_MFR_OFFSET) {
return (-1);
}
return (-1);
}
/* read the board info */
} else {
}
/*
* We dont need the FRU FILE ID, so just skip the field
* and get the offset to read the custom MFG. info fields
*/
/* read the custom mfg. info fields */
return (0);
}
/*
* Read the IPMI information from hardware and translate it into
* MANR(SUN format)
*/
int
{
int ret = 0;
return (-1);
}
if (ret != 0) {
return (-1);
}
}
return (ret);
}
static void
int length, int extra_bytes)
{
uint8_t x, y;
int index = 0;
for (i = 0; ; i += 3) {
x = 0x0;
y = 0x0;
if (i == idx && extra_bytes == 0) {
break;
}
/* get the first six bits */
x += ASCII_MAP;
break;
}
/*
* get last 2 bits of first byte and first
* 4 bits of second byte
*/
x = (data[i] >> 6);
x |= y + ASCII_MAP;
if (i == idx) {
break;
}
/* get last 4 bits of second byte and 2 bits of last byte */
x |= y + ASCII_MAP;
/* get last six bits of third byte */
index += 4;
}
}
static void
{
int i, j, index = 0;
struct {
int a:4;
int b:4;
} val;
for (i = 0; i < len; i++) {
for (j = 0; j < 2; j++) {
if (j == 0) {
} else
if (tmp <= 9) {
/* ascii conversion */
continue;
}
switch (tmp) {
case 0xa:
break;
case 0xb:
break;
case 0xc:
break;
default:
}
}
}
}
/* converts ipmi format time to UTC time (unix 32 bit timestamp) */
static time_t
{
/* get UTC time for 0:00 1/1/96 (ipmi epoch) */
return (time);
}
/*
* routine to write information to BMC
*/
static int
{
return (-1);
}
return (-1);
}
/* initialize ipmi request packet */
/* send ipmi request packet */
POLL_TIMEOUT) != SMC_SUCCESS) {
return (-1);
}
/* check the completion code */
return (-1);
}
return (0);
}
static int
{
int ipmi = 0;
return (-1);
}
ipmi = 0;
} else {
ipmi = 1;
}
switch (ipmi) {
case 0: /* on board info (local i2c) */
/* data field for request */
} else {
}
/* make a call to smc library to send cmd */
POLL_TIMEOUT) != SMC_SUCCESS) {
return (-1);
}
break;
default: /* read data from remote device (ipmi) */
return (-1);
}
} else {
}
POLL_TIMEOUT) != SMC_SUCCESS) {
return (-1);
}
/* check the completion code */
return (-1);
}
break;
} /* end of switch */
return (0);
}
/*
* This routine splits the data to write into smaller chunks and
* write it to FRUID chip using SMC drv APIs
*/
/* ARGSUSED */
{
int ret;
int index = 0;
} else {
}
while (bytes_to_write != 0) {
retry = 3;
ret = 1;
if (bytes_to_write > SIZE_TO_READ_WRITE) {
} else {
}
retry--;
}
if (ret != 0) {
return (ret);
}
}
return (size);
}
/*
* This routine reads the data in smaller chunks and
* sends it to upper layer(frudata plugin) in the sw stack
*/
/* ARGSUSED */
{
int ret;
int index = 0;
} else {
}
while (bytes_to_read != 0) {
retry = 3;
ret = 1;
if (bytes_to_read > SIZE_TO_READ_WRITE) {
} else {
}
retry--;
}
if (ret != 0) {
return (ret);
}
}
return (size);
}
/*
* routine to check if IPMI fruid info is available,
* return 0: IPMI fruid not present
* return 1: IPMI fruid present
*/
static int
{
/* on board access */
/* data field for request */
/* make a call to smc library to send cmd */
POLL_TIMEOUT) != SMC_SUCCESS) {
return (0);
}
/* version check */
return (0);
} else {
return (1);
}
}
/* ipmi access */
return (0);
}
return (1);
} else {
return (0);
}
}
/*
* routine to check if fruid info is available on BMC,
* return 0: fruid not present
* return 1: fruid present
*/
static int
{
int ret;
/* passing dummy fd */
/* for now read the first 3 bytes and check the info */
if (ret < 0) {
return (0);
}
if (buffer[0] != SECTION_HDR_TAG) {
return (0);
}
return (1);
}
/*
* checks if the remote device intelligent device (IPMI capable) or not
* return 0: not ipmi capable
* return 1: ipmi capable
*/
static int
{
return (1);
}
return (0);
}
return (1); /* got response */
}
int
{
return (ret);
}
if (cpu_no == 0) { /* get the geo_addr */
/* initialize the request packet */
(void) smc_init_smc_msg(&req_pkt,
/* make a call to smc library to send cmd */
POLL_TIMEOUT) != SMC_SUCCESS) {
return (0);
}
if (SC_MSG_LEN(&rsp_pkt) == 0) {
return (0);
}
}
/* check if it is IPMI intelligent or not */
if (ret == 0) { /* dumb I/O card */
return (0);
}
}
/* check if ipmi frudata is present or not */
if (ret == 1) {
/* no need to look for sun format */
if (precedence == IPMI_FORMAT) {
return (fru_format->format);
}
}
/* check if sun fruid is present */
/* check the hdr version */
if (ret != BYTE_TO_READ_SUN_CHK) {
(~ (SUN_FORMAT));
}
if (data[0] != SECTION_HDR_TAG) {
(~ (SUN_FORMAT));
}
}
return (fru_format->format);
}