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

##### Functions

    dmcattach         X
    dmcinit           X
    dmcload           X
    dmcoutput         X
    dmcprobe          X
    dmcrint           X
    dmcstart          X
    dmcxint           X

##### Variables

    dmc_base          X
    dmc_softc         X
    dmcdebug          X
    dmcdriver         X
    dmcinfo           X
    dmcstd            X

##### Macros

    DMCBMAPPED        X
    DMCRUN            X
    DMC_AF            X
    DMC_NET           X
    hiword            X
    loword            X
    printd            X

##### struct's

    dmc_base          X
    dmc_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_dmc.c	1.1 (2.10BSD Berkeley) 12/1/86
       7:  */
       8:
       9: #include "dmc.h"
      10: #if NDMC > 0
      11:
      12: #define printd if(dmcdebug)printf
      13: int dmcdebug = 1;
      14: /*
      15:  * DMC11 device driver, internet version
      16:  *
      17:  * TODO
      18:  *	allow more than one outstanding read or write.
      19:  */
      20:
      21: #include "param.h"
      22: #include "systm.h"
      23: #include "mbuf.h"
      24: #include "buf.h"
      25: #include "ioctl.h"
      26: #include "tty.h"
      27: #include "domain.h"
      28: #include "protosw.h"
      29: #include "socket.h"
      30: #include "pdpuba/ubavar.h"
      31: #include "netinet/in.h"
      32: #include "netinet/in_systm.h"
      33: #include "net/if.h"
      34: #include "pdpif/if_uba.h"
      35: #include "pdpif/if_dmc.h"
      36: #include "netinet/ip.h"
      37: #include "netinet/in_var.h"
      38: #include "netinet/ip_var.h"
      39: #include "net/route.h"
      40: #include "net/netisr.h"
      41: #include "errno.h"
      42:
      43: /*
      44:  * Driver information for auto-configuration stuff.
      45:  */
      46: int dmcprobe(), dmcattach(), dmcinit(), dmcoutput();
      47: struct  uba_device *dmcinfo[NDMC];
      48: u_short dmcstd[] = { 0 };
      49: struct  uba_driver dmcdriver =
      50:     { dmcprobe, 0, dmcattach, 0, dmcstd, "dmc", dmcinfo };
      51:
      52: #define DMC_AF  0xff        /* 8 bits of address type in ui_flags */
      53: #define DMC_NET 0xffffff00  /* 24 bits of net number in ui_flags */
      54:
      55: /*
      56:  * DMC software status per interface.
      57:  *
      58:  * Each interface is referenced by a network interface structure,
      59:  * sc_if, which the routing code uses to locate the interface.
      60:  * This structure contains the output queue for the interface, its address, ...
      61:  * We also have, for each interface, a UBA interface structure, which
      62:  * contains information about the UNIBUS resources held by the interface:
      63:  * map registers, buffered data paths, etc.  Information is cached in this
      64:  * structure for use by the if_uba.c routines in running the interface
      65:  * efficiently.
      66:  */
      67: struct dmc_softc {
      68:     struct  ifnet sc_if;        /* network-visible interface */
      69:     struct  ifuba sc_ifuba;     /* UNIBUS resources */
      70:     short   sc_flag;        /* flags */
      71:     short   sc_oactive;     /* output active */
      72:     int sc_ubinfo;      /* UBA mapping info for base table */
      73:     struct clist sc_que;        /* command queue */
      74: } dmc_softc[NDMC];
      75:
      76: /* flags */
      77: #define DMCRUN      01
      78: #define DMCBMAPPED  02      /* base table mapped */
      79:
      80: struct dmc_base {
      81:     short   d_base[128];        /* DMC base table */
      82: } dmc_base[NDMC];
      83:
      84: #define loword(x)   ((short *)&x)[0]
      85: #define hiword(x)   ((short *)&x)[1]
      86:
      87: dmcprobe(reg)
      88:     caddr_t reg;
      89: {
      90:     register int br, cvec;
      91:     register struct dmcdevice *addr = (struct dmcdevice *)reg;
      92:     register int i;
      93:
      94: #ifdef lint
      95:     br = 0; cvec = br; br = cvec;
      96:     dmcrint(0); dmcxint(0);
      97: #endif
      98:     addr->bsel1 = DMC_MCLR;
      99:     for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
     100:         ;
     101:     if ((addr->bsel1 & DMC_RUN) == 0)
     102:         return (0);
     103:     addr->bsel1 &= ~DMC_MCLR;
     104:     addr->bsel0 = DMC_RQI|DMC_IEI;
     105:     DELAY(100000L);
     106:     addr->bsel1 = DMC_MCLR;
     107:     for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)
     108:         ;
     109: #ifdef ECHACK
     110:     br = 0x16;
     111: #endif
     112:     return (1);
     113: }
     114:
     115: /*
     116:  * Interface exists: make available by filling in network interface
     117:  * record.  System will initialize the interface when it is ready
     118:  * to accept packets.
     119:  */
     120: dmcattach(ui)
     121:     register struct uba_device *ui;
     122: {
     123:     register struct dmc_softc *sc = &dmc_softc[ui->ui_unit];
     124:     register struct sockaddr_in *sin;
     125:
     126:     sc->sc_if.if_unit = ui->ui_unit;
     127:     sc->sc_if.if_name = "dmc";
     128:     sc->sc_if.if_mtu = DMCMTU;
     129:     sc->sc_if.if_init = dmcinit;
     130:     sc->sc_if.if_output = dmcoutput;
     131:     sc->sc_if.if_reset = 0;
     132:     sc->sc_if.if_flags = IFF_POINTOPOINT;
     133:     /* DON'T KNOW IF THIS WILL WORK WITH A BDP AT HIGH SPEEDS */
     134:     sc->sc_ifuba.ifu_flags = UBA_NEEDBDP | UBA_CANTWAIT;
     135:     if_attach(&sc->sc_if);
     136: }
     137:
     138: /*
     139:  * Initialization of interface; reinitialize UNIBUS usage.
     140:  */
     141: dmcinit(unit)
     142:     int unit;
     143: {
     144:     register struct dmc_softc *sc = &dmc_softc[unit];
     145:     register struct uba_device *ui = dmcinfo[unit];
     146:     register struct dmcdevice *addr;
     147:     int base;
     148:
     149:     printd("dmcinit\n");
     150:     if ((sc->sc_flag&DMCBMAPPED) == 0) {
     151:         sc->sc_ubinfo = uballoc((caddr_t)&dmc_base[unit],
     152:                     sizeof (struct dmc_base));
     153:         sc->sc_flag |= DMCBMAPPED;
     154:     }
     155:     if (if_ubainit(&sc->sc_ifuba, ui->ui_ubanum, 0,
     156:         (int)btoc(DMCMTU)) == 0) {
     157:         printf("dmc%d: can't initialize\n", unit);
     158:         sc->sc_if.if_flags &= ~IFF_UP;
     159:         return;
     160:     }
     161:     addr = (struct dmcdevice *)ui->ui_addr;
     162:     addr->bsel2 |= DMC_IEO;
     163:     base = sc->sc_ubinfo & 0x3ffff;
     164:     printd("  base 0x%x\n", base);
     165:     dmcload(sc, DMC_BASEI, base, (base>>2)&DMC_XMEM);
     166:     dmcload(sc, DMC_CNTLI, 0, 0);
     167:     base = sc->sc_ifuba.ifu_r.ifrw_info & 0x3ffff;
     168:     dmcload(sc, DMC_READ, base, ((base>>2)&DMC_XMEM)|DMCMTU);
     169:     printd("  first read queued, addr 0x%x\n", base);
     170:     sc->sc_if.if_flags |= IFF_UP;
     171: }
     172:
     173: /*
     174:  * Start output on interface.  Get another datagram
     175:  * to send from the interface queue and map it to
     176:  * the interface before starting output.
     177:  */
     178: dmcstart(dev)
     179:     dev_t dev;
     180: {
     181:     int unit = minor(dev);
     182:     struct uba_device *ui = dmcinfo[unit];
     183:     register struct dmc_softc *sc = &dmc_softc[unit];
     184:     int addr, len;
     185:     struct mbuf *m;
     186:
     187:     printd("dmcstart\n");
     188:     /*
     189: 	 * Dequeue a request and map it to the UNIBUS.
     190: 	 * If no more requests, just return.
     191: 	 */
     192:     IF_DEQUEUE(&sc->sc_if.if_snd, m);
     193:     if (m == 0)
     194:         return;
     195:     len = if_wubaput(&sc->sc_ifuba, m);
     196:
     197:     addr = sc->sc_ifuba.ifu_w.ifrw_info & 0x3ffff;
     198:     printd("  len %d, addr 0x%x, ", len, addr);
     199:     printd("mr 0x%lx\n", sc->sc_ifuba.ifu_w.ifrw_info);
     200:     dmcload(sc, DMC_WRITE, addr, (len&DMC_CCOUNT)|((addr>>2)&DMC_XMEM));
     201:     sc->sc_oactive = 1;
     202: }
     203:
     204: /*
     205:  * Utility routine to load the DMC device registers.
     206:  */
     207: dmcload(sc, type, w0, w1)
     208:     register struct dmc_softc *sc;
     209:     int type, w0, w1;
     210: {
     211:     register struct dmcdevice *addr;
     212:     register int unit, sps, n;
     213:
     214:     printd("dmcload: 0x%x 0x%x 0x%x\n", type, w0, w1);
     215:     unit = sc - dmc_softc;
     216:     addr = (struct dmcdevice *)dmcinfo[unit]->ui_addr;
     217:     sps = splimp();
     218:     if ((n = sc->sc_que.c_cc) == 0)
     219:         addr->bsel0 = type | DMC_RQI;
     220:     else
     221:         (void) putc(type | DMC_RQI, &sc->sc_que);
     222:     (void) putw(w0, &sc->sc_que);
     223:     (void) putw(w1, &sc->sc_que);
     224:     if (n == 0)
     225:         dmcrint(unit);
     226:     splx(sps);
     227: }
     228:
     229: /*
     230:  * DMC interface receiver interrupt.
     231:  * Ready to accept another command,
     232:  * pull one off the command queue.
     233:  */
     234: dmcrint(unit)
     235:     int unit;
     236: {
     237:     register struct dmc_softc *sc;
     238:     register struct dmcdevice *addr;
     239:     register int n;
     240:
     241:     addr = (struct dmcdevice *)dmcinfo[unit]->ui_addr;
     242:     sc = &dmc_softc[unit];
     243:     while (addr->bsel0&DMC_RDYI) {
     244:         addr->sel4 = getw(&sc->sc_que);
     245:         addr->sel6 = getw(&sc->sc_que);
     246:         addr->bsel0 &= ~(DMC_IEI|DMC_RQI);
     247:         while (addr->bsel0&DMC_RDYI)
     248:             ;
     249:         if (sc->sc_que.c_cc == 0)
     250:             return;
     251:         addr->bsel0 = getc(&sc->sc_que);
     252:         n = RDYSCAN;
     253:         while (n-- && (addr->bsel0&DMC_RDYI) == 0)
     254:             ;
     255:     }
     256:     if (sc->sc_que.c_cc)
     257:         addr->bsel0 |= DMC_IEI;
     258: }
     259:
     260: /*
     261:  * DMC interface transmitter interrupt.
     262:  * A transfer has completed, check for errors.
     263:  * If it was a read, notify appropriate protocol.
     264:  * If it was a write, pull the next one off the queue.
     265:  */
     266: dmcxint(unit)
     267:     int unit;
     268: {
     269:     register struct dmc_softc *sc;
     270:     struct uba_device *ui = dmcinfo[unit];
     271:     struct dmcdevice *addr;
     272:     struct mbuf *m;
     273:     register struct ifqueue *inq;
     274:     int arg, cmd, len;
     275:
     276:     addr = (struct dmcdevice *)ui->ui_addr;
     277:     arg = addr->sel6;
     278:     cmd = addr->bsel2&7;
     279:     addr->bsel2 &= ~DMC_RDYO;
     280:     sc = &dmc_softc[unit];
     281:     printd("dmcxint\n");
     282:     switch (cmd) {
     283:
     284:     case DMC_OUR:
     285:         /*
     286: 		 * A read has completed.  Purge input buffered
     287: 		 * data path.  Pass packet to type specific
     288: 		 * higher-level input routine.
     289: 		 */
     290:         sc->sc_if.if_ipackets++;
     291:         len = arg & DMC_CCOUNT;
     292:         printd("  read done, len %d\n", len);
     293:         switch (sc->sc_flag & DMC_AF) {
     294: #ifdef INET
     295:         case AF_INET:
     296:             schednetisr(NETISR_IP);
     297:             inq = &ipintrq;
     298:             break;
     299: #endif
     300:
     301:         default:
     302:             printf("dmc%d: unknown address type %d\n", unit,
     303:                 sc->sc_flag & DMC_AF);
     304:             goto setup;
     305:         }
     306:         m = if_rubaget(&sc->sc_ifuba, len, 0, &sc->sc_if);
     307:         if (m == 0)
     308:             goto setup;
     309:         if (IF_QFULL(inq)) {
     310:             IF_DROP(inq);
     311:             (void) m_freem(m);
     312:         } else
     313:             IF_ENQUEUE(inq, m);
     314:
     315: setup:
     316:         arg = sc->sc_ifuba.ifu_r.ifrw_info & 0x3ffff;
     317:         dmcload(sc, DMC_READ, arg, ((arg >> 2) & DMC_XMEM) | DMCMTU);
     318:         return;
     319:
     320:     case DMC_OUX:
     321:         /*
     322: 		 * A write has completed, start another
     323: 		 * transfer if there is more data to send.
     324: 		 */
     325:         if (sc->sc_oactive == 0)
     326:             return;     /* SHOULD IT BE A FATAL ERROR? */
     327:         printd("  write done\n");
     328:         sc->sc_if.if_opackets++;
     329:         sc->sc_oactive = 0;
     330:         if (sc->sc_ifuba.ifu_xtofree) {
     331:             (void) m_freem(sc->sc_ifuba.ifu_xtofree);
     332:             sc->sc_ifuba.ifu_xtofree = 0;
     333:         }
     334:         if (sc->sc_if.if_snd.ifq_head == 0)
     335:             return;
     336:         dmcstart(unit);
     337:         return;
     338:
     339:     case DMC_CNTLO:
     340:         arg &= DMC_CNTMASK;
     341:         if (arg&DMC_FATAL) {
     342:             addr->bsel1 = DMC_MCLR;
     343:             sc->sc_flag &= ~DMCRUN;
     344:             /*** DO SOMETHING TO RESTART DEVICE ***/
     345:             printf("DMC FATAL ERROR 0%o\n", arg);
     346:         } else {
     347:             /* ACCUMULATE STATISTICS */
     348:             printf("DMC SOFT ERROR 0%o\n", arg);
     349:         }
     350:         return;
     351:
     352:     default:
     353:         printf("dmc%d: bad control %o\n", unit, cmd);
     354:     }
     355: }
     356:
     357: /*
     358:  * DMC output routine.
     359:  * Just send the data, header was supplied by
     360:  * upper level protocol routines.
     361:  */
     362: dmcoutput(ifp, m, dst)
     363:     register struct ifnet *ifp;
     364:     register struct mbuf *m;
     365:     struct sockaddr *dst;
     366: {
     367:     struct uba_device *ui = dmcinfo[ifp->if_unit];
     368:     int s;
     369:
     370:     printd("dmcoutput\n");
     371:     if (dst->sa_family != AF_INET) {
     372:         printf("dmc%d: af%d not supported\n", ifp->if_unit, AF_INET);
     373:         m_freem(m);
     374:         return (EAFNOSUPPORT);
     375:     }
     376:     s = splimp();
     377:     if (IF_QFULL(&ifp->if_snd)) {
     378:         IF_DROP(&ifp->if_snd);
     379:         m_freem(m);
     380:         splx(s);
     381:         return (ENOBUFS);
     382:     }
     383:     IF_ENQUEUE(&ifp->if_snd, m);
     384:     if (dmc_softc[ifp->if_unit].sc_oactive == 0)
     385:         dmcstart(ifp->if_unit);
     386:     splx(s);
     387:     return (0);
     388: }
     389: #endif NDMC

#### Defined functions

dmcattach defined in line 120; used 2 times

- in line 46-50(2)

dmcinit defined in line 141; used 2 times

- in line 46, 129

dmcload defined in line 207; used 5 times

- in line 165-168(3), 200, 317

dmcoutput defined in line 362; used 2 times

- in line 46, 130

dmcprobe defined in line 87; used 2 times

- in line 46-50(2)

dmcrint defined in line 234; used 2 times

- in line 96, 225

dmcstart defined in line 178; used 2 times

- in line 336, 385

dmcxint defined in line 266; used 1 times

- in line 96

#### Defined variables

dmc_base defined in line 82; used 1 times

- in line 151

dmc_softc defined in line 74; used 7 times

- in line 123, 144, 183, 215, 242, 280, 384

dmcdebug defined in line 13; used 1 times

- in line 12

dmcdriver defined in line 49; never used
dmcinfo defined in line 47; used 7 times

- in line 50, 145, 182, 216, 241, 270, 367

dmcstd defined in line 48; used 1 times

- in line 50

#### Defined struct's

dmc_base defined in line 80; used 2 times

- in line 152(2)

dmc_softc defined in line 67; used 12 times

- in line 123(2), 144(2), 183(2), 208(2), 237(2), 269(2)

#### Defined macros

DMCBMAPPED defined in line 78; used 2 times

- in line 150-153(2)

DMCRUN defined in line 77; used 1 times

- in line 343

DMC_AF defined in line 52; used 2 times

- in line 293, 303

DMC_NET defined in line 53; never used
hiword defined in line 85; never used
loword defined in line 84; never used
printd defined in line 12; used 11 times

- in line 149, 164-169(2), 187, 198-199(2), 214, 281, 292, 327, 370

Last modified: 1990-09-10 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1314 |