edt_xilinx.c

00001 /*
00002 * FPGA header read and other utilities
00003 * 
00004 * Originally written it was only Xilinx (hence the name), now encompasses Alterra, may
00005 * include in FPGA types in the future; nevertheless Xilinx will likely be found here
00006 * and there for a long time used generically for all types of FPGAs.   
00007 */
00008 
00009 #include "edtdef.h"
00010 
00011 #ifdef _KERNEL
00012 
00013 #include "edtdrv.h"
00014 
00015 #define EdtDev Edt_Dev
00016 
00017 #ifdef _NT_DRIVER_ 
00018 
00019 #define edt_strtol strtol
00020 
00021 #endif
00022 
00023 /* #include <linux/string.h> */
00024 #include "pciload.h"
00025 
00026 
00027 #else
00028 
00029 #include "edtinc.h"
00030 
00031 #include "pciload.h"
00032 
00033 #define edt_set edt_reg_write
00034 #define edt_get edt_reg_read
00035 
00036 #define edt_delay edt_msleep
00037 
00038 #define EDTPRINTF(a,b,c) if (edt_get_verbosity() > b) { printf c ; }
00039 
00040 #define edt_strtol strtol
00041 
00042 #endif
00043 
00044 
00045 #ifdef DOXYGEN_SHOW_UNDOC
00046 
00050 #endif
00051 
00052 u_int ida_4013e(void *dmy, int sector);
00053 u_int ida_4013xla(void *dmy, int sector);
00054 u_int ida_4028xla(void *dmy, int sector); /* and xc2s150 */
00055 u_int ida_xc2s100(void *dmy, int sector); /* and 200 and 300e */
00056 u_int ida_xc3s1200e(void *dmy, int sector);
00057 u_int ida_xc2s1200e(void *dmy, int sector);
00058 u_int ida_xc5vlx30t(void * edt_p, int dmy); /* and 50t and ep2sgx30d */
00059 u_int edt_get_fpga_info_index(EdtDev *edt_p);
00060 
00061 Edt_prominfo ep;
00062 
00063 /* get from edt_get_prominfo */
00064 Edt_prominfo EPinfo[16] =
00065 {
00066 /*   comment             name           prom                bus     type       magic        sectorsize       scts/seg dfltseg id_addr(),     s0, s1 */
00067                         {"unknown [0]", "na",               "na",   0,         0,           0,               0,       0,      NULL,          -1, -1},
00068 /* AMD_4013E      1 */  {"4013e",       "AMD 29F010",       "PCI",  XTYPE_X,   XilinxMagic, E_SECTOR_SIZE,   8,       0,      ida_4013e,      1, -1},
00069 /* AMD_4013XLA    2 */  {"4013xla",     "AMD 29F010",       "PCI",  XTYPE_X,   XilinxMagic, XLA_SECTOR_SIZE, 1,       1,      ida_4013xla,    1, 3},
00070 /* AMD_4028XLA    3 */  {"4028xla",     "AMD 29F010",       "PCI",  XTYPE_BT,  XilinxMagic, XLA_SECTOR_SIZE, 2,       2,      ida_4028xla,    2, 3},
00071 /* AMD_XC2S150    4 */  {"xc2s150",     "AMD 29LV040B",     "PCI",  XTYPE_BT,  XilinxMagic, XLA_SECTOR_SIZE, 2,       2,      ida_4028xla,    2, 3},
00072 /* AMD_XC2S200_4M 5 */  {"xc2s200",     "AMD 29LV040B 4MB", "PCI",  XTYPE_BT,  XilinxMagic, XLA_SECTOR_SIZE, 4,       2,      ida_xc2s100,    0, 1},
00073 /* AMD_XC2S200_8M 6 */  {"xc2s200",     "AMD 29LV081B 8MB", "PCI",  XTYPE_BT,  XilinxMagic, XLA_SECTOR_SIZE, 4,       2,      ida_xc2s100,    2, 3},
00074 /* AMD_XC2S100_8M 7 */  {"xc2s100",     "AMD 29LV081B 8MB", "PCI",  XTYPE_BT,  XilinxMagic, XLA_SECTOR_SIZE, 4,       2,      ida_xc2s100,    2, 3},
00075 /* AMD_XC2S300E   8 */  {"xc2s300e",    "AMD 29LV081B 8MB", "PCI",  XTYPE_LTX, XilinxMagic, XLA_SECTOR_SIZE, 4,       2,      ida_xc2s100,   -1, -1},
00076 /* SPI_XC3S1200E  9 */  {"xc3s1200e",   "SPI W25P16",       "PCIe", XTYPE_SPI, XilinxMagic, SPI_SECTOR_SIZE, 32,      0,      ida_xc3s1200e,  0, -1},
00077 /* AMD_XC5VLX30T 10 */  {"xc5vlx30t",   "AMD S29GL064N",    "PCIe", XTYPE_BT2, XilinxMagic, XLA_SECTOR_SIZE, 32,      3,      ida_xc5vlx30t,  3, -1},
00078 /* AMD_XC5VLX50T 11 */  {"xc5vlx50t",   "AMD S29GL064N",    "PCIe", XTYPE_BT2, XilinxMagic, XLA_SECTOR_SIZE, 32,      3,      ida_xc5vlx30t,  3, -1},
00079 /* AMD_EP2SGX30D 12 */  {"ep2sgx30d",   "AMD S29GL128N",    "PCIe", XTYPE_BT2, AlteraMagic, XLA_SECTOR_SIZE, 32,      3,      ida_xc5vlx30t,  3, -1},
00080 /* AMD_XC5VLX70T 13 */  {"xc5vlx70t",   "AMD S29GL064N",    "PCIe", XTYPE_BT2, XilinxMagic, XLA_SECTOR_SIZE, 64,      0,      ida_xc5vlx30t,  0, -1},
00081 /* DUMMY         14 */  {"unknown [14]", "na",              "na",   0,         0,           0,                0,      0,       NULL,         -1, -1},
00082 /* DUMMY         15 */  {"unknown [15]", "na",              "na",   0,         0,           0,                0,      0,       NULL,         -1, -1},
00083 };
00084 
00085 /*  PROM_UNKN   0 */
00086 
00087 #define EDT_MAX_PROMCODE 13
00088 
00089 static struct
00090 {
00091     u_int   mid;
00092     u_int   devid;
00093     u_int   prom;
00094 }       older_devices[] =
00095 
00096 {
00097     {
00098         0x1, 0x20, AMD_4013E
00099     },
00100     {
00101         0x1, 0x4f, AMD_4013XLA
00102     },
00103         {
00104             0x20, 0xe3, AMD_4013XLA
00105         },
00106         {
00107             0x00, 0x00, 0
00108         }
00109 };
00110 
00111 /* shorthand debug level */
00112 #define DEBUG1 EDTLIB_MSG_INFO_1
00113 #define DEBUG2 EDTLIB_MSG_INFO_2
00114 
00115 /*
00116 * command bits for the 4028xla boot controller
00117 */
00118 #define BT_EN_READ      0x8000
00119 
00120 /*
00121 * bit to set in all prom addresses to enable the upper 2 bits of prom
00122 * address after we have read the status (jumper and 5/3.3v)
00123 */
00124 #define EN_HIGH_ADD     0x00800000
00125 
00126 static int needswap = 0;
00127 
00128 static void     spi_read(EdtDev *edt_p, int addr, u_char *rbuf, int rcnt);
00129 static int      spi_reset(EdtDev *edt_p);
00130 static void     spiprim(EdtDev *edt_p, int opcode, int wbytes, int rbytes, unsigned char* wbuf, unsigned char* rbuf);
00131 static void     spi_xwr(EdtDev *edt_p, int val);
00132 static int      spi_xrd(EdtDev *edt_p);
00133 static void     spi_xw(EdtDev *edt_p, u_int addr, u_int data);
00134 static u_int    spi_xr(EdtDev *edt_p, u_int addr);
00135 
00136 static void   bt_write(EdtDev *edt_p,u_int addr, u_char val);
00137 static u_char bt_read(EdtDev *edt_p, u_int addr);
00138 static void   bt_reset(EdtDev *edt_p);
00139 static u_char bt_readstat(EdtDev *edt_p);
00140 
00141 static void   bt2_reset(EdtDev *edt_p);
00142 
00143 static void   xwrite(EdtDev *edt_p, u_int addr, u_char val);
00144 static u_char xread(EdtDev *edt_p, u_int addr);
00145 static void   xreset(EdtDev *edt_p);
00146 static u_char xreadstat(EdtDev *edt_p);
00147 
00148 
00149 static void   tst_write(EdtDev * edt_p, uint_t desc, uint_t val);
00150 static uint_t tst_read(EdtDev * edt_p, uint_t desc);
00151 
00152 /* on some sun platforms memset isn't in the kernel */
00153 static void
00154 edt_zero(void *s, size_t n)
00155 {
00156 #ifdef __sun
00157     bzero(s, n);
00158 #else
00159     memset(s, 0, n);
00160 #endif
00161 }
00162 
00163 int
00164 edt_x_prom_detect(EdtDev * edt_p, u_char *stat);
00165 void
00166 edt_readinfo_keys(EdtDev *edt_p, int promcode, int segment, char *id, char *edtsn, char *oemsn, char *keys);
00167 
00168 void tst_pflash(EdtDev *edt_p, uint_t addr, uint_t val);
00169 
00170 void
00171 edt_x_block_program(EdtDev *edt_p, u_int addr, u_char *data, int nbytes, int xtype);
00172 
00173 void
00174 edt_get_sns(EdtDev *edt_p, char *esn, char *osn);
00175 
00176 
00177 static int 
00178 spi_block_program(EdtDev *edt_p, int addr0, int size, u_char *spibuf, int verify_only);
00179 
00180 char *
00181 read_x_block(EdtDev *edt_p, u_int addr, u_char *buf, int size, int xtype);
00182 
00183 void 
00184 edt_read_prom_data(EdtDev *edt_p, int promcode, int segment, 
00185              EdtPromData *pdata);
00186 
00187 /*
00188  * get prom info
00189  */
00190 Edt_prominfo *
00191 edt_get_prominfo(int promcode)
00192 {
00193     return &EPinfo[promcode];
00194 }
00195 
00196 /*
00197  * get max promcode
00198  */
00199 int
00200 edt_get_max_promcode()
00201 {
00202     return EDT_MAX_PROMCODE;
00203 }
00204 
00205 /* return true if machine is little_endian */
00206 
00207 #ifdef _KERNEL
00208 
00209 static int
00210 edt_little_endian()
00211 {
00212     u_short test;
00213     u_char *byte_p;
00214 
00215     byte_p = (u_char *) & test;
00216     *byte_p++ = 0x11;
00217     *byte_p = 0x22;
00218     if (test == 0x1122)
00219     {
00220         return (0);
00221     }
00222     else
00223     {
00224         return (1);
00225     }
00226 }
00227 
00228 #endif
00229 
00230 #define DQ7 0x80
00231 #define DQ5 0x20
00232 #define DQ3 0x08
00233 static int maxloops = 0;
00234 
00235 
00236 static int debug_fast = 0;
00237 static int do_fast = 0;
00238 static int force_slow = 0;
00239 
00240 int
00241 edt_get_debug_fast()
00242 {
00243     return (debug_fast) ;
00244 }
00245 int
00246 edt_set_debug_fast(int val)
00247 {
00248     (debug_fast = val) ;
00249     return val;
00250 }
00251 int
00252 edt_get_do_fast()
00253 {
00254     return (do_fast) ;
00255 }
00256 void
00257 edt_set_do_fast(int val)
00258 {
00259     do_fast = val ;
00260 }
00261 
00262 int
00263 edt_get_force_slow()
00264 {
00265     return (force_slow) ;
00266 }
00267 void
00268 edt_set_force_slow(int val)
00269 {
00270     force_slow = val ;
00271 }
00272 
00273 
00274 
00275 static char *device_name[NUM_DEVICE_TYPES] = {"pcd", "pdv", "p11w", "p16d", "p53b"};
00276 char *read_x_string(EdtDev *edt_p, u_int addr, char *buf, int size, int xtype);
00277 
00278 
00279 
00280 /* what are these? */
00281 
00282 volatile caddr_t dmyaddr = 0;
00283 volatile u_int *cfgaddr ;
00284 volatile u_int *tstaddr ;
00285 
00286 
00287 u_int
00288 swap32(u_int val)
00289 {
00290     /* already set hardware swap if LTX hub */
00291     return (
00292         ((val & 0x000000ff) << 24)
00293         | ((val & 0x0000ff00) << 8)
00294         | ((val & 0x00ff0000) >> 8)
00295         | ((val & 0xff000000) >> 24));
00296 }
00297 
00298 
00299 /*
00300 * print 16 bytes at the address passed read from 4028xla boot controller
00301 */
00302 static void
00303 bt_print16(EdtDev * edt_p, u_int addr)
00304 {
00305     int     i;
00306 
00307     EDTPRINTF(edt_p,2,("%08x ", addr));
00308     for (i = 1; i < 16; i++)
00309     {
00310         EDTPRINTF(edt_p,2,(" %02x", bt_read(edt_p, addr)));
00311         addr++;
00312     }
00313     EDTPRINTF(edt_p,2,("\n"));
00314 }
00315 
00316 /*
00317 * print 16 bytes at the address passed
00318 */
00319 static void
00320 xprint16(EdtDev * edt_p, u_int addr)
00321 {
00322     int     i;
00323 
00324     EDTPRINTF(edt_p,2,("%08x ", addr));
00325     for (i = 1; i < 16; i++)
00326     {
00327         EDTPRINTF(edt_p,2,(" %02x", xread(edt_p, addr)));
00328         addr++;
00329     }
00330     EDTPRINTF(edt_p,2,("\n"));
00331 }
00332 
00333 /*
00334 * print 16 bytes at the address passed
00335 */
00336 static void
00337 spi_print16(EdtDev * edt_p, u_int addr)
00338 {
00339     int     i;
00340     u_char val;
00341 
00342     EDTPRINTF(edt_p,2,("%08x ", addr));
00343     for (i = 1; i < 16; i++)
00344     {
00345         spi_read(edt_p, (u_int)addr, &val, 1);
00346         EDTPRINTF(edt_p,2,(" %02x", val));
00347         addr++;
00348     }
00349     EDTPRINTF(edt_p,2,("\n"));
00350 }
00351 
00352 
00353 
00354 void
00355 edt_x_print16(EdtDev * edt_p, u_int addr, int xtype)
00356 {
00357     switch(xtype)
00358     {
00359     case XTYPE_SPI:
00360         spi_print16(edt_p, (u_int)addr);
00361         break;
00362     case XTYPE_BT:
00363     case XTYPE_BT2:
00364         bt_print16(edt_p, addr);
00365         break;
00366     case XTYPE_X:
00367         xprint16(edt_p, addr);
00368         break;
00369     }
00370 }
00371 
00372 u_char
00373 edt_x_read(EdtDev * edt_p, u_int addr, int xtype)
00374 {
00375     u_char  val;
00376 
00377     switch(xtype)
00378     {
00379     case XTYPE_SPI:
00380         spi_read(edt_p, addr, &val, 1);
00381         return val;
00382     case XTYPE_BT:
00383     case XTYPE_BT2:
00384         return bt_read(edt_p, addr);
00385     case XTYPE_X:
00386         return xread(edt_p, addr);
00387     }
00388 
00389     return 0;
00390 }
00391 
00392 /*
00393 * sector erase for AMD 29LV0XXX
00394 */
00395 static int
00396 bt_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00397 {
00398     u_int   addr;
00399     int     done = 0;
00400     int     loops = 0;
00401     u_char  val;
00402 
00403     addr = sector * sec_size;
00404     bt_write(edt_p, 0x5555, 0xaa);
00405     bt_write(edt_p, 0x2aaa, 0x55);
00406     bt_write(edt_p, 0x5555, 0x80);
00407     bt_write(edt_p, 0x5555, 0xaa);
00408     bt_write(edt_p, 0x2aaa, 0x55);
00409     bt_write(edt_p, addr, 0x30);
00410     done = 0;
00411     while (!done)
00412     {
00413         val = bt_read(edt_p, addr);
00414         loops++;
00415         if (val & DQ7)
00416         {
00417             done = 1;
00418         }
00419     }
00420     return 0;
00421 }
00422 
00423 /*
00424  * sector erase for AMD S29GL64N, S29GL128N
00425  */
00426 static int
00427 bt2_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00428 {
00429     u_int   addr;
00430     int     done = 0;
00431     int     loops = 0;
00432     u_char  val;
00433 
00434     addr = sector * sec_size;
00435     bt_write(edt_p, 0xaaa, 0xaa);
00436     bt_write(edt_p, 0x555, 0x55);
00437     bt_write(edt_p, 0xaaa, 0x80);
00438     bt_write(edt_p, 0xaaa, 0xaa);
00439     bt_write(edt_p, 0x555, 0x55);
00440     bt_write(edt_p, addr, 0x30);
00441     done = 0;
00442     while (!done)
00443     {
00444         val = bt_read(edt_p, addr);
00445         loops++;
00446         if (val & DQ7)
00447         {
00448             done = 1;
00449         }
00450     }
00451     return 0;
00452 }
00453 
00454 static int
00455 xsector_erase(EdtDev * edt_p, u_int sector, u_int sec_size)
00456 {
00457     u_int   addr;
00458     int     done = 0;
00459     int     loops = 0;
00460     u_char  val;
00461 
00462     addr = sector * sec_size;
00463     xwrite(edt_p, 0x5555, 0xaa);
00464     xwrite(edt_p, 0x2aaa, 0x55);
00465     xwrite(edt_p, 0x5555, 0x80);
00466     xwrite(edt_p, 0x5555, 0xaa);
00467     xwrite(edt_p, 0x2aaa, 0x55);
00468     xwrite(edt_p, addr, 0x30);
00469     done = 0;
00470     while (!done)
00471     {
00472         val = xread(edt_p, addr);
00473         loops++;
00474         if (val & DQ7)
00475         {
00476             done = 1;
00477             break;
00478         }
00479     }
00480     return 0;
00481 }
00482 
00483 
00484 
00485 /*
00486 * for 4028xla, xc2s100, xc2s200
00487 */
00488 static int
00489 bt_byte_program(EdtDev * edt_p, int xtype, u_int addr, u_char data)
00490 {
00491     u_char  val;
00492     int     done = 0;
00493     int     loops = 0;
00494 
00495     bt_write(edt_p, 0x5555, 0xaa);
00496     bt_write(edt_p, 0x2aaa, 0x55);
00497     bt_write(edt_p, 0x5555, 0xa0);
00498     bt_write(edt_p, addr, data);
00499     tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00500 
00501     while (!done)
00502     {
00503         val = (u_char) tst_read(edt_p, EDT_FLASHROM_DATA);
00504 
00505         if (val == data)
00506             done = 1;
00507         if (loops > 1000)
00508         {
00509             EDTPRINTF(edt_p,1,("bt_byte_program: failed on %x data %x val %x\n",
00510                 addr, data, val));
00511             bt_reset(edt_p );
00512             bt_write(edt_p, 0x555, 0xaa);
00513             bt_write(edt_p, 0x2aa, 0x55);
00514             bt_write(edt_p, 0x555, 0xa0);
00515             bt_write(edt_p, addr, data);
00516             tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00517             loops = 0;
00518         }
00519         loops++;
00520     }
00521     if (loops > maxloops)
00522     {
00523         maxloops = loops;
00524     }
00525     if (done)
00526         return (0);
00527     else
00528         return (addr);
00529 }
00530 
00531 
00532 /*
00533  * for xc5vlx30t, xc5vlx50t, ep2sgx30d
00534  */
00535 static int
00536 bt2_byte_program(EdtDev * edt_p, int xtype, u_int addr, u_char data)
00537 {
00538     u_char  val;
00539     int     done = 0;
00540     int     loops = 0;
00541     int     failures = 0;
00542 
00543     bt_write(edt_p, 0xaaa, 0xaa);
00544     bt_write(edt_p, 0x555, 0x55);
00545     bt_write(edt_p, 0xaaa, 0xa0);
00546     bt_write(edt_p, addr, data);
00547     tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00548 
00549     while (!done)
00550     {
00551         val = (u_char) tst_read(edt_p, EDT_FLASHROM_DATA);
00552 
00553         if (val == data)
00554             done = 1;
00555         if (loops > 1000)
00556         {
00557             bt2_reset(edt_p);
00558             bt_write(edt_p, 0xaaa, 0xaa);
00559             bt_write(edt_p, 0x555, 0x55);
00560             bt_write(edt_p, 0xaaa, 0xa0);
00561             bt_write(edt_p, addr, data);
00562             tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
00563             loops = 0;
00564             failures++;
00565         }
00566         loops++;
00567 
00568         if (failures > 5)
00569         {
00570             EDTPRINTF(edt_p,0,("bt2_byte_program: failed on %x data %x val %x\n", addr, data, val));
00571             return(1);
00572         }
00573     }
00574     if (loops > maxloops)
00575     {
00576         maxloops = loops;
00577     }
00578     if (done)
00579         return (0);
00580     else
00581         return (addr);
00582 }
00583 
00584 
00585 /*
00586 * for 4013e and others
00587 */
00588 
00589 /* return 0 for success */
00590 static int
00591 xbyte_program(EdtDev * edt_p, u_int addr, u_char data)
00592 {
00593     u_char  val;
00594     int     done = 0;
00595     int     loops = 0;
00596 
00597         tst_pflash(edt_p, addr, data) ;
00598     while (!done)
00599     {
00600         loops++;
00601         val = xread(edt_p, addr);
00602         if (val == data)
00603             done = 1;
00604         if (loops > 100)
00605         {
00606             EDTPRINTF(edt_p,1,("xbyte_program: failed on %x data %x val %x\n",
00607                 addr, data, val));
00608             loops = 0;
00609         }
00610     }
00611     if (loops > maxloops)
00612     {
00613         if (loops > 10)
00614             EDTPRINTF(edt_p,1,("maxloops %x %d\n", addr, loops));
00615         maxloops = loops;
00616     }
00617     if (done)
00618         return (0);
00619     else
00620         return (addr);
00621 }
00622 
00623 
00624 /*
00625  * Program xilinx: 1 byte
00626  */
00627 void
00628 edt_x_byte_program(EdtDev *edt_p, u_int addr, u_char data, int xtype)
00629 {
00630     u_char buf[2];
00631 
00632     switch(xtype)
00633     {
00634 
00635     case XTYPE_SPI:
00636         buf[0] = data;
00637         edt_x_block_program(edt_p, addr, buf, 1, xtype);
00638 
00639         break;
00640     case XTYPE_BT:
00641         bt_byte_program(edt_p, xtype, addr, data);
00642         break;
00643     case XTYPE_BT2:
00644         bt2_byte_program(edt_p, xtype, addr, data);
00645         break;
00646     case XTYPE_X:
00647         xbyte_program(edt_p, addr, data); 
00648         break;
00649     }
00650 }
00651 
00652 /*
00653  * Program Xilinx: N bytes starting at addr
00654  */
00655 void
00656 edt_x_block_program(EdtDev *edt_p, u_int addr, u_char *data, int nbytes, int xtype)
00657 {
00658     int i;
00659     u_char *dp = data;
00660 
00661     switch(xtype)
00662     {
00663 
00664     case XTYPE_SPI:
00665         spi_block_program(edt_p, addr, nbytes, data, 0);
00666         break;
00667 
00668     case XTYPE_BT:
00669         for (i=0; i<nbytes; i++)
00670             bt_byte_program(edt_p, xtype, addr++, *(dp++));
00671         break;
00672     case XTYPE_BT2:
00673         for (i=0; i<nbytes; i++)
00674             bt2_byte_program(edt_p, xtype, addr++, *(dp++));
00675         break;
00676     case XTYPE_X:
00677         for (i=0; i<nbytes; i++)
00678             xbyte_program(edt_p, addr++, *(dp++)); 
00679         break;
00680     
00681     }
00682 }
00683 
00684 /*
00685  * Verify Xilinx: N bytes starting at addr
00686  */
00687 void
00688 edt_x_verify(EdtDev *edt_p, u_int addr, u_char *data, int nbytes, int xtype)
00689 {
00690     switch(xtype)
00691     {
00692     case XTYPE_SPI:
00693         spi_block_program(edt_p, addr, nbytes, data, 1);
00694         break;
00695     default:
00696         EDTPRINTF(edt_p,1,("Oops! Can't verify type %d xilinx with edt_x_verify (pciload internal)\n", xtype));
00697         break;
00698     }
00699 }
00700 
00701 
00702 
00724 void
00725 edt_get_esn(EdtDev *edt_p, char *esn)
00726 {
00727     char dmy[128];
00728     edt_get_sns(edt_p, esn, dmy);
00729 }
00730 
00746 void
00747 edt_get_osn(EdtDev *edt_p, char *osn)
00748 {
00749     char dmy[128];
00750     edt_get_sns(edt_p, dmy, osn);
00751 }
00752 
00753 static int
00754 isdigit_str(char *s)
00755 {
00756     unsigned int i;
00757 
00758     for (i=0; i<strlen(s); i++)
00759         if ((s[i]) < '0' || s[i] > '9')
00760             return 0;
00761     return 1;
00762 }
00763 
00764 
00765 
00766 
00782 int
00783 edt_x_get_fname(EdtDev *edt_p, char *name)
00784 {
00785     int promcode;
00786     char *p;
00787     char *idstr;
00788     EdtPromData pdata;
00789     Edt_prominfo *ep;
00790     u_char stat;
00791 
00792     promcode = edt_x_prom_detect(edt_p, &stat);
00793     
00794     ep = edt_get_prominfo(promcode);
00795 
00796     edt_read_prom_data(edt_p, promcode, ep->defaultseg,
00797                    &pdata);    
00798 
00799     idstr = pdata.id;
00800 
00801     if ((p = strrchr(idstr, '.')) != NULL)
00802         *p = '\0' ;
00803 
00804     if ((p = strrchr(idstr, '_')) != NULL)
00805     {
00806         if (( *(p + 1) == '3' || *(p + 1) == '5' )  && ( *(p + 2) == 'v' ))
00807             *p = '\0' ;
00808     }
00809         
00810     if ((p = strrchr(idstr, '-')) != NULL)
00811     {
00812         *p = '\0' ;
00813     }
00814  
00815     strcpy(name, idstr);
00816 
00817     return 0;
00818 }
00819 
00836 int
00837 edt_x_get_fname_auto(EdtDev *edt_p, char *name)
00838 {
00839     Edt_prominfo *ep;
00840     char *p;
00841     char *idstr;
00842     EdtPromData pdata;
00843     int promcode;
00844     u_char stat;
00845 
00846     promcode = edt_x_prom_detect(edt_p, &stat);
00847 
00848     ep = edt_get_prominfo(promcode);
00849     edt_read_prom_data(edt_p, promcode, ep->defaultseg,
00850                    &pdata);    
00851 
00852     idstr = pdata.id;
00853 
00854     /* strip off trailing .ncd (etc) */
00855     if ((p = strrchr(idstr, '.')) != NULL)
00856     {
00857         *p = '\0' ;
00858 
00859         /* strip off trailing _[35]v */
00860         if ((strlen(idstr) > 3) && ((strcmp(p-3, "_3v") == 0) || (strcmp(p-3, "_5v") == 0)))
00861             *(p-3) = '\0' ;
00862 
00863     }
00864 
00865     /* if present, strip off trailing -xxx (version number) */
00866     if ((p = strrchr(idstr, '-')) != NULL)
00867         *p = '\0';
00868 
00869 
00870     strcpy(name, idstr);
00871 
00872     return 0;
00873 }
00874 
00875 
00900 void
00901 edt_get_sns_sector(EdtDev *edt_p, char *esn, char *osn, int sector)
00902 {
00903     int promcode;
00904     u_char stat;
00905     EdtPromData pdata;
00906 
00907     promcode = edt_x_prom_detect(edt_p, &stat);
00908 
00909     if ((promcode == PROM_UNKN) || (promcode > edt_get_max_promcode()))
00910     {
00911         esn[0] = 0;
00912         osn[0] = 0;
00913     }
00914     else
00915     {
00916         edt_read_prom_data(edt_p, promcode, sector, &pdata);
00917         strcpy(esn, pdata.esn);
00918         strcpy(osn, pdata.osn);
00919     }
00920 }
00921 
00922 void
00923 edt_get_sns(EdtDev *edt_p, char *esn, char *osn)
00924 {
00925     u_char stat; 
00926     int promcode = edt_x_prom_detect(edt_p, &stat);
00927     Edt_prominfo *ep = edt_get_prominfo(promcode);
00928     
00929 
00930     edt_get_sns_sector(edt_p, esn, osn, ep->defaultseg);
00931 }
00932 
00933 /***************************************************************************/
00934 /* Instruction set for ST M25P20 SPI Flash Memory used on EDT TLKRCI */
00935 #define SPI_WREN  0x06  /* Write Enable,  0 params                   */
00936 #define SPI_WRDI  0x04  /* Write Disable, 0 params                   */
00937 #define SPI_RDSR  0x05  /* Read Status,   0 wbytes,         1 rbyte  */
00938 #define SPI_WRSR  0x01  /* Write Status,  1 wbyte                    */
00939 #define SPI_READ  0x03  /* Read data,     3 addr,           n rbytes */
00940 #define SPI_FREAD 0x0B  /* Fast Read,     3 addr + 1 dummy, n rbytes */
00941 #define SPI_PP    0x02  /* Page Program,  3 addr + 1-256 wbytes      */
00942 #define SPI_SE    0xD8  /* Sector Erase,  3 addr                     */
00943 #define SPI_BE    0xC7  /* Bulk Erase,    0 params                   */
00944 #define SPI_DP    0xB9  /* Power Down,    0 params                   */
00945 #define SPI_RES   0xAB  /* Read Sig,      3 wdummy,         1 rbyte  (DP off)*/
00946 
00947 #define SPI_REG   0x02000084    /* PCI Register for flash writes */
00948 #define SPI_EN    0x8000        /* Enable access to SPI reads and writes */
00949 #define SPI_S     0x2000        /* SEL, low true */
00950 #define SPI_D     0x1000        /* DATA out to serial flash */
00951 #define SPI_Q     0x0200        /* Data from flash spi_q is in bit 9 */
00952 
00953 
00954 /* SPI WORKING VARIABLES */
00955 unsigned char  Spi_wbufa[260];          /* Need 3 addr + 256 data for PP */
00956 unsigned char* Spi_wbuf=Spi_wbufa+3;            /* Just the 256 bytes of data */
00957 unsigned char  Spi_rbuf[260];           /* Read buffer, could use 256 Kbytes? */
00958 volatile caddr_t Spi_mapaddr = 0;
00959 
00960 
00961 /* for addr=0x040100C0     04:byte_count 01:interface_Xilinx, C0:PCI_address */
00962 static void
00963 spi_xw(EdtDev *edt_p, u_int addr, u_int data)
00964 {
00965     u_int       dmy;
00966     edt_set(edt_p, addr, data) ;
00967     dmy = edt_get(edt_p, 0x04000080) ;  /*flush chipset write buffers*/
00968 }
00969 
00970 static u_int
00971 spi_xr(EdtDev *edt_p, u_int addr)
00972 {
00973     return(edt_get(edt_p, addr)) ;
00974 }
00975 
00976 
00977 static void
00978 spi_xwr(EdtDev *edt_p, int val)
00979 {
00980     int d;
00981     d = SPI_EN | val;                           /* Set SEREN bit */
00982     spi_xw(edt_p, SPI_REG, d);
00983 }
00984 
00985 static int
00986 spi_xrd(EdtDev *edt_p)
00987 {
00988     int v;
00989     v = spi_xr(edt_p, 0x02000084);
00990     if (v & SPI_Q)  return(1);
00991     else return(0);
00992 }
00993 
00994 
00995 static void 
00996 spiprim(EdtDev *edt_p, int opcode, int wbytes, int rbytes, unsigned char* wbuf, unsigned char* rbuf) 
00997 {
00998     int c, b, cdat;
00999 
01000     /* spi_xwr(edt_p, SPI_S); */        /* SEL hi, goes low with first bit*/
01001 
01002     cdat = opcode;
01003     for (b=0; b<8; b++)  {              /* for each bit in the char */
01004         if (cdat & 0x80) {
01005             spi_xwr(edt_p, SPI_D);
01006         } else {
01007             spi_xwr(edt_p, 0);
01008         }
01009         cdat <<= 1;
01010     }
01011 
01012     for (c=0; c<wbytes; c++) {          /* for each char in wbuf */
01013         cdat = wbuf[c];
01014         for (b=0; b<8; b++)  {          /* for each bit in the char */
01015             if (cdat & 0x80) {
01016                 spi_xwr(edt_p, SPI_D);
01017             } else {
01018                 spi_xwr(edt_p, 0);
01019             }
01020             cdat <<= 1;
01021         }
01022     }
01023 
01024     for (c=0; c<rbytes; c++) {          /* for each char in rbuf */
01025         cdat = 0;
01026         for (b=0; b<8; b++)  {          /* for each bit in the char */
01027             cdat <<= 1;
01028             if (spi_xrd(edt_p) & 1)  
01029                 cdat |= 1;
01030             if ((b!=7) || (c!=(rbytes-1)))  {
01031                 spi_xwr(edt_p, 0);
01032             }
01033         }
01034         rbuf[c] = (char) cdat;
01035     }
01036 
01037     spi_xwr(edt_p, SPI_S);              /* Raise the Select line (to deselect) */
01038 }
01039 
01040 /*
01041  * Read electronic signature
01042  */
01043 static int
01044 spi_reset(EdtDev *edt_p)
01045 {
01046     unsigned char rval;
01047     char *magic = "555";                /* For M25P20 should be 0x11/0x13 */
01048 
01049     spiprim(edt_p, SPI_RES, 3, 1, (unsigned char *)magic, &rval);
01050 
01051     return(rval&0xff);                      /* Also out of Power Down mode  */
01052 }
01053 
01054 
01055 
01056 /* Read rcnt bytes starting from address addr, store in rbuf[] */
01057 static void
01058 spi_read(EdtDev *edt_p, int addr, u_char *rbuf, int rcnt)
01059 {
01060     if ((rcnt<1) || (rcnt > 256))   {
01061         EDTPRINTF(edt_p,1,("Error, bad spi_read() rcnt of %d\n", rcnt));
01062         return;
01063     }
01064     Spi_wbufa[0]=addr>>16; 
01065     Spi_wbufa[1]=addr>>8; 
01066     Spi_wbufa[2]=(char) addr;     /* 24 bit address */
01067     Spi_wbufa[3]=0;                                         /* dummy byte */
01068 
01069     spiprim(edt_p, SPI_FREAD, 4, rcnt, Spi_wbufa, rbuf);    
01070 }
01071 
01072 static int
01073 spi_write(EdtDev *edt_p, u_int addr, int wcnt)
01074 {
01075     int statcnt;
01076 
01077     if ((wcnt<1) || (wcnt>256))   {
01078         EDTPRINTF(edt_p,1,("Error, bad spi_write() wcnt of %d\n", wcnt));
01079         return -1;
01080     }
01081     spiprim(edt_p, SPI_WREN, 0, 0, NULL, NULL);             /* write-enable */
01082 
01083     Spi_wbufa[0]=addr>>16; 
01084     Spi_wbufa[1]=addr>>8; 
01085     Spi_wbufa[2]=(char) addr;     /* 24 bit address */
01086 
01087     spiprim(edt_p, SPI_PP,  3+wcnt, 0, Spi_wbufa, NULL);                    /* page program */
01088 
01089     statcnt=0;
01090     do {
01091         spiprim(edt_p, SPI_RDSR, 0, 1, NULL, Spi_rbuf);         /* Read Status reg */
01092         statcnt++;
01093     } while ((Spi_rbuf[0] & 1) == 1);           /* Could hang here forever? */
01094 
01095         return 0;
01096 }
01097 
01098 #define TOO_MANY 100000
01099 
01100 
01101 
01102 
01103 static int
01104 spi_sector_erase(EdtDev *edt_p, u_int addr)
01105 {
01106     int statcnt;
01107 
01108     spiprim(edt_p, SPI_WREN, 0, 0, NULL, NULL);             /* write-enable */
01109     Spi_wbufa[0]=addr>>16; 
01110     Spi_wbufa[1]=addr>>8; 
01111     Spi_wbufa[2]=(u_char) addr;     /* 24 bit address */
01112     spiprim(edt_p, SPI_SE,  3, 0, Spi_wbufa, NULL);    
01113 
01114     statcnt=0;
01115     do {
01116         spiprim(edt_p, SPI_RDSR, 0, 1, NULL, Spi_rbuf);         /* Read Status reg */
01117         if (statcnt++ > TOO_MANY)
01118         {
01119             EDTPRINTF(edt_p,1,("erase spun for too long, bailing out\n"));
01120             return(-1);
01121         }
01122     } while ((Spi_rbuf[0] & 1) == 1);           /* Could hang here forever? */
01123                     /* ALERT also should check all 8 status bits says JG */ 
01124 
01125     return(0);
01126 }
01127 
01128 /* 
01129  * check a string for forward or back slashes
01130  */
01131 int
01132 has_slashes(char *name)
01133 {
01134     char   *p = name;
01135 
01136     while (*p)
01137     {
01138         if ((*p == '/') || (*p == '\\'))
01139             return 1;
01140         ++p;
01141     }
01142     return 0;
01143 }
01144 
01145 
01146 /*
01147  * from spiw in pdbx.c
01148  */
01149 static int 
01150 spi_block_program(EdtDev *edt_p, int addr0, int size, u_char *spibuf, int verify_only)
01151 {
01152     int i, addr, n, bcnt, errorcnt, val, first, last;
01153 
01154     /* reset HACK -- sometimes it doesn't work the first time (?) */
01155     for (i=0; i<5; i++)
01156     {
01157         if ((val = spi_reset(edt_p)) != 0)
01158             break;
01159         (void)edt_delay(100);
01160     }
01161 
01162     if ((val != 0x11) && (val != 0x13) && (val != 0x14))
01163     {
01164         EDTPRINTF(edt_p,0,("    Error, did not detect SPI flash device, \n"));
01165         EDTPRINTF(edt_p,0,("      spi_reset() returned 0x%02x, not 0x11/0x13/0x14\n", val));
01166         return -1;
01167     }
01168 
01169     if (!verify_only)
01170     {
01171         first = (addr0&0xff0000)>>16;
01172         last  = ((addr0+size)&0xff0000)>>16;
01173         EDTPRINTF(edt_p,0,("  First sector is %d, last is %d, erasing", first, last));
01174 
01175         for (n=first; n<=last; n++)
01176         {
01177             spi_sector_erase(edt_p, n<<16);
01178             EDTPRINTF(edt_p,0,(".")); 
01179         }
01180         EDTPRINTF(edt_p,0,("\n"));
01181 
01182         EDTPRINTF(edt_p,0,("  Writing 0x%x bytes to spiflash at 0x%x.",size,addr0));
01183         bcnt=0;  addr=addr0;
01184         while (bcnt<size)
01185         {
01186             n=0;
01187             while (bcnt<size)
01188             {
01189                 if ((n!=0) && (((addr+n)&0xff)==0)) break;  /* page end */
01190 #ifndef _KERNEL                
01191                 if (!(bcnt % 10000)) {printf("."); fflush(stdout); }
01192 #endif
01193                 Spi_wbuf[n] = spibuf[bcnt]; 
01194                 n = n+1;
01195                 bcnt = bcnt+1;
01196             }
01197             if (n>0) spi_write(edt_p, addr, n); /* Write 1-256 bytes from Spi_wbuf*/
01198             addr = addr + n;
01199         }
01200     }
01201 
01202     EDTPRINTF(edt_p,0,("\n"));
01203     EDTPRINTF(edt_p,0,("  Verifying."));
01204     bcnt=0;  addr=addr0; errorcnt=0;
01205     while (bcnt<size)
01206     {
01207         spi_read(edt_p, addr, Spi_rbuf, 256);
01208         n=0;
01209         while (bcnt<size)  {
01210             if ((n!=0) && (((addr+n)&0xff)==0)) break;  /* page end */
01211 #ifndef _KERNEL                
01212             if (!(bcnt % 10000)) {printf("."); fflush(stdout); }
01213 #endif
01214             if ((Spi_rbuf[n]&0xff) != (spibuf[bcnt]&0xff)) {
01215                 if (errorcnt++ <= 10) {
01216                     EDTPRINTF(edt_p,0,("Error at 0x%x: wrote:%02x, read:%02x\n", 
01217                                 addr0+bcnt, spibuf[bcnt], Spi_rbuf[n]));
01218                 }
01219             }
01220             n = n+1;
01221             bcnt = bcnt+1;
01222         }
01223         addr = addr + n;
01224     }
01225     if (errorcnt)
01226         EDTPRINTF(edt_p,0,("    Saw %d errors\n", errorcnt));
01227 
01228     if (!errorcnt)
01229         EDTPRINTF(edt_p,0,("\nno errors\n"));
01230 
01231     return 0;
01232 }
01233 
01234 
01235 
01236 /* write a byte to the PCI interface prom (only 4013E and 4013XLA) */
01237 static void
01238 xwrite(EdtDev * edt_p, u_int addr, u_char val)
01239 {
01240 
01241         (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01242         tst_write(edt_p, EDT_FLASHROM_DATA, val) ;
01243         (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01244         tst_write(edt_p, EDT_FLASHROM_ADDR, EN_HIGH_ADD | addr | EDT_WRITECMD) ;
01245 }
01246 
01247 /* read a byte from the PCI interface prom (only 4013E and 4013XLA) */
01248 static u_char
01249 xread(EdtDev * edt_p, u_int addr)
01250 {
01251 
01252         (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01253         tst_write(edt_p, EDT_FLASHROM_ADDR, EN_HIGH_ADD | addr) ;
01254         (void)tst_read(edt_p, EDT_FLASHROM_ADDR);
01255         return (u_char) (tst_read(edt_p, EDT_FLASHROM_DATA));
01256  
01257 }
01258 
01259 
01260 /* ?reset? 4013e or 4013xla */
01261 static void 
01262 xreset(EdtDev * edt_p)
01263 {
01264     xwrite(edt_p, 0x5555, 0xaa);
01265     xwrite(edt_p, 0x2aaa, 0x55);
01266     xwrite(edt_p, 0x5555, 0xf0);
01267 }
01268 
01269 
01270 /*
01271 * write a byte to the PROM thru the boot controller on the 4028xla
01272 */
01273 static void
01274 bt_write(EdtDev * edt_p, u_int addr, u_char val)
01275 {
01276     /* write the address out in three chunks to the boot controller */
01277     /* first all commands are off */
01278     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01279     /* first byte of address */
01280     tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_LO | (addr & 0xff));
01281     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01282     /* second byte of address */
01283     tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_MID | ((addr >> 8) & 0xff));
01284     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01285 
01286     /* third byte of address */
01287     tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_HI | ((addr >> 16) & 0xff));
01288     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01289 
01290     tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_ROM | (val & 0xff));
01291     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01292 }
01293 
01294 
01295 
01296 /* ?reset? the 4028xla */
01297 static void 
01298 bt_reset(EdtDev * edt_p)
01299 {
01300     bt_write(edt_p, 0x555, 0xaa);
01301     bt_write(edt_p, 0x2aa, 0x55);
01302     bt_write(edt_p, 0x555, 0xf0);
01303 }
01304 
01305 /* ?reset? for xc5vlx30t, xc5vlx50t, ep2sgx30d */
01306 static void 
01307 bt2_reset(EdtDev * edt_p)
01308 {
01309     bt_write(edt_p, 0x0, 0xf0);
01310 }
01311 
01312 
01313 static u_char
01314 xreadstat(EdtDev * edt_p)
01315 {
01316     u_char  stat;
01317     uint_t  rdval;
01318 
01319     /*
01320     * disable the high address drive by writing 0 to bit24 of FPROM address
01321     * register.
01322     */
01323     tst_write(edt_p, EDT_FLASHROM_ADDR, 0);
01324     rdval = tst_read(edt_p, EDT_FLASHROM_DATA);
01325     stat = (u_char) (rdval >> 8);
01326     return (stat);
01327 }
01328 
01329 /*
01330 * read a byte from the 4028xla prom through the boot controller.
01331 */
01332 static u_char
01333 bt_read(EdtDev * edt_p, u_int addr)
01334 {
01335     u_char  stat;
01336 
01337     /* write the address out in three chunks to the boot controller */
01338     /* first all commands are off */
01339     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01340     /* first byte of address */
01341     tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_LO | (addr & 0xff));
01342     /* clear BT_LD_LO */
01343     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01344     /* second byte of address */
01345     tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_MID | ((addr >> 8) & 0xff));
01346     /* clear BT_LD_MID */
01347     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01348     /* third byte of address */
01349     tst_write(edt_p, EDT_FLASHROM_DATA, BT_LD_HI | ((addr >> 16) & 0xff));
01350     /* clear BT_LD_HI , set rd command and disable output buffer */
01351     tst_write(edt_p, EDT_FLASHROM_DATA, BT_RD_ROM);
01352 
01353     /* read the byte */
01354     stat = (u_char) tst_read(edt_p, EDT_FLASHROM_DATA);
01355     /* all commands are off */
01356     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01357     return (stat);
01358 }
01359 
01360 /*
01361 * read the jumper position and bus voltage from the boot controller
01362 */
01363 static u_char
01364 bt_readstat(EdtDev * edt_p)
01365 {
01366     u_char  stat;
01367     uint_t rdval;
01368 
01369     /*
01370     * read the boot controller status A0 and A1 low with read asserted -
01371     * enables boot controller on bus
01372     */
01373     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01374     tst_write(edt_p, EDT_FLASHROM_DATA, BT_EN_READ | BT_READ);
01375     rdval = tst_read(edt_p, EDT_FLASHROM_DATA);
01376     stat = (u_char) rdval;
01377     /* reset all boot command */
01378     tst_write(edt_p, EDT_FLASHROM_DATA, 0);
01379     return (stat);
01380 }
01381 
01382 
01383 
01384 void
01385 edt_x_reset(EdtDev *edt_p, int xtype)
01386 {
01387     switch(xtype)
01388     {
01389     case XTYPE_SPI:
01390         spi_reset(edt_p);
01391         break;
01392     case XTYPE_BT:
01393         bt_reset(edt_p);
01394         break;
01395     case XTYPE_BT2:
01396         bt2_reset(edt_p);
01397         break;
01398     case XTYPE_X:
01399         xreset(edt_p) ;
01400         break;
01401     }
01402 }
01403 
01404 
01405 /*
01406  * get the sector size -- from array for older (pre PCIe), 1st 4 bytes of PROM
01407  * for newer (PCIe8, etc.) 
01408  */
01409 u_int
01410 edt_get_fpga_sectorsize(EdtDev *edt_p, Edt_prominfo *ep)
01411 {
01412     u_int tmpval;
01413 
01414     if (ep->xtype == XTYPE_BT)
01415     {
01416         tmpval = bt_read(edt_p, 0x0)        |
01417                 (bt_read(edt_p, 0x1) << 8)  | 
01418                 (bt_read(edt_p, 0x2) << 16) | 
01419                 (bt_read(edt_p, 0x3) << 24) ;
01420         return tmpval;
01421     }
01422     else return ep->sectorsize;
01423 }
01424 
01425 /*
01426  * new fpgas (pcie8, etc) info addr is indexed from 2nd 4 bytes of prom
01427  */
01428 u_int
01429 edt_get_fpga_info_index(EdtDev *edt_p)
01430 {
01431     u_int tmpval;
01432 
01433     tmpval = bt_read(edt_p, 0x4)        |
01434             (bt_read(edt_p, 0x5) << 8)  | 
01435             (bt_read(edt_p, 0x6) << 16) | 
01436             (bt_read(edt_p, 0x7) << 24) ;
01437     return tmpval;
01438 }
01439 
01440 
01441 /*
01442  * get the onboard PROM device info from the string at the end of the segment
01443  *  NOTE: don't call directly -- instead use edt_get_promaddrs
01444  */
01445 u_int
01446 edt_get_id_addr(int promcode, int segment)
01447 {
01448     u_int id_addr;
01449     Edt_prominfo *ep = edt_get_prominfo(promcode);
01450 
01451     if (ep->sectorsize == 0)
01452         return 1;
01453 
01454     switch(promcode)
01455     {
01456 
01457         case AMD_4013E:
01458             id_addr = (ep->sectsperseg * ep->sectorsize) - PCI_ID_SIZE;
01459             break;
01460 
01461         case SPI_XC3S1200E:
01462             id_addr = segment * ep->sectorsize;
01463             break;
01464 
01465         default: 
01466             id_addr = ((segment + 1) * ep->sectsperseg * ep->sectorsize) - PCI_ID_SIZE;
01467             break;
01468 
01469     }
01470     return id_addr;
01471 }
01472 
01473 
01474 /*
01475  * get id addresses, ==>including serial numbers<== (since they're not all the same 
01476  * any more -- specifically with newer PCIE (XC3S1200E, XCVLX30/50T) we put the ID
01477  * at the beginning not the end, and have up to 1024 bytes (though the sizes,
01478  * particularly OSN, are still the same so far) (OSN will stay the same I think too)
01479  */
01480 u_int
01481 edt_get_promaddrs(EdtDev *edt_p, int promcode, int segment, 
01482                  EdtPromIdAddresses *paddr)
01483             
01484 {
01485     Edt_prominfo *ep = edt_get_prominfo(promcode);
01486     char tst[4];
01487     /* u_int info_addr = ep->id_addr((u_long)edt_p, segment); */
01488          /* STORE MORE STUFF HERE ?? */
01489 
01490     paddr->id_addr = edt_get_id_addr(promcode, segment);
01491 
01492     /*
01493      * SPI devices: 
01494      *   PROM ID 128
01495      *   OSN 32
01496      *   ESN 64 (or more up to total of 1024)
01497      *   data
01498      */
01499     if (ep->xtype == XTYPE_SPI)
01500     {
01501         paddr->osn_addr = paddr->id_addr + PCI_ID_SIZE;
01502         paddr->esn_addr = paddr->osn_addr + OSN_SIZE;
01503         paddr->extra_tag_addr = paddr->esn_addr + ESN_SIZE;
01504         paddr->extra_size_addr = paddr->extra_tag_addr + 4;
01505         paddr->extra_data_addr = paddr->extra_size_addr + 4;
01506 
01507         
01508     }
01509     /*
01510      * All other devices:
01511      *   data (0 up to segment size minus 128 [PCI_ID_SIZE])
01512      *   .
01513      *   .
01514      *   .
01515      *   OSN 32
01516      *   ESN 64 
01517      *   PROM ID 128
01518      */
01519     else
01520     {
01521         paddr->osn_addr = paddr->id_addr - OSN_SIZE;
01522         paddr->esn_addr = paddr->osn_addr - ESN_SIZE;
01523         paddr->extra_tag_addr = paddr->esn_addr - 4;
01524         paddr->extra_size_addr = paddr->extra_tag_addr - 4;
01525         /* we don't know extra_data_addr yet */
01526 
01527     }
01528 
01529     read_x_block(edt_p, paddr->extra_tag_addr, (u_char *)tst, 4, ep->xtype);
01530 
01531     if (strncmp(tst,"XTR:",4) == 0)
01532     {
01533     
01534         read_x_block(edt_p, paddr->extra_size_addr, (u_char *)&paddr->extra_size, 4, ep->xtype);
01535 
01536         if (needswap)
01537         {
01538             paddr->extra_size = swap32(paddr->extra_size);
01539         }
01540         if (ep->xtype != XTYPE_SPI)
01541             paddr->extra_data_addr = paddr->extra_size_addr - (4 + paddr->extra_size);
01542 
01543     }
01544     else
01545         paddr->extra_size = 0;
01546 
01547     return paddr->id_addr;
01548 }
01549 
01550 
01551 /*
01552  * addresses for id information, per xilinx type
01553  */
01554 u_int
01555 ida_4013e(void *dmy, int segment)
01556 {
01557     return (8 * E_SECTOR_SIZE) - PCI_ID_SIZE;
01558 }
01559 
01560 u_int
01561 ida_4013xla(void *dmy, int segment)
01562 {
01563     return (segment * XLA_SECTOR_SIZE) + XLA_SECTOR_SIZE - PCI_ID_SIZE;
01564 }
01565 
01566 u_int
01567 ida_4028xla(void *dmy, int segment)
01568 {
01569     return ((segment + 1) * 2 * XLA_SECTOR_SIZE) - PCI_ID_SIZE;
01570 }
01571 
01572 u_int
01573 ida_xc2s100(void *dmy, int segment)
01574 {
01575     return ((segment + 1) * 4 * XLA_SECTOR_SIZE) - PCI_ID_SIZE;
01576 }
01577 
01578 u_int
01579 ida_xc3s1200e(void *dmy, int segment)
01580 {
01581     return segment * SPI_SECTOR_SIZE;
01582 }
01583 
01584 u_int
01585 ida_xc5vlx30t(void * edt_p , int dmy)
01586 {
01587     return edt_get_fpga_info_index((EdtDev *)edt_p);
01588 }
01589 
01590 void tst_init(EdtDev *edt_p)
01591 {
01592 
01593 #ifndef _KERNEL
01594 
01595     if (!edt_p->mapaddr)
01596         edt_p->mapaddr = (caddr_t)edt_mapmem(edt_p, 0, 256) ;
01597 
01598 #endif
01599 
01600     needswap = !edt_little_endian();
01601 }
01602 
01603 static void
01604 tst_write(EdtDev * edt_p, uint_t desc, uint_t val)
01605 {
01606 
01607 #ifndef _KERNEL
01608     u_int dmy;
01609 
01610     if (edt_p->mapaddr)
01611     {
01612 
01613         tstaddr = (volatile u_int *)(edt_p->mapaddr + (desc & 0xff)) ;
01614 
01615         if (needswap)
01616         {
01617             *tstaddr = swap32(val) ;
01618         }
01619         else
01620         {
01621             *tstaddr = val ;
01622         }
01623 
01624         dmy = *tstaddr;
01625     }
01626     else
01627 #endif
01628         edt_set(edt_p, desc, val) ;
01629 
01630 }
01631 
01632 static uint_t
01633 tst_read(EdtDev * edt_p, uint_t desc)
01634 {
01635 
01636 #ifndef _KERNEL
01637     
01638     if (edt_p->mapaddr)
01639     {
01640 
01641         tstaddr = (volatile u_int *)(edt_p->mapaddr + (desc & 0xff)) ;
01642 
01643         if (needswap)
01644         {
01645             return (swap32(*tstaddr)) ;
01646         }
01647         else 
01648             return  (*tstaddr) ;
01649 
01650     }
01651     else
01652 #endif
01653         return(edt_get(edt_p, desc)) ;
01654 }
01655 
01656 void tst_pflash(EdtDev *edt_p, uint_t addr, uint_t val)
01657 {
01658 
01659     tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0xaa);
01660     (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01661     tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x5555 | EDT_WRITECMD));
01662     (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01663     tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0x55);
01664     (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01665     tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x2aaa | EDT_WRITECMD));
01666     (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01667     tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) 0xa0);
01668     (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01669     tst_write(edt_p, EDT_FLASHROM_ADDR, (u_int) (0x5555 | EDT_WRITECMD));
01670     (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01671     tst_write(edt_p, EDT_FLASHROM_DATA, (u_char) val);
01672     (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01673     tst_write(edt_p, EDT_FLASHROM_ADDR, 
01674         (u_int) (EN_HIGH_ADD | addr | EDT_WRITECMD));
01675     (void) tst_read(edt_p, EDT_FLASHROM_ADDR);
01676 }
01677 
01678 /*
01679 * read a string out of the xilinx, of a given size, from a given address.
01680 * used for Xilinx ID id string and serial number strings
01681 *
01682 * ARGUMENTS
01683 *   edt_p     pointer to already opened edt device
01684 *   addr      address to start reading the string
01685 *   buf       buffer to read the string into
01686 *   size      number of bytes to read
01687 *
01688 * RETURNS
01689 *   pointer to magic first valid ASCII character in string (should be
01690 *   0th but may not be, esp. if blank)
01691 *
01692 */
01693 char *
01694 read_x_string(EdtDev *edt_p, u_int addr, char *buf, int size, int xtype)
01695 {
01696     int  i;
01697     char *ret = 0;
01698     u_char  val;
01699 
01700     /* EDTPRINTF(edt_p,1,("full string = ")); */
01701     for (i = 0; i < size; i++)
01702     {
01703         switch(xtype)
01704         {
01705         case XTYPE_SPI:
01706             spi_reset(edt_p);
01707             spi_read(edt_p, (u_int)addr, &val, 1);
01708             break;
01709         case XTYPE_BT:
01710         case XTYPE_BT2:
01711             val = bt_read(edt_p, (u_int)addr);
01712             break;
01713         case XTYPE_X:
01714             val = xread(edt_p, (u_int)addr);
01715             break;
01716         }
01717         buf[i] = val;
01718         addr++;
01719         /* EDTPRINTF(edt_p,1,("%x ", val)); */
01720         /* record start of string */
01721         if (!ret && val >= 0x20 && val <= 0x7e)
01722             ret = &buf[i];
01723     }
01724     buf[i] = 0;
01725     return ret;
01726 }
01727 
01728 /*
01729 * read a string out of the xilinx, of a given size, from a given address.
01730 * used for Xilinx ID id string and serial number strings
01731 *
01732 * ARGUMENTS
01733 *   edt_p     pointer to already opened edt device
01734 *   addr      address to start reading the string
01735 *   buf       buffer to read the string into
01736 *   size      number of bytes to read
01737 *
01738 * RETURNS
01739 *
01740 */
01741 
01742 char *
01743 read_x_block(EdtDev *edt_p, u_int addr, u_char *buf, int size, int xtype)
01744 {
01745     int  i;
01746     char *ret = 0;
01747     u_char  val;
01748 
01749     /* EDTPRINTF(edt_p,1,("full string = ")); */
01750     for (i = 0; i < size; i++)
01751     {
01752         switch(xtype)
01753         {
01754         case XTYPE_SPI:
01755             spi_reset(edt_p);
01756             spi_read(edt_p, (u_int)addr, &val, 1);
01757             break;
01758         case XTYPE_BT:
01759         case XTYPE_BT2:
01760             val = bt_read(edt_p, (u_int)addr);
01761             break;
01762         case XTYPE_X:
01763             val = xread(edt_p, (u_int)addr);
01764             break;
01765         }
01766         buf[i] = val;
01767         addr++;
01768 
01769     }
01770     
01771     return (char *) buf;
01772 }
01773 
01774 int
01775 edt_sector_erase(EdtDev * edt_p, u_int sector, u_int sec_size, int xtype)
01776 {
01777     switch(xtype)
01778     {
01779     case XTYPE_SPI:
01780         spi_sector_erase(edt_p, sector << 16);
01781         break;
01782     case XTYPE_BT:
01783         bt_sector_erase(edt_p, sector, sec_size);
01784         break;
01785     case XTYPE_BT2:
01786         bt2_sector_erase(edt_p, sector, sec_size);
01787         break;
01788     case XTYPE_X:
01789         xsector_erase(edt_p, sector, sec_size);
01790         break;
01791     }
01792     return 0;
01793 }
01794 
01795 
01796 int
01797 edt_x_prom_detect(EdtDev * edt_p, u_char *stat)
01798 {
01799     u_int   desc = EDT_FLASHROM_DATA;
01800     u_int   flashrom_bits, idbits;
01801     u_char  mid, devid;
01802     int     prom;
01803 
01804     EDTPRINTF(edt_p, 2, ("edt_x_prom_detect\n"));
01805 
01806     /* set up structures for direct peek/poke */
01807     tst_init(edt_p) ;
01808 
01809     /*
01810     * if the BT_A0 bit in the PROM_DATA can be written high
01811     * this must be a new board with a 4028xla or XC2S___
01812     */
01813 
01814     tst_write(edt_p, desc, BT_A0);
01815     flashrom_bits = tst_read(edt_p, desc) & BT_A0;
01816 
01817     if (flashrom_bits == BT_A0)
01818     {
01819         EDTPRINTF(edt_p,2,("  FLASHROM command BT_A0 can be set board has boot controller\n"));
01820 
01821         *stat = bt_readstat(edt_p);
01822         idbits = (u_int)((*stat & STAT_IDMASK) >> STAT_IDSHFT);
01823         EDTPRINTF(edt_p,2,("\t\tRead code %02x id bits %x\n", *stat, idbits));
01824 
01825 
01826             switch (idbits)
01827             {
01828                 case STAT_EP2SGX30D:
01829                     prom = AMD_EP2SGX30D;
01830                     break;
01831                 case STAT_XC3S1200E:
01832                     prom = SPI_XC3S1200E;
01833                     break;
01834                 case STAT_XC5VLX30T:
01835                     prom = AMD_XC5VLX30T;
01836                     break;
01837                 case STAT_XC5VLX50T:
01838                     prom = AMD_XC5VLX50T;
01839                     break;
01840                 case STAT_XC5VLX70T:
01841                     prom = AMD_XC5VLX70T;
01842                     break;
01843                 case STAT_XC4028XLA:
01844                     prom = AMD_4028XLA;
01845                     break;
01846                 case STAT_XC2S150:
01847                     prom = AMD_XC2S150;
01848                     break;
01849                 case STAT_XC2S200_NP:
01850                     prom = AMD_XC2S200_4M;
01851                     break;
01852                 case STAT_XC2S200:
01853                     prom = AMD_XC2S200_8M;
01854                     break;
01855                 case STAT_XC2S100:
01856                     prom = AMD_XC2S100_8M;
01857                     break;
01858                 default:
01859                     prom = PROM_UNKN;
01860                     break;
01861             }
01862 
01863 
01864     }
01865     else
01866     {
01867         EDTPRINTF(edt_p,2,("  BT_A0 wrote, read back %02x, must not have boot controller\n", flashrom_bits));
01868         prom = PROM_UNKN;
01869     }
01870     /*
01871     * if prom code is not set yet test for other prom types by reading 
01872     * manufacturer code in flash prom.
01873     */
01874     if (prom == PROM_UNKN)  
01875     {
01876         int i;
01877 
01878         edt_x_reset(edt_p, 0);
01879 
01880         /* this code borrowed from xautoselect() */
01881         xwrite(edt_p, 0x5555, 0xaa);
01882         xwrite(edt_p, 0x2aaa, 0x55);
01883         xwrite(edt_p, 0x5555, 0x90);
01884         mid = xread(edt_p, 0x0);
01885         devid = xread(edt_p, 0x1);
01886 
01887         for (i = 0; older_devices[i].prom != 0; i++)
01888         {
01889             if (mid == older_devices[i].mid && devid == older_devices[i].devid)
01890             {
01891                 prom = older_devices[i].prom;
01892                 break;
01893             }
01894         }
01895 
01896             EDTPRINTF(edt_p,2,("  edt_x_prom_detect: autoselect manuf id %02x devid %02x code %d\n",
01897             mid, devid, prom));
01898         edt_x_reset(edt_p, 0);
01899 
01900         *stat = xreadstat(edt_p);
01901     }
01902     return (prom);
01903 }
01904 
01905 
01906 EdtPromParmBlock *
01907 edt_get_parms_block(EdtPromData *pdata, char *id)
01908 
01909 {
01910     EdtPromParmBlock *p;
01911 
01912     p = (EdtPromParmBlock *) pdata->extra_buf;
01913 
01914     if (p->size > (u_int) pdata->extra_size)
01915         return BAD_PARMS_BLOCK;
01916 
01917     while (p->size && ((u_char *) p - pdata->extra_buf) < pdata->extra_size)
01918     {
01919         if (strncmp(id, p->type,4) == 0)
01920             return p;
01921         p = (EdtPromParmBlock *) ((u_char *) p + p->size);
01922     }
01923 
01924     return NULL;
01925 
01926 }
01927 EdtPromParmBlock *edt_add_parmblock(EdtPromData *pdata, char *type,  int datasize)
01928 
01929 {
01930     
01931     EdtPromParmBlock *p;
01932 
01933     p = edt_get_parms_block(pdata, type);
01934 
01935     if (p)
01936         return NULL;
01937 
01938     if (pdata->extra_size + datasize + 8 > PROM_EXTRA_SIZE)
01939         return NULL;
01940 
01941     p = (EdtPromParmBlock *) (pdata->extra_buf + pdata->extra_size);
01942     strncpy(p->type,type,4);
01943     p->size = datasize;
01944     
01945     pdata->extra_size += 8 + datasize;
01946 
01947     return p;
01948 }
01949 
01950 
01951 
01952 
01953 void
01954 edt_x_program_extra(EdtDev *edt_p, int promcode, EdtPromData *pdata, int sect)
01955 {
01956     u_int   id_addr;
01957     Edt_prominfo *ep = edt_get_prominfo(promcode);
01958     int sector;
01959     EdtPromIdAddresses addr;
01960     char *key_str = "XTR:";
01961 
01962     sector = (sect == IS_DEFAULT_SECTOR)? ep->defaultseg:sect;
01963 
01964     if ((id_addr = edt_get_promaddrs(edt_p, promcode, sector, &addr)) == 1)
01965     {
01966         EDTPRINTF(edt_p, 0, ("invalid device; no ID info\n"));
01967         return;
01968     }
01969 
01970     edt_x_reset(edt_p, ep->xtype);
01971 
01972     if (pdata->extra_size)
01973     {
01974         u_int size;
01975 
01976         size = pdata->extra_size;
01977         if (!edt_little_endian())
01978             size = swap32(size);
01979 
01980         if (ep->xtype != XTYPE_SPI)
01981             addr.extra_data_addr = addr.extra_size_addr - (4 + pdata->extra_size);
01982         
01983         edt_x_block_program(edt_p, addr.extra_tag_addr, (u_char *) key_str, 4, ep->xtype);
01984         edt_x_block_program(edt_p, addr.extra_size_addr, (u_char *) &size, 4, ep->xtype);
01985         edt_x_block_program(edt_p, addr.extra_data_addr, pdata->extra_buf, pdata->extra_size, ep->xtype);
01986     }
01987    
01988     edt_x_reset(edt_p, ep->xtype);
01989     
01990 }
01991 
01992 static void
01993 edt_program_sn_str(EdtDev *edt_p, u_int addr, char *str, char *tag, int size, int xtype)
01994 
01995 {
01996     char    sn_str[ESN_SIZE];
01997     if (str[0])
01998     {
01999         edt_x_reset(edt_p, xtype);
02000         edt_zero(sn_str, size);
02001         if (strncmp(str, "erase", 5) != 0)
02002         {
02003             strcpy(sn_str, tag);
02004             strcat(sn_str, str);
02005         }
02006         
02007         edt_x_block_program(edt_p, addr, (u_char *)sn_str, size, xtype);
02008     }
02009 }
02010 
02011 
02012 void
02013 edt_program_promdata(EdtDev *edt_p, 
02014                 int promcode, 
02015                 int sector, 
02016                 EdtPromData *pdata)
02017 {
02018 
02019     Edt_prominfo *ep = edt_get_prominfo(promcode);
02020 
02021     EdtPromIdAddresses addr;
02022 
02023     /* get addresses */
02024     addr.id_addr = edt_get_promaddrs(edt_p, promcode, sector, &addr);
02025 
02026     EDTPRINTF(edt_p, 2, 
02027         ("\nedt_program_promdata id_addr %x oemsn addr %x edtsn addr %x\n", 
02028         addr.id_addr, addr.osn_addr, addr.esn_addr));
02029 
02030     edt_program_sn_str(edt_p, addr.osn_addr,pdata->osn, "OSN:", OSN_SIZE, ep->xtype);
02031 
02032     edt_program_sn_str(edt_p, addr.esn_addr,pdata->esn, "ESN:", ESN_SIZE, ep->xtype);
02033 
02034     edt_x_program_extra(edt_p, promcode, pdata, sector);
02035 }
02036 
02037 /*
02038  * return a string containing the Xilinx type; mainly for debug output
02039  */
02040 char *
02041 edt_x_type_string(int xtype)
02042 {
02043     switch (xtype)
02044     {
02045         case XTYPE_X: return("XTYPE_X");
02046         case XTYPE_BT: return("XTYPE_BT");
02047         case XTYPE_LTX: return( "XTYPE_LTX");
02048         case XTYPE_SPI: return( "XTYPE_SPI");
02049         case XTYPE_BT2: return( "XTYPE_BT2");
02050         default: return("UNKNOWN");
02051     }   
02052 }
02053 
02054 /*
02055 * get the onboard PROM device info from the string at the end of the segment
02056 * TODO: maybe implement larger PCIE_ID_SIZE
02057 */
02058 void 
02059 edt_read_prom_data(EdtDev *edt_p, int promcode, int segment, 
02060              EdtPromData *pdata)
02061 
02062 {
02063     Edt_prominfo *ep = edt_get_prominfo(promcode);
02064     char    idbuf[PCI_ID_SIZE + 1];
02065     char    oemsnbuf[OSN_SIZE + 1];
02066     char    edtsnbuf[ESN_SIZE + 1];
02067 
02068     char    *ret;
02069 
02070     EdtPromIdAddresses addr;
02071 
02072     edt_zero(pdata,  sizeof(EdtPromData));
02073 
02074     /* get addresses */
02075     addr.id_addr = edt_get_promaddrs(edt_p, promcode, segment, &addr);
02076 
02077     EDTPRINTF(edt_p, 2, 
02078         ("\nedt_read_prom_data id_addr %x oemsn addr %x edtsn addr %x\n", 
02079         addr.id_addr, addr.osn_addr, addr.esn_addr));
02080 
02081     /* BITFILE ID */
02082     if ((ret = read_x_string(edt_p, addr.id_addr, idbuf, PCI_ID_SIZE, ep->xtype)) != NULL) 
02083         strncpy(pdata->id, ret, PCI_ID_SIZE);
02084 
02085     /* OSN */
02086     if ((ret = read_x_string(edt_p, addr.osn_addr, oemsnbuf, OSN_SIZE, ep->xtype)) != NULL)
02087     {
02088         if (strncmp(ret, "OSN:", 4) == 0)
02089         {
02090             strncpy(pdata->osn, &ret[4], OSN_SIZE);
02091             if (pdata->osn[strlen(pdata->osn)-1] == ':')
02092                 pdata->osn[strlen(pdata->osn)-1] = '\0';
02093         }
02094     }
02095 
02096     /* ESN */
02097     if ((ret = read_x_string(edt_p, addr.esn_addr, edtsnbuf, ESN_SIZE, ep->xtype)) != NULL)
02098         if (strncmp(ret, "ESN:", 4) == 0)
02099             strncpy(pdata->esn, &ret[4], ESN_SIZE);
02100 
02101     /* EXTRA  */
02102 
02103     if (addr.extra_size)
02104     {
02105         if ((ret = read_x_block(edt_p, addr.extra_data_addr, pdata->extra_buf, addr.extra_size, ep->xtype)) != NULL)
02106         {
02107             pdata->extra_size = addr.extra_size;
02108         }
02109     }
02110 
02111 #ifndef _KERNEL
02112     if (pdata->esn)
02113         edt_parse_esn(pdata->esn, &pdata->ei);
02114 #endif
02115 
02116     edt_x_reset(edt_p, ep->xtype);
02117 }
02118 
02119 #ifndef _KERNEL
02120 
02141 int
02142 edt_parse_esn(char *str, Edt_embinfo *ei)
02143 {
02144     unsigned int i,j=0;
02145     int n;
02146     int nfields=0;
02147     char sn[128], pn[128], ifx[128], rev[128], clock[128], opt[128];
02148     char tmpstr[128];
02149 
02150     edt_zero(ei,sizeof(*ei));
02151 
02152     sn[0] = pn[0] = clock[0] = opt[0] = ifx[0] = '\0';
02153 
02154     for (i=0; i<strlen(str); i++)
02155     {
02156         tmpstr[j++] = str[i];
02157         if (str[i] == ':')
02158         {
02159             ++nfields;
02160             if (str[i+1] == ':') /* insert space if empty field */
02161                 tmpstr[j++] = ' ';
02162         }
02163     }
02164     tmpstr[j] = '\0';
02165 
02166     if (nfields < 4)
02167         return -1;
02168 
02169 
02170     n = sscanf(tmpstr, "%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:", sn, pn, clock, opt, rev, ifx);
02171 
02172     /* first pass we had 10-digit p/ns; still may be some around that have that */
02173     if (strlen(sn) > 10)
02174         sn[10] = '\0';
02175 
02176     if ((strlen(pn) > 10) || (strlen(opt) > 10) || !isdigit_str(clock))
02177         return -1;
02178 
02179     if (n < 4)
02180         return -1;
02181 
02182     if (n < 5)
02183         rev[0] = '\0';
02184 
02185     if (n < 6)
02186         ifx[0] = '\0';
02187 
02188     strcpy(ei->sn, sn);
02189     strcpy(ei->pn, pn);
02190     strcpy(ei->opt, opt);
02191     strcpy(ei->ifx, ifx);
02192     ei->clock = edt_strtol(clock,0,0);
02193     ei->rev = edt_strtol(rev,0,0);
02194 
02195     return 0;
02196 }
02197 
02198 #endif

Generated on Mon Mar 21 14:14:40 2011 by  doxygen 1.4.7