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

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

unix.superglobalmegacorp.com

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