[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     ! 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