uboot/board/hymod/eeprom.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001
   3 * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au>
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25#include <mpc8260.h>
  26
  27/* imports from fetch.c */
  28extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
  29
  30/* imports from input.c */
  31extern int hymod_get_serno (const char *);
  32
  33/* this is relative to the root of the server's tftp directory */
  34static char *def_bddb_cfgdir = "/hymod/bddb";
  35
  36static int
  37hymod_eeprom_load (int which, hymod_eeprom_t *ep)
  38{
  39        unsigned dev_addr = CONFIG_SYS_I2C_EEPROM_ADDR | \
  40                (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
  41        unsigned offset = 0;
  42        uchar data[HYMOD_EEPROM_MAXLEN], *dp, *edp;
  43        hymod_eehdr_t hdr;
  44        ulong len, crc;
  45
  46        memset (ep, 0, sizeof *ep);
  47
  48        eeprom_read (dev_addr, offset, (uchar *)&hdr, sizeof (hdr));
  49        offset += sizeof (hdr);
  50
  51        if (hdr.id != HYMOD_EEPROM_ID || hdr.ver > HYMOD_EEPROM_VER ||
  52          (len = hdr.len) > HYMOD_EEPROM_MAXLEN)
  53            return (0);
  54
  55        eeprom_read (dev_addr, offset, data, len);
  56        offset += len;
  57
  58        eeprom_read (dev_addr, offset, (uchar *)&crc, sizeof (ulong));
  59        offset += sizeof (ulong);
  60
  61        if (crc32 (crc32 (0, (uchar *)&hdr, sizeof hdr), data, len) != crc)
  62                return (0);
  63
  64        ep->ver = hdr.ver;
  65        dp = data; edp = dp + len;
  66
  67        for (;;) {
  68                ulong rtyp;
  69                uchar rlen, *rdat;
  70
  71                rtyp = *dp++;
  72                if ((rtyp & 0x80) == 0)
  73                        rlen = *dp++;
  74                else {
  75                        uchar islarge = rtyp & 0x40;
  76
  77                        rtyp = ((rtyp & 0x3f) << 8) | *dp++;
  78                        if (islarge) {
  79                                rtyp = (rtyp << 8) | *dp++;
  80                                rtyp = (rtyp << 8) | *dp++;
  81                        }
  82
  83                        rlen = *dp++;
  84                        rlen = (rlen << 8) | *dp++;
  85                        if (islarge) {
  86                                rlen = (rlen << 8) | *dp++;
  87                                rlen = (rlen << 8) | *dp++;
  88                        }
  89                }
  90
  91                if (rtyp == 0)
  92                        break;
  93
  94                rdat = dp;
  95                dp += rlen;
  96
  97                if (dp > edp)   /* error? */
  98                        break;
  99
 100                switch (rtyp) {
 101
 102                case HYMOD_EEREC_SERNO:         /* serial number */
 103                        if (rlen == sizeof (ulong))
 104                                ep->serno = \
 105                                        ((ulong)rdat[0] << 24) | \
 106                                        ((ulong)rdat[1] << 16) | \
 107                                        ((ulong)rdat[2] << 8) | \
 108                                        (ulong)rdat[3];
 109                        break;
 110
 111                case HYMOD_EEREC_DATE:          /* date */
 112                        if (rlen == sizeof (hymod_date_t)) {
 113                                ep->date.year = ((ushort)rdat[0] << 8) | \
 114                                        (ushort)rdat[1];
 115                                ep->date.month = rdat[2];
 116                                ep->date.day = rdat[3];
 117                        }
 118                        break;
 119
 120                case HYMOD_EEREC_BATCH:         /* batch */
 121                        if (rlen <= HYMOD_MAX_BATCH)
 122                                memcpy (ep->batch, rdat, ep->batchlen = rlen);
 123                        break;
 124
 125                case HYMOD_EEREC_TYPE:          /* board type */
 126                        if (rlen == 1)
 127                                ep->bdtype = *rdat;
 128                        break;
 129
 130                case HYMOD_EEREC_REV:           /* board revision */
 131                        if (rlen == 1)
 132                                ep->bdrev = *rdat;
 133                        break;
 134
 135                case HYMOD_EEREC_SDRAM:         /* sdram size(s) */
 136                        if (rlen > 0 && rlen <= HYMOD_MAX_SDRAM) {
 137                                int i;
 138
 139                                for (i = 0; i < rlen; i++)
 140                                        ep->sdramsz[i] = rdat[i];
 141                                ep->nsdram = rlen;
 142                        }
 143                        break;
 144
 145                case HYMOD_EEREC_FLASH:         /* flash size(s) */
 146                        if (rlen > 0 && rlen <= HYMOD_MAX_FLASH) {
 147                                int i;
 148
 149                                for (i = 0; i < rlen; i++)
 150                                        ep->flashsz[i] = rdat[i];
 151                                ep->nflash = rlen;
 152                        }
 153                        break;
 154
 155                case HYMOD_EEREC_ZBT:           /* zbt ram size(s) */
 156                        if (rlen > 0 && rlen <= HYMOD_MAX_ZBT) {
 157                                int i;
 158
 159                                for (i = 0; i < rlen; i++)
 160                                        ep->zbtsz[i] = rdat[i];
 161                                ep->nzbt = rlen;
 162                        }
 163                        break;
 164
 165                case HYMOD_EEREC_XLXTYP:        /* xilinx fpga type(s) */
 166                        if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
 167                                int i;
 168
 169                                for (i = 0; i < rlen; i++)
 170                                        ep->xlx[i].type = rdat[i];
 171                                ep->nxlx = rlen;
 172                        }
 173                        break;
 174
 175                case HYMOD_EEREC_XLXSPD:        /* xilinx fpga speed(s) */
 176                        if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
 177                                int i;
 178
 179                                for (i = 0; i < rlen; i++)
 180                                        ep->xlx[i].speed = rdat[i];
 181                        }
 182                        break;
 183
 184                case HYMOD_EEREC_XLXTMP:        /* xilinx fpga temperature(s) */
 185                        if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
 186                                int i;
 187
 188                                for (i = 0; i < rlen; i++)
 189                                        ep->xlx[i].temp = rdat[i];
 190                        }
 191                        break;
 192
 193                case HYMOD_EEREC_XLXGRD:        /* xilinx fpga grade(s) */
 194                        if (rlen > 0 && rlen <= HYMOD_MAX_XLX) {
 195                                int i;
 196
 197                                for (i = 0; i < rlen; i++)
 198                                        ep->xlx[i].grade = rdat[i];
 199                        }
 200                        break;
 201
 202                case HYMOD_EEREC_CPUTYP:        /* CPU type */
 203                        if (rlen == 1)
 204                                ep->mpc.type = *rdat;
 205                        break;
 206
 207                case HYMOD_EEREC_CPUSPD:        /* CPU speed */
 208                        if (rlen == 1)
 209                                ep->mpc.cpuspd = *rdat;
 210                        break;
 211
 212                case HYMOD_EEREC_CPMSPD:        /* CPM speed */
 213                        if (rlen == 1)
 214                                ep->mpc.cpmspd = *rdat;
 215                        break;
 216
 217                case HYMOD_EEREC_BUSSPD:        /* bus speed */
 218                        if (rlen == 1)
 219                                ep->mpc.busspd = *rdat;
 220                        break;
 221
 222                case HYMOD_EEREC_HSTYPE:        /* hs-serial chip type */
 223                        if (rlen == 1)
 224                                ep->hss.type = *rdat;
 225                        break;
 226
 227                case HYMOD_EEREC_HSCHIN:        /* num hs-serial input chans */
 228                        if (rlen == 1)
 229                                ep->hss.nchin = *rdat;
 230                        break;
 231
 232                case HYMOD_EEREC_HSCHOUT:       /* num hs-serial output chans */
 233                        if (rlen == 1)
 234                                ep->hss.nchout = *rdat;
 235                        break;
 236
 237                default:        /* ignore */
 238                        break;
 239                }
 240        }
 241
 242        return (1);
 243}
 244
 245/* maps an ascii "name=value" into a binary eeprom data record */
 246typedef
 247        struct _eerec_map {
 248                char *name;
 249                uint type;
 250                uchar *(*handler) \
 251                        (struct _eerec_map *, uchar *, uchar *, uchar *);
 252                uint length;
 253                uint maxlen;
 254        }
 255eerec_map_t;
 256
 257static uchar *
 258uint_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
 259{
 260        char *eval;
 261        ulong lval;
 262
 263        lval = simple_strtol ((char *)val, &eval, 10);
 264
 265        if ((uchar *)eval == val || *eval != '\0') {
 266                printf ("%s rec (%s) is not a valid uint\n", rp->name, val);
 267                return (NULL);
 268        }
 269
 270        if (dp + 2 + rp->length > edp) {
 271                printf ("can't fit %s rec into eeprom\n", rp->name);
 272                return (NULL);
 273        }
 274
 275        *dp++ = rp->type;
 276        *dp++ = rp->length;
 277
 278        switch (rp->length) {
 279
 280        case 1:
 281                if (lval >= 256) {
 282                        printf ("%s rec value (%lu) out of range (0-255)\n",
 283                                rp->name, lval);
 284                        return (NULL);
 285                }
 286                *dp++ = lval;
 287                break;
 288
 289        case 2:
 290                if (lval >= 65536) {
 291                        printf ("%s rec value (%lu) out of range (0-65535)\n",
 292                                rp->name, lval);
 293                        return (NULL);
 294                }
 295                *dp++ = lval >> 8;
 296                *dp++ = lval;
 297                break;
 298
 299        case 4:
 300                *dp++ = lval >> 24;
 301                *dp++ = lval >> 16;
 302                *dp++ = lval >> 8;
 303                *dp++ = lval;
 304                break;
 305
 306        default:
 307                printf ("huh? rp->length not 1, 2 or 4! (%d)\n", rp->length);
 308                return (NULL);
 309        }
 310
 311        return (dp);
 312}
 313
 314static uchar *
 315date_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
 316{
 317        hymod_date_t date;
 318        char *p = (char *)val;
 319        char *ep;
 320        ulong lval;
 321
 322        lval = simple_strtol (p, &ep, 10);
 323        if (ep == p || *ep++ != '-') {
 324bad_date:
 325                printf ("%s rec (%s) is not a valid date\n", rp->name, val);
 326                return (NULL);
 327        }
 328        if (lval >= 65536)
 329                goto bad_date;
 330        date.year = lval;
 331
 332        lval = simple_strtol (p = ep, &ep, 10);
 333        if (ep == p || *ep++ != '-' || lval == 0 || lval > 12)
 334                goto bad_date;
 335        date.month = lval;
 336
 337        lval = simple_strtol (p = ep, &ep, 10);
 338        if (ep == p || *ep != '\0' || lval == 0 || lval > 31)
 339                goto bad_date;
 340        date.day = lval;
 341
 342        if (dp + 2 + rp->length > edp) {
 343                printf ("can't fit %s rec into eeprom\n", rp->name);
 344                return (NULL);
 345        }
 346
 347        *dp++ = rp->type;
 348        *dp++ = rp->length;
 349        *dp++ = date.year >> 8;
 350        *dp++ = date.year;
 351        *dp++ = date.month;
 352        *dp++ = date.day;
 353
 354        return (dp);
 355}
 356
 357static uchar *
 358string_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
 359{
 360        uint len;
 361
 362        if ((len = strlen ((char *)val)) > rp->maxlen) {
 363                printf ("%s rec (%s) string is too long (%d>%d)\n",
 364                        rp->name, val, len, rp->maxlen);
 365                return (NULL);
 366        }
 367
 368        if (dp + 2 + len > edp) {
 369                printf ("can't fit %s rec into eeprom\n", rp->name);
 370                return (NULL);
 371        }
 372
 373        *dp++ = rp->type;
 374        *dp++ = len;
 375        memcpy (dp, val, len);
 376        dp += len;
 377
 378        return (dp);
 379}
 380
 381static uchar *
 382bytes_handler (eerec_map_t *rp, uchar *val, uchar *dp, uchar *edp)
 383{
 384        uchar bytes[HYMOD_MAX_BYTES], nbytes, *p;
 385        char *ep;
 386
 387        for (nbytes = 0, p = val; *p != '\0'; p = (uchar *)ep) {
 388                ulong lval;
 389
 390                lval = simple_strtol ((char *)p, &ep, 10);
 391                if ((uchar *)ep == p || (*ep != '\0' && *ep != ',') || \
 392                    lval >= 256) {
 393                        printf ("%s rec (%s) byte array has invalid uint\n",
 394                                rp->name, val);
 395                        return (NULL);
 396                }
 397                if (nbytes >= HYMOD_MAX_BYTES) {
 398                        printf ("%s rec (%s) byte array too long\n",
 399                                rp->name, val);
 400                        return (NULL);
 401                }
 402                bytes[nbytes++] = lval;
 403
 404                if (*ep != '\0')
 405                        ep++;
 406        }
 407
 408        if (dp + 2 + nbytes > edp) {
 409                printf ("can't fit %s rec into eeprom\n", rp->name);
 410                return (NULL);
 411        }
 412
 413        *dp++ = rp->type;
 414        *dp++ = nbytes;
 415        memcpy (dp, bytes, nbytes);
 416        dp += nbytes;
 417
 418        return (dp);
 419}
 420
 421static eerec_map_t eerec_map[] = {
 422        /* name      type                 handler         len max             */
 423        { "serno",   HYMOD_EEREC_SERNO,   uint_handler,   4,  0               },
 424        { "date",    HYMOD_EEREC_DATE,    date_handler,   4,  0               },
 425        { "batch",   HYMOD_EEREC_BATCH,   string_handler, 0,  HYMOD_MAX_BATCH },
 426        { "type",    HYMOD_EEREC_TYPE,    uint_handler,   1,  0               },
 427        { "rev",     HYMOD_EEREC_REV,     uint_handler,   1,  0               },
 428        { "sdram",   HYMOD_EEREC_SDRAM,   bytes_handler,  0,  HYMOD_MAX_SDRAM },
 429        { "flash",   HYMOD_EEREC_FLASH,   bytes_handler,  0,  HYMOD_MAX_FLASH },
 430        { "zbt",     HYMOD_EEREC_ZBT,     bytes_handler,  0,  HYMOD_MAX_ZBT   },
 431        { "xlxtyp",  HYMOD_EEREC_XLXTYP,  bytes_handler,  0,  HYMOD_MAX_XLX   },
 432        { "xlxspd",  HYMOD_EEREC_XLXSPD,  bytes_handler,  0,  HYMOD_MAX_XLX   },
 433        { "xlxtmp",  HYMOD_EEREC_XLXTMP,  bytes_handler,  0,  HYMOD_MAX_XLX   },
 434        { "xlxgrd",  HYMOD_EEREC_XLXGRD,  bytes_handler,  0,  HYMOD_MAX_XLX   },
 435        { "cputyp",  HYMOD_EEREC_CPUTYP,  uint_handler,   1,  0               },
 436        { "cpuspd",  HYMOD_EEREC_CPUSPD,  uint_handler,   1,  0               },
 437        { "cpmspd",  HYMOD_EEREC_CPMSPD,  uint_handler,   1,  0               },
 438        { "busspd",  HYMOD_EEREC_BUSSPD,  uint_handler,   1,  0               },
 439        { "hstype",  HYMOD_EEREC_HSTYPE,  uint_handler,   1,  0               },
 440        { "hschin",  HYMOD_EEREC_HSCHIN,  uint_handler,   1,  0               },
 441        { "hschout", HYMOD_EEREC_HSCHOUT, uint_handler,   1,  0               },
 442};
 443
 444static int neerecs = sizeof eerec_map / sizeof eerec_map[0];
 445
 446static uchar data[HYMOD_EEPROM_SIZE], *sdp, *dp, *edp;
 447
 448static int
 449eerec_callback (uchar *name, uchar *val)
 450{
 451        eerec_map_t *rp;
 452
 453        for (rp = eerec_map; rp < &eerec_map[neerecs]; rp++)
 454                if (strcmp ((char *)name, rp->name) == 0)
 455                        break;
 456
 457        if (rp >= &eerec_map[neerecs])
 458                return (0);
 459
 460        if ((dp = (*rp->handler) (rp, val, dp, edp)) == NULL)
 461                return (0);
 462
 463        return (1);
 464}
 465
 466static int
 467hymod_eeprom_fetch(int which, char *filename, ulong addr)
 468{
 469        unsigned dev_addr = CONFIG_SYS_I2C_EEPROM_ADDR | \
 470                (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
 471        hymod_eehdr_t *hp = (hymod_eehdr_t *)&data[0];
 472        ulong crc;
 473
 474        memset (hp, 0, sizeof *hp);
 475        hp->id = HYMOD_EEPROM_ID;
 476        hp->ver = HYMOD_EEPROM_VER;
 477
 478        dp = sdp = (uchar *)(hp + 1);
 479        edp = dp + HYMOD_EEPROM_MAXLEN;
 480
 481        if (fetch_and_parse (filename, addr, eerec_callback) == 0)
 482                return (0);
 483
 484        hp->len = dp - sdp;
 485
 486        crc = crc32 (0, data, dp - data);
 487        memcpy (dp, &crc, sizeof (ulong));
 488        dp += sizeof (ulong);
 489
 490        eeprom_write (dev_addr, 0, data, dp - data);
 491
 492        return (1);
 493}
 494
 495static char *type_vals[] = {
 496        "NONE", "IO", "CLP", "DSP", "INPUT", "ALT-INPUT", "DISPLAY"
 497};
 498
 499static char *xlxtyp_vals[] = {
 500        "NONE", "XCV300E", "XCV400E", "XCV600E"
 501};
 502
 503static char *xlxspd_vals[] = {
 504        "NONE", "6", "7", "8"
 505};
 506
 507static char *xlxtmp_vals[] = {
 508        "NONE", "COM", "IND"
 509};
 510
 511static char *xlxgrd_vals[] = {
 512        "NONE", "NORMAL", "ENGSAMP"
 513};
 514
 515static char *cputyp_vals[] = {
 516        "NONE", "MPC8260"
 517};
 518
 519static char *clk_vals[] = {
 520        "NONE", "33", "66", "100", "133", "166", "200"
 521};
 522
 523static char *hstype_vals[] = {
 524        "NONE", "AMCC-S2064A"
 525};
 526
 527static void
 528print_mem (char *l, char *s, uchar n, uchar a[])
 529{
 530        if (n > 0) {
 531                if (n == 1)
 532                        printf ("%s%dMB %s", s, 1 << (a[0] - 20), l);
 533                else {
 534                        ulong t = 0;
 535                        int i;
 536
 537                        for (i = 0; i < n; i++)
 538                                t += 1 << (a[i] - 20);
 539
 540                        printf ("%s%luMB %s (%d banks:", s, t, l, n);
 541
 542                        for (i = 0; i < n; i++)
 543                                printf ("%dMB%s",
 544                                        1 << (a[i] - 20),
 545                                        (i == n - 1) ? ")" : ",");
 546                }
 547        }
 548        else
 549                printf ("%sNO %s", s, l);
 550}
 551
 552void
 553hymod_eeprom_print (hymod_eeprom_t *ep)
 554{
 555        int i;
 556
 557        printf ("         Hymod %s board, rev %03d\n",
 558                type_vals[ep->bdtype], ep->bdrev);
 559
 560        printf ("         serial #: %010lu, date %04d-%02d-%02d",
 561                ep->serno, ep->date.year, ep->date.month, ep->date.day);
 562        if (ep->batchlen > 0)
 563                printf (", batch \"%.*s\"", ep->batchlen, ep->batch);
 564        puts ("\n");
 565
 566        switch (ep->bdtype) {
 567
 568        case HYMOD_BDTYPE_IO:
 569        case HYMOD_BDTYPE_CLP:
 570        case HYMOD_BDTYPE_DSP:
 571                printf ("         Motorola %s CPU, speeds: %s/%s/%s",
 572                    cputyp_vals[ep->mpc.type], clk_vals[ep->mpc.cpuspd],
 573                    clk_vals[ep->mpc.cpmspd], clk_vals[ep->mpc.busspd]);
 574
 575                print_mem ("SDRAM", ", ", ep->nsdram, ep->sdramsz);
 576
 577                print_mem ("FLASH", ", ", ep->nflash, ep->flashsz);
 578
 579                puts ("\n");
 580
 581                print_mem ("ZBT", "         ", ep->nzbt, ep->zbtsz);
 582
 583                if (ep->nxlx > 0) {
 584                        hymod_xlx_t *xp;
 585
 586                        if (ep->nxlx == 1) {
 587                                xp = &ep->xlx[0];
 588                                printf (", Xilinx %s FPGA (%s/%s/%s)",
 589                                        xlxtyp_vals[xp->type],
 590                                        xlxspd_vals[xp->speed],
 591                                        xlxtmp_vals[xp->temp],
 592                                        xlxgrd_vals[xp->grade]);
 593                        }
 594                        else {
 595                                printf (", %d Xilinx FPGAs (", ep->nxlx);
 596                                for (i = 0; i < ep->nxlx; i++) {
 597                                        xp = &ep->xlx[i];
 598                                        printf ("%s[%s/%s/%s]%s",
 599                                            xlxtyp_vals[xp->type],
 600                                            xlxspd_vals[xp->speed],
 601                                            xlxtmp_vals[xp->temp],
 602                                            xlxgrd_vals[xp->grade],
 603                                            (i == ep->nxlx - 1) ? ")" : ", ");
 604                                }
 605                        }
 606                }
 607                else
 608                        puts(", NO FPGAs");
 609
 610                puts ("\n");
 611
 612                if (ep->hss.type > 0)
 613                        printf ("         High Speed Serial: "
 614                                "%s, %d input%s, %d output%s\n",
 615                                hstype_vals[ep->hss.type],
 616                                ep->hss.nchin,
 617                                (ep->hss.nchin == 1 ? "" : "s"),
 618                                ep->hss.nchout,
 619                                (ep->hss.nchout == 1 ? "" : "s"));
 620                break;
 621
 622        case HYMOD_BDTYPE_INPUT:
 623        case HYMOD_BDTYPE_ALTINPUT:
 624        case HYMOD_BDTYPE_DISPLAY:
 625                break;
 626
 627        default:
 628                /* crap! */
 629                printf ("         UNKNOWN BOARD TYPE: %d\n", ep->bdtype);
 630                break;
 631        }
 632}
 633
 634int
 635hymod_eeprom_read (int which, hymod_eeprom_t *ep)
 636{
 637        char *label = which ? "mezzanine" : "main";
 638        unsigned dev_addr = CONFIG_SYS_I2C_EEPROM_ADDR | \
 639                (which ? HYMOD_EEOFF_MEZZ : HYMOD_EEOFF_MAIN);
 640        char filename[50], prompt[50], *dir;
 641        int serno, count = 0, rc;
 642
 643        rc = eeprom_probe (dev_addr, 0);
 644
 645        if (rc > 0) {
 646                printf ("*** probe for eeprom failed with code %d\n", rc);
 647                return (0);
 648        }
 649
 650        if (rc < 0)
 651                return (rc);
 652
 653        sprintf (prompt, "Enter %s board serial number: ", label);
 654
 655        if ((dir = getenv ("bddb_cfgdir")) == NULL)
 656                dir = def_bddb_cfgdir;
 657
 658        for (;;) {
 659                int rc;
 660
 661                if (hymod_eeprom_load (which, ep))
 662                        return (1);
 663
 664                printf ("*** %s board EEPROM contents are %sinvalid\n",
 665                        label, count == 0 ? "" : "STILL ");
 666
 667                puts ("*** will fetch from server (Ctrl-C to abort)\n");
 668
 669                serno = hymod_get_serno (prompt);
 670
 671                if (serno < 0) {
 672                        if (serno == -1)
 673                                puts ("\n*** interrupted!");
 674                        else
 675                                puts ("\n*** timeout!");
 676                        puts (" - ignoring eeprom contents\n");
 677                        return (0);
 678                }
 679
 680                sprintf (filename, "%s/%010d.cfg", dir, serno);
 681
 682                printf ("*** fetching %s board EEPROM contents from server\n",
 683                        label);
 684
 685                rc = hymod_eeprom_fetch (which, filename, CONFIG_SYS_LOAD_ADDR);
 686
 687                if (rc == 0) {
 688                        puts ("*** fetch failed - ignoring eeprom contents\n");
 689                        return (0);
 690                }
 691
 692                count++;
 693        }
 694}
 695