Annotation of Net2/arch/vax/if/if_hy.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * This code is derived from software contributed to Berkeley by
        !             6:  * Tektronix Inc.
        !             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 the University of
        !            19:  *     California, Berkeley and its contributors.
        !            20:  * 4. Neither the name of the University nor the names of its contributors
        !            21:  *    may be used to endorse or promote products derived from this software
        !            22:  *    without specific prior written permission.
        !            23:  *
        !            24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            34:  * SUCH DAMAGE.
        !            35:  *
        !            36:  *     @(#)if_hy.c     7.7 (Berkeley) 12/16/90
        !            37:  */
        !            38: 
        !            39: /*
        !            40:  * 4.2 BSD Unix Kernel - Vax Network Interface Support
        !            41:  *
        !            42:  * $Header: if_hy.c,v 10.1 84/07/22 21:02:56 steveg Exp $
        !            43:  * $Locker:  $
        !            44:  *
        !            45:  * Modifications from Berkeley 4.2 BSD
        !            46:  * Copyright (c) 1983, Tektronix Inc.
        !            47:  * All Rights Reserved
        !            48:  *
        !            49:  * $Log:       if_hy.c,v $
        !            50:  *     Revision 10.1  84/07/22  21:02:56  steveg
        !            51:  *     define PI13 (moved from if_hyreg.h, somehow got dropped in the process)
        !            52:  *     rework hywatch to check for power fails first
        !            53:  *     
        !            54:  *     Revision 10.0  84/06/30  19:54:27  steveg
        !            55:  *     Big Build
        !            56:  *     
        !            57:  *     Revision 3.17  84/06/20  19:20:28  steveg
        !            58:  *     increment hy_ntime in hywatch
        !            59:  *     print out state name, csr, last command, and hy_flags when watchdog timer
        !            60:  *     expires
        !            61:  *     
        !            62:  *     Revision 3.16  84/06/20  19:09:34  steveg
        !            63:  *     turn on continuous logging by default
        !            64:  *     
        !            65:  *     Revision 3.15  84/05/30  22:19:09  steveg
        !            66:  *     changes to reflect new layout ot statistics data
        !            67:  *     
        !            68:  *     Revision 3.14  84/05/30  19:25:15  steveg
        !            69:  *     move driver states to if_hy.h so log printing programs can use them
        !            70:  *     
        !            71:  *     Revision 3.13  84/05/30  17:13:26  steveg
        !            72:  *     make it compile
        !            73:  *     
        !            74:  *     Revision 3.12  84/05/30  13:46:16  steveg
        !            75:  *     rework logging
        !            76:  *     
        !            77:  *     Revision 3.11  84/05/18  19:35:02  steveg
        !            78:  *     clear IFF_RUNNING and IFF_UP on unibus reset to force resource allocation
        !            79:  *     by the init routine
        !            80:  *     
        !            81:  *     Revision 3.10  84/05/04  12:14:44  steveg
        !            82:  *     more rework to make it actually work under 4.2
        !            83:  *     
        !            84:  *     Revision 3.9  84/05/01  23:34:52  steveg
        !            85:  *     fix typo so it compiles (unit -> ui->ui_unit)
        !            86:  *     
        !            87:  *     Revision 3.8  84/05/01  23:18:30  steveg
        !            88:  *     changes after talking with rickk
        !            89:  *     - check power off more closely
        !            90:  *     - support remote loopback through A710 adapters
        !            91:  *     - IMPLINK -> HYLINK
        !            92:  *     - return EHOSTUNREACH on hyroute failure
        !            93:  *     - bump if_collisions on abnormal interrupts that aren't input or output
        !            94:  *     
        !            95:  *
        !            96:  */
        !            97: 
        !            98: 
        !            99: #include "hy.h"
        !           100: #if NHY > 0
        !           101: 
        !           102: /*
        !           103:  * Network Systems Copropration Hyperchanel interface
        !           104:  */
        !           105: #include "../include/pte.h"
        !           106: 
        !           107: #include "sys/param.h"
        !           108: #include "sys/systm.h"
        !           109: #include "sys/mbuf.h"
        !           110: #include "sys/buf.h"
        !           111: #include "sys/protosw.h"
        !           112: #include "sys/socket.h"
        !           113: #include "sys/vmmac.h"
        !           114: #include "sys/errno.h"
        !           115: #include "sys/time.h"
        !           116: #include "sys/kernel.h"
        !           117: #include "sys/ioctl.h"
        !           118: 
        !           119: #include "net/if.h"
        !           120: #include "net/netisr.h"
        !           121: #include "net/route.h"
        !           122: 
        !           123: #ifdef INET
        !           124: #include "netinet/in.h"
        !           125: #include "netinet/in_systm.h"
        !           126: #include "netinet/in_var.h"
        !           127: #include "netinet/ip.h"
        !           128: #endif
        !           129: 
        !           130: #include "../include/cpu.h"
        !           131: #include "../include/mtpr.h"
        !           132: #include "../uba/ubareg.h"
        !           133: #include "../uba/ubavar.h"
        !           134: 
        !           135: /*
        !           136:  * configuration specific paramters
        !           137:  *     - change as appropriate for particular installaions
        !           138:  */
        !           139: #define        HYROUTE
        !           140: #define        HYELOG
        !           141: #define        HYLOG
        !           142: #define        HYMTU   1100
        !           143: #define PI13
        !           144: 
        !           145: #ifdef DEBUG
        !           146: #define        HYLOG
        !           147: #endif
        !           148: 
        !           149: #include "if_hy.h"
        !           150: #include "if_hyreg.h"
        !           151: #include "if_uba.h"
        !           152: 
        !           153: int    hyprobe(), hyattach(), hyinit(), hyioctl();
        !           154: int    hyoutput(), hyreset(), hywatch();
        !           155: struct uba_device *hyinfo[NHY];
        !           156: u_short hystd[] = { 0772410, 0 };
        !           157: struct uba_driver hydriver =
        !           158:        { hyprobe, 0, hyattach, 0, hystd, "hy", hyinfo };
        !           159: 
        !           160: /*
        !           161:  * Hyperchannel software status per interface.
        !           162:  *
        !           163:  * Each interface is referenced by a network interface structure,
        !           164:  * hy_if, which the routing code uses to locate the interface.
        !           165:  * This structure contains the output queue for the interface, its address, ...
        !           166:  * We also have, for each interface, a UBA interface structure, which
        !           167:  * contains information about the UNIBUS resources held by the interface:
        !           168:  * map registers, buffered data paths, etc.  Information is cached in this
        !           169:  * structure for use by the if_uba.c routines in running the interface
        !           170:  * efficiently.
        !           171:  */
        !           172: struct hy_softc {
        !           173:        struct  ifnet hy_if;            /* network-visible interface */
        !           174:        struct  ifuba hy_ifuba;         /* UNIBUS resources */
        !           175:        short   hy_flags;               /* flags */
        !           176:        short   hy_state;               /* driver state */
        !           177:        u_short hy_host;                /* local host number */
        !           178:        struct  in_addr hy_addr;        /* internet address */
        !           179:        int     hy_olen;                /* packet length on output */
        !           180:        int     hy_lastwcr;             /* last command's word count */
        !           181:        short   hy_savedstate;          /* saved for reissue after status */
        !           182:        short   hy_savedcmd;            /* saved command for reissue */
        !           183:        int     hy_savedcount;          /* saved byte count for reissue */
        !           184:        int     hy_savedaddr;           /* saved unibus address for reissue */
        !           185:        int     hy_ntime;               /* number of timeouts since last cmd */
        !           186:        int     hy_retry;               /* retry counter */
        !           187:        struct  hy_stat hy_stat;        /* statistics */
        !           188:        struct  hy_status hy_status;    /* status */
        !           189: } hy_softc[NHY];
        !           190: 
        !           191: #ifdef HYELOG
        !           192: u_long hy_elog[HYE_SIZE];
        !           193: #endif
        !           194: 
        !           195: #ifdef HYLOG
        !           196: struct hy_log hy_log;
        !           197: #endif
        !           198: 
        !           199: #ifdef HYROUTE
        !           200: struct hy_route hy_route[NHY];
        !           201: #endif
        !           202: 
        !           203: #ifdef DEBUG
        !           204: #define printL printf
        !           205: #define printD if (hy_debug_flag) printf
        !           206: int    hy_debug_flag = 0;
        !           207: /*
        !           208:  * hy_nodebug bit 0x01 set hy_debug_flag on hycancel
        !           209:  * hy_nodebug bit 0x02 set hy_debug_flag on command reissue
        !           210:  * hy_nodebug bit 0x04 set hy_debug_flag on abnormal interrupt
        !           211:  */
        !           212: int    hy_nodebug = 0x0;
        !           213: #endif
        !           214: 
        !           215: #define SCANINTERVAL   10      /* seconds */
        !           216: #define MAXINTERVAL    20      /* seconds (max action) */
        !           217: 
        !           218: /*
        !           219:  * Cause a device interrupt.  This code uses a buffer starting at
        !           220:  * location zero on the unibus (which is already mapped by the
        !           221:  * autoconfigure code in the kernel).
        !           222:  */
        !           223: hyprobe(reg)
        !           224:        caddr_t reg;
        !           225: {
        !           226:        register int br, cvec;          /* r11, r10 value-result */
        !           227:        register struct hydevice *addr = (struct hydevice *) reg;
        !           228: 
        !           229: #ifdef lint
        !           230:        br = 0; cvec = br; br = cvec;
        !           231:        hyint(0);
        !           232: #endif
        !           233:        /*
        !           234:         * request adapter status to a buffer starting at unibus location 0
        !           235:         */
        !           236:        addr->hyd_bar = 0;
        !           237:        addr->hyd_wcr = -((sizeof(struct hy_status) + 1) >> 1);
        !           238:        addr->hyd_dbuf = HYF_STATUS;
        !           239: #ifdef PI13
        !           240:        addr->hyd_csr |= S_GO | S_IE | S_IATTN;
        !           241: #else
        !           242:        addr->hyd_csr |= S_GO | S_IE;
        !           243: #endif
        !           244:        DELAY(10000);
        !           245: #ifdef PI13
        !           246:        addr->hyd_csr |= S_CLRINT;      /* clear any stacked interrupts */
        !           247: #endif
        !           248:        addr->hyd_csr &= ~(S_IE | S_CLRINT);    /* disable further interrupts */
        !           249:        return(sizeof(struct hydevice));
        !           250: }
        !           251: 
        !           252: /*
        !           253:  * Interface exists: make available by filling in network interface
        !           254:  * record.  System will initialize the interface when it is ready
        !           255:  * to accept packets.
        !           256:  */
        !           257: hyattach(ui)
        !           258:        struct uba_device *ui;
        !           259: {
        !           260:        register struct hy_softc *is = &hy_softc[ui->ui_unit];
        !           261:        register struct ifnet *ifp = &is->hy_if;
        !           262: 
        !           263:        ifp->if_unit = ui->ui_unit;
        !           264:        ifp->if_name = "hy";
        !           265:        ifp->if_mtu = HYMTU;
        !           266:        is->hy_state = STARTUP;         /* don't allow state transitions yet */
        !           267:        ifp->if_init = hyinit;
        !           268:        ifp->if_ioctl = hyioctl;
        !           269:        ifp->if_output = hyoutput;
        !           270:        ifp->if_reset = hyreset;
        !           271:        ifp->if_watchdog = hywatch;
        !           272:        ifp->if_timer = SCANINTERVAL;
        !           273:        is->hy_ifuba.ifu_flags = UBA_CANTWAIT;
        !           274: #ifdef notdef
        !           275:        is->hy_ifuba.ifu_flags |= UBA_NEEDBDP;
        !           276: #endif
        !           277:        if_attach(ifp);
        !           278: }
        !           279: 
        !           280: /*
        !           281:  * Reset of interface after UNIBUS reset.
        !           282:  * If interface is on specified uba, reset its state.
        !           283:  */
        !           284: hyreset(unit, uban)
        !           285:        int unit, uban;
        !           286: {
        !           287:        register struct uba_device *ui;
        !           288:        register struct hy_softc *is;
        !           289: 
        !           290:        if (unit >= NHY || (ui = hyinfo[unit]) == 0 || ui->ui_alive == 0 ||
        !           291:          ui->ui_ubanum != uban)
        !           292:                return;
        !           293:        printf(" hy%d", unit);
        !           294:        is = &hy_softc[unit];           /* force unibus resource allocation */
        !           295:        is->hy_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
        !           296:        hyinit(unit);
        !           297: }
        !           298: 
        !           299: /*
        !           300:  * Initialization of interface; clear recorded pending
        !           301:  * operations, and reinitialize UNIBUS usage.
        !           302:  */
        !           303: hyinit(unit)
        !           304:        int unit;
        !           305: {
        !           306:        register struct hy_softc *is = &hy_softc[unit];
        !           307:        register struct uba_device *ui = hyinfo[unit];
        !           308:        register struct mbuf *m;
        !           309:        int s;
        !           310: 
        !           311:        if (is->hy_if.if_addrlist == 0)         /* address still unknown */
        !           312:                return;
        !           313:        if (is->hy_if.if_flags & IFF_RUNNING)   /* just reset the device */
        !           314:                goto justreset;
        !           315:        if (if_ubainit(&is->hy_ifuba, ui->ui_ubanum,
        !           316:            sizeof (struct hym_hdr), (int)btoc(HYMTU)) == 0) { 
        !           317: #ifdef DEBUG
        !           318:                if (hy_nodebug & 4)
        !           319:                        hy_debug_flag = 1;
        !           320: #endif
        !           321:                printf("hy%d: can't initialize\n", unit);
        !           322:                is->hy_if.if_flags &= ~IFF_UP;
        !           323:                return;
        !           324:        }
        !           325:        is->hy_if.if_flags |= IFF_RUNNING;
        !           326: 
        !           327: justreset:
        !           328:        /*
        !           329:         * remove any left over outgoing messages, reset the hardware and
        !           330:         * start the state machine
        !           331:         */
        !           332:        s = splimp();
        !           333: #ifdef HYLOG
        !           334:        hylog(HYL_RESET, 0, (char *)0);
        !           335: #endif
        !           336:        is->hy_state = IDLE;
        !           337:        is->hy_flags = RQ_STATUS | RQ_STATISTICS | RQ_MARKUP;
        !           338:        is->hy_retry = 0;
        !           339:        for(;;) {
        !           340:                IF_DEQUEUE(&is->hy_if.if_snd, m);
        !           341:                if (m != NULL)
        !           342:                        m_freem(m);
        !           343:                else
        !           344:                        break;
        !           345:        }
        !           346:        hycancel(ui);           /* also bumps the state machine */
        !           347:        splx(s);
        !           348: }
        !           349: 
        !           350: /*
        !           351:  * Issue a command to the adapter
        !           352:  */
        !           353: hystart(ui, cmd, count, ubaddr)
        !           354:        struct uba_device *ui;
        !           355:        int cmd, count, ubaddr;
        !           356: {
        !           357:        register struct hy_softc *is = &hy_softc[ui->ui_unit];
        !           358:        register struct hydevice *addr = (struct hydevice *)ui->ui_addr;
        !           359: 
        !           360: #ifdef DEBUG
        !           361:        printD("hy%d: hystart cmd = 0x%x count=%d ubaddr=0x%x\n",
        !           362:                ui->ui_unit, cmd, count, ubaddr);
        !           363:        printD("hy%d: - csr = 0x%b, bar = 0x%x, wcr = 0x%x\n",
        !           364:                ui->ui_unit, addr->hyd_csr, HY_CSR_BITS, addr->hyd_bar,
        !           365:                addr->hyd_wcr);
        !           366: #endif
        !           367:        if (((is->hy_flags & RQ_REISSUE) == 0) &&
        !           368:          (cmd != HYF_STATUS) && (cmd != HYF_END_OP) && (cmd != HYF_RSTATS)) {
        !           369:                is->hy_savedstate = is->hy_state;
        !           370:                is->hy_savedcmd = cmd;
        !           371:                is->hy_savedcount = count;
        !           372:                is->hy_savedaddr = ubaddr;
        !           373:        }
        !           374: #ifdef PI13
        !           375:        if (addr->hyd_csr & S_POWEROFF) {
        !           376:                printf("hy%d: \"Soft\" Adapter Power Failure (hystart)\n", ui->ui_unit);
        !           377:                addr->hyd_csr |= S_POWEROFF;
        !           378:                DELAY(100);
        !           379:                if (addr->hyd_csr & S_POWEROFF) {
        !           380:                        printf( "hy%d: \"Hard\" Adapter Power Failure, Network Shutdown (hystart)\n", ui->ui_unit);
        !           381:                        if_down(&is->hy_if);
        !           382:                        is->hy_if.if_flags &= ~IFF_UP;
        !           383:                        is->hy_state = STARTUP;
        !           384:                } else {
        !           385:                        printf("hy%d: Adapter Power Restored (hystart)\n", ui->ui_unit);
        !           386:                }
        !           387:                return;
        !           388:        }
        !           389: #endif
        !           390:        addr->hyd_bar = ubaddr & 0xffff;
        !           391:        addr->hyd_wcr = is->hy_lastwcr = -((count+1) >> 1);
        !           392:        addr->hyd_dbuf = cmd;
        !           393: #ifdef PI13
        !           394:        addr->hyd_csr = ((ubaddr >> XBASHIFT) & S_XBA) | S_GO | S_IE | S_IATTN;
        !           395: #else
        !           396:        addr->hyd_csr = ((ubaddr >> XBASHIFT) & S_XBA) | S_GO | S_IE;
        !           397: #endif
        !           398: #ifdef DEBUG
        !           399:        printD("hy%d: exit hystart - csr = 0x%b, bar = 0x%x, wcr = 0x%x\n",
        !           400:                ui->ui_unit, addr->hyd_csr, HY_CSR_BITS, addr->hyd_bar,
        !           401:                addr->hyd_wcr);
        !           402: #endif
        !           403: #ifdef HYLOG
        !           404:        {
        !           405:                struct {
        !           406:                        u_char  hcmd;
        !           407:                        u_char  hstate;
        !           408:                        short   hcount;
        !           409:                } hcl;
        !           410: 
        !           411:                hcl.hcmd = cmd;
        !           412:                hcl.hstate = is->hy_state;
        !           413:                hcl.hcount = count;
        !           414:                hylog(HYL_CMD, sizeof(hcl), (char *)&hcl);
        !           415:        }
        !           416: #endif
        !           417:        is->hy_ntime = 0;
        !           418: }
        !           419: 
        !           420: int hyint_active = 0;          /* set during hy interrupt */
        !           421: /*
        !           422:  * Hyperchannel interface interrupt.
        !           423:  *
        !           424:  * An interrupt can occur for many reasons.  Examine the status of
        !           425:  * the hyperchannel status bits to determine what to do next.
        !           426:  *
        !           427:  * If input error just drop packet.
        !           428:  * Otherwise purge input buffered data path and examine 
        !           429:  * packet to determine type.  Othewise decapsulate
        !           430:  * packet based on type and pass to type specific higher-level
        !           431:  * input routine.
        !           432:  */
        !           433: hyint(unit)
        !           434:        int unit;
        !           435: {
        !           436:        register struct hy_softc *is = &hy_softc[unit];
        !           437:        register struct uba_device *ui = hyinfo[unit];
        !           438:        register struct hydevice *addr = (struct hydevice *)ui->ui_addr;
        !           439: 
        !           440:        if (hyint_active)
        !           441:                panic("RECURSIVE HYPERCHANNEL INTERRUPT");
        !           442:        hyint_active++;
        !           443: #ifdef DEBUG
        !           444:        printD("hy%d: hyint enter - csr = 0x%b, bar = 0x%x, wcr = 0x%x\n",
        !           445:                unit, addr->hyd_csr, HY_CSR_BITS, addr->hyd_bar, addr->hyd_wcr);
        !           446: #endif
        !           447: #ifdef HYLOG
        !           448: logit:
        !           449:        {
        !           450:                struct {
        !           451:                        u_char  hstate;
        !           452:                        u_char  hflags;
        !           453:                        short   hcsr;
        !           454:                        short   hwcr;
        !           455:                } hil;
        !           456:                hil.hstate = is->hy_state;
        !           457:                hil.hflags = is->hy_flags;
        !           458:                hil.hcsr = addr->hyd_csr;
        !           459:                hil.hwcr = addr->hyd_wcr;
        !           460:                hylog(HYL_INT, sizeof(hil), (char *)&hil);
        !           461:        }
        !           462: #endif
        !           463:        if (HYS_ERROR(addr) && ((addr->hyd_csr & S_ATTN) == 0)) {
        !           464:                /*
        !           465:                 * Error bit set, some sort of error in the interface.
        !           466:                 *
        !           467:                 * The adapter sets attn on command completion so that's not
        !           468:                 * a real error even though the interface considers it one.
        !           469:                 */
        !           470: #ifdef DEBUG
        !           471:                if (hy_nodebug & 4)
        !           472:                        hy_debug_flag = 1;
        !           473: #endif
        !           474:                printf("csr = 0x%b\nbar = 0x%x\nwcr = 0x%x\n",
        !           475:                        addr->hyd_csr, HY_CSR_BITS, addr->hyd_bar,
        !           476:                        addr->hyd_wcr);
        !           477:                if (addr->hyd_csr & S_NEX) {
        !           478:                        printf("hy%d: NEX - Non Existant Memory\n", unit);
        !           479: #ifdef PI13
        !           480:                        addr->hyd_csr |= S_NEX;  /* as per PI13 manual */
        !           481: #else
        !           482:                        addr->hyd_csr &= ~S_NEX;
        !           483: #endif
        !           484:                        hycancel(ui);
        !           485: #ifdef PI13
        !           486:                } else if (addr->hyd_csr & S_POWEROFF) {
        !           487:                        printf("hy%d: \"Soft\" Adapter Power Failure (hyint)\n", unit);
        !           488:                        addr->hyd_csr |= S_POWEROFF;
        !           489:                        DELAY(100);
        !           490:                        if (addr->hyd_csr & S_POWEROFF) {
        !           491:                                printf( "hy%d: \"Hard\" Adapter Power Failure, Network Shutdown (hyint)\n", unit);
        !           492:                                if_down(&is->hy_if);
        !           493:                                is->hy_if.if_flags &= ~IFF_UP;
        !           494:                                is->hy_state = STARTUP;
        !           495:                        } else {
        !           496:                                printf("hy%d: Adapter Power Restored (hyint)\n", unit);
        !           497:                        }
        !           498: #endif
        !           499:                } else {
        !           500:                        printf("hy%d:  BAR overflow\n", unit);
        !           501:                        hycancel(ui);
        !           502:                }
        !           503:        } else if (HYS_NORMAL(addr)) {
        !           504:                /*
        !           505:                 * Normal interrupt, bump state machine unless in state
        !           506:                 * waiting and no data present (assumed to be word count
        !           507:                 * zero interrupt or other hardware botch).
        !           508:                 */
        !           509:                if (is->hy_state != WAITING || HYS_RECVDATA(addr))
        !           510:                        hyact(ui);
        !           511:        } else if (HYS_ABNORMAL(addr)) {
        !           512:                /*
        !           513:                 * Abnormal termination.
        !           514:                 * bump error counts, retry the last function
        !           515:                 * 'MAXRETRY' times before kicking the bucket.
        !           516:                 *
        !           517:                 * Don't reissue the cmd if in certain states, abnormal
        !           518:                 * on a reissued cmd or max retry exceeded.
        !           519:                 */
        !           520: #ifdef HYLOG
        !           521:                if (hy_log.hyl_enable != hy_log.hyl_onerr) {
        !           522:                        hy_log.hyl_enable = hy_log.hyl_onerr;
        !           523:                        goto logit;
        !           524:                }
        !           525: #endif
        !           526: #ifdef DEBUG
        !           527:                if (hy_nodebug & 4)
        !           528:                        hy_debug_flag = 1;
        !           529:                printD("hy%d: abnormal interrupt, driver state \"%s\" (%d)\n",
        !           530:                        unit, hy_state_names[is->hy_state], is->hy_state);
        !           531:                printD("\tflags 0x%x olen %d lastwcr %d retry %d\n",
        !           532:                        is->hy_flags, is->hy_olen, is->hy_lastwcr, is->hy_retry);
        !           533:                printD("\tsaved: state %d count %d cmd 0x%x ptr 0x%x\n",
        !           534:                        is->hy_savedstate, is->hy_savedcount,
        !           535:                        is->hy_savedaddr, is->hy_savedcmd);
        !           536: #endif
        !           537: #ifdef PI13
        !           538:                addr->hyd_csr &= ~S_C;  /* clear the damned PI-13 */
        !           539: #endif
        !           540:                if (is->hy_state == XMITSENT || is->hy_state == XMITDATASENT)
        !           541:                        is->hy_if.if_oerrors++;
        !           542:                else if (is->hy_state == RECVSENT || is->hy_state == RECVDATASENT)
        !           543:                        is->hy_if.if_ierrors++;
        !           544:                else
        !           545:                        is->hy_if.if_collisions++;      /* other errors */
        !           546:                if (is->hy_state == XMITDATASENT ||
        !           547:                    is->hy_state == RECVSENT ||
        !           548:                    is->hy_state == RECVDATASENT ||
        !           549:                    (is->hy_flags & RQ_REISSUE) != 0 || is->hy_retry > MAXRETRY)
        !           550:                        hycancel(ui);
        !           551:                else {
        !           552: #ifdef DEBUG
        !           553:                        if (hy_nodebug & 2)
        !           554:                                hy_debug_flag = 1;
        !           555: #endif
        !           556:                        is->hy_retry++;
        !           557:                        is->hy_flags |= RQ_ENDOP | RQ_STATUS | RQ_REISSUE;
        !           558:                        is->hy_state = IDLE;
        !           559:                        hyact(ui);
        !           560:                }
        !           561:        } else {
        !           562:                /*
        !           563:                 * Interrupt is neither normal, abnormal, or interface error.
        !           564:                 * Ignore it. It's either stacked or a word count 0.
        !           565:                 */
        !           566: #ifdef HYLOG
        !           567:                if (hy_log.hyl_enable != hy_log.hyl_onerr) {
        !           568:                        hy_log.hyl_enable = hy_log.hyl_onerr;
        !           569:                        goto logit;
        !           570:                }
        !           571: #endif
        !           572: #ifdef DEBUG
        !           573:                printD("hy%d: possible stacked interrupt ignored\n", unit);
        !           574: #endif
        !           575:        }
        !           576: #ifdef DEBUG
        !           577:        printD("hy%d: hyint exit\n\n", unit);
        !           578: #endif
        !           579:        hyint_active = 0;
        !           580: 
        !           581: }
        !           582: 
        !           583: int hyoutprint = 0;
        !           584: 
        !           585: /*
        !           586:  * Encapsulate a packet of type family for the local net.
        !           587:  */
        !           588: hyoutput(ifp, m0, dst)
        !           589:        struct ifnet *ifp;
        !           590:        struct mbuf *m0;
        !           591:        struct sockaddr *dst;
        !           592: {
        !           593:        register struct hym_hdr *hym;
        !           594:        register struct mbuf *m;
        !           595:        register char *mp;
        !           596:        int dlen;       /* packet size, incl hardware header, but not sw header */
        !           597:        int error = 0;
        !           598:        int s;
        !           599: 
        !           600:        /*
        !           601:         * Calculate packet length for later deciding whether it will fit
        !           602:         * in a message proper or we also need associated data.
        !           603:         */
        !           604:        dlen = 0;
        !           605:        for (m = m0; m; m = m->m_next)
        !           606:                dlen += m->m_len;
        !           607:        m = m0;
        !           608:        if (dst->sa_family == AF_HYLINK) {      /* don't add header */
        !           609:                dlen -= HYM_SWLEN;
        !           610:                goto headerexists;
        !           611:        }
        !           612: 
        !           613:        /*
        !           614:         * Add the software and hardware hyperchannel headers.
        !           615:         * If there's not enough space in the first mbuf, allocate another.
        !           616:         * If that should fail, drop this sucker.
        !           617:         * No extra space for headers is allocated.
        !           618:         */
        !           619:        mp = mtod(m, char *);   /* save pointer to real message */
        !           620:        M_PREPEND(m, sizeof(struct hym_hdr), M_DONTWAIT);
        !           621:        if (m == 0) {
        !           622:                error = ENOBUFS;
        !           623:                goto bad;
        !           624:        }
        !           625:        dlen += sizeof(struct hym_hdr) - HYM_SWLEN;
        !           626: 
        !           627:        hym = mtod(m, struct hym_hdr *);
        !           628: 
        !           629:        bzero((caddr_t)hym, sizeof(struct hym_hdr));
        !           630: 
        !           631:        switch(dst->sa_family) {
        !           632: 
        !           633: #ifdef INET
        !           634:        case AF_INET: {
        !           635:                int i;
        !           636: 
        !           637:                /*
        !           638:                 * if loopback address, swizzle ip header so when
        !           639:                 * it comes back it looks like it was addressed to us
        !           640:                 */
        !           641:                i = hyroute(ifp, (u_long)in_lnaof(((struct sockaddr_in *)dst)->sin_addr), hym);
        !           642:                if (i < 0)
        !           643:                        goto notfound;
        !           644:                if (i > 0) {
        !           645:                        struct in_addr temp;
        !           646: 
        !           647:                        temp.s_addr = ((struct ip *)mp)->ip_dst.s_addr;
        !           648:                        ((struct ip *)mp)->ip_dst.s_addr = ((struct ip *)mp)->ip_src.s_addr;
        !           649:                        ((struct ip *)mp)->ip_src.s_addr = temp.s_addr;
        !           650:                }
        !           651:                /*
        !           652:                 * If entire packet won't fit in message proper, just
        !           653:                 * send hyperchannel hardware header and ip header in
        !           654:                 * message proper.
        !           655:                 *
        !           656:                 * This insures that the associated data is at least a
        !           657:                 * TCP/UDP header in length and thus prevents potential
        !           658:                 * problems with very short word counts.
        !           659:                 */
        !           660:                if (dlen > MPSIZE)
        !           661:                        hym->hym_mplen = sizeof(struct hy_hdr) + (((struct ip *)mp)->ip_hl << 2);
        !           662:                hym->hym_type = HYLINK_IP;
        !           663:                break;
        !           664:        }
        !           665: #endif
        !           666: 
        !           667:        default:
        !           668:                printf("hy%d: can't handle af%d\n", ifp->if_unit,
        !           669:                        dst->sa_family);
        !           670:                error = EAFNOSUPPORT;
        !           671:                goto drop;
        !           672:        }
        !           673: 
        !           674: 
        !           675: headerexists:
        !           676: 
        !           677:        /*
        !           678:         * insure message proper is below the maximum
        !           679:         */
        !           680:        if (hym->hym_mplen > MPSIZE || (dlen > MPSIZE && hym->hym_mplen == 0))
        !           681:                hym->hym_mplen = MPSIZE;
        !           682: 
        !           683:        hym->hym_from = htons(hy_softc[ifp->if_unit].hy_host);
        !           684:        if (hym->hym_mplen)
        !           685:                hym->hym_ctl |= H_ASSOC;
        !           686:        else
        !           687:                hym->hym_ctl &= ~H_ASSOC;
        !           688:        if (hyoutprint) printf("hy%d: output mplen=%x ctl=%x access=%x to=%x from=%x param=%x type=%x\n",
        !           689:                ifp->if_unit, hym->hym_mplen, hym->hym_ctl,
        !           690:                hym->hym_access, hym->hym_to, hym->hym_from,
        !           691:                hym->hym_param, hym->hym_type);
        !           692: #ifdef DEBUG
        !           693:        printD("hy%d: output mplen=%x ctl=%x access=%x to=%x from=%x param=%x type=%x\n",
        !           694:                ifp->if_unit, hym->hym_mplen, hym->hym_ctl,
        !           695:                hym->hym_access, hym->hym_to, hym->hym_from,
        !           696:                hym->hym_param, hym->hym_type);
        !           697: #endif
        !           698:        s = splimp();
        !           699:        if (IF_QFULL(&ifp->if_snd)) {
        !           700:                IF_DROP(&ifp->if_snd);
        !           701:                error = ENOBUFS;
        !           702:                splx(s);
        !           703:                goto drop;
        !           704:        }
        !           705:        IF_ENQUEUE(&ifp->if_snd, m);
        !           706:        if (hy_softc[ifp->if_unit].hy_state == WAITING)
        !           707:                hyact(hyinfo[ifp->if_unit]);
        !           708:        splx(s);
        !           709:        return (0);
        !           710: notfound:
        !           711:        error = EHOSTUNREACH;
        !           712: drop:
        !           713:        m_freem(m);
        !           714:        return (error);
        !           715: }
        !           716: 
        !           717: int
        !           718: hyroute(ifp, dest, hym)
        !           719:        register struct ifnet *ifp;
        !           720:        u_long dest;
        !           721:        register struct hym_hdr *hym;
        !           722: {
        !           723: #ifdef HYROUTE
        !           724:        register struct hy_route *rt = &hy_route[ifp->if_unit];
        !           725:        register struct hyr_hash *rhash;
        !           726:        register int i;
        !           727: #endif
        !           728: 
        !           729:        hym->hym_param = 0;
        !           730: #ifdef HYROUTE
        !           731:        if (rt->hyr_lasttime != 0) {
        !           732:                i = HYRHASH(dest);
        !           733:                rhash = &rt->hyr_hash[i];
        !           734:                i = 0;
        !           735:                while (rhash->hyr_key != dest) {
        !           736:                        if (rhash->hyr_flags == 0 || i > HYRSIZE)
        !           737:                                return(-1);
        !           738:                        rhash++; i++;
        !           739:                        if (rhash >= &rt->hyr_hash[HYRSIZE])
        !           740:                                rhash = &rt->hyr_hash[0];
        !           741:                }
        !           742:                if (rhash->hyr_flags & HYR_GATE) {
        !           743:                        i = rhash->hyr_nextgate;
        !           744:                        if (i >= rhash->hyr_egate)
        !           745:                                rhash->hyr_nextgate = rhash->hyr_pgate;
        !           746:                        else
        !           747:                                rhash->hyr_nextgate++;
        !           748:                        rhash = &rt->hyr_hash[rt->hyr_gateway[i]];
        !           749:                        if ((rhash->hyr_flags & HYR_DIR) == 0)
        !           750:                                return(-1);
        !           751:                } else if (rhash->hyr_flags & HYR_LOOP) {
        !           752:                        hym->hym_param = H_LOOPBK;      /* adapter loopback */
        !           753:                } else if (rhash->hyr_flags & HYR_RLOOP) {
        !           754:                        hym->hym_param = H_RLOOPBK;     /* A710 remote loopback */
        !           755:                }
        !           756:                hym->hym_ctl = rhash->hyr_ctl;
        !           757:                hym->hym_access = rhash->hyr_access;
        !           758:                hym->hym_to = rhash->hyr_dst;
        !           759:        } else {
        !           760: #endif
        !           761:                hym->hym_ctl = H_XTRUNKS | H_RTRUNKS;
        !           762:                hym->hym_access = 0;
        !           763:                hym->hym_to = htons((u_short)dest);
        !           764:                if (dest & 0x010000)
        !           765:                        hym->hym_param = H_LOOPBK;      /* adapter loopback */
        !           766:                else if (dest & 0x020000)
        !           767:                        hym->hym_param = H_RLOOPBK;     /* A710 remote loopback */
        !           768: #ifdef HYROUTE
        !           769:        }
        !           770: #endif
        !           771: 
        !           772:        if (hym->hym_param == 0)
        !           773:                return(0);
        !           774:        else
        !           775:                return(1);
        !           776: }
        !           777: 
        !           778: hyact(ui)
        !           779:        register struct uba_device *ui;
        !           780: {
        !           781:        register struct hy_softc *is = &hy_softc[ui->ui_unit];
        !           782:        register struct hydevice *addr = (struct hydevice *)ui->ui_addr;
        !           783: 
        !           784: actloop:
        !           785: #ifdef DEBUG
        !           786:        printD("hy%d: hyact, enter state \"%s\"\n", ui->ui_unit,
        !           787:                hy_state_names[is->hy_state]);
        !           788: #endif
        !           789:        switch (is->hy_state) {
        !           790: 
        !           791:        case STARTUP:
        !           792:                goto endintr;
        !           793: 
        !           794:        case IDLE: {
        !           795:                register rq = is->hy_flags;
        !           796: 
        !           797:                if (rq & RQ_STATUS) {
        !           798:                        is->hy_flags &= ~RQ_STATUS;
        !           799:                        is->hy_state = STATSENT;
        !           800:                        hystart(ui, HYF_STATUS, sizeof (is->hy_status),
        !           801:                            is->hy_ifuba.ifu_r.ifrw_info);
        !           802:                } else if (rq & RQ_ENDOP) {
        !           803:                        is->hy_flags &= ~RQ_ENDOP;
        !           804:                        is->hy_state = ENDOPSENT;
        !           805:                        hystart(ui, HYF_END_OP, 0, 0);
        !           806:                } else if (rq & RQ_STATISTICS) {
        !           807:                        is->hy_flags &= ~RQ_STATISTICS;
        !           808:                        is->hy_state = RSTATSENT;
        !           809:                        hystart(ui, HYF_RSTATS, sizeof (is->hy_stat),
        !           810:                            is->hy_ifuba.ifu_r.ifrw_info);
        !           811:                } else if (HYS_RECVDATA(addr)) {
        !           812:                        is->hy_state = RECVSENT;
        !           813:                        is->hy_retry = 0;
        !           814:                        hystart(ui, HYF_INPUTMSG, MPSIZE, is->hy_ifuba.ifu_r.ifrw_info + HYM_SWLEN);
        !           815:                } else if (rq & RQ_REISSUE) {
        !           816:                        is->hy_flags &= ~RQ_REISSUE;
        !           817:                        is->hy_state = is->hy_savedstate;
        !           818: #ifdef DEBUG
        !           819:                        printD("hy%d: reissue cmd=0x%x count=%d",
        !           820:                          ui->ui_unit, is->hy_savedcmd, is->hy_savedcount);
        !           821:                        printD(" ubaddr=0x%x retry=%d\n",
        !           822:                          is->hy_savedaddr, is->hy_retry);
        !           823: #endif
        !           824:                        hystart(ui, is->hy_savedcmd, is->hy_savedcount,
        !           825:                            is->hy_savedaddr);
        !           826:                } else {
        !           827:                        register struct mbuf *m;
        !           828: 
        !           829:                        IF_DEQUEUE(&is->hy_if.if_snd, m);
        !           830:                        if (m != NULL) {
        !           831:                                register struct hym_hdr *hym;
        !           832:                                register int mplen;
        !           833:                                register int cmd;
        !           834: 
        !           835:                                is->hy_state = XMITSENT;
        !           836:                                is->hy_retry = 0;
        !           837:                                hym = mtod(m, struct hym_hdr *);
        !           838: #ifdef HYLOG
        !           839:                                hylog(HYL_XMIT, sizeof(struct hym_hdr),
        !           840:                                    (char *)hym);
        !           841: #endif
        !           842:                                mplen = hym->hym_mplen;
        !           843:                                if (hym->hym_to_adapter == hym->hym_from_adapter)
        !           844:                                        cmd = HYF_XMITLOCMSG;
        !           845:                                else
        !           846:                                        cmd = HYF_XMITMSG;
        !           847: #ifdef DEBUG
        !           848:                                printD("hy%d: hym_hdr = ", ui->ui_unit);
        !           849:                                if (hy_debug_flag)
        !           850:                                        hyprintdata((char *)hym,
        !           851:                                            sizeof (struct hym_hdr));
        !           852: #endif
        !           853:                                is->hy_olen = if_wubaput(&is->hy_ifuba, m) - HYM_SWLEN;
        !           854:                                if (is->hy_ifuba.ifu_flags & UBA_NEEDBDP)
        !           855:                                        UBAPURGE(is->hy_ifuba.ifu_uba,
        !           856:                                                is->hy_ifuba.ifu_w.ifrw_bdp);
        !           857: #ifdef DEBUG
        !           858:                                printD(
        !           859:                "hy%d: sending packet (mplen = %d, hy_olen = %d) data = ",
        !           860:                                        ui->ui_unit, mplen, is->hy_olen);
        !           861:                                if (hy_debug_flag)
        !           862:                                        hyprintdata(
        !           863:                                            is->hy_ifuba.ifu_w.ifrw_addr,
        !           864:                                            is->hy_olen + HYM_SWLEN);
        !           865: #endif
        !           866:                                if (mplen == 0) {
        !           867:                                        is->hy_flags &= ~RQ_XASSOC;
        !           868:                                        mplen = is->hy_olen;
        !           869:                                } else {
        !           870:                                        is->hy_flags |= RQ_XASSOC;
        !           871:                                }
        !           872:                                hystart(ui, cmd, mplen, is->hy_ifuba.ifu_w.ifrw_info + HYM_SWLEN);
        !           873:                        } else if (rq & RQ_MARKDOWN) {
        !           874:                                is->hy_flags &= ~(RQ_MARKUP | RQ_MARKDOWN);
        !           875:                                is->hy_state = MARKPORT;
        !           876:                                is->hy_retry = 0;
        !           877:                                /*
        !           878:                                 * Port number is taken from status data
        !           879:                                 */
        !           880:                                hystart(ui,
        !           881:                                 (int)(HYF_MARKP0|(PORTNUM(&is->hy_status)<<2)),
        !           882:                                 0, 0);
        !           883:                        } else if (rq & RQ_MARKUP) {
        !           884:                                register struct ifnet *ifp = &is->hy_if;
        !           885: 
        !           886:                                is->hy_flags &= ~RQ_MARKUP;
        !           887:                                is->hy_retry = 0;
        !           888:                                /*
        !           889:                                 * Fill in the host number
        !           890:                                 * from the status buffer
        !           891:                                 */
        !           892:                                printf(
        !           893:        "hy%d: unit number 0x%x port %d type %x microcode level 0x%x\n",
        !           894:                                        ui->ui_unit,
        !           895:                                        is->hy_stat.hyc_uaddr,
        !           896:                                        PORTNUM(&is->hy_status),
        !           897:                                        (is->hy_stat.hyc_atype[0]<<8) |
        !           898:                                                is->hy_stat.hyc_atype[1],
        !           899:                                        is->hy_stat.hyc_atype[2]);
        !           900: 
        !           901:                                is->hy_host =
        !           902:                                  (is->hy_stat.hyc_uaddr << 8) |
        !           903:                                        PORTNUM(&is->hy_status);
        !           904:                                ifp->if_flags |= IFF_UP;
        !           905: #ifdef HYLOG
        !           906:                                hylog(HYL_UP, 0, (char *)0);
        !           907: #endif
        !           908:                        } else {
        !           909:                                is->hy_state = WAITING;
        !           910:                                is->hy_retry = 0;
        !           911:                                hystart(ui, HYF_WAITFORMSG, 0, 0);
        !           912:                        }
        !           913:                }
        !           914:                break;
        !           915:        }
        !           916: 
        !           917:        case STATSENT:
        !           918:                bcopy(is->hy_ifuba.ifu_r.ifrw_addr, (caddr_t)&is->hy_status,
        !           919:                  sizeof (struct hy_status));
        !           920: #ifdef DEBUG
        !           921:                printD("hy%d: status - %x %x %x %x %x %x %x %x\n",
        !           922:                        ui->ui_unit, is->hy_status.hys_gen_status,
        !           923:                        is->hy_status.hys_last_fcn,
        !           924:                        is->hy_status.hys_resp_trunk,
        !           925:                        is->hy_status.hys_status_trunk,
        !           926:                        is->hy_status.hys_recd_resp,
        !           927:                        is->hy_status.hys_error,
        !           928:                        is->hy_status.hys_caddr,
        !           929:                        is->hy_status.hys_pad);
        !           930: #endif
        !           931:                is->hy_state = IDLE;
        !           932: #ifdef HYLOG
        !           933:                hylog(HYL_STATUS, sizeof (struct hy_status),
        !           934:                        (char *)&is->hy_status);
        !           935: #endif
        !           936: #ifdef HYELOG
        !           937:                {
        !           938:                        register int i;
        !           939:                        
        !           940:                        i = is->hy_status.hys_error;
        !           941:                        if (i > HYE_MAX)
        !           942:                                i = HYE_MAX;
        !           943:                        switch (is->hy_status.hys_last_fcn) {
        !           944:                                case HYF_XMITLOCMSG:
        !           945:                                        i += HYE_MAX+1; /* fall through */
        !           946:                                case HYF_XMITLSTDATA:
        !           947:                                        i += HYE_MAX+1; /* fall through */
        !           948:                                case HYF_XMITMSG:
        !           949:                                        i += HYE_MAX+1;
        !           950:                        }
        !           951:                        hy_elog[i]++;
        !           952:                }
        !           953: #endif
        !           954:                break;
        !           955: 
        !           956:        case RSTATSENT: {
        !           957:                register struct hy_stat *p =
        !           958:                        (struct hy_stat *)is->hy_ifuba.ifu_r.ifrw_addr;
        !           959: 
        !           960:                bcopy((caddr_t)p, (caddr_t)&is->hy_stat, sizeof(struct hy_stat));
        !           961: #ifdef DEBUG
        !           962: 
        !           963:                printD("hy%d: statistics - df0 %d df1 %d df2 %d df3 %d\n",
        !           964:                        ui->ui_unit,
        !           965:                        (is->hy_stat.hyc_df0[0]<<16) | (is->hy_stat.hyc_df0[1]<<8) | is->hy_stat.hyc_df0[2],
        !           966:                        (is->hy_stat.hyc_df1[0]<<16) | (is->hy_stat.hyc_df1[1]<<8) | is->hy_stat.hyc_df1[2],
        !           967:                        (is->hy_stat.hyc_df2[0]<<16) | (is->hy_stat.hyc_df2[1]<<8) | is->hy_stat.hyc_df2[2],
        !           968:                        (is->hy_stat.hyc_df3[0]<<16) | (is->hy_stat.hyc_df3[1]<<8) | is->hy_stat.hyc_df3[2]);
        !           969:                printD("        ret0 %d ret1 %d ret2 %d ret3 %d\n",
        !           970:                        (is->hy_stat.hyc_ret0[0]<<16) | (is->hy_stat.hyc_ret0[1]<<8) | is->hy_stat.hyc_ret0[2],
        !           971:                        (is->hy_stat.hyc_ret1[0]<<16) | (is->hy_stat.hyc_ret1[1]<<8) | is->hy_stat.hyc_ret1[2],
        !           972:                        (is->hy_stat.hyc_ret2[0]<<16) | (is->hy_stat.hyc_ret2[1]<<8) | is->hy_stat.hyc_ret2[2],
        !           973:                        (is->hy_stat.hyc_ret3[0]<<16) | (is->hy_stat.hyc_ret3[1]<<8) | is->hy_stat.hyc_ret3[2]);
        !           974:                printD("        cancel %d abort %d atype %x %x %x uaddr %x\n",
        !           975:                        (is->hy_stat.hyc_cancel[0]<<8) | is->hy_stat.hyc_cancel[1],
        !           976:                        (is->hy_stat.hyc_abort[0]<<8) | is->hy_stat.hyc_abort[1],
        !           977:                        is->hy_stat.hyc_atype[0], is->hy_stat.hyc_atype[1],
        !           978:                        is->hy_stat.hyc_atype[2], is->hy_stat.hyc_uaddr);
        !           979: #endif
        !           980:                is->hy_state = IDLE;
        !           981: #ifdef HYLOG
        !           982:                hylog(HYL_STATISTICS, sizeof (struct hy_stat),
        !           983:                        (char *)&is->hy_stat);
        !           984: #endif
        !           985:                break;
        !           986:        }
        !           987: 
        !           988:        case CLEARSENT:
        !           989:                is->hy_state = IDLE;
        !           990:                break;
        !           991: 
        !           992:        case ENDOPSENT:
        !           993:                is->hy_state = IDLE;
        !           994:                break;
        !           995: 
        !           996:        case RECVSENT: {
        !           997:                register struct hym_hdr *hym;
        !           998:                register unsigned len;
        !           999: 
        !          1000:                if (is->hy_ifuba.ifu_flags & UBA_NEEDBDP)
        !          1001:                        UBAPURGE(is->hy_ifuba.ifu_uba,
        !          1002:                            is->hy_ifuba.ifu_r.ifrw_bdp);
        !          1003:                hym = (struct hym_hdr *) (is->hy_ifuba.ifu_r.ifrw_addr);
        !          1004:                len = (0xffff & (addr->hyd_wcr - is->hy_lastwcr)) << 1;
        !          1005:                if (len > MPSIZE) {
        !          1006:                        printf("hy%d: RECVD MP > MPSIZE (%d)\n",
        !          1007:                            ui->ui_unit, len);
        !          1008:                        is->hy_state = IDLE;
        !          1009: #ifdef DEBUG
        !          1010:                        hy_debug_flag = 1;
        !          1011:                        printD("hy%d: csr = 0x%b, bar = 0x%x, wcr = 0x%x\n",
        !          1012:                                ui->ui_unit, addr->hyd_csr, HY_CSR_BITS,
        !          1013:                                addr->hyd_bar, addr->hyd_wcr);
        !          1014: #endif
        !          1015:                }
        !          1016:                hym->hym_mplen = len;
        !          1017: #ifdef DEBUG
        !          1018:                printD("hy%d: recvd mp, len = %d, data = ", ui->ui_unit, len);
        !          1019:                if (hy_debug_flag)
        !          1020:                        hyprintdata((char *)hym, len + HYM_SWLEN);
        !          1021: #endif
        !          1022:                if (hym->hym_ctl & H_ASSOC) {
        !          1023:                        is->hy_state = RECVDATASENT;
        !          1024:                        is->hy_retry = 0;
        !          1025:                        hystart(ui, HYF_INPUTDATA,
        !          1026:                            (int)(HYMTU + sizeof (struct hy_hdr) - len),
        !          1027:                            (int)(HYM_SWLEN + is->hy_ifuba.ifu_r.ifrw_info + len));
        !          1028:                } else {
        !          1029:                        hyrecvdata(ui, hym, (int)len + HYM_SWLEN);
        !          1030:                        is->hy_state = IDLE;
        !          1031:                }
        !          1032:                break;
        !          1033:        }
        !          1034: 
        !          1035:        case RECVDATASENT: {
        !          1036:                register struct hym_hdr *hym;
        !          1037:                register unsigned len;
        !          1038: 
        !          1039:                if (is->hy_ifuba.ifu_flags & UBA_NEEDBDP)
        !          1040:                        UBAPURGE(is->hy_ifuba.ifu_uba,
        !          1041:                            is->hy_ifuba.ifu_r.ifrw_bdp);
        !          1042:                hym = (struct hym_hdr *) (is->hy_ifuba.ifu_r.ifrw_addr);
        !          1043:                len = (0xffff & (addr->hyd_wcr - is->hy_lastwcr)) << 1;
        !          1044: #ifdef DEBUG
        !          1045:                printD("hy%d: recvd assoc data, len = %d, data = ",
        !          1046:                        ui->ui_unit, len);
        !          1047:                if (hy_debug_flag)
        !          1048:                        hyprintdata((char *)hym + hym->hym_mplen, len);
        !          1049: #endif
        !          1050:                hyrecvdata(ui, hym, (int)(len + hym->hym_mplen + HYM_SWLEN));
        !          1051:                is->hy_state = IDLE;
        !          1052:                break;
        !          1053:        }
        !          1054: 
        !          1055:        case XMITSENT:
        !          1056:                if (is->hy_flags & RQ_XASSOC) {
        !          1057:                        register int len;
        !          1058: 
        !          1059:                        is->hy_flags &= ~RQ_XASSOC;
        !          1060:                        is->hy_state = XMITDATASENT;
        !          1061:                        is->hy_retry = 0;
        !          1062:                        len = (0xffff & (addr->hyd_wcr - is->hy_lastwcr)) << 1;
        !          1063:                        if (len > is->hy_olen) {
        !          1064:                                printf(
        !          1065:                                "hy%d: xmit error - len > hy_olen [%d > %d]\n",
        !          1066:                                ui->ui_unit, len, is->hy_olen);
        !          1067: #ifdef DEBUG
        !          1068:                                hy_debug_flag = 1;
        !          1069: #endif
        !          1070:                        }
        !          1071:                        hystart(ui, HYF_XMITLSTDATA, is->hy_olen - len,
        !          1072:                            is->hy_ifuba.ifu_w.ifrw_info + HYM_SWLEN + len);
        !          1073:                        break;
        !          1074:                }
        !          1075:                /* fall through to ... */
        !          1076:                
        !          1077:        case XMITDATASENT:
        !          1078:                hyxmitdata(ui);
        !          1079:                is->hy_state = IDLE;
        !          1080:                break;
        !          1081: 
        !          1082:        case WAITING:   /* wait for message complete or output requested */
        !          1083:                if (HYS_RECVDATA(addr))
        !          1084:                        is->hy_state = IDLE;
        !          1085:                else {
        !          1086:                        is->hy_state = CLEARSENT;
        !          1087:                        is->hy_retry = 0;
        !          1088:                        hystart(ui, HYF_CLRWFMSG, 0, 0);
        !          1089:                }
        !          1090:                break;
        !          1091: 
        !          1092:        case MARKPORT:
        !          1093:                is->hy_state = STARTUP;
        !          1094:                if_down(&is->hy_if);
        !          1095:                is->hy_if.if_flags &= ~IFF_UP;
        !          1096:                goto endintr;
        !          1097:        
        !          1098:        default:
        !          1099:                printf("hy%d: DRIVER BUG - INVALID STATE %d\n",
        !          1100:                        ui->ui_unit, is->hy_state);
        !          1101:                panic("HYPERCHANNEL IN INVALID STATE");
        !          1102:                /*NOTREACHED*/
        !          1103:        }
        !          1104:        if (is->hy_state == IDLE)
        !          1105:                goto actloop;
        !          1106: endintr:
        !          1107:        ;
        !          1108: #ifdef DEBUG
        !          1109:        printD("hy%d: hyact, exit at \"%s\"\n", ui->ui_unit,
        !          1110:                hy_state_names[is->hy_state]);
        !          1111: #endif
        !          1112: }
        !          1113: 
        !          1114: struct sockproto hypproto = { PF_HYLINK };
        !          1115: struct sockaddr_in hypdst = { sizeof(hypdst), AF_HYLINK };
        !          1116: struct sockaddr_in hypsrc = { sizeof(hypsrc), AF_HYLINK };
        !          1117: 
        !          1118: /*
        !          1119:  * Called from device interrupt when receiving data.
        !          1120:  * Examine packet to determine type.  Decapsulate packet
        !          1121:  * based on type and pass to type specific higher-level
        !          1122:  * input routine.
        !          1123:  */
        !          1124: hyrecvdata(ui, hym, len)
        !          1125:        struct uba_device *ui;
        !          1126:        register struct hym_hdr *hym;
        !          1127:        int len;
        !          1128: {
        !          1129:        register struct hy_softc *is = &hy_softc[ui->ui_unit];
        !          1130:        struct mbuf *m;
        !          1131:        register struct ifqueue *inq;
        !          1132: 
        !          1133:        is->hy_if.if_ipackets++;
        !          1134: #ifdef DEBUG
        !          1135:        printD("hy%d: recieved packet, len = %d\n", ui->ui_unit, len);
        !          1136: #endif
        !          1137: #ifdef HYLOG
        !          1138:        {
        !          1139:                struct {
        !          1140:                        short hlen;
        !          1141:                        struct hym_hdr hhdr;
        !          1142:                } hh;
        !          1143:                hh.hlen = len;
        !          1144:                hh.hhdr = *hym;
        !          1145:                hylog(HYL_RECV, sizeof(hh), (char *)&hh);
        !          1146:        }
        !          1147: #endif
        !          1148:        if (len > HYMTU + MPSIZE || len == 0)
        !          1149:                return;                 /* sanity */
        !          1150:        /*
        !          1151:         * Pull packet off interface.
        !          1152:         */
        !          1153:        m = if_rubaget(&is->hy_ifuba, len, 0, &is->hy_if);
        !          1154:        if (m == NULL)
        !          1155:                return;
        !          1156: 
        !          1157:        /*
        !          1158:         * if normal or adapter loopback response packet believe hym_type,
        !          1159:         * otherwise, use the raw input queue cause it's a response from an
        !          1160:         * adapter command.
        !          1161:         */
        !          1162:        if (hym->hym_param != 0 && (u_short)hym->hym_param != 0x80ff)
        !          1163:                goto rawlinkin;
        !          1164: 
        !          1165:        switch (hym->hym_type) {
        !          1166: 
        !          1167: #ifdef INET
        !          1168:        case HYLINK_IP:
        !          1169:                schednetisr(NETISR_IP);
        !          1170:                inq = &ipintrq;
        !          1171:                break;
        !          1172: #endif
        !          1173:        default:
        !          1174:        rawlinkin:
        !          1175:                {
        !          1176:                        M_PREPEND(m, sizeof(struct hym_hdr), M_DONTWAIT);
        !          1177:                        if (m == 0) {
        !          1178:                                m_freem(m);
        !          1179:                                return;
        !          1180:                        }
        !          1181:                        bcopy((caddr_t)hym, mtod(m, caddr_t), sizeof(struct hym_hdr));
        !          1182:                        hypproto.sp_protocol = 0;
        !          1183:                        hypdst.sin_addr = is->hy_addr;
        !          1184:                        hypsrc.sin_addr = is->hy_addr;
        !          1185:                        raw_input(m, &hypproto, (struct sockaddr *)&hypsrc,
        !          1186:                                (struct sockaddr *)&hypdst);
        !          1187:                        return;
        !          1188:                }
        !          1189:        }
        !          1190:        if (IF_QFULL(inq)) {
        !          1191:                IF_DROP(inq);
        !          1192:                m_freem(m);
        !          1193:        } else
        !          1194:                IF_ENQUEUE(inq, m);
        !          1195: }
        !          1196: 
        !          1197: /*
        !          1198:  * Transmit done, release resources, bump counters.
        !          1199:  */
        !          1200: hyxmitdata(ui)
        !          1201:        struct uba_device *ui;
        !          1202: {
        !          1203:        register struct hy_softc *is = &hy_softc[ui->ui_unit];
        !          1204: 
        !          1205:        is->hy_if.if_opackets++;
        !          1206:        if (is->hy_ifuba.ifu_xtofree) {
        !          1207:                m_freem(is->hy_ifuba.ifu_xtofree);
        !          1208:                is->hy_ifuba.ifu_xtofree = 0;
        !          1209:        }
        !          1210: }
        !          1211: 
        !          1212: hycancel(ui)
        !          1213:        register struct uba_device *ui;
        !          1214: {
        !          1215:        register struct hy_softc *is = &hy_softc[ui->ui_unit];
        !          1216: 
        !          1217:        if (is->hy_ifuba.ifu_xtofree) {
        !          1218:                m_freem(is->hy_ifuba.ifu_xtofree);
        !          1219:                is->hy_ifuba.ifu_xtofree = 0;
        !          1220:        }
        !          1221: #ifdef HYLOG
        !          1222:        hylog(HYL_CANCEL, 0, (char *)0);
        !          1223: #endif
        !          1224: #ifdef DEBUG
        !          1225:        if (hy_nodebug & 1)
        !          1226:                hy_debug_flag = 1;
        !          1227: #endif
        !          1228: #ifdef DEBUG
        !          1229:        printD("hy%d: cancel from state \"%s\" cmd=0x%x count=%d ptr=0x%x\n",
        !          1230:                ui->ui_unit, hy_state_names[is->hy_state], is->hy_savedcmd,
        !          1231:                is->hy_savedcount, is->hy_savedaddr);
        !          1232:        printD("\tflags 0x%x olen %d lastwcr %d retry %d\n",
        !          1233:                is->hy_flags, is->hy_olen, is->hy_lastwcr, is->hy_retry);
        !          1234:        printD("\tsaved: state %d count %d ptr 0x%x cmd 0x%x\n",
        !          1235:                is->hy_savedstate, is->hy_savedcount, is->hy_savedaddr,
        !          1236:                is->hy_savedcmd);
        !          1237: #endif
        !          1238:        is->hy_state = IDLE;
        !          1239:        is->hy_flags |= (RQ_ENDOP | RQ_STATUS);
        !          1240:        hyact(ui);
        !          1241: }
        !          1242: 
        !          1243: #ifdef DEBUG
        !          1244: hyprintdata(cp, len)
        !          1245:        register char *cp;
        !          1246:        register int len;
        !          1247: {
        !          1248:        register int count = 16;
        !          1249:        register char *fmt;
        !          1250:        static char regfmt[] = "\n\t %x";
        !          1251: 
        !          1252:        fmt = &regfmt[2];
        !          1253:        while (--len >= 0) {
        !          1254:                printL(fmt, *cp++ & 0xff);
        !          1255:                fmt = &regfmt[2];
        !          1256:                if (--count <= 0) {
        !          1257:                        fmt = &regfmt[0];
        !          1258:                        count = 16;
        !          1259:                }
        !          1260:        }
        !          1261:        printL("\n");
        !          1262: }
        !          1263: #endif
        !          1264: 
        !          1265: hywatch(unit)
        !          1266:        int unit;
        !          1267: {
        !          1268:        register struct hy_softc *is = &hy_softc[unit];
        !          1269:        register struct uba_device *ui = hyinfo[unit];
        !          1270:        register struct hydevice *addr = (struct hydevice *)ui->ui_addr;
        !          1271:        int s;
        !          1272: 
        !          1273:        s = splimp();
        !          1274: #ifdef PI13
        !          1275:        if ((addr->hyd_csr & S_POWEROFF) != 0) {
        !          1276:                addr->hyd_csr |= S_POWEROFF;
        !          1277:                DELAY(100);
        !          1278:                if ((addr->hyd_csr & S_POWEROFF) == 0) {
        !          1279:                        printf("hy%d: Adapter Power Restored (hywatch)\n", unit);
        !          1280:                        is->hy_state = IDLE;
        !          1281:                        is->hy_flags |=
        !          1282:                          (RQ_MARKUP | RQ_STATISTICS | RQ_ENDOP | RQ_STATUS);
        !          1283:                        hyact(ui);
        !          1284:                }
        !          1285:        }
        !          1286: #endif
        !          1287:        if (++is->hy_ntime >= 2 && is->hy_state != WAITING &&
        !          1288:          is->hy_state != STARTUP && is->hy_state != IDLE) {
        !          1289: #ifdef HYLOG
        !          1290:                printf("hy%d: watchdog timer expired in state \"%s\"\n", unit,
        !          1291:                        hy_state_names[is->hy_state]);
        !          1292: #else
        !          1293:                printf("hy%d: watchdog timer expired in state %d\n", unit,
        !          1294:                        is->hy_state);
        !          1295: #endif
        !          1296:                printf("hy%d: last command 0x%x, flags 0x%x, csr 0x%b\n", unit,
        !          1297:                        is->hy_savedcmd, is->hy_flags, addr->hyd_csr, HY_CSR_BITS);
        !          1298:                hycancel(ui);
        !          1299:        }
        !          1300:        splx(s);
        !          1301:        is->hy_if.if_timer = SCANINTERVAL;
        !          1302: }
        !          1303: 
        !          1304: #ifdef HYLOG
        !          1305: hylog(code, len, ptr)
        !          1306:        int code, len;
        !          1307:        char *ptr;
        !          1308: {
        !          1309:        register unsigned char *p;
        !          1310:        int s;
        !          1311: 
        !          1312:        s = splimp();
        !          1313:        if (hy_log.hyl_self != &hy_log) {
        !          1314:                hy_log.hyl_eptr = &hy_log.hyl_buf[HYL_SIZE];
        !          1315:                hy_log.hyl_ptr = &hy_log.hyl_buf[0];
        !          1316:                hy_log.hyl_self = &hy_log;
        !          1317:                hy_log.hyl_enable = HYL_CONTINUOUS;
        !          1318:                hy_log.hyl_onerr = HYL_CONTINUOUS;
        !          1319:                hy_log.hyl_count = 0;
        !          1320:                hy_log.hyl_icount = 16;
        !          1321:                hy_log.hyl_filter = 0xffff;     /* enable all */
        !          1322:        }
        !          1323:        if (hy_log.hyl_enable == HYL_DISABLED || ((1 << code) & hy_log.hyl_filter) == 0)
        !          1324:                goto out;
        !          1325:        p = hy_log.hyl_ptr;
        !          1326:        if (p + len + 3 >= hy_log.hyl_eptr) {
        !          1327:                bzero((caddr_t)p, (unsigned)(hy_log.hyl_eptr - p));
        !          1328:                p = &hy_log.hyl_buf[0];
        !          1329:                if (hy_log.hyl_enable != HYL_CONTINUOUS) {
        !          1330:                        hy_log.hyl_enable = HYL_DISABLED;
        !          1331:                        goto out;
        !          1332:                }
        !          1333:        }
        !          1334:        *p++ = code;
        !          1335:        *p++ = len;
        !          1336:        bcopy((caddr_t)ptr, (caddr_t)p, (unsigned)len);
        !          1337:        if (hy_log.hyl_count != 0 && --hy_log.hyl_count == 0) {
        !          1338:                *p++ = '\0';
        !          1339:                hy_log.hyl_enable = HYL_DISABLED;
        !          1340:                hy_log.hyl_count = hy_log.hyl_icount;
        !          1341:        }
        !          1342:        p += len;
        !          1343:        if (hy_log.hyl_wait != 0) {             /* wakeup HYGETLOG if wanted */
        !          1344:                if (hy_log.hyl_wait <= p - hy_log.hyl_ptr) {
        !          1345:                        wakeup((caddr_t)&hy_log);
        !          1346:                        hy_log.hyl_wait = 0;
        !          1347:                } else
        !          1348:                        hy_log.hyl_wait -= p - hy_log.hyl_ptr;
        !          1349:        }
        !          1350:        hy_log.hyl_ptr = p;
        !          1351: out:
        !          1352:        splx(s);
        !          1353: }
        !          1354: #endif
        !          1355: 
        !          1356: /*ARGSUSED*/
        !          1357: hyioctl(ifp, cmd, data)
        !          1358:        register struct ifnet *ifp;
        !          1359:        int cmd;
        !          1360:        caddr_t data;
        !          1361: {
        !          1362:        struct ifaddr *ifa = (struct ifaddr *) data;
        !          1363:        struct hyrsetget *sg = (struct hyrsetget *)data;
        !          1364: #if defined(HYLOG) || defined(HYELOG)
        !          1365:        struct hylsetget *sgl = (struct hylsetget *)data;
        !          1366: #endif
        !          1367:        struct hy_route *r = (struct hy_route *)&hy_route[ifp->if_unit];
        !          1368:        int s = splimp(), error = 0;
        !          1369: #ifdef HYLOG
        !          1370:        struct hy_softc *is = &hy_softc[ifp->if_unit];
        !          1371:        struct {
        !          1372:                u_char  hstate;
        !          1373:                u_char  hflags;
        !          1374:                u_short iflags;
        !          1375:                int     hcmd;   
        !          1376:                int     herror;
        !          1377:                u_long  haddr;
        !          1378:                u_long  hmisc;
        !          1379:        } hil;
        !          1380: 
        !          1381:        hil.hmisc = -1;
        !          1382:        hil.hstate = is->hy_state;
        !          1383:        hil.hflags = is->hy_flags;
        !          1384:        hil.hcmd = cmd;
        !          1385: #endif
        !          1386: 
        !          1387:        switch(cmd) {
        !          1388: 
        !          1389:        case SIOCSIFADDR:
        !          1390:                if (ifa->ifa_addr->sa_family != AF_INET)
        !          1391:                        return(EINVAL);
        !          1392:                if ((ifp->if_flags & IFF_RUNNING) == 0)
        !          1393:                        hyinit(ifp->if_unit);
        !          1394:                hy_softc[ifp->if_unit].hy_addr = IA_SIN(ifa)->sin_addr;
        !          1395: #ifdef HYLOG
        !          1396:                hil.haddr = is->hy_addr.s_addr;
        !          1397: #endif
        !          1398:                break;
        !          1399: 
        !          1400:        case HYSETROUTE:
        !          1401:                if (error = suser(u.u_cred, &u.u_acflag))
        !          1402:                        goto out;
        !          1403: 
        !          1404:                if (sg->hyrsg_len != sizeof(struct hy_route)) {
        !          1405:                        error = EINVAL;
        !          1406:                        goto out;
        !          1407:                }
        !          1408:                if (copyin((caddr_t)(sg->hyrsg_ptr), (caddr_t)r, sg->hyrsg_len)) {
        !          1409:                        r->hyr_lasttime = 0;    /* disable further routing if trouble */
        !          1410:                        error = EFAULT;
        !          1411:                        goto out;
        !          1412:                }
        !          1413:                r->hyr_lasttime = time.tv_sec;
        !          1414: #ifdef HYLOG
        !          1415:                hil.hmisc = r->hyr_lasttime;
        !          1416: #endif
        !          1417:                break;
        !          1418: 
        !          1419:        case HYGETROUTE:
        !          1420:                if (sg->hyrsg_len < sizeof(struct hy_route)) {
        !          1421:                        error = EINVAL;
        !          1422:                        goto out;
        !          1423:                }
        !          1424:                if (copyout((caddr_t)r, (caddr_t) (sg->hyrsg_ptr), sizeof(struct hy_route))) {
        !          1425:                        error = EFAULT;
        !          1426:                        goto out;
        !          1427:                }
        !          1428:                break;
        !          1429: 
        !          1430: #ifdef HYELOG
        !          1431:        case HYGETELOG:
        !          1432:                if (sgl->hylsg_len < sizeof(hy_elog)) {
        !          1433:                        error = EINVAL;
        !          1434:                        goto out;
        !          1435:                }
        !          1436:                if (copyout((caddr_t)hy_elog, sgl->hylsg_ptr, sizeof(hy_elog))) {
        !          1437:                        error = EFAULT;
        !          1438:                        goto out;
        !          1439:                }
        !          1440:                if (sgl->hylsg_cmd) {
        !          1441:                        if (error = suser(u.u_cred, &u.u_acflag))
        !          1442:                                goto out;
        !          1443:                        bzero((caddr_t)hy_elog, sizeof(hy_elog));
        !          1444:                }
        !          1445:                break;
        !          1446: #endif
        !          1447: 
        !          1448: #ifdef HYLOG
        !          1449:        case HYSETLOG:
        !          1450:                if (error = suser(u.u_cred, &u.u_acflag))
        !          1451:                        goto out;
        !          1452:                hy_log.hyl_enable = HYL_DISABLED;
        !          1453:                hylog(HYL_NOP, 0, (char *)0);           /* force log init */
        !          1454:                hy_log.hyl_enable = sgl->hylsg_cmd & 0x0f;
        !          1455:                hy_log.hyl_onerr = (sgl->hylsg_cmd >> 4) & 0x0f;
        !          1456:                hy_log.hyl_filter = (sgl->hylsg_cmd >> 8) & 0xffffff;
        !          1457:                hy_log.hyl_count = hy_log.hyl_icount = sgl->hylsg_len;
        !          1458:                wakeup((caddr_t)&hy_log);       /* wakeup sleeping HYGETLOG */
        !          1459:                break;
        !          1460: 
        !          1461:        case HYGETLOG:
        !          1462:                if (sgl->hylsg_len < sizeof(hy_log)) {
        !          1463:                        error = EINVAL;
        !          1464:                        goto out;
        !          1465:                }
        !          1466:                if (sgl->hylsg_cmd != 0) {
        !          1467:                        if (hy_log.hyl_wait) {
        !          1468:                                error = EBUSY;
        !          1469:                                goto out;
        !          1470:                        }
        !          1471:                        hy_log.hyl_wait = sgl->hylsg_cmd;
        !          1472:                        sleep((caddr_t)&hy_log, PZERO - 1);
        !          1473:                }
        !          1474: 
        !          1475:                if (copyout((caddr_t)&hy_log, sgl->hylsg_ptr, sizeof(hy_log))) {
        !          1476:                        error = EFAULT;
        !          1477:                        goto out;
        !          1478:                }
        !          1479:                break;
        !          1480: #endif
        !          1481: 
        !          1482:        default:
        !          1483:                error = EINVAL;
        !          1484:                break;
        !          1485:        }
        !          1486: out:
        !          1487: #ifdef HYLOG
        !          1488:        hil.herror = error;
        !          1489:        hil.iflags = ifp->if_flags;
        !          1490:        hil.haddr = is->hy_addr.s_addr;
        !          1491:        hylog(HYL_IOCTL, sizeof(hil), (char *)&hil);
        !          1492: #endif
        !          1493:        splx(s);
        !          1494:        return (error);
        !          1495: }
        !          1496: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.