⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysmotvpd.c

📁 VxWorks下 Mcpn750的BSP源代码
💻 C
字号:
/* sysMotVpd.c - Motorola Vital Product Data Routines. *//* Copyright 1998,1999 Motorola, Inc., All Rights Reserved *//*modification history--------------------01d,18oct01,mil  Fixed sysVpdPktParse() for vpdBrdShow() error (SPR 35714)                 and cleaned up compiler warnings.01c,20apr99,srr  Enhanced file description.01b,09apr99,srr  Changed name to sysMotVpd.c01a,14sep98,rhv  Created by Motorola.*//*DESCRIPTIONThis file contains the Vital Product Data utility routines.  They providethe support functionality to use the I2C serial eeprom (SROM) by validatingthe header and parsing the data into packets.  There is a packet searchcapability as well as the means to read and write a range of bytes directlyto and from the SROM.  CAVEATSThese routines are needed before the kernel is un-compressed. For properoperation, this file must be added to the BOOT_EXTRA list in the Makefile toprevent it from being compressed during kernel generation.*/#include "vxWorks.h"#include "config.h"#include "mcpx750.h"#include "sysMotVpd.h"/* defines */#define ENET_INSTANCE_SIZE  7   /* size of an extended ethernet packet */#ifndef I2C_BYTE_READIMPORT STATUS sysHawkI2cByteRead(UCHAR, UCHAR, UCHAR *);#define I2C_BYTE_READ(device, offset, bfr) \    sysHawkI2cByteRead(device, offset, bfr)#endif#ifndef I2C_BYTE_WRITEIMPORT STATUS sysHawkI2cByteWrite(UCHAR, UCHAR, UCHAR *);#define I2C_BYTE_WRITE(device, offset, bfr) \    sysHawkI2cByteWrite(device, offset, bfr)#endif#ifndef I2C_BYTE_RANGE_READIMPORT STATUS sysHawkI2cRangeRead(UCHAR, UCHAR, UINT16, UCHAR *);#define I2C_BYTE_RANGE_READ(device, offset, count, bfr) \    sysHawkI2cRangeRead(device, offset, count, bfr)#endif#ifndef I2C_BYTE_RANGE_WRITEIMPORT STATUS sysI2cSromRangeWrite(UCHAR, UCHAR, UINT16, UCHAR *);#define I2C_BYTE_RANGE_WRITE(device, offset, count, bfr) \    sysI2cSromRangeWrite(device, offset, count, bfr)#endif/* globals */VPD sysBrdVpd; /* board vital product data */VPD sysTmVpd;  /* transition module vital product data */VPD_PACKET * sysBrdVpdPkts[VPD_PKT_LIMIT] = { 0 }; /* board vpd packets */VPD_PACKET * sysTmVpdPkts[VPD_PKT_LIMIT] = { 0 };  /* trans mod vpd packets *//********************************************************************************* sysI2cSromRangeRead - reads a range of bytes from an I2C serial eeprom (SROM)** This routine simply calls the I2C byte read routine for each requested byte.* The I2C byte read call is written using a macro to accommodate alternate* read routines.** RETURNS: OK, or ERROR if the I2C byte read fails.** SEE ALSO: sysI2cSromRangeWrite**/STATUS sysI2cSromRangeRead     (    UCHAR    devAdrs,    /* i2c address of the serial eeprom */    UCHAR    devOffset,  /* starting offset within the serial eeprom to read */    UINT16   byteCount,  /* number of bytes to read (one-based) */    UCHAR *  pBfr        /* destination buffer */    )    {    for ( ; byteCount != 0; ++devOffset, ++pBfr, --byteCount)        {        if (I2C_BYTE_READ(devAdrs, devOffset, pBfr) != OK)            return (ERROR);        }    return (OK);    }/********************************************************************************* sysI2cSromRangeWrite - writes a range of bytes to an I2C serial eeprom (SROM)** This routine simply calls the I2C byte write routine for each requested byte.* The I2C byte write call is written using a macro to accommodate alternate* I2C byte write routines.** RETURNS: OK, or ERROR if the I2C byte write fails.** SEE ALSO: sysI2cSromRangeRead**/STATUS sysI2cSromRangeWrite     (    UCHAR    devAdrs,    /* i2c address of the serial eeprom */    UCHAR    devOffset,  /* starting offset within the serial eeprom to write */    UINT16   byteCount,  /* number of bytes to write (one-based) */    UCHAR *  pBfr        /* source buffer */    )    {    for ( ; byteCount != 0; ++devOffset, ++pBfr, --byteCount)        {        if (I2C_BYTE_WRITE(devAdrs, devOffset, pBfr) != OK)            return (ERROR);        }    return (OK);    }/********************************************************************************* sysVpdHdrVld - validate a vital product data header** This routine validates the header of a vital product data structure. The* validation is performed by checking the contents of the "eyecatcher" and size* fields.** RETURNS: OK, or ERROR if vpd header contents are invalid.**/STATUS sysVpdHdrVld     (    VPD * pVpd   /* pointer to vpd structure */    )    {    UCHAR  eyePat[] = "MOTOROLA";    /* expected "eyecatcher" contents */    UINT32 index;                    /* current character */    /* verify that the contents of the eyecatcher are correct. */    for (index = 0; index < VPD_EYE_SIZE; index++)         if (pVpd->header.eyeCatcher[index] != eyePat[index])            return (ERROR);    /*     * make sure the eeprom contents will fit into our vpd structure     * and that the eeprom size is at least large enough to hold the header and     * a termination packet.     */    if ( (pVpd->header.size > sizeof(VPD)) ||         (pVpd->header.size < (sizeof(VPD_HEADER) + 1)) )        return (ERROR);    return (OK);    }/********************************************************************************* sysVpdPktParse - parse the vital product data packets** This routine parses a raw VPD data array into an array of VPD packet pointers.* The parser walks through the data area of the vital product data structure and* saves the starting address of each packet it finds into an array of packet* pointers. When a desired packet is needed at a later time, the packet pointer* array can be scanned without having to re-parse the packets for each search.** RETURNS: OK, or ERROR and NULLs the first pointer in the array if an error*          is encountered while parsing or the size of the pointer array is*          exceeded. ** SEE ALSO: sysVpdPktGet()*/STATUS sysVpdPktParse    (    VPD *         pVpd,        /* pointer to vpd structure */    VPD_PACKET ** pVpdPtr,     /* packet ptr array */    UINT32        vpdPktLimit  /* number of pointers in the array */    )    {    VPD_PACKET ** p;           /* address of first array element */    UCHAR type;                /* type of current packet */    UINT32 limit;              /* end of valid packet data */    UINT32 index = 0;          /* current position in packet data */    UINT32 pkt = 0;            /* number of packets found */    /* verify that the header is correct */    if (sysVpdHdrVld (pVpd) != OK)        {        *pVpdPtr = NULL;        return (ERROR);        }    /* save the address of the first element in the pointer array */    p = pVpdPtr;    /* calculate the size of the data array */    limit = (UINT32)pVpd->header.size - sizeof(VPD_HEADER);    /* walk through the vpd data area parsing each packet */    do        {        /* save the packet type */        type =  pVpd->packets[index];        /*         * save the address of the current packet in the packet pointer array         * and advance the packet pointer to the next array entry.         */        *pVpdPtr++ = (VPD_PACKET *)&pVpd->packets[index++];        /* increment the packet count and advance to the next packet */        ++pkt;        index += pVpd->packets[index];        index++;        /*         * check the packet type and bail out of the loop if: 1) the termination         * packet has been found, 2) the packet type is illegal, or 3) if we've         * reached or exceeded the end of the data array or the packet pointer         * array.         */        if ( (type == VPD_PID_TERM) ||             (type == VPD_PID_GI)   ||             (index >= limit)       ||             (pkt >= vpdPktLimit) )            break;        /* continue until termination packet is found */        } while (type != VPD_PID_TERM);     /*     * if we didn't stop due to finding a termination packet, invalidate the     * first entry in the pointer array and return an error indication.     */    if (type != VPD_PID_TERM)        {        *p = NULL;        return (ERROR);        }    else        return (OK);    }/********************************************************************************* sysVpdPktGet - search the vital product data for a specific packet** This routine searches the a caller-supplied array of vpd packet pointers* looking for the specified instance of a specific packet type. Instances are* numbered starting at 0.** NOTE: There are two types of ethernet address packets defined: The base type* has 6 data bytes and no trailing instance number. The alternate type contains* 6 bytes of ethernet address plus a trailing instance byte. Instances are* numbered starting at zero. This routine will handle both packet types. It will* also handle multiple instances of the other packet types (except only one* termination packet is allowed).** RETURNS: A pointer to the desired packet and OK if the packet was found,*          otherwise it returns ERROR.** SEE ALSO: sysVpdPktParse()*/STATUS sysVpdPktGet    (    UCHAR         vpdType,     /* target packet type */    UINT32        vpdInstance, /* instance number of desired packet (0-based) */    VPD_PACKET ** pVpdPtr,     /* address of the array of packet pointers */    VPD_PACKET ** pVpdPacket   /* address of the return variable */    )    {    UCHAR        type;         /* current packet type */    VPD_PACKET * p;            /* pointer to current packet */    /* if the first pointer in the array is NULL, return an error indication. */    if (*pVpdPtr == NULL)        return (ERROR);    do        {        /* get the current packet pointer */        p = *pVpdPtr;        /* if the packet type matches the caller's requested type */        if ( (type = p->type) == vpdType )            {            /*             * see if the type is an ethernet address and has a trailing             * instance value. if it does, see of the instance number matches             * the caller's requested instance.             */            if ( (vpdType == VPD_PID_EA) &&                 (p->size == ENET_INSTANCE_SIZE) &&                 (vpdInstance == p->data[ENET_INSTANCE_SIZE-1]) )                {                *pVpdPacket = p;                return (OK);                }            else                {                /*                 * see if this is the instance the caller requested, if not                 * decrement the instance count and go around again.                 */                if (vpdInstance-- == 0)                    {                    *pVpdPacket = p;                    return (OK);                    }                }            }        /* advance to the next packet. */        pVpdPtr++;        /* terminate on reaching the term packet. */        } while ( type != VPD_PID_TERM);    return (ERROR);    }/********************************************************************************* sysVpdPktInit - initialize a vital product data structure.** This routine reads the vital product data header from a serial eeprom and* validates it. If the header is valid, the remainder of the vpd data* is read from the serial eeprom and parsed into vpd packets for general* purpose use.** RETURNS: OK, if successful or ERROR if unsuccessful.** SEE ALSO: sysVpdPktParse(), sysVpdPktGet() */STATUS sysVpdPktInit    (    UCHAR         devAdrs,   /* i2c address of the serial eeprom */    UCHAR         devOffset, /* offset to vpd within the serial eeprom */    VPD *         pVpd,      /* address of vpd structure */    VPD_PACKET ** pVpdPtr,   /* address of packet ptr array */    UINT32        PktLimit   /* number of entries in the packet ptr array */    )    {    /* mark vpd packet pointer contents invalid. */    *pVpdPtr = NULL;    /* read just the header from serial eeprom. */    if (I2C_BYTE_RANGE_READ (devAdrs, devOffset, sizeof(VPD_HEADER),                        (UCHAR *)pVpd) != OK)        return (ERROR);    /* check for a valid header */    if (sysVpdHdrVld (pVpd) != OK)        return (ERROR);    /* read the rest of the vpd from the serial eeprom. */    if (I2C_BYTE_RANGE_READ (devAdrs, devOffset + sizeof(VPD_HEADER),                        pVpd->header.size - sizeof(VPD_HEADER),                        (UCHAR *)&pVpd->packets) != OK)        return (ERROR);    /* parse the raw vpd data into vpd packets. */    return (sysVpdPktParse (pVpd, pVpdPtr, PktLimit) );    }/********************************************************************************* sysVpdBrdInit - initialize the board vital product data structures.** This routine is simply a wrapper around sysVpdPktInit to hide the vpd details* from the upper level code.** RETURNS: OK, if successful or ERROR if unsuccessful.** SEE ALSO: sysVpdTmInit()*/STATUS sysVpdBrdInit(void)    {    return (sysVpdPktInit (VPD_BRD_EEPROM_ADRS, VPD_BRD_OFFSET, &sysBrdVpd,                      &sysBrdVpdPkts[0], VPD_PKT_LIMIT) );    }/********************************************************************************* sysVpdTmInit - initialize the transition module vital product data structures.** This routine is simply a wrapper around sysVpdPktInit to hide the vpd details* from the upper level code.** RETURNS: OK, if successful or ERROR if unsuccessful.** SEE ALSO: sysVpdBrdInit()*/STATUS sysVpdTmInit(void)    {    return (sysVpdPktInit (VPD_TM_EEPROM_ADRS, VPD_TM_OFFSET, &sysTmVpd,                      &sysTmVpdPkts[0], VPD_PKT_LIMIT) );    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -