rusty@sdccsu3.UUCP (02/27/84)
these diffs fix various bugs in the uda driver. the line switch (mp->mslg_format & 0xff) { fixes the bug where the drive hangs forever. the rest of the fixes are useful and should be installed but are not crucial. ------- uda.c ------- *** /tmp/d19774 Mon Feb 27 12:13:25 1984 --- uda.c Sat Jan 14 09:48:43 1984 *************** *** 1,4 ! /* %M% %I% (CARL) %G% %U% */ /* uda.c 6.1 83/07/29 */ --- 1,4 ----- ! /* uda.c 1.2 (CARL) 1/14/84 09:48:12 */ /* uda.c 6.1 83/07/29 */ *************** *** 21,26 #include "../h/conf.h" #include "../h/dir.h" #include "../h/user.h" #include "../h/map.h" #include "../h/vm.h" #include "../h/dk.h" --- 21,27 ----- #include "../h/conf.h" #include "../h/dir.h" #include "../h/user.h" + #include "../h/kernel.h" #include "../h/map.h" #include "../h/vm.h" #include "../h/dk.h" *************** *** 48,53 short sc_credits; /* transfer credits */ short sc_lastcmd; /* pointer into command ring */ short sc_lastrsp; /* pointer into response ring */ } uda_softc[NUDA]; /* --- 49,55 ----- short sc_credits; /* transfer credits */ short sc_lastcmd; /* pointer into command ring */ short sc_lastrsp; /* pointer into response ring */ + int sc_wticks; /* watchdog ticks */ } uda_softc[NUDA]; /* *************** *** 139,144 udattach(ui) register struct uba_device *ui; { if (ui->ui_dk >= 0) dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256); /* approx */ --- 168,175 ----- udattach(ui) register struct uba_device *ui; { + extern int udwatch(); + register struct buf *bp; if (udwstart == 0) { timeout(udwatch, (caddr_t) 0, hz); *************** *** 140,145 register struct uba_device *ui; { if (ui->ui_dk >= 0) dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256); /* approx */ ui->ui_flags = 0; --- 171,181 ----- extern int udwatch(); register struct buf *bp; + if (udwstart == 0) { + timeout(udwatch, (caddr_t) 0, hz); + udwstart++; + } + if (ui->ui_dk >= 0) dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256); /* approx */ ui->ui_flags = 0; *************** *** 145,150 ui->ui_flags = 0; udip[ui->ui_ctlr][ui->ui_slave] = ui; radsize[ui->ui_unit] = (daddr_t)0xffffff; /* max possible size */ } /* --- 181,188 ----- ui->ui_flags = 0; udip[ui->ui_ctlr][ui->ui_slave] = ui; radsize[ui->ui_unit] = (daddr_t)0xffffff; /* max possible size */ + bp = &udwtab[ui->ui_ctlr]; + bp->av_forw = bp->av_back = bp; } /* *************** *** 431,436 struct uda *uud; struct mscp *mp; printd("udintr: state %d, udasa %o\n", sc->sc_state, udaddr->udasa); switch (sc->sc_state) { case S_IDLE: --- 470,476 ----- struct uda *uud; struct mscp *mp; + sc->sc_wticks = 0; printd("udintr: state %d, udasa %o\n", sc->sc_state, udaddr->udasa); switch (sc->sc_state) { case S_IDLE: *************** *** 726,732 { printf("uda%d: %s error, ", um->um_ctlr, mp->mslg_flags&M_LF_SUCC ? "soft" : "hard"); ! switch (mp->mslg_format) { case M_FM_CNTERR: printf("controller error, event 0%o\n", mp->mslg_event); break; --- 777,783 ----- { printf("uda%d: %s error, ", um->um_ctlr, mp->mslg_flags&M_LF_SUCC ? "soft" : "hard"); ! switch (mp->mslg_format & 0xff) { case M_FM_CNTERR: printf("controller error, event 0%o\n", mp->mslg_event); break; *************** *** 817,822 return (physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys, uio)); } udreset(uban) int uban; { --- 868,911 ----- return (physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys, uio)); } + /* + * Wake up every second and if an interrupt is pending + * but nothing has happened increment a counter. + * If nothing happens for 20 seconds, reset the UNIBUS + * and begin anew. + */ + udwatch() { + register struct uba_ctlr *um; + register uda, unit; + register struct uda_softc *sc; + + timeout(udwatch, (caddr_t) 0, hz); + for (uda = 0; uda < NUDA; uda++) { + if ((um = udminfo[uda]) == 0) + continue; + if (um->um_alive == 0) + continue; + sc = &uda_softc[uda]; + if (um->um_tab.b_active == 0) { + for (unit = 0; unit < NRA; unit++) { + if (udutab[unit].b_active) { + if (uddinfo[unit]->ui_mi == um) + goto active; + } + } + sc->sc_wticks = 0; + continue; + } + active: + sc->sc_wticks++; + if (sc->sc_wticks >= 20) { + sc->sc_wticks = 0; + printf("ud%d: lost interrupt\n", uda); + ubareset(um->um_ubanum); + } + } + } + udreset(uban) int uban; { *************** *** 823,828 register struct uba_ctlr *um; register struct uba_device *ui; register struct buf *bp, *dp; register int unit; struct buf *nbp; int d; --- 912,918 ----- register struct uba_ctlr *um; register struct uba_device *ui; register struct buf *bp, *dp; + register struct uda_softc *sc; register int unit; struct buf *nbp; int d; *************** *** 869,874 dp->b_active = 1; } } udinit(d); } } --- 959,966 ----- dp->b_active = 1; } } + sc = &uda_softc[d]; + sc->sc_mapped = 0; udinit(d); } }