chris@mimsy.UUCP (Chris Torek) (11/01/87)
Index: sys/vaxuba/ts.c 4.3BSD Fix Description: The configuration code for the ts11 driver guesses at the interrupt vector (0224 or 0260) instead of making the device interrupt. The open routine can allow two processes to open the drive simultaneously. [Other bugs, not fixed here, include - large raw I/O (>63kB) fails (not a problem ... yet) - configuring two ts'es on one zs break things - the dump code does not do anything] Repeat-by: The race is hard to repeat. The other problem is obvious. Fix: Beware: this is not what I am running. (I changed many other things; that context diff is bigger than the source.) It should work though. The DELAYs can probably be reduced, but an extra 40 milliseconds per boot is not long. RCS file: RCS/ts.c,v retrieving revision 1.1 retrieving revision 1.2.1.2 diff -c2 -r1.1 -r1.2.1.2 *** /tmp/,RCSt1007746 Sun Nov 1 04:52:25 1987 --- /tmp/,RCSt2007746 Sun Nov 1 04:52:33 1987 *************** *** 116,123 **** */ /*ARGSUSED*/ ! tsprobe(reg) caddr_t reg; { register int br, cvec; /* must be r11,r10; value-result */ #ifdef lint --- 116,129 ---- */ /*ARGSUSED*/ ! tsprobe(reg, ctlr, um) caddr_t reg; + int ctlr; + struct uba_ctlr *um; { register int br, cvec; /* must be r11,r10; value-result */ + register struct tsdevice *addr = (struct tsdevice *)reg; + register struct ts_softc *sc; + register int i; + int a; #ifdef lint *************** *** 125,135 **** tsintr(0); #endif ! ((struct tsdevice *)reg)->tssr = 0; DELAY(100); ! if ((((struct tsdevice *)reg)->tssr & TS_NBA) == 0) ! return(0); ! /* IT'S TOO HARD TO MAKE THIS THING INTERRUPT JUST TO FIND ITS VECTOR */ ! cvec = ((unsigned)reg) & 07 ? 0260 : 0224; ! br = 0x15; return (sizeof (struct tsdevice)); } --- 131,168 ---- tsintr(0); #endif ! addr->tssr = 0; /* initialize subsystem */ DELAY(100); ! if ((addr->tssr & TS_NBA) == 0) ! return (0); ! ! /* ! * Make it interrupt. ! * TS_SETCHR|TS_IE alone refuses to interrupt for me. ! */ ! sc = &ts_softc[ctlr]; ! a = uballoc(numuba, (caddr_t)sc, sizeof(*sc), 0); ! sc->sc_ubaddr = (struct ts_softc *)UBAI_ADDR(a); ! i = (int)&sc->sc_ubaddr->sc_cmd; ! sc->sc_uba = i + ((i >> 16) & 3); ! i = (int)&sc->sc_ubaddr->sc_char; ! sc->sc_cmd.c_loba = i; ! sc->sc_cmd.c_hiba = (i >> 16) & 3; ! sc->sc_cmd.c_size = sizeof(struct ts_char); ! sc->sc_cmd.c_cmd = TS_ACK | TS_SETCHR; ! sc->sc_char.char_addr = (int)&sc->sc_ubaddr->sc_sts; ! sc->sc_char.char_size = sizeof(struct ts_sts); ! sc->sc_char.char_mode = 0; /* mode is unimportant */ ! addr->tsdb = sc->sc_uba; ! DELAY(20000); ! sc->sc_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | TS_SENSE; ! sc->sc_cmd.c_repcnt = 1; ! addr->tsdb = sc->sc_uba; ! DELAY(20000); ! /* should have interrupted by now */ ! ! addr->tssr = 0; /* put it back the way it was */ ! DELAY(100); ! ubarelse(numuba, &a); ! return (sizeof (struct tsdevice)); } *************** *** 184,191 **** if ((sc = &ts_softc[tsunit])->sc_openf) return (EBUSY); ! if (tsinit(tsunit)) return (ENXIO); tscommand(dev, TS_SENSE, 1); if ((sc->sc_sts.s_xs0&TS_ONL) == 0) { uprintf("ts%d: not online\n", tsunit); return (EIO); --- 217,228 ---- if ((sc = &ts_softc[tsunit])->sc_openf) return (EBUSY); ! sc->sc_openf = 1; ! if (tsinit(tsunit)) { ! sc->sc_openf = 0; return (ENXIO); + } tscommand(dev, TS_SENSE, 1); if ((sc->sc_sts.s_xs0&TS_ONL) == 0) { + sc->sc_openf = 0; uprintf("ts%d: not online\n", tsunit); return (EIO); *************** *** 192,199 **** } if ((flag&FWRITE) && (sc->sc_sts.s_xs0&TS_WLK)) { uprintf("ts%d: no write ring\n", tsunit); return (EIO); } - sc->sc_openf = 1; sc->sc_blkno = (daddr_t)0; sc->sc_nxrec = INF; --- 229,236 ---- } if ((flag&FWRITE) && (sc->sc_sts.s_xs0&TS_WLK)) { + sc->sc_openf = 0; uprintf("ts%d: no write ring\n", tsunit); return (EIO); } sc->sc_blkno = (daddr_t)0; sc->sc_nxrec = INF; *************** *** 252,260 **** */ if (sc->sc_mapped == 0) { ! ctsbuf[unit].b_un.b_addr = (caddr_t)sc; ! ctsbuf[unit].b_bcount = sizeof(*sc); ! i = ubasetup(um->um_ubanum, &ctsbuf[unit], 0); ! i &= 0777777; ! sc->sc_ubaddr = (struct ts_softc *)i; sc->sc_mapped++; } --- 289,295 ---- */ if (sc->sc_mapped == 0) { ! sc->sc_ubaddr = ! (struct ts_softc *)UBAI_ADDR(uballoc(um->um_ubanum, ! (caddr_t)sc, sizeof(*sc), 0)); sc->sc_mapped++; } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris