# 2.11BSD#431 - /usr/src/sys/vaxif/if_acc.c

##### Functions

    accattach         X
    accdown           X
    accinit           X
    accinputreset     X
    accoutput         X
    accprobe          X
    accreset          X
    accrint           X
    accxint           X

##### Variables

    acc_softc         X
    accdriver         X
    accinfo           X
    accstd            X

##### struct's

    acc_softc         X

       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 this notice is preserved and that due credit is given
       7:  * to the University of California at Berkeley. The name of the University
       8:  * may not be used to endorse or promote products derived from this
       9:  * software without specific prior written permission. This software
      10:  * is provided ``as is'' without express or implied warranty.
      11:  *
      12:  *	%W% (Berkeley) %G%
      13:  */
      14:
      15: #include "acc.h"
      16: #if NACC > 0
      17:
      18: /*
      19:  * ACC LH/DH ARPAnet IMP interface driver.
      20:  */
      21: #include "../machine/pte.h"
      22:
      23: #include "param.h"
      24: #include "systm.h"
      25: #include "mbuf.h"
      26: #include "buf.h"
      27: #include "protosw.h"
      28: #include "socket.h"
      29: #include "vmmac.h"
      30:
      31: #include "../net/if.h"
      32: #include "../netimp/if_imp.h"
      33:
      34: #include "../vax/cpu.h"
      35: #include "../vax/mtpr.h"
      36: #include "if_accreg.h"
      37: #include "if_uba.h"
      38: #include "../vaxuba/ubareg.h"
      39: #include "../vaxuba/ubavar.h"
      40:
      41: int     accprobe(), accattach(), accrint(), accxint();
      42: struct  uba_device *accinfo[NACC];
      43: u_short accstd[] = { 0 };
      44: struct  uba_driver accdriver =
      45:     { accprobe, 0, accattach, 0, accstd, "acc", accinfo };
      46:
      47: int accinit(), accoutput(), accdown(), accreset();
      48:
      49: /*
      50:  * "Lower half" of IMP interface driver.
      51:  *
      52:  * Each IMP interface is handled by a common module which handles
      53:  * the IMP-host protocol and a hardware driver which manages the
      54:  * hardware specific details of talking with the IMP.
      55:  *
      56:  * The hardware portion of the IMP driver handles DMA and related
      57:  * management of UNIBUS resources.  The IMP protocol module interprets
      58:  * contents of these messages and "controls" the actions of the
      59:  * hardware module during IMP resets, but not, for instance, during
      60:  * UNIBUS resets.
      61:  *
      62:  * The two modules are coupled at "attach time", and ever after,
      63:  * through the imp interface structure.  Higher level protocols,
      64:  * e.g. IP, interact with the IMP driver, rather than the ACC.
      65:  */
      66: struct  acc_softc {
      67:     struct  imp_softc *acc_imp; /* data structure shared with IMP */
      68:     struct  ifuba acc_ifuba;    /* UNIBUS resources */
      69:     struct  mbuf *acc_iq;       /* input reassembly queue */
      70:     short   acc_olen;       /* size of last message sent */
      71:     char    acc_flush;      /* flush remainder of message */
      72: } acc_softc[NACC];
      73:
      74: /*
      75:  * Reset the IMP and cause a transmitter interrupt by
      76:  * performing a null DMA.
      77:  */
      78: accprobe(reg)
      79:     caddr_t reg;
      80: {
      81:     register int br, cvec;      /* r11, r10 value-result */
      82:     register struct accdevice *addr = (struct accdevice *)reg;
      83:
      84: #ifdef lint
      85:     br = 0; cvec = br; br = cvec;
      86:     accrint(0); accxint(0);
      87: #endif
      88:     addr->icsr = ACC_RESET; DELAY(5000);
      89:     addr->ocsr = ACC_RESET; DELAY(5000);
      90:     addr->ocsr = OUT_BBACK; DELAY(5000);
      91:     addr->owc = 0;
      92:     addr->ocsr = ACC_IE | ACC_GO; DELAY(5000);
      93:     addr->ocsr = 0;
      94:     if (cvec && cvec != 0x200)  /* transmit -> receive */
      95:         cvec -= 4;
      96:     return (1);
      97: }
      98:
      99: /*
     100:  * Call the IMP module to allow it to set up its internal
     101:  * state, then tie the two modules together by setting up
     102:  * the back pointers to common data structures.
     103:  */
     104: accattach(ui)
     105:     register struct uba_device *ui;
     106: {
     107:     register struct acc_softc *sc = &acc_softc[ui->ui_unit];
     108:     register struct impcb *ip;
     109:
     110:     if ((sc->acc_imp = impattach(ui->ui_driver->ud_dname, ui->ui_unit,
     111:         accreset)) == 0)
     112:         return;
     113:     ip = &sc->acc_imp->imp_cb;
     114:     ip->ic_init = accinit;
     115:     ip->ic_output = accoutput;
     116:     ip->ic_down = accdown;
     117:     sc->acc_ifuba.ifu_flags = UBA_CANTWAIT;
     118: #ifdef notdef
     119:     sc->acc_ifuba.ifu_flags |= UBA_NEEDBDP;
     120: #endif
     121: }
     122:
     123: /*
     124:  * Reset interface after UNIBUS reset.
     125:  * If interface is on specified uba, reset its state.
     126:  */
     127: accreset(unit, uban)
     128:     int unit, uban;
     129: {
     130:     register struct uba_device *ui;
     131:     struct acc_softc *sc;
     132:
     133:     if (unit >= NACC || (ui = accinfo[unit]) == 0 || ui->ui_alive == 0 ||
     134:         ui->ui_ubanum != uban)
     135:         return;
     136:     printf(" acc%d", unit);
     137:     sc = &acc_softc[unit];
     138:     sc->acc_imp->imp_if.if_flags &= ~IFF_RUNNING;
     139:     /* must go through IMP to allow it to set state */
     140:     (*sc->acc_imp->imp_if.if_init)(sc->acc_imp->imp_if.if_unit);
     141: }
     142:
     143: /*
     144:  * Initialize interface: clear recorded pending operations,
     145:  * and retrieve, and initialize UNIBUS resources.  Note
     146:  * return value is used by IMP init routine to mark IMP
     147:  * unavailable for outgoing traffic.
     148:  */
     149: accinit(unit)
     150:     int unit;
     151: {
     152:     register struct acc_softc *sc;
     153:     register struct uba_device *ui;
     154:     register struct accdevice *addr;
     155:     int info;
     156:
     157:     if (unit >= NACC || (ui = accinfo[unit]) == 0 || ui->ui_alive == 0) {
     158:         printf("acc%d: not alive\n", unit);
     159:         return (0);
     160:     }
     161:     sc = &acc_softc[unit];
     162:     /*
     163: 	 * Header length is 0 since we have to passs
     164: 	 * the IMP leader up to the protocol interpretation
     165: 	 * routines.  If we had the header length as
     166: 	 * sizeof(struct imp_leader), then the if_ routines
     167: 	 * would asssume we handle it on input and output.
     168: 	 */
     169:     if ((sc->acc_imp->imp_if.if_flags & IFF_RUNNING) == 0 &&
     170:         if_ubainit(&sc->acc_ifuba, ui->ui_ubanum, 0,
     171:          (int)btoc(IMP_RCVBUF)) == 0) {
     172:         printf("acc%d: can't initialize\n", unit);
     173:         sc->acc_imp->imp_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
     174:         return (0);
     175:     }
     176:     sc->acc_imp->imp_if.if_flags |= IFF_RUNNING;
     177:     addr = (struct accdevice *)ui->ui_addr;
     178:
     179:     /*
     180: 	 * Reset the imp interface;
     181: 	 * the delays are pure guesswork.
     182: 	 */
     183:         addr->ocsr = ACC_RESET; DELAY(5000);
     184:     addr->ocsr = OUT_BBACK; DELAY(5000);    /* reset host master ready */
     185:     addr->ocsr = 0;
     186:     if (accinputreset(addr, unit) == 0) {
     187:         ui->ui_alive = 0;
     188:         return (0);
     189:     }
     190:
     191:     /*
     192: 	 * Put up a read.  We can't restart any outstanding writes
     193: 	 * until we're back in synch with the IMP (i.e. we've flushed
     194: 	 * the NOOPs it throws at us).
     195: 	 * Note: IMP_RCVBUF includes the leader.
     196: 	 */
     197:     info = sc->acc_ifuba.ifu_r.ifrw_info;
     198:     addr->iba = (u_short)info;
     199:     addr->iwc = -((IMP_RCVBUF) >> 1);
     200: #ifdef LOOPBACK
     201:     addr->ocsr |= OUT_BBACK;
     202: #endif
     203:     addr->icsr =
     204:         IN_MRDY | ACC_IE | IN_WEN | ((info & 0x30000) >> 12) | ACC_GO;
     205:     return (1);
     206: }
     207:
     208: accinputreset(addr, unit)
     209:     register struct accdevice *addr;
     210:     register int unit;
     211: {
     212:     register int i;
     213:
     214:     addr->icsr = ACC_RESET; DELAY(5000);
     215:     addr->icsr = IN_MRDY | IN_WEN;      /* close the relay */
     216:     DELAY(10000);
     217:     /* YECH!!! */
     218:     for (i = 0; i < 500; i++) {
     219:         if ((addr->icsr & IN_HRDY) ||
     220:             (addr->icsr & (IN_RMR | IN_IMPBSY)) == 0)
     221:             return (1);
     222:         addr->icsr = IN_MRDY | IN_WEN; DELAY(10000);
     223:         /* keep turning IN_RMR off */
     224:     }
     225:     printf("acc%d: imp doesn't respond, icsr=%b\n", unit,
     226:         addr->icsr, ACC_INBITS);
     227:     return (0);
     228: }
     229:
     230: /*
     231:  * Drop the host ready line to mark host down.
     232:  */
     233: accdown(unit)
     234:     int unit;
     235: {
     236:     register struct accdevice *addr;
     237:
     238:     addr = (struct accdevice *)(accinfo[unit]->ui_addr);
     239:         addr->ocsr = ACC_RESET;
     240:     DELAY(5000);
     241:     addr->ocsr = OUT_BBACK;     /* reset host master ready */
     242:     return (1);
     243: }
     244:
     245: /*
     246:  * Start output on an interface.
     247:  */
     248: accoutput(unit, m)
     249:     int unit;
     250:     struct mbuf *m;
     251: {
     252:     int info;
     253:     register struct acc_softc *sc = &acc_softc[unit];
     254:     register struct accdevice *addr;
     255:     u_short cmd;
     256:
     257:     sc->acc_olen = if_wubaput(&sc->acc_ifuba, m);
     258:     /*
     259: 	 * Have request mapped to UNIBUS for
     260: 	 * transmission; start the output.
     261: 	 */
     262:     if (sc->acc_ifuba.ifu_flags & UBA_NEEDBDP)
     263:         UBAPURGE(sc->acc_ifuba.ifu_uba, sc->acc_ifuba.ifu_w.ifrw_bdp);
     264:     addr = (struct accdevice *)accinfo[unit]->ui_addr;
     265:     info = sc->acc_ifuba.ifu_w.ifrw_info;
     266:     addr->oba = (u_short)info;
     267:     addr->owc = -((sc->acc_olen + 1) >> 1);
     268:     cmd = ACC_IE | OUT_ENLB | ((info & 0x30000) >> 12) | ACC_GO;
     269: #ifdef LOOPBACK
     270:     cmd |= OUT_BBACK;
     271: #endif
     272:     addr->ocsr = cmd;
     273:     sc->acc_imp->imp_cb.ic_oactive = 1;
     274: }
     275:
     276: /*
     277:  * Output interrupt handler.
     278:  */
     279: accxint(unit)
     280:     int unit;
     281: {
     282:     register struct acc_softc *sc = &acc_softc[unit];
     283:     register struct accdevice *addr;
     284:
     285:     addr = (struct accdevice *)accinfo[unit]->ui_addr;
     286:     if (sc->acc_imp->imp_cb.ic_oactive == 0) {
     287:         printf("acc%d: stray xmit interrupt, csr=%b\n", unit,
     288:             addr->ocsr, ACC_OUTBITS);
     289:         return;
     290:     }
     291:     sc->acc_imp->imp_if.if_opackets++;
     292:     sc->acc_imp->imp_cb.ic_oactive = 0;
     293:     if (addr->ocsr & ACC_ERR) {
     294:         printf("acc%d: output error, ocsr=%b, icsr=%b\n", unit,
     295:             addr->ocsr, ACC_OUTBITS, addr->icsr, ACC_INBITS);
     296:         sc->acc_imp->imp_if.if_oerrors++;
     297:     }
     298:     if (sc->acc_ifuba.ifu_xtofree) {
     299:         m_freem(sc->acc_ifuba.ifu_xtofree);
     300:         sc->acc_ifuba.ifu_xtofree = 0;
     301:     }
     302:     impstart(sc->acc_imp);
     303: }
     304:
     305: /*
     306:  * Input interrupt handler
     307:  */
     308: accrint(unit)
     309:     int unit;
     310: {
     311:     register struct acc_softc *sc = &acc_softc[unit];
     312:     register struct accdevice *addr;
     313:         struct mbuf *m;
     314:     int len, info;
     315:
     316:     addr = (struct accdevice *)accinfo[unit]->ui_addr;
     317:     sc->acc_imp->imp_if.if_ipackets++;
     318:
     319:     /*
     320: 	 * Purge BDP; flush message if error indicated.
     321: 	 */
     322:     if (sc->acc_ifuba.ifu_flags & UBA_NEEDBDP)
     323:         UBAPURGE(sc->acc_ifuba.ifu_uba, sc->acc_ifuba.ifu_r.ifrw_bdp);
     324:     if (addr->icsr & ACC_ERR) {
     325:         printf("acc%d: input error, csr=%b\n", unit,
     326:             addr->icsr, ACC_INBITS);
     327:         sc->acc_imp->imp_if.if_ierrors++;
     328:         sc->acc_flush = 1;
     329:     }
     330:
     331:     if (sc->acc_flush) {
     332:         if (addr->icsr & IN_EOM)
     333:             sc->acc_flush = 0;
     334:         goto setup;
     335:     }
     336:     len = IMP_RCVBUF + (addr->iwc << 1);
     337:     if (len < 0 || len > IMP_RCVBUF) {
     338:         printf("acc%d: bad length=%d\n", unit, len);
     339:         sc->acc_imp->imp_if.if_ierrors++;
     340:         goto setup;
     341:     }
     342:
     343:     /*
     344: 	 * The offset parameter is always 0 since using
     345: 	 * trailers on the ARPAnet is insane.
     346: 	 */
     347:     m = if_rubaget(&sc->acc_ifuba, len, 0, &sc->acc_imp->imp_if);
     348:     if (m == 0)
     349:         goto setup;
     350:     if ((addr->icsr & IN_EOM) == 0) {
     351:         if (sc->acc_iq)
     352:             m_cat(sc->acc_iq, m);
     353:         else
     354:             sc->acc_iq = m;
     355:         goto setup;
     356:     }
     357:     if (sc->acc_iq) {
     358:         m_cat(sc->acc_iq, m);
     359:         m = sc->acc_iq;
     360:         sc->acc_iq = 0;
     361:     }
     362:     impinput(unit, m);
     363:
     364: setup:
     365:     /*
     366: 	 * Setup for next message.
     367: 	 */
     368:     info = sc->acc_ifuba.ifu_r.ifrw_info;
     369:     addr->iba = (u_short)info;
     370:     addr->iwc = -((IMP_RCVBUF)>> 1);
     371:     addr->icsr =
     372:         IN_MRDY | ACC_IE | IN_WEN | ((info & 0x30000) >> 12) | ACC_GO;
     373: }
     374: #endif

#### Defined functions

accattach defined in line 104; used 2 times

- in line 41-45(2)

accdown defined in line 233; used 2 times

- in line 47, 116

accinit defined in line 149; used 2 times

- in line 47, 114

accinputreset defined in line 208; used 1 times

- in line 186

accoutput defined in line 248; used 2 times

- in line 47, 115

accprobe defined in line 78; used 2 times

- in line 41-45(2)

accreset defined in line 127; used 2 times

- in line 47, 111

accrint defined in line 308; used 2 times

- in line 41, 86

accxint defined in line 279; used 2 times

- in line 41, 86

#### Defined variables

acc_softc defined in line 72; used 6 times

- in line 107, 137, 161, 253, 282, 311

accdriver defined in line 44; never used
accinfo defined in line 42; used 7 times

- in line 45, 133, 157, 238, 264, 285, 316

accstd defined in line 43; used 1 times

- in line 45

#### Defined struct's

acc_softc defined in line 66; used 12 times

- in line 107(2), 131(2), 152(2), 253(2), 282(2), 311(2)

Last modified: 1988-02-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 301 |