[BACK]Return to if_prom.c CVS log [TXT][DIR] Up to [local] / sys / arch / alpha / stand / netboot

Annotation of sys/arch/alpha/stand/netboot/if_prom.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_prom.c,v 1.3 1997/05/05 06:02:01 millert Exp $     */
                      2: /*     $NetBSD: if_prom.c,v 1.9 1997/04/06 08:41:26 cgd Exp $  */
                      3:
                      4: /*
                      5:  * Copyright (c) 1997 Christopher G. Demetriou.  All rights reserved.
                      6:  * Copyright (c) 1993 Adam Glass.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by Adam Glass.
                     19:  * 4. The name of the Author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include <sys/param.h>
                     36: #include <sys/types.h>
                     37:
                     38: #include <netinet/in.h>
                     39: #include <netinet/in_systm.h>
                     40:
                     41: #include <include/rpb.h>
                     42: #include <include/prom.h>
                     43:
                     44: #include <lib/libkern/libkern.h>
                     45: #include <lib/libsa/netif.h>
                     46: #include <lib/libsa/stand.h>
                     47:
                     48: #include "stand/bbinfo.h"
                     49:
                     50: int prom_probe();
                     51: int prom_match();
                     52: void prom_init();
                     53: int prom_get();
                     54: int prom_put();
                     55: void prom_end();
                     56:
                     57: extern struct netif_stats      prom_stats[];
                     58:
                     59: struct netif_dif prom_ifs[] = {
                     60: /*     dif_unit        dif_nsel        dif_stats       dif_private     */
                     61: {      0,              1,              &prom_stats[0], 0,              },
                     62: };
                     63:
                     64: struct netif_stats prom_stats[NENTS(prom_ifs)];
                     65:
                     66: struct netbbinfo netbbinfo = {
                     67:        0xfeedbabedeadbeef,                     /* magic number */
                     68:        0,                                      /* set */
                     69:        0, 0, 0, 0, 0, 0,                       /* ether address */
                     70:        0,                                      /* force */
                     71:        { 0, },                                 /* pad2 */
                     72:        0,                                      /* cksum */
                     73:        0xfeedbeefdeadbabe,                     /* magic number */
                     74: };
                     75:
                     76: struct netif_driver prom_netif_driver = {
                     77:        "prom",                 /* netif_bname */
                     78:        prom_match,             /* netif_match */
                     79:        prom_probe,             /* netif_probe */
                     80:        prom_init,              /* netif_init */
                     81:        prom_get,               /* netif_get */
                     82:        prom_put,               /* netif_put */
                     83:        prom_end,               /* netif_end */
                     84:        prom_ifs,               /* netif_ifs */
                     85:        NENTS(prom_ifs)         /* netif_nifs */
                     86: };
                     87:
                     88: int netfd, broken_firmware;
                     89:
                     90: int
                     91: prom_match(nif, machdep_hint)
                     92:        struct netif *nif;
                     93:        void *machdep_hint;
                     94: {
                     95:
                     96:        return (1);
                     97: }
                     98:
                     99: int
                    100: prom_probe(nif, machdep_hint)
                    101:        struct netif *nif;
                    102:        void *machdep_hint;
                    103: {
                    104:
                    105:        return 0;
                    106: }
                    107:
                    108: int
                    109: prom_put(desc, pkt, len)
                    110:        struct iodesc *desc;
                    111:        void *pkt;
                    112:        int len;
                    113: {
                    114:
                    115:        prom_write(netfd, len, pkt, 0);
                    116:
                    117:        return len;
                    118: }
                    119:
                    120:
                    121: int
                    122: prom_get(desc, pkt, len, timeout)
                    123:        struct iodesc *desc;
                    124:        void *pkt;
                    125:        int len;
                    126:        time_t timeout;
                    127: {
                    128:        prom_return_t ret;
                    129:        time_t t;
                    130:        int cc;
                    131:        char hate[2000];
                    132:
                    133:        t = getsecs();
                    134:        cc = 0;
                    135:        while (((getsecs() - t) < timeout) && !cc) {
                    136:                if (broken_firmware)
                    137:                        ret.bits = prom_read(netfd, 0, hate, 0);
                    138:                else
                    139:                        ret.bits = prom_read(netfd, sizeof hate, hate, 0);
                    140:                if (ret.u.status == 0)
                    141:                        cc = ret.u.retval;
                    142:        }
                    143:        if (broken_firmware)
                    144:                cc = min(cc, len);
                    145:        else
                    146:                cc = len;
                    147:        bcopy(hate, pkt, cc);
                    148:
                    149:        return cc;
                    150: }
                    151:
                    152: extern char *strchr();
                    153:
                    154: void
                    155: prom_init(desc, machdep_hint)
                    156:        struct iodesc *desc;
                    157:        void *machdep_hint;
                    158: {
                    159:        prom_return_t ret;
                    160:        char devname[64];
                    161:        int devlen, i, netbbinfovalid;
                    162:        char *enet_addr;
                    163:        u_int64_t *qp, csum;
                    164:
                    165:        broken_firmware = 0;
                    166:
                    167:        csum = 0;
                    168:        for (i = 0, qp = (u_int64_t *)&netbbinfo;
                    169:            i < (sizeof netbbinfo / sizeof (u_int64_t)); i++, qp++)
                    170:                csum += *qp;
                    171:        netbbinfovalid = (csum == 0);
                    172:        if (netbbinfovalid)
                    173:                netbbinfovalid = netbbinfo.set;
                    174:
                    175: #if 0
                    176:        printf("netbbinfo ");
                    177:        if (!netbbinfovalid)
                    178:                printf("invalid\n");
                    179:        else
                    180:                printf("valid: force = %d, ea = %s\n", netbbinfo.force,
                    181:                    ether_sprintf(netbbinfo.ether_addr));
                    182: #endif
                    183:
                    184:        ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname));
                    185:        devlen = ret.u.retval;
                    186:
                    187:        /* Ethernet address is the 9th component of the booted_dev string. */
                    188:        enet_addr = devname;
                    189:        for (i = 0; i < 8; i++) {
                    190:                enet_addr = strchr(enet_addr, ' ');
                    191:                if (enet_addr == NULL) {
                    192:                        printf("boot: boot device name does not contain ethernet address.\n");
                    193:                        goto punt;
                    194:                }
                    195:                enet_addr++;
                    196:        }
                    197:        if (enet_addr != NULL) {
                    198:                int hv, lv;
                    199:
                    200: #define        dval(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
                    201:                 (((c) >= 'A' && (c) <= 'F') ? (10 + (c) - 'A') : \
                    202:                  (((c) >= 'a' && (c) <= 'f') ? (10 + (c) - 'a') : -1)))
                    203:
                    204:                for (i = 0; i < 6; i++) {
                    205:                        hv = dval(*enet_addr); enet_addr++;
                    206:                        lv = dval(*enet_addr); enet_addr++;
                    207:                        enet_addr++;
                    208:
                    209:                        if (hv == -1 || lv == -1) {
                    210:                                printf("boot: boot device name contains bogus ethernet address.\n");
                    211:                                goto punt;
                    212:                        }
                    213:
                    214:                        desc->myea[i] = (hv << 4) | lv;
                    215:                }
                    216: #undef dval
                    217:        }
                    218:
                    219:        if (netbbinfovalid && netbbinfo.force) {
                    220:                printf("boot: using hard-coded ethernet address (forced).\n");
                    221:                bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea);
                    222:        }
                    223:
                    224: gotit:
                    225:        printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea));
                    226:
                    227:        ret.bits = prom_open(devname, devlen + 1);
                    228:        if (ret.u.status) {
                    229:                printf("prom_init: open failed: %d\n", ret.u.status);
                    230:                goto reallypunt;
                    231:        }
                    232:        netfd = ret.u.retval;
                    233:        return;
                    234:
                    235: punt:
                    236:        broken_firmware = 1;
                    237:        if (netbbinfovalid) {
                    238:                printf("boot: using hard-coded ethernet address.\n");
                    239:                bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea);
                    240:                goto gotit;
                    241:        }
                    242:
                    243: reallypunt:
                    244:        printf("\n");
                    245:        printf("Boot device name was: \"%s\"\n", devname);
                    246:        printf("\n");
                    247:        printf("Your firmware may be too old to network-boot OpenBSD/Alpha,\n");
                    248:        printf("or you might have to hard-code an ethernet address into\n");
                    249:        printf("your network boot block with setnetbootinfo(8).\n");
                    250:        halt();
                    251: }
                    252:
                    253: void
                    254: prom_end(nif)
                    255:        struct netif *nif;
                    256: {
                    257:
                    258:        prom_close(netfd);
                    259: }

CVSweb