]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
* Patch by Erik Theisen, 9 Mar 2002:
authorwdenk <wdenk>
Sun, 10 Mar 2002 22:52:58 +0000 (22:52 +0000)
committerwdenk <wdenk>
Sun, 10 Mar 2002 22:52:58 +0000 (22:52 +0000)
  VPD patch for W7O boards

board/w7o/cmd_vpd.c [new file with mode: 0644]
board/w7o/vpd.c [new file with mode: 0644]
board/w7o/vpd.h [new file with mode: 0644]

diff --git a/board/w7o/cmd_vpd.c b/board/w7o/cmd_vpd.c
new file mode 100644 (file)
index 0000000..f8b49c1
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <ppcboot.h>
+#include <command.h>
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+#include "vpd.h"
+#include "cmd_bsp.h"
+
+/* ======================================================================
+ * Interpreter command to retrieve board specific Vital Product Data, "VPD"
+ * ======================================================================
+ */
+int do_vpd( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] )
+{
+    VPD vpd;                                /* Board specific data struct */
+    uchar dev_addr = CFG_DEF_EEPROM_ADDR;
+
+    /* Validate usage */
+    if (argc > 2) {
+       printf ("Usage:\n%s\n", cmdtp->usage);
+       return 1;
+    }
+
+    /* Passed in EEPROM address */
+    if (argc == 2)
+       dev_addr = (uchar)simple_strtoul(argv[1], NULL, 16);
+
+    /* Read VPD and output it */
+    if (!vpd_get_data(dev_addr, &vpd)) {
+       vpd_print(&vpd);
+       return 0;
+    }
+
+    return 1;
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_BSP) */
diff --git a/board/w7o/vpd.c b/board/w7o/vpd.c
new file mode 100644 (file)
index 0000000..598360a
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#if defined(VXWORKS)
+# include <stdio.h>
+# include <string.h>
+# define CFG_DEF_EEPROM_ADDR 0xa0
+extern char iicReadByte( char, char );
+extern ulong_t crc32( unsigned char *, unsigned long );
+#else
+#include <ppcboot.h>
+#endif
+
+#include "vpd.h"
+
+/*
+ * vpd_reader() - reads VPD data from I2C EEPROMS.
+ *                returns pointer to buffer or NULL.
+ */
+static unsigned char *
+vpd_reader(unsigned char *buf, unsigned dev_addr, unsigned off, unsigned count)
+{
+    unsigned offset = off;                     /* Calculated offset */
+
+    /*
+     * The main board EEPROM contains
+     * SDRAM SPD in the first 128 bytes,
+     * so skew the offset.
+     */
+    if (dev_addr == CFG_DEF_EEPROM_ADDR)
+       offset += SDRAM_SPD_DATA_SIZE;
+
+    /* Try to read the I2C EEPROM */
+#if defined(VXWORKS)
+    {
+       int i;
+       for( i = 0; i < count; ++i ) {
+           buf[ i ] = iicReadByte( dev_addr, offset+i );
+       }
+    }
+#else
+    if (eeprom_read(dev_addr, offset, buf, count)) {
+       printf("Failed to read %d bytes from VPD EEPROM 0x%x @ 0x%x\n", 
+              count, dev_addr, offset);
+       return NULL;
+    }
+#endif
+
+    return buf;
+} /* vpd_reader() */
+
+
+/*
+ * vpd_get_packet() - returns next VPD packet or NULL.
+ */
+static vpd_packet_t *vpd_get_packet(vpd_packet_t *vpd_packet)
+{
+    vpd_packet_t *packet = vpd_packet;
+
+    if (packet != NULL) {
+       if (packet->identifier == VPD_PID_TERM)
+           return NULL;
+       else
+           packet = (vpd_packet_t *)((char *)packet + packet->size + 2);
+    }
+
+    return packet;
+} /* vpd_get_packet() */
+
+
+/*
+ * vpd_find_packet() - Locates and returns the specified
+ *                    VPD packet or NULL on error.
+ */
+static vpd_packet_t *vpd_find_packet(vpd_t *vpd, unsigned char ident)
+{
+    vpd_packet_t *packet = (vpd_packet_t *)&vpd->packets;
+
+    /* Guaranteed illegal */
+    if (ident == VPD_PID_GI)
+       return NULL;
+
+    /* Scan tuples looking for a match */
+    while ((packet->identifier != ident) &&
+          (packet->identifier != VPD_PID_TERM))
+       packet = vpd_get_packet(packet);
+
+    /* Did we find it? */
+    if ((packet->identifier) && (packet->identifier != ident))
+       return NULL;
+    return packet;
+}
+
+
+/*
+ * vpd_is_valid() - Validates contents of VPD data
+ *                 in I2C EEPROM.  Returns 1 for
+ *                 success or 0 for failure.
+ */
+static int vpd_is_valid(unsigned dev_addr, unsigned char *buf)
+{
+    unsigned       num_bytes;
+    vpd_packet_t    *packet;
+    vpd_t          *vpd = (vpd_t *)buf;
+    unsigned short  stored_crc16, calc_crc16 = 0xffff;    
+
+    /* Check Eyecatcher */
+    if (strncmp(vpd->header.eyecatcher, VPD_EYECATCHER, VPD_EYE_SIZE) != 0) {
+       unsigned offset = 0;
+       if (dev_addr == CFG_DEF_EEPROM_ADDR)
+           offset += SDRAM_SPD_DATA_SIZE;
+       printf("Error: VPD EEPROM 0x%x corrupt @ 0x%x\n", dev_addr, offset);
+
+       return 0;
+    }
+
+    /* Check Length */
+    if (vpd->header.size> VPD_MAX_EEPROM_SIZE) {
+       printf("Error: VPD EEPROM 0x%x contains bad size 0x%x\n",
+              dev_addr, vpd->header.size);
+       return 0;
+    }
+
+    /* Now find the termination packet */
+    if ((packet = vpd_find_packet(vpd, VPD_PID_TERM)) == NULL) {
+       printf("Error: VPD EEPROM 0x%x missing termination packet\n",
+              dev_addr);
+       return 0;
+    }
+
+    /* Calculate data size */
+    num_bytes = (unsigned long)((unsigned char *)packet -
+                               (unsigned char *)vpd + sizeof(vpd_packet_t));
+
+    /* Find stored CRC and clear it */
+    if ((packet = vpd_find_packet(vpd, VPD_PID_CRC)) == NULL) {
+       printf("Error: VPD EEPROM 0x%x missing CRC\n", dev_addr);
+       return 0;
+    }
+    stored_crc16 = *((ushort *)packet->data);   
+    *(ushort *)packet->data = 0;
+
+    /* OK, lets calculate the CRC and check it */
+#if defined(VXWORKS)
+    calc_crc16 = (0xffff & crc32(buf, num_bytes));
+#else
+    calc_crc16 = (0xffff & crc32(0, buf, num_bytes));
+#endif
+    *(ushort *)packet->data = stored_crc16;     /* Now restore the CRC */
+    if (stored_crc16 != calc_crc16) {
+       printf("Error: VPD EEPROM 0x%x has bad CRC 0x%x\n",
+              dev_addr, stored_crc16);
+       return 0;
+    }
+
+    return 1;
+} /* vpd_is_valid() */
+
+
+/*
+ * size_ok() - Check to see if packet size matches
+ *            size of data we want. Returns 1 for
+ *            good match or 0 for failure.
+ */
+static int size_ok(vpd_packet_t *packet, unsigned long size)
+{
+    if (packet->size != size) {
+       printf("VPD Packet 0x%x corrupt.\n", packet->identifier);
+       return 0;
+    }
+    return 1;
+} /* size_ok() */
+
+
+/*
+ * strlen_ok() - Check to see if packet size matches
+ *              strlen of the string we want to populate.
+ *              Returns 1 for valid length or 0 for failure.
+ */
+static int strlen_ok(vpd_packet_t *packet, unsigned long length)
+{
+    if (packet->size >= length) {
+       printf("VPD Packet 0x%x corrupt.\n", packet->identifier);
+       return 0;
+    }
+    return 1;
+} /* strlen_ok() */
+
+/*
+ * get_vpd_data() - populates the passed VPD structure 'vpdInfo'
+ *                 with data obtained from the specified
+ *                 I2C EEPROM 'dev_addr'.  Returns 0 for
+ *                 success or 1 for failure.
+ */      
+int vpd_get_data(unsigned char dev_addr, VPD *vpdInfo)
+{
+    unsigned char buf[VPD_EEPROM_SIZE];
+    vpd_t *vpd = (vpd_t *)buf;
+    vpd_packet_t *packet;
+
+    if (vpdInfo == NULL)
+       return 1;
+
+     /*
+      * Fill vpdInfo with 0s to blank out
+      * unused fields, fill vpdInfo->ethAddrs
+      * with all 0xffs so that other's code can
+      * determine how many real Ethernet addresses
+      * there are.  OUIs starting with 0xff are
+      * broadcast addresses, and would never be
+      * permantely stored.
+      */
+    memset((void *)vpdInfo, 0, sizeof(VPD));
+    memset((void *)&vpdInfo->ethAddrs, 0xff, sizeof(vpdInfo->ethAddrs));
+    vpdInfo->_devAddr = dev_addr;
+
+    /* Read the minimum size first */
+    if (vpd_reader(buf, dev_addr, 0, VPD_EEPROM_SIZE) == NULL) {
+       return 1;
+    }
+
+    /* Check validity of VPD data */
+    if (!vpd_is_valid(dev_addr, buf)) {
+       printf("VPD Data is INVALID!\n");
+       return 1;
+    }
+
+    /*
+      * Walk all the packets and populate
+      * the VPD info structure.
+      */
+    packet = (vpd_packet_t *)&vpd->packets;  
+    do {
+       switch (packet->identifier) {
+           case VPD_PID_GI:
+               printf("Error: Illegal VPD value\n");
+               break;
+           case VPD_PID_PID:
+               if (strlen_ok(packet, MAX_PROD_ID)) {
+                   strncpy(vpdInfo->productId,
+                           packet->data, packet->size);
+               }
+               break;
+           case VPD_PID_REV:
+               if (size_ok(packet, sizeof(char)))
+                   vpdInfo->revisionId = *packet->data;
+               break;
+           case VPD_PID_SN:
+               if (size_ok(packet, sizeof(unsigned long))) {
+                   vpdInfo->serialNum =
+                       *(unsigned long *)packet->data;
+               }
+               break;
+           case VPD_PID_MANID:
+               if (size_ok(packet, sizeof(unsigned char)))
+                   vpdInfo->manuID = *packet->data;
+               break;
+           case VPD_PID_PCO:
+               if (size_ok(packet, sizeof(unsigned long))) {
+                   vpdInfo->configOpt =
+                       *(unsigned long *)packet->data;
+               }
+               break;
+           case VPD_PID_SYSCLK:
+               if (size_ok(packet, sizeof(unsigned long)))
+                   vpdInfo->sysClk = *(unsigned long *)packet->data;
+               break;
+           case VPD_PID_SERCLK:
+               if (size_ok(packet, sizeof(unsigned long)))
+                   vpdInfo->serClk = *(unsigned long *)packet->data;
+               break;
+           case VPD_PID_FLASH:
+               if (size_ok(packet, 9)) {       /* XXX - hardcoded,
+                                                  padding in struct */
+                   memcpy(&vpdInfo->flashCfg, packet->data, 9);
+               }
+               break;
+           case VPD_PID_ETHADDR:
+               memcpy(vpdInfo->ethAddrs, packet->data, packet->size);
+               break;
+           case VPD_PID_POTS:
+               if (size_ok(packet, sizeof(char)))
+                   vpdInfo->numPOTS = (unsigned)*packet->data;
+               break;
+           case VPD_PID_DS1:
+               if (size_ok(packet, sizeof(char)))
+                   vpdInfo->numDS1 = (unsigned)*packet->data;
+           case VPD_PID_GAL:
+           case VPD_PID_CRC:
+           case VPD_PID_TERM:
+               break;
+           default:
+               printf("Warning: Found unknown VPD packet ID 0x%x\n",
+                      packet->identifier);
+               break;
+       }
+    } while ((packet = vpd_get_packet(packet)));
+
+    return 0;
+} /* end get_vpd_data() */
+
+
+/*
+ * vpd_init() - Initialize default VPD environment
+ */
+int vpd_init(unsigned char dev_addr)
+{
+    return (0);
+} /* vpd_init() */
+
+
+/*
+ * vpd_print() - Pretty print the VPD data.
+ */
+void vpd_print(VPD *vpdInfo)
+{
+    const char *const sp    = "";
+    const char *const sfmt  = "%4s%-20s: \"%s\"\n";
+    const char *const cfmt  = "%4s%-20s: '%c'\n";
+    const char *const dfmt  = "%4s%-20s: %ld\n";
+    const char *const hfmt  = "%4s%-20s: %08lX\n";
+    const char *const dsfmt = "%4s%-20s: %d\n";
+    const char *const hsfmt = "%4s%-20s: %04X\n";
+    const char *const dhfmt = "%4s%-20s: %ld (%lX)\n";
+
+    printf("VPD read from I2C device: %02X\n", vpdInfo->_devAddr);
+
+    if (vpdInfo->productId[0])    
+       printf(sfmt, sp, "Product ID", vpdInfo->productId);
+    else
+       printf(sfmt, sp, "Product ID", "UNKNOWN");
+
+    if (vpdInfo->revisionId)
+       printf(cfmt, sp, "Revision ID", vpdInfo->revisionId);
+
+    if (vpdInfo->serialNum)
+       printf(dfmt, sp, "Serial Number", vpdInfo->serialNum);
+
+    if (vpdInfo->manuID)
+       printf(dfmt, sp, "Manufacture ID", (long)vpdInfo->manuID);
+
+    if (vpdInfo->configOpt)
+       printf(hfmt, sp, "Configuration", vpdInfo->configOpt);
+
+    if (vpdInfo->sysClk)
+       printf(dhfmt, sp, "System Clock", vpdInfo->sysClk, vpdInfo->sysClk);
+
+    if (vpdInfo->serClk)
+       printf(dhfmt, sp, "Serial Clock", vpdInfo->serClk, vpdInfo->serClk);
+
+    if (vpdInfo->numPOTS)
+       printf(dfmt, sp, "Number of POTS lines", vpdInfo->numPOTS);
+
+    if (vpdInfo->numDS1)
+       printf(dfmt, sp, "Number of DS1s", vpdInfo->numDS1);
+
+    /* Print Ethernet Addresses */
+    if (vpdInfo->ethAddrs[0][0] != 0xff) {
+       int i, j;
+       printf("%4sEtherNet Address(es): ", sp);
+       for (i = 0; i < MAX_ETH_ADDRS; i++) {
+           if (vpdInfo->ethAddrs[i][0] != 0xff) {
+               for (j = 0; j < 6; j++) {
+                   printf("%02X", vpdInfo->ethAddrs[i][j]);
+                   if (((j + 1) % 6) != 0)
+                       printf(":");
+                   else
+                       printf(" ");
+               }
+               if (((i + 1) % 3) == 0) printf("\n%24s: ", sp);
+           }
+       }
+       printf("\n");
+    }
+
+    if (vpdInfo->flashCfg.mfg && vpdInfo->flashCfg.dev) {        
+       printf("Main Flash Configuration:\n");
+       printf(hsfmt, sp, "Manufacture ID", vpdInfo->flashCfg.mfg);
+       printf(hsfmt, sp, "Device ID",      vpdInfo->flashCfg.dev);
+       printf(dsfmt, sp, "Device Width",   vpdInfo->flashCfg.devWidth);
+       printf(dsfmt, sp, "Num. Devices",   vpdInfo->flashCfg.numDevs);
+       printf(dsfmt, sp, "Num. Columns",   vpdInfo->flashCfg.numCols);
+       printf(dsfmt, sp, "Column Width",   vpdInfo->flashCfg.colWidth);
+       printf(dsfmt, sp, "WE Data Width",  vpdInfo->flashCfg.weDataWidth);
+    }
+} /* vpd_print() */
+
diff --git a/board/w7o/vpd.h b/board/w7o/vpd.h
new file mode 100644 (file)
index 0000000..6f7d10a
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _VPD_H_
+#define _VPD_H_
+
+/*
+ * Main Flash Configuration.
+ */
+typedef struct flashCfg_s {
+    unsigned short mfg;                                /* Manufacture ID */
+    unsigned short dev;                                /* Device ID */
+    unsigned char devWidth;                    /* Device Width */
+    unsigned char numDevs;                     /* Number of devices */
+    unsigned char numCols;                     /* Number of columns */
+    unsigned char colWidth;                    /* Width of a column */
+    unsigned char weDataWidth;                 /* Write/Erase Data Width */
+} flashCfg_t;
+
+/*
+ * Vital Product Data - VPD
+ */
+#define MAX_PROD_ID            15
+#define MAX_ETH_ADDRS          10
+typedef unsigned char EthAddr[6];
+typedef struct vpd {
+    unsigned char _devAddr;                    /* Device address during read */
+    char productId[MAX_PROD_ID];               /* Product ID */
+    char revisionId;                           /* Revision ID as a char */
+    unsigned long serialNum;                   /* Serial number */
+    unsigned char  manuID;                     /* Manufact ID - byte int */
+    unsigned long configOpt;                   /* Config Option - bit field */
+    unsigned long sysClk;                      /* System clock in Hertz */
+    unsigned long serClk;                      /* Ext. clock in Hertz */
+    flashCfg_t flashCfg;                       /* Flash configuration */
+    unsigned long numPOTS;                     /* Number of POTS lines */
+    unsigned long numDS1;                      /* Number of DS1 circuits */
+    EthAddr ethAddrs[MAX_ETH_ADDRS];           /* Ethernet MAC, 1st = craft */
+} VPD;
+
+
+#define VPD_MAX_EEPROM_SIZE    512             /* Max size VPD EEPROM */
+#define SDRAM_SPD_DATA_SIZE    128             /* Size SPD in VPD EEPROM */
+
+/*
+ * PIDs - Packet Identifiers
+ */
+#define VPD_PID_GI             0x0             /* Guaranted Illegal */
+#define VPD_PID_PID            0x1             /* Product Identifier */
+#define VPD_PID_REV            0x2             /* Product Revision */
+#define VPD_PID_SN             0x3             /* Serial Number */
+#define VPD_PID_MANID          0x4             /* Manufacture ID */
+#define VPD_PID_PCO            0x5             /* Product configuration */
+#define VPD_PID_SYSCLK         0x6             /* System Clock */
+#define VPD_PID_SERCLK         0x7             /* Ser. Clk. Speed in Hertz */
+#define VPD_PID_CRC            0x8             /* VPD CRC */
+#define VPD_PID_FLASH          0x9             /* Flash Configuration */
+#define VPD_PID_ETHADDR                0xA             /* Ethernet Address(es) */
+#define VPD_PID_GAL            0xB             /* Galileo Switch Config */
+#define VPD_PID_POTS           0xC             /* Number of POTS Lines */ 
+#define VPD_PID_DS1            0xD             /* Number of DS1s */
+#define VPD_PID_TERM           0xFF            /* Termination packet */
+
+/*
+ * VPD - Eyecatcher/Magic
+ */
+#define VPD_EYECATCHER         "W7O"
+#define VPD_EYE_SIZE           3
+typedef struct vpd_header {
+    unsigned char eyecatcher[VPD_EYE_SIZE];    /* eyecatcher - "W7O" */
+    unsigned short size __attribute__((packed)); /* size of EEPROM */
+} vpd_header_t;
+
+
+#define VPD_DATA_SIZE (VPD_MAX_EEPROM_SIZE - SDRAM_SPD_DATA_SIZE - \
+                        sizeof(vpd_header_t))
+typedef struct vpd_s {
+    vpd_header_t header;
+    unsigned char packets[VPD_DATA_SIZE];
+} vpd_t;
+
+typedef struct vpd_packet {
+    unsigned char identifier;
+    unsigned char size;
+    unsigned char data[1];
+} vpd_packet_t;
+
+/*
+ * VPD configOpt bit mask
+ */
+#define VPD_HAS_BBRAM          0x1             /* Battery backed SRAM */
+#define VPD_HAS_RTC            0x2             /* Battery backed RTC */
+#define VPD_HAS_EXT_SER_CLK    0x4             /* External serial clock */
+#define VPD_HAS_SER_TRANS_1    0x8             /* COM1 transceiver */
+#define VPD_HAS_SER_TRANS_2    0x10            /* COM2 transceiver */
+#define VPD_HAS_CRAFT_PHY      0x20            /* CRAFT Ethernet */
+#define VPD_HAS_DTT_1          0x40            /* I2C Digital therm. #1 */
+#define VPD_HAS_DTT_2          0x80            /* I2C Digital therm. #2 */
+#define VPD_HAS_1000_UP_LASER  0x100           /* GMM - 1000Mbit Uplink */
+#define VPD_HAS_70KM_UP_LASER  0x200           /* CMM - 70KM Uplink laser */
+#define VPD_HAS_2_UPLINKS      0x400           /* CMM - 2 uplink lasers */
+#define VPD_HAS_FPGA           0x800           /* Has 1 or more FPGAs */
+#define VPD_HAS_DFA            0x1000          /* CLM - Has 2 Fiber Inter. */
+#define VPD_HAS_GAL_SWITCH     0x2000          /* GMM - Has a Gal switch */
+#define VPD_HAS_POTS_LINES     0x4000          /* GMM - Has POTS lines */
+#define VPD_HAS_DS1_CHANNELS   0x8000          /* GMM - Has DS1 channels */
+#define VPD_HAS_CABLE_RETURN   0x10000         /* GBM/GBR - Cable ret. path */
+
+#define VPD_EEPROM_SIZE         (256 - SDRAM_SPD_DATA_SIZE) /* Size EEPROM */
+
+extern int vpd_get_data(unsigned char dev_addr, VPD *vpd);
+extern void vpd_print(VPD *vpdInfo);
+
+#endif /* _VPD_H_ */
+