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

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

unix.superglobalmegacorp.com

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