X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/a0b7c7fb19b3c0f54cdd3c30d33b8c0c2348dfbe..68776750b2b19e673ac889f73dd08c2b8db64ad3:/usr/src/sys/vax/if/if_acc.c diff --git a/usr/src/sys/vax/if/if_acc.c b/usr/src/sys/vax/if/if_acc.c index 836c1d4631..fe0f95addb 100644 --- a/usr/src/sys/vax/if/if_acc.c +++ b/usr/src/sys/vax/if/if_acc.c @@ -1,4 +1,4 @@ -/* if_acc.c 4.2 82/02/01 */ +/* if_acc.c 4.7 82/02/27 */ #include "acc.h" #ifdef NACC > 0 @@ -16,13 +16,13 @@ #include "../h/socket.h" #include "../h/ubareg.h" #include "../h/ubavar.h" -#include "../h/accreg.h" #include "../h/cpu.h" #include "../h/mtpr.h" #include "../h/vmmac.h" #include "../net/in.h" #include "../net/in_systm.h" #include "../net/if.h" +#include "../net/if_acc.h" #include "../net/if_imp.h" #include "../net/if_uba.h" @@ -76,19 +76,13 @@ COUNT(ACCPROBE); br = 0; cvec = br; br = cvec; accrint(0); accxint(0); #endif - addr->acc_icsr = ACC_RESET; - DELAY(500000); - addr->acc_ocsr = ACC_RESET; - DELAY(500000); - - addr->acc_ocsr = OUT_BBACK; - DELAY(500000); - addr->acc_owc = 0; - addr->acc_ocsr = ACC_IE | ACC_GO; - DELAY(500000); - addr->acc_ocsr = 0; - /* interrupt was for transmit, push back to receive vector */ - if (cvec && cvec != 0x200) + addr->icsr = ACC_RESET; DELAY(5000); + addr->ocsr = ACC_RESET; DELAY(5000); + addr->ocsr = OUT_BBACK; DELAY(5000); + addr->owc = 0; + addr->ocsr = ACC_IE | ACC_GO; DELAY(5000); + addr->ocsr = 0; + if (cvec && cvec != 0x200) /* transmit -> receive */ cvec -= 4; return (1); } @@ -110,12 +104,15 @@ accattach(ui) COUNT(ACCATTACH); if ((ifimp = (struct ifimpcb *)impattach(ui)) == 0) - panic("accattach"); /* XXX */ + panic("accattach"); sc->acc_if = &ifimp->ifimp_if; ip = &ifimp->ifimp_impcb; sc->acc_ic = ip; ip->ic_init = accinit; ip->ic_start = accstart; +#ifdef notdef + sc->acc_ifuba.ifu_flags = UBA_NEEDBDP; +#endif } /* @@ -140,59 +137,84 @@ COUNT(ACCRESET); /* * Initialize interface: clear recorded pending operations, - * and retrieve, and reinitialize UNIBUS resources. + * and retrieve, and initialize UNIBUS resources. Note + * return value is used by IMP init routine to mark IMP + * unavailable for outgoing traffic. */ accinit(unit) int unit; { - register struct acc_softc *sc = &acc_softc[unit]; - register struct uba_device *ui = accinfo[unit]; + register struct acc_softc *sc; + register struct uba_device *ui; register struct accdevice *addr; int x, info; COUNT(ACCINIT); - if (if_ubainit(&sc->acc_ifuba, ui->ui_ubanum, - sizeof(struct imp_leader), (int)btop(IMP_MTU)) == 0) { + if (unit >= NACC || (ui = accinfo[unit]) == 0 || ui->ui_alive == 0) { + printf("acc%d: not alive\n", unit); + return (0); + } + sc = &acc_softc[unit]; + /* + * Header length is 0 since we have to passs + * the IMP leader up to the protocol interpretation + * routines. If we had the header length as + * sizeof(struct imp_leader), then the if_ routines + * would asssume we handle it on input and output. + */ + if (if_ubainit(&sc->acc_ifuba, ui->ui_ubanum, 0, btoc(IMP_MTU)) == 0) { printf("acc%d: can't initialize\n", unit); - return; + goto down; } addr = (struct accdevice *)ui->ui_addr; /* - * Reset the imp interface. - * the delays are totally guesses + * Reset the imp interface; + * the delays are pure guesswork. */ x = spl5(); - addr->acc_icsr = ACC_RESET; - DELAY(100); - addr->acc_ocsr = ACC_RESET; - DELAY(1000); - addr->acc_ocsr = OUT_BBACK; /* reset host master ready */ - DELAY(1000); - addr->acc_ocsr = 0; - addr->acc_icsr = IN_MRDY; /* close the relay */ + addr->icsr = ACC_RESET; DELAY(5000); + addr->ocsr = ACC_RESET; DELAY(5000); + addr->ocsr = OUT_BBACK; DELAY(1000); /* reset host master ready */ + addr->ocsr = 0; splx(x); - + addr->icsr = IN_MRDY | IN_WEN; /* close the relay */ + DELAY(5000); /* YECH!!! */ - while ((addr->acc_icsr & IN_HRDY) == 0 || - (addr->acc_icsr & (IN_RMR | IN_IMPBSY))) { - /* keep turning IN_RMR off */ - addr->acc_icsr = IN_MRDY; - sleep((caddr_t)&lbolt, PZERO); /* ??? */ + x = 500; + while (x-- > 0) { + if ((addr->icsr & IN_HRDY) || + (addr->icsr & (IN_RMR | IN_IMPBSY) == 0)) + break; + addr->icsr = IN_MRDY | IN_WEN; + DELAY(5000); /* keep turning IN_RMR off */ + } + if (x <= 0) { + printf("acc%d: imp doesn't respond, icsr=%b\n", unit, + addr->icsr, ACC_INBITS); + goto down; } /* * Put up a read. We can't restart any outstanding writes * until we're back in synch with the IMP (i.e. we've flushed * the NOOPs it throws at us). + * Note: IMP_MTU includes the leader. */ x = spl5(); info = sc->acc_ifuba.ifu_r.ifrw_info; - addr->acc_iba = (u_short)info; - addr->acc_iwc = -(sizeof(struct imp_leader) + IMP_MTU) >> 1; - addr->acc_icsr = + addr->iba = (u_short)info; + addr->iwc = -(IMP_MTU >> 1); +#ifdef LOOPBACK + addr->ocsr |= OUT_BBACK; +#endif + addr->icsr = IN_MRDY | ACC_IE | IN_WEN | ((info & 0x30000) >> 12) | ACC_GO; splx(x); + return (1); +down: + ui->ui_alive = 0; + return (0); } /* @@ -202,7 +224,6 @@ accstart(dev) dev_t dev; { int unit = ACCUNIT(dev), info; - struct uba_device *ui = accinfo[unit]; register struct acc_softc *sc = &acc_softc[unit]; register struct accdevice *addr; struct mbuf *m; @@ -226,16 +247,20 @@ COUNT(ACCSTART); restart: /* - * Have request mapped to UNIBUS for transmission. - * Purge any stale data from the BDP, and start the output. + * Have request mapped to UNIBUS for + * transmission; start the output. */ - UBAPURGE(sc->acc_ifuba.ifu_uba, sc->acc_ifuba.ifu_w.ifrw_bdp); - addr = (struct accdevice *)ui->ui_addr; + if (sc->acc_ifuba.ifu_flags & UBA_NEEDBDP) + UBAPURGE(sc->acc_ifuba.ifu_uba, sc->acc_ifuba.ifu_w.ifrw_bdp); + addr = (struct accdevice *)accinfo[unit]->ui_addr; info = sc->acc_ifuba.ifu_w.ifrw_info; - addr->acc_oba = (u_short)info; - addr->acc_owc = -((sc->acc_olen + 1) >> 1); + addr->oba = (u_short)info; + addr->owc = -((sc->acc_olen + 1) >> 1); cmd = ACC_IE | OUT_ENLB | ((info & 0x30000) >> 12) | ACC_GO; - addr->acc_ocsr = cmd; +#ifdef LOOPBACK + cmd |= OUT_BBACK; +#endif + addr->ocsr = cmd; sc->acc_ic->ic_oactive = 1; } @@ -244,31 +269,28 @@ restart: */ accxint(unit) { - register struct uba_device *ui = accinfo[unit]; register struct acc_softc *sc = &acc_softc[unit]; register struct accdevice *addr; COUNT(ACCXINT); if (sc->acc_ic->ic_oactive == 0) { - printf("acc%d: stray send interrupt\n", unit); + printf("acc%d: stray xmit interrupt\n", unit); return; } - addr = (struct accdevice *)ui->ui_addr; + addr = (struct accdevice *)accinfo[unit]->ui_addr; sc->acc_if->if_opackets++; sc->acc_ic->ic_oactive = 0; - if (addr->acc_ocsr & ACC_ERR) { - printf("acc%d: send error, csr=%b\n", unit, - addr->acc_ocsr, ACC_OUTBITS); + if (addr->ocsr & ACC_ERR) { + printf("acc%d: output error, csr=%b\n", unit, + addr->ocsr, ACC_OUTBITS); sc->acc_if->if_oerrors++; } - if (sc->acc_if->if_snd.ifq_head == 0) { - if (sc->acc_ifuba.ifu_xtofree) { - m_freem(sc->acc_ifuba.ifu_xtofree); - sc->acc_ifuba.ifu_xtofree = 0; - } - return; + if (sc->acc_ifuba.ifu_xtofree) { + m_freem(sc->acc_ifuba.ifu_xtofree); + sc->acc_ifuba.ifu_xtofree = 0; } - accstart(unit); + if (sc->acc_if->if_snd.ifq_head) + accstart(unit); } /* @@ -288,21 +310,27 @@ COUNT(ACCRINT); /* * Purge BDP; flush message if error indicated. */ - UBAPURGE(sc->acc_ifuba.ifu_uba, sc->acc_ifuba.ifu_r.ifrw_bdp); + if (sc->acc_ifuba.ifu_flags & UBA_NEEDBDP) + UBAPURGE(sc->acc_ifuba.ifu_uba, sc->acc_ifuba.ifu_r.ifrw_bdp); addr = (struct accdevice *)accinfo[unit]->ui_addr; - if (addr->acc_icsr & ACC_ERR) { - printf("acc%d: recv error, csr=%b\n", unit, - addr->acc_icsr, ACC_INBITS); + if (addr->icsr & ACC_ERR) { + printf("acc%d: input error, csr=%b\n", unit, + addr->icsr, ACC_INBITS); sc->acc_if->if_ierrors++; sc->acc_flush = 1; } if (sc->acc_flush) { - if (addr->acc_icsr & IN_EOM) + if (addr->icsr & IN_EOM) sc->acc_flush = 0; goto setup; } - len = sizeof(struct imp_leader) + (addr->acc_iwc << 1); + len = IMP_MTU + (addr->iwc << 1); + if (len < 0 || len > IMP_MTU) { + printf("acc%d: bad length=%d\n", len); + sc->acc_if->if_ierrors++; + goto setup; + } /* * The last parameter is always 0 since using @@ -311,15 +339,13 @@ COUNT(ACCRINT); m = if_rubaget(&sc->acc_ifuba, len, 0); if (m == 0) goto setup; - if ((addr->acc_icsr & IN_EOM) == 0) { + if ((addr->icsr & IN_EOM) == 0) { if (sc->acc_iq) m_cat(sc->acc_iq, m); else sc->acc_iq = m; goto setup; } - /* adjust message length for padding. */ - m->m_len -= 2; if (sc->acc_iq) { m_cat(sc->acc_iq, m); m = sc->acc_iq; @@ -332,9 +358,9 @@ setup: * Setup for next message. */ info = sc->acc_ifuba.ifu_r.ifrw_info; - addr->acc_iba = (u_short)info; - addr->acc_iwc = - (sizeof(struct imp_leader) + IMP_MTU) >> 1; - addr->acc_icsr = + addr->iba = (u_short)info; + addr->iwc = -(IMP_MTU >> 1); + addr->icsr = IN_MRDY | ACC_IE | IN_WEN | ((info & 0x30000) >> 12) | ACC_GO; } #endif