Annotation of 43BSDReno/sys/vaxif/if_css.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution is only permitted until one year after the first shipment
                      6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                      7:  * binary forms are permitted provided that: (1) source distributions retain
                      8:  * this entire copyright notice and comment, and (2) distributions including
                      9:  * binaries display the following acknowledgement:  This product includes
                     10:  * software developed by the University of California, Berkeley and its
                     11:  * contributors'' in the documentation or other materials provided with the
                     12:  * distribution and in all advertising materials mentioning features or use
                     13:  * of this software.  Neither the name of the University nor the names of
                     14:  * its contributors may be used to endorse or promote products derived from
                     15:  * this software without specific prior written permission.
                     16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     19:  *
                     20:  *     @(#)if_css.c    7.8 (Berkeley) 6/28/90
                     21:  */
                     22: 
                     23: #include "css.h"
                     24: #if NCSS > 0
                     25: 
                     26: /*
                     27:  * DEC/CSS IMP11-A ARPAnet IMP interface driver.
                     28:  * Since "imp11a" is such a mouthful, it is called
                     29:  * "css" after the LH/DH being called "acc".
                     30:  *
                     31:  * Configuration notes:
                     32:  *
                     33:  * As delivered from DEC/CSS, it
                     34:  * is addressed and vectored as two DR11-B's.  This makes
                     35:  * Autoconfig almost IMPOSSIBLE.  To make it work, the
                     36:  * interrupt vectors must be restrapped to make the vectors
                     37:  * consecutive.  The 020 hole between the CSR addresses is
                     38:  * tolerated, althought that could be cleaned-up also.
                     39:  *
                     40:  * Additionally, the TRANSMIT side of the IMP11-A has the
                     41:  * lower address of the two subunits, so the vector ordering
                     42:  * in the CONFIG file is reversed from most other devices.
                     43:  * It should be:
                     44:  *
                     45:  * device css0 ....  cssxint cssrint
                     46:  *
                     47:  * If you get it wrong, it will still autoconfig, but will just
                     48:  * sit there with RECEIVE IDLE indicated on the front panel.
                     49:  */
                     50: #include "param.h"
                     51: #include "systm.h"
                     52: #include "mbuf.h"
                     53: #include "buf.h"
                     54: #include "protosw.h"
                     55: #include "socket.h"
                     56: #include "vmmac.h"
                     57: 
                     58: #include "machine/pte.h"
                     59: 
                     60: #include "../net/if.h"
                     61: #include "../netimp/if_imp.h"
                     62: 
                     63: #include "../vax/cpu.h"
                     64: #include "../vax/mtpr.h"
                     65: #include "if_cssreg.h"
                     66: #include "if_uba.h"
                     67: #include "../vaxuba/ubareg.h"
                     68: #include "../vaxuba/ubavar.h"
                     69: 
                     70: int     cssprobe(), cssattach(), cssrint(), cssxint();
                     71: struct  uba_device *cssinfo[NCSS];
                     72: u_short cssstd[] = { 0 };
                     73: struct  uba_driver cssdriver =
                     74:         { cssprobe, 0, cssattach, 0, cssstd, "css", cssinfo };
                     75: 
                     76: int     cssinit(), cssoutput(), cssdown(), cssreset();
                     77: 
                     78: /*
                     79:  * "Lower half" of IMP interface driver.
                     80:  *
                     81:  * Each IMP interface is handled by a common module which handles
                     82:  * the IMP-host protocol and a hardware driver which manages the
                     83:  * hardware specific details of talking with the IMP.
                     84:  *
                     85:  * The hardware portion of the IMP driver handles DMA and related
                     86:  * management of UNIBUS resources.  The IMP protocol module interprets
                     87:  * contents of these messages and "controls" the actions of the
                     88:  * hardware module during IMP resets, but not, for instance, during
                     89:  * UNIBUS resets.
                     90:  *
                     91:  * The two modules are coupled at "attach time", and ever after,
                     92:  * through the imp interface structure.  Higher level protocols,
                     93:  * e.g. IP, interact with the IMP driver, rather than the CSS.
                     94:  */
                     95: struct  css_softc {
                     96:        struct  imp_softc *css_imp;     /* pointer to IMP's imp_softc struct */
                     97:        struct  ifuba css_ifuba;        /* UNIBUS resources */
                     98:        struct  mbuf *css_iq;           /* input reassembly queue */
                     99:        short   css_olen;               /* size of last message sent */
                    100:        char    css_flush;              /* flush remainder of message */
                    101: } css_softc[NCSS];
                    102: 
                    103: /*
                    104:  * Reset the IMP and cause a transmitter interrupt by
                    105:  * performing a null DMA.
                    106:  */
                    107: cssprobe(reg)
                    108:         caddr_t reg;
                    109: {
                    110:         register int br, cvec;          /* r11, r10 value-result */
                    111:         register struct cssdevice *addr = (struct cssdevice *)reg;
                    112: 
                    113: #ifdef lint
                    114:         br = 0; cvec = br; br = cvec;
                    115:         cssrint(0); cssxint(0);
                    116: #endif
                    117: 
                    118:         addr->css_icsr = CSS_CLR;
                    119:         addr->css_ocsr = CSS_CLR;
                    120:         DELAY(50000);
                    121:        addr->css_icsr = 0;
                    122:        addr->css_ocsr = 0;
                    123:         DELAY(50000);
                    124: 
                    125:        addr->css_oba = 0;
                    126:        addr->css_owc = -1;
                    127:         addr->css_ocsr = CSS_IE | CSS_GO;      /* enable interrupts */
                    128:         DELAY(50000);
                    129:         addr->css_ocsr = 0;
                    130: 
                    131:         return (1);
                    132: }
                    133: 
                    134: /*
                    135:  * Call the IMP module to allow it to set up its internal
                    136:  * state, then tie the two modules together by setting up
                    137:  * the back pointers to common data structures.
                    138:  */
                    139: cssattach(ui)
                    140:         register struct uba_device *ui;
                    141: {
                    142:         register struct css_softc *sc = &css_softc[ui->ui_unit];
                    143:         register struct impcb *ip;
                    144: 
                    145:         if ((sc->css_imp = impattach(ui->ui_driver->ud_dname, ui->ui_unit,
                    146:            cssreset)) == 0)
                    147:                 return;
                    148:        ip = &sc->css_imp->imp_cb;
                    149:         ip->ic_init = cssinit;
                    150:         ip->ic_output = cssoutput;
                    151:         ip->ic_down = cssdown;
                    152:        sc->css_ifuba.ifu_flags = UBA_CANTWAIT | UBA_NEED16;
                    153: #ifdef notdef
                    154:        sc->css_ifuba.ifu_flags |= UBA_NEEDBDP;
                    155: #endif
                    156: }
                    157: 
                    158: /*
                    159:  * Reset interface after UNIBUS reset.
                    160:  * If interface is on specified uba, reset its state.
                    161:  */
                    162: cssreset(unit, uban)
                    163:         int unit, uban;
                    164: {
                    165:         register struct uba_device *ui;
                    166:         register struct css_softc *sc;
                    167: 
                    168:         if (unit >= NCSS || (ui = cssinfo[unit]) == 0 || ui->ui_alive == 0 ||
                    169:             ui->ui_ubanum != uban)
                    170:                 return;
                    171:         printf(" css%d", unit);
                    172:         sc = &css_softc[unit];
                    173:        sc->css_imp->imp_if.if_flags &= ~IFF_RUNNING;
                    174:        cssoflush(unit);
                    175:         /* must go through IMP to allow it to set state */
                    176:         (*sc->css_imp->imp_if.if_init)(sc->css_imp->imp_if.if_unit);
                    177: }
                    178: 
                    179: /*
                    180:  * Initialize interface: clear recorded pending operations,
                    181:  * and retrieve, and reinitialize UNIBUS resources.
                    182:  */
                    183: cssinit(unit)
                    184:         int unit;
                    185: {       
                    186:         register struct css_softc *sc;
                    187:         register struct uba_device *ui;
                    188:         register struct cssdevice *addr;
                    189:         int x, info;
                    190: 
                    191:        if (unit >= NCSS || (ui = cssinfo[unit]) == 0 || ui->ui_alive == 0) {
                    192:                printf("css%d: not alive\n", unit);
                    193:                return(0);
                    194:        }
                    195:        sc = &css_softc[unit];
                    196: 
                    197:        /*
                    198:         * Header length is 0 to if_ubainit since we have to pass
                    199:         * the IMP leader up to the protocol interpretaion
                    200:         * routines.  If we had the deader length as
                    201:         * sizeof(struct imp_leader), then the if_ routines
                    202:         * would assume we handle it on input and output.
                    203:         */
                    204:        
                    205:         if ((sc->css_imp->imp_if.if_flags & IFF_RUNNING) == 0 &&
                    206:            if_ubainit(&sc->css_ifuba, ui->ui_ubanum, 0,
                    207:            (int)btoc(IMP_RCVBUF)) == 0) {
                    208:                 printf("css%d: can't initialize\n", unit);
                    209:                ui->ui_alive = 0;
                    210:                sc->css_imp->imp_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
                    211:                return(0);
                    212:         }
                    213:        sc->css_imp->imp_if.if_flags |= IFF_RUNNING;
                    214:         addr = (struct cssdevice *)ui->ui_addr;
                    215: 
                    216:         /* reset the imp interface. */
                    217:         x = spl5();
                    218:         addr->css_icsr = CSS_CLR;
                    219:         addr->css_ocsr = CSS_CLR;
                    220:        DELAY(100);
                    221:        addr->css_icsr = 0;
                    222:        addr->css_ocsr = 0;
                    223:         addr->css_icsr = IN_HRDY;       /* close the relay */
                    224:        DELAY(5000);
                    225:         splx(x);
                    226: 
                    227:         /*
                    228:         * This may hang if the imp isn't really there.
                    229:         * Will test and verify safe operation.
                    230:         */
                    231: 
                    232:        x = 500;
                    233:        while (x-- > 0) {
                    234:                if ((addr->css_icsr & (IN_HRDY|IN_IMPNR)) == IN_HRDY) 
                    235:                        break;
                    236:                 addr->css_icsr = IN_HRDY;      /* close the relay */
                    237:                 DELAY(5000);
                    238:         }
                    239: 
                    240:        if (x <= 0) {
                    241:                printf("css%d: imp doesn't respond, icsr=%b\n", unit,
                    242:                        CSS_INBITS, addr->css_icsr);
                    243:                goto down;
                    244:        }
                    245: 
                    246:         /*
                    247:          * Put up a read.  We can't restart any outstanding writes
                    248:          * until we're back in synch with the IMP (i.e. we've flushed
                    249:          * the NOOPs it throws at us).
                    250:         * Note: IMP_RCVBUF includes the leader.
                    251:          */
                    252: 
                    253:         x = spl5();
                    254:         info = sc->css_ifuba.ifu_r.ifrw_info;
                    255:         addr->css_iba = (u_short)info;
                    256:         addr->css_iwc = -(IMP_RCVBUF >> 1);
                    257:         addr->css_icsr = 
                    258:                 IN_HRDY | CSS_IE | IN_WEN | ((info & 0x30000) >> 12) | CSS_GO;
                    259:         splx(x);
                    260:        return(1);
                    261: 
                    262: down:
                    263:        ui->ui_alive = 0;
                    264:        return(0);
                    265: }
                    266: 
                    267: /*
                    268:  * Drop the host ready line to mark host down.
                    269:  * UNTESTED.
                    270:  */
                    271: cssdown(unit)
                    272:        int unit;
                    273: {
                    274:         register struct cssdevice *addr;
                    275: 
                    276:        addr = (struct cssdevice *)(cssinfo[unit]->ui_addr);
                    277:         /* reset the imp interface. */
                    278:         addr->css_icsr = CSS_CLR;
                    279:         addr->css_ocsr = CSS_CLR;
                    280:        DELAY(100);
                    281:        addr->css_icsr = 0;
                    282:        addr->css_ocsr = 0;
                    283:        cssoflush(unit);
                    284:        return (1);
                    285: }
                    286: 
                    287: cssoflush(unit)
                    288:        int unit;
                    289: {
                    290:        register struct css_softc *sc = &css_softc[unit];
                    291: 
                    292:        sc->css_imp->imp_cb.ic_oactive = 0;
                    293:        if (sc->css_ifuba.ifu_xtofree) {
                    294:                m_freem(sc->css_ifuba.ifu_xtofree);
                    295:                sc->css_ifuba.ifu_xtofree = 0;
                    296:        }
                    297: }
                    298: 
                    299: /*
                    300:  * Start output on an interface.
                    301:  */
                    302: cssoutput(unit, m)
                    303:         int unit;
                    304:         struct mbuf *m;
                    305: {
                    306:         int info;
                    307:         struct uba_device *ui = cssinfo[unit];
                    308:         register struct css_softc *sc = &css_softc[unit];
                    309:         register struct cssdevice *addr;
                    310: 
                    311:         sc->css_olen = if_wubaput(&sc->css_ifuba, m);
                    312:         /*
                    313:          * Have request mapped to UNIBUS for transmission.
                    314:          * Purge any stale data from the BDP, and start the output.
                    315:          */
                    316:        if (sc->css_ifuba.ifu_flags & UBA_NEEDBDP)
                    317:                UBAPURGE(sc->css_ifuba.ifu_uba, sc->css_ifuba.ifu_w.ifrw_bdp);
                    318:         addr = (struct cssdevice *)ui->ui_addr;
                    319:         info = sc->css_ifuba.ifu_w.ifrw_info;
                    320:         addr->css_oba = (u_short)info;
                    321:         addr->css_owc = -((sc->css_olen + 1) >> 1);
                    322:         addr->css_ocsr =
                    323:            (u_short)(CSS_IE | OUT_ENLB | ((info & 0x30000) >> 12) | CSS_GO);
                    324:         sc->css_imp->imp_cb.ic_oactive = 1;
                    325: }
                    326: 
                    327: /*
                    328:  * Output interrupt handler.
                    329:  */
                    330: cssxint(unit)
                    331: {
                    332:         register struct uba_device *ui = cssinfo[unit];
                    333:         register struct css_softc *sc = &css_softc[unit];
                    334:         register struct cssdevice *addr;
                    335: 
                    336:         addr = (struct cssdevice *)ui->ui_addr;
                    337:         if (sc->css_imp->imp_cb.ic_oactive == 0) {
                    338:                 printf("css%d: stray output interrupt csr=%b\n",
                    339:                        unit, addr->css_ocsr, CSS_OUTBITS);
                    340:                 return;
                    341:         }
                    342:         sc->css_imp->imp_if.if_opackets++;
                    343:         sc->css_imp->imp_cb.ic_oactive = 0;
                    344:         if (addr->css_ocsr & CSS_ERR){
                    345:                 sc->css_imp->imp_if.if_oerrors++;
                    346:                 printf("css%d: output error, ocsr=%b icsr=%b\n", unit,
                    347:                         addr->css_ocsr, CSS_OUTBITS,
                    348:                        addr->css_icsr, CSS_INBITS);
                    349:        }
                    350:        if (sc->css_ifuba.ifu_xtofree) {
                    351:                m_freem(sc->css_ifuba.ifu_xtofree);
                    352:                sc->css_ifuba.ifu_xtofree = 0;
                    353:        }
                    354:        impstart(sc->css_imp);
                    355: }
                    356: 
                    357: /*
                    358:  * Input interrupt handler
                    359:  */
                    360: cssrint(unit)
                    361: {
                    362:         register struct css_softc *sc = &css_softc[unit];
                    363:         register struct cssdevice *addr;
                    364:         struct mbuf *m;
                    365:         int len, info;
                    366: 
                    367:         sc->css_imp->imp_if.if_ipackets++;
                    368: 
                    369:         /*
                    370:          * Purge BDP; flush message if error indicated.
                    371:          */
                    372: 
                    373:         addr = (struct cssdevice *)cssinfo[unit]->ui_addr;
                    374:        if (sc->css_ifuba.ifu_flags & UBA_NEEDBDP)
                    375:                UBAPURGE(sc->css_ifuba.ifu_uba, sc->css_ifuba.ifu_r.ifrw_bdp);
                    376:         if (addr->css_icsr & CSS_ERR) {
                    377:                 printf("css%d: recv error, csr=%b\n", unit,
                    378:                     addr->css_icsr, CSS_INBITS);
                    379:                 sc->css_imp->imp_if.if_ierrors++;
                    380:                 sc->css_flush = 1;
                    381:         }
                    382: 
                    383:         if (sc->css_flush) {
                    384:                 if (addr->css_icsr & IN_EOM)
                    385:                         sc->css_flush = 0;
                    386:                 goto setup;
                    387:         }
                    388: 
                    389:         len = IMP_RCVBUF + (addr->css_iwc << 1);
                    390:        if (len < 0 || len > IMP_RCVBUF) {
                    391:                printf("css%d: bad length=%d\n", len);
                    392:                sc->css_imp->imp_if.if_ierrors++;
                    393:                goto setup;
                    394:        }
                    395: 
                    396:         /*
                    397:          * The offset parameter is always 0 since using
                    398:          * trailers on the ARPAnet is insane.
                    399:          */
                    400:         m = if_rubaget(&sc->css_ifuba, len, 0, &sc->css_imp->imp_if);
                    401:         if (m == 0)
                    402:                 goto setup;
                    403:         if ((addr->css_icsr & IN_EOM) == 0) {
                    404:                if (sc->css_iq)
                    405:                        m_cat(sc->css_iq, m);
                    406:                else
                    407:                        sc->css_iq = m;
                    408:                goto setup;
                    409:        }
                    410:        if (sc->css_iq) {
                    411:                m_cat(sc->css_iq, m);
                    412:                m = sc->css_iq;
                    413:                sc->css_iq = 0;
                    414:         }
                    415:         impinput(unit, m);
                    416: 
                    417: setup:
                    418:         /*
                    419:          * Setup for next message.
                    420:          */
                    421:         info = sc->css_ifuba.ifu_r.ifrw_info;
                    422:         addr->css_iba = (u_short)info;
                    423:         addr->css_iwc = - (IMP_RCVBUF >> 1);
                    424:         addr->css_icsr =
                    425:                 IN_HRDY | CSS_IE | IN_WEN | ((info & 0x30000) >> 12) | CSS_GO;
                    426: }
                    427: #endif

unix.superglobalmegacorp.com

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