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