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

unix.superglobalmegacorp.com

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