# 2.11BSD#431 - /usr/src/sys/pdpif/if_sri.c

##### Functions

    sriattach         X
    sridebug          X
    sridump           X
    sriinit           X
    sriprobe          X
    srireset          X
    srirint           X
    sristart          X
    srixint           X

##### Variables

    sri_softc         X
    sridriver         X
    sriinfo           X
    sristd            X

##### Macros

    IFRADDR           X
    IFWADDR           X
    SRIUNIT           X

##### struct's

    ifimpcb           X
    sri_softc         X

       1: /*
       2:  * Copyright (c) 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_sri.c	1.1 (2.10BSD Berkeley) 12/1/86
       7:  */
       8:
       9: #include "sri.h"
      10: #if NSRI > 0
      11:
      12: /*
      13:  * SRI dr11c ARPAnet IMP interface driver.
      14:  */
      15:
      16: #include "param.h"
      17: #include "systm.h"
      18: #include "mbuf.h"
      19: #include "buf.h"
      20: #include "domain.h"
      21: #include "protosw.h"
      22: #include "socket.h"
      23: #include "pdpuba/ubavar.h"
      24: #include "netinet/in.h"
      25: #include "netinet/in_systm.h"
      26: #include "net/if.h"
      27: #include "pdpif/if_sri.h"
      28: #include "netimp/if_imp.h"
      29: #include "pdpif/if_uba.h"
      30:
      31: int     sriprobe(), sriattach(), srirint(), srixint();
      32: struct  uba_device *sriinfo[NSRI];
      33: u_short sristd[] = { 0 };
      34: struct  uba_driver sridriver =
      35:     { sriprobe, 0, sriattach, 0, sristd, "sri", sriinfo };
      36: #define SRIUNIT(x)  minor(x)
      37:
      38: #define IFRADDR sc->sri_ifuba.ifu_r.ifrw_info
      39: #define IFWADDR sc->sri_ifuba.ifu_w.ifrw_info
      40:
      41: int sriinit(), sristart(), srireset();
      42:
      43: /*
      44:  * "Lower half" of IMP interface driver.
      45:  *
      46:  * Each IMP interface is handled by a common module which handles
      47:  * the IMP-host protocol and a hardware driver which manages the
      48:  * hardware specific details of talking with the IMP.
      49:  *
      50:  * The hardware portion of the IMP driver handles DMA and related
      51:  * management of UNIBUS resources.  The IMP protocol module interprets
      52:  * contents of these messages and "controls" the actions of the
      53:  * hardware module during IMP resets, but not, for instance, during
      54:  * UNIBUS resets.
      55:  *
      56:  * The two modules are coupled at "attach time", and ever after,
      57:  * through the imp interface structure.  Higher level protocols,
      58:  * e.g. IP, interact with the IMP driver, rather than the SRI.
      59:  */
      60: struct  sri_softc {
      61:     /* pdma registers, shared with assembly helper */
      62:     struct sridevice *sri_addr;     /* hardware address */
      63:     char    *sri_iba;               /* in byte addr */
      64:     short   sri_ibc;                /* in byte count */
      65:     short   sri_iclick;             /* in click addr */
      66:     short   sri_ibf;                /* in buf (last byte, plus flags) */
      67:     short   sri_ibusy;              /* in dma busy flag */
      68:     char    *sri_oba;               /* out byte addr */
      69:     short   sri_obc;                /* out byte count */
      70:     short   sri_oclick;             /* out click addr */
      71:     short   sri_oend;               /* out end flags */
      72:     /* end pdma */
      73:     struct  ifnet *sri_if;      /* pointer to IMP's ifnet struct */
      74:     struct  impcb *sri_ic;      /* data structure shared with IMP */
      75:     struct  ifuba sri_ifuba;    /* UNIBUS resources */
      76:     struct  mbuf *sri_iq;       /* input reassembly queue */
      77:     short   sri_olen;       /* size of last message sent */
      78:     char    sri_flush;      /* flush remainder of message */
      79: } sri_softc[NSRI];
      80:
      81: /*
      82:  * Reset the IMP and cause a transmitter interrupt.
      83:  */
      84: sriprobe(reg)
      85:     caddr_t reg;
      86: {
      87: #if !pdp11
      88:     register int br, cvec;      /* r11, r10 value-result */
      89:     register struct sridevice *addr = (struct sridevice *)reg;
      90:     int i;
      91:
      92: #ifdef lint
      93:     br = 0; cvec = br; br = cvec;
      94:     srirint(0); srixint(0);
      95: #endif
      96:     addr->csr = 0;
      97:     addr->obf = OUT_HRDY;
      98:     DELAY(100000L);
      99:     addr->csr = SRI_OINT|SRI_OENB;
     100:     addr->obf = OUT_LAST;
     101:     DELAY(100000L);
     102:     addr->csr = 0;
     103:     addr->obf = OUT_HNRDY;
     104:     if(cvec && cvec != 0x200)
     105:         return(1);
     106:     addr->csr = SRI_IINT|SRI_IENB;
     107:     i = addr->ibf;
     108:     DELAY(100000L);
     109:     addr->csr = 0;
     110:     if(cvec && cvec != 0x200)
     111:         cvec -= 4;              /* report as xmit intr */
     112:     return(1);
     113: #endif
     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: sriattach(ui)
     122:     struct uba_device *ui;
     123: {
     124:     register struct sri_softc *sc = &sri_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, srireset)) == 0)
     132:         panic("sriattach");
     133:     sc->sri_if = &ifimp->ifimp_if;
     134:     ip = &ifimp->ifimp_impcb;
     135:     sc->sri_ic = ip;
     136:     ip->ic_init = sriinit;
     137:     ip->ic_start = sristart;
     138:     sc->sri_if->if_reset = srireset;
     139:     sc->sri_addr = (struct sridevice *) ui->ui_addr;
     140: }
     141:
     142: /*
     143:  * Reset interface after UNIBUS reset.
     144:  * If interface is on specified uba, reset its state.
     145:  */
     146: srireset(unit, uban)
     147:     int unit, uban;
     148: {
     149:     register struct uba_device *ui;
     150:     struct sri_softc *sc;
     151:
     152:     if (unit >= NSRI || (ui = sriinfo[unit]) == 0 || ui->ui_alive == 0 ||
     153:         ui->ui_ubanum != uban)
     154:         return;
     155:     printf(" sri%d", unit);
     156:     sc = &sri_softc[unit];
     157:     /* must go through IMP to allow it to set state */
     158:     (*sc->sri_if->if_init)(unit);
     159: }
     160:
     161: /*
     162:  * Initialize interface: clear recorded pending operations,
     163:  * and retrieve, and initialize UNIBUS resources.  Note
     164:  * return value is used by IMP init routine to mark IMP
     165:  * unavailable for outgoing traffic.
     166:  */
     167: sriinit(unit)
     168:     int unit;
     169: {
     170:     register struct sri_softc *sc;
     171:     register struct uba_device *ui;
     172:     register struct sridevice *addr;
     173:     int x, info;
     174:
     175:     if (unit >= NSRI || (ui = sriinfo[unit]) == 0 || ui->ui_alive == 0) {
     176:         printf("sri%d: not alive\n", unit);
     177:         return (0);
     178:     }
     179:     sc = &sri_softc[unit];
     180:     /*
     181: 	 * Header length is 0 since we have to passs
     182: 	 * the IMP leader up to the protocol interpretation
     183: 	 * routines.  If we had the header length as
     184: 	 * sizeof(struct imp_leader), then the if_ routines
     185: 	 * would asssume we handle it on input and output.
     186: 	 */
     187:
     188:     if (if_ubainit(&sc->sri_ifuba, ui->ui_ubanum, 0,
     189:          (int)btoc(IMPMTU)) == 0) {
     190:         printf("sri%d: can't initialize\n", unit);
     191:         goto down;
     192:     }
     193:     addr = (struct sridevice *)ui->ui_addr;
     194: #if pdp11
     195:     sc->sri_iclick = (sc->sri_ifuba.ifu_r.ifrw_click);
     196:     sc->sri_oclick = (sc->sri_ifuba.ifu_w.ifrw_click);
     197: #endif
     198:
     199:     /*
     200: 	 * Reset the imp interface;
     201: 	 * the delays are pure guesswork.
     202: 	 */
     203:     addr->csr = 0; DELAY(5000L);
     204:     addr->obf = OUT_HRDY;           /* close the relay */
     205:     DELAY(10000L);
     206:     addr->obf = 0;
     207:     /* YECH!!! */
     208:     x = 5;              /* was 500 before rdy line code!!! */
     209:     while (x-- > 0) {
     210:         if ((addr->ibf & IN_INRDY) == 0 )
     211:             break;
     212:         DELAY(10000L);
     213:     }
     214:     if (x <= 0) {
     215: /*		printf("sri%d: imp doesn't respond, ibf=%b\n", unit,
     216: 			addr->ibf, SRI_INBITS);
     217: */
     218:         return(0);  /* goto down;*/
     219:     }
     220:
     221:     /*
     222: 	 * Put up a read.  We can't restart any outstanding writes
     223: 	 * until we're back in synch with the IMP (i.e. we've flushed
     224: 	 * the NOOPs it throws at us).
     225: 	 * Note: IMPMTU includes the leader.
     226: 	 */
     227:     x = splimp();
     228:     sc->sri_iba = (char *)IFRADDR;
     229:     sc->sri_ibc = IMPMTU;
     230:     sc->sri_ibusy = -1;     /* skip leading zeros */
     231:     addr->csr |= (SRI_IINT|SRI_IENB);
     232:     splx(x);
     233:     return (1);
     234: down:
     235:     ui->ui_alive = 0;
     236:     return (0);
     237: }
     238:
     239: /*
     240:  * Start output on an interface.
     241:  */
     242: sristart(dev)
     243:     dev_t dev;
     244: {
     245:     int unit = SRIUNIT(dev), info;
     246:     register struct sri_softc *sc = &sri_softc[unit];
     247:     register struct sridevice *addr;
     248:     struct mbuf *m;
     249:     u_short cmd;
     250:
     251:     if (sc->sri_ic->ic_oactive)
     252:         goto restart;
     253:
     254:     /*
     255: 	 * Not already active, deqeue a request and
     256: 	 * map it onto the UNIBUS.  If no more
     257: 	 * requeusts, just return.
     258: 	 */
     259:     IF_DEQUEUE(&sc->sri_if->if_snd, m);
     260:     if (m == 0) {
     261:         sc->sri_ic->ic_oactive = 0;
     262:         return;
     263:     }
     264:     sc->sri_olen = ((if_wubaput(&sc->sri_ifuba, m) + 1 ) & ~1);
     265:
     266: restart:
     267:     addr = (struct sridevice *)sriinfo[unit]->ui_addr;
     268:     sc->sri_oba = (char *)IFWADDR;
     269:     sc->sri_obc = sc->sri_olen;
     270:     sc->sri_oend = OUT_LAST;
     271:     sc->sri_obc--;
     272:     addr->csr |= (SRI_OENB|SRI_OINT);
     273:     addr->obf = (*sc->sri_oba++ & 0377);
     274:     sc->sri_ic->ic_oactive = 1;
     275: }
     276:
     277: /*
     278:  * Output interrupt handler.
     279:  */
     280: srixint(unit)
     281: {
     282:     register struct sri_softc *sc = &sri_softc[unit];
     283:     register struct sridevice *addr = sc->sri_addr;
     284:     int burst,delay;
     285:     register int x;
     286:
     287:     burst = 0;
     288:     while(sc->sri_obc > 0) {
     289:         x = (*sc->sri_oba++ & 0377);
     290:         if(--sc->sri_obc <= 0) x |= sc->sri_oend;
     291:         addr->obf = x;
     292:         if(++burst > 16) goto out;
     293:         for(delay=0 ;; delay++) {
     294:             if(delay > 12) goto out;
     295:             if(addr->csr&SRI_OREQ) break;
     296:         }
     297:     }
     298:
     299:     addr->csr &= ~SRI_OINT;
     300:     if (sc->sri_ic->ic_oactive == 0) {
     301:         printf("sri%d: stray xmit interrupt\n", unit);
     302:         goto out;
     303:     }
     304:     sridump("out",IFWADDR,sc->sri_olen);
     305:     sc->sri_if->if_opackets++;
     306:     sc->sri_ic->ic_oactive = 0;
     307:     if (sc->sri_obc != 0) { /* only happens if IMP ready drop */
     308:         printf("sri%d: output error, csr=%b\n", unit,
     309:             addr->csr, SRI_BITS);
     310:         sc->sri_if->if_oerrors++;
     311:     }
     312:     if (sc->sri_ifuba.ifu_xtofree) {
     313:         m_freem(sc->sri_ifuba.ifu_xtofree);
     314:         sc->sri_ifuba.ifu_xtofree = 0;
     315:     }
     316:     if (sc->sri_if->if_snd.ifq_head)
     317:         sristart(unit);
     318: out:
     319:     return;
     320: }
     321:
     322: /*
     323:  * Input interrupt handler
     324:  */
     325: srirint(unit)
     326: {
     327:     register struct sri_softc *sc = &sri_softc[unit];
     328:         struct mbuf *m;
     329:     int len, info;
     330:     register struct sridevice *addr = sc->sri_addr;
     331:     int burst,delay;
     332:     register int x;
     333:
     334:     burst = 0;
     335:     for(;;) {
     336:         addr->csr &= ~SRI_IENB; /* prevents next read from starting */
     337:         sc->sri_ibf = x = addr->ibf;
     338:         if(x & IN_CHECK) break; /* LAST or error */
     339:         if(sc->sri_ibc <= 0) break;     /* spurrious int */
     340:         x &= 0377;
     341:         if(sc->sri_ibusy < 0) { /* flushing leading zeros */
     342:             if(x == 0) goto next;
     343:             sc->sri_ibusy = 1;
     344:         }
     345:         *sc->sri_iba++ = x;
     346:         if(--sc->sri_ibc <= 0) break;   /* count exhausted */
     347:     next:
     348:         addr->csr |= SRI_IENB;  /* start next read */
     349:         if(++burst > 16) goto out;
     350:         for(delay=0 ;; delay++) {
     351:             if(delay > 12) goto out;
     352:             if(addr->csr&SRI_IREQ) break;
     353:         }
     354:     }
     355:
     356:     x = sc->sri_ibf;
     357:     /* grab the last byte if EOM */
     358:     if((x & IN_LAST) && !(x & IN_INRDY) && sc->sri_ibc > 0) {
     359:         *sc->sri_iba++ = (x & 0377);
     360:         sc->sri_ibc--;
     361:     }
     362:     addr->csr &= ~SRI_IINT;
     363:     sc->sri_if->if_ipackets++;
     364:     if ((x & IN_INRDY)) {
     365:         printf("sri%d: input error, ibf=%b\n", unit,
     366:             x, SRI_INBITS);
     367:         sc->sri_if->if_ierrors++;
     368:         sc->sri_flush = 1;
     369:         if(sc->sri_obc > 0) {   /* if output active */
     370:             sc->sri_obc = -1;       /* flush it */
     371:             srixint(unit);
     372:         }
     373:         /* tell "other half" of module that ready line just dropped */
     374:         /* Kludge, I know, but the alternative is to create an mbuf */
     375:         impinput(unit, (struct  mbuf *) 0); /* ready line dropped */
     376:         goto out; /* leave interrupts un-enabled */ /* FIX THIS!!!! */
     377:     }
     378:
     379:     if (sc->sri_flush) {
     380:         if (x & IN_LAST)
     381:             sc->sri_flush = 0;
     382:         goto setup;
     383:     }
     384:     len = IMPMTU - sc->sri_ibc;
     385:     if (len < 10 || len > IMPMTU) {
     386:         printf("sri%d: bad length=%d\n", len);
     387:         sc->sri_if->if_ierrors++;
     388:         goto setup;
     389:     }
     390:     sridump("in ",IFRADDR,len);
     391:
     392:     /*
     393: 	 * The next to last parameter is always 0 since using
     394: 	 * trailers on the ARPAnet is insane.
     395: 	 */
     396:     m = if_rubaget(&sc->sri_ifuba, len, 0, &sc->sri_if);
     397:     if (m == 0)
     398:         goto setup;
     399:     if ((x & IN_LAST) == 0) {
     400:         if (sc->sri_iq)
     401:             m_cat(sc->sri_iq, m);
     402:         else
     403:             sc->sri_iq = m;
     404:         goto setup;
     405:     }
     406:     if (sc->sri_iq) {
     407:         m_cat(sc->sri_iq, m);
     408:         m = sc->sri_iq;
     409:         sc->sri_iq = 0;
     410:     }
     411:     impinput(unit, m);
     412:
     413: setup:
     414:     /*
     415: 	 * Setup for next message.
     416: 	 */
     417:     sc->sri_iba = (char *)IFRADDR;
     418:     sc->sri_ibc = IMPMTU;
     419:     sc->sri_ibusy = -1;     /* skip leading zeros */
     420:     addr->csr |= (SRI_IINT|SRI_IENB);
     421: out:
     422:     return;
     423: }
     424:
     425: sridump(str,aba,abc)
     426: char *str,*aba;
     427: {
     428:     int col,i;
     429:
     430:     if(str[0] != 07)
     431:         if(!sridebug()) return;
     432:     printf("%s  ",str);
     433:     col = 0;
     434:     for(; abc ; abc--) {
     435:         i = *aba++ & 0377;
     436:         printf("%o ",i);
     437:         if(++col > 31) {
     438:             col = 0;
     439:             printf("\n   ");
     440:         }
     441:     }
     442:     printf("\n");
     443: }
     444:
     445: #if vax
     446:
     447: sridebug()
     448: {
     449:         return( (mfpr(RXCS) & RXCS_DONE) == 0 &&
     450:             (mfpr(RXDB) & 0177) == 07);
     451: }
     452:
     453: #endif
     454: #if pdp11
     455:
     456: sridebug()
     457: {
     458:         return( (*(char *)0177560 & 0200) == 0 &&
     459:             (*(char *)0177562 & 0177) == 07);
     460: }
     461:
     462: #endif
     463: #endif NSRI

#### Defined functions

sriattach defined in line 121; used 2 times

- in line 31-35(2)

sridebug defined in line 456; used 1 times

- in line 431

sridump defined in line 425; used 2 times

- in line 304, 390

sriinit defined in line 167; used 2 times

- in line 41, 136

sriprobe defined in line 84; used 2 times

- in line 31-35(2)

srireset defined in line 146; used 3 times

- in line 41, 131, 138

srirint defined in line 325; used 2 times

- in line 31, 94

sristart defined in line 242; used 3 times

- in line 41, 137, 317

srixint defined in line 280; used 3 times

- in line 31, 94, 371

#### Defined variables

sri_softc defined in line 79; used 6 times

- in line 124, 156, 179, 246, 282, 327

sridriver defined in line 34; never used
sriinfo defined in line 32; used 4 times

- in line 35, 152, 175, 267

sristd defined in line 33; used 1 times

- in line 35

#### Defined struct's

ifimpcb defined in line 126; used 2 times

- in line 131(2)

sri_softc defined in line 60; used 12 times

- in line 124(2), 150(2), 170(2), 246(2), 282(2), 327(2)

#### Defined macros

IFRADDR defined in line 38; used 3 times

- in line 228, 390, 417

IFWADDR defined in line 39; used 2 times

- in line 268, 304

SRIUNIT defined in line 36; used 1 times

- in line 245

Last modified: 1990-05-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1318 |