summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2003-07-01 12:03:54 +0000
committersimokawa <simokawa@FreeBSD.org>2003-07-01 12:03:54 +0000
commit7c05940afff0eb863d9007f54f42ed5046a3b086 (patch)
treef053dec36922acd85d86435e685681e0563b12dd
parenta8a0d26127c8062c4cd673666e9c6f3b6362aaba (diff)
downloadFreeBSD-src-7c05940afff0eb863d9007f54f42ed5046a3b086.zip
FreeBSD-src-7c05940afff0eb863d9007f54f42ed5046a3b086.tar.gz
Fix tsleep/wakup race on FreeBSD-4.
-rw-r--r--sys/dev/firewire/fwmem.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/sys/dev/firewire/fwmem.c b/sys/dev/firewire/fwmem.c
index 7a0fda7..8271217 100644
--- a/sys/dev/firewire/fwmem.c
+++ b/sys/dev/firewire/fwmem.c
@@ -276,7 +276,7 @@ fwmem_read (dev_t dev, struct uio *uio, int ioflag)
u_int16_t dst_hi;
u_int32_t dst_lo;
off_t offset;
- int len;
+ int len, s;
sc = devclass_get_softc(firewire_devclass, unit);
fwdev = fw_noderesolve_eui64(sc->fc, (struct fw_eui64 *)dev->si_drv1);
@@ -293,13 +293,16 @@ fwmem_read (dev_t dev, struct uio *uio, int ioflag)
dst_lo = offset & 0xffffffff;
len = uio->uio_resid;
if (len == 4 && (dst_lo & 3) == 0) {
+ s = splfw();
xfer = fwmem_read_quad(fwdev, NULL, fwmem_speed,
dst_hi, dst_lo, fw_asy_callback);
if (xfer == NULL) {
err = EINVAL;
+ splx(s);
break;
}
err = tsleep((caddr_t)xfer, FWPRI, "fwmrq", 0);
+ splx(s);
if (xfer->recv.buf == NULL)
err = EIO;
else if (xfer->resp != 0)
@@ -309,13 +312,16 @@ fwmem_read (dev_t dev, struct uio *uio, int ioflag)
} else {
if (len > MAXLEN)
len = MAXLEN;
+ s = splfw();
xfer = fwmem_read_block(fwdev, NULL, fwmem_speed,
dst_hi, dst_lo, len, fw_asy_callback);
if (xfer == NULL) {
err = EINVAL;
+ splx(s);
break;
}
err = tsleep((caddr_t)xfer, FWPRI, "fwmrb", 0);
+ splx(s);
if (xfer->recv.buf == NULL)
err = EIO;
else if (xfer->resp != 0)
@@ -339,7 +345,7 @@ fwmem_write (dev_t dev, struct uio *uio, int ioflag)
u_int32_t dst_lo, quad;
char *data;
off_t offset;
- int len;
+ int len, s;
sc = devclass_get_softc(firewire_devclass, unit);
fwdev = fw_noderesolve_eui64(sc->fc, (struct fw_eui64 *)dev->si_drv1);
@@ -361,13 +367,16 @@ fwmem_write (dev_t dev, struct uio *uio, int ioflag)
len = uio->uio_resid;
if (len == 4 && (dst_lo & 3) == 0) {
err = uiomove((char *)&quad, sizeof(quad), uio);
+ s = splfw();
xfer = fwmem_write_quad(fwdev, NULL, fwmem_speed,
dst_hi, dst_lo, quad, fw_asy_callback);
if (xfer == NULL) {
err = EINVAL;
+ splx(s);
break;
}
err = tsleep((caddr_t)xfer, FWPRI, "fwmwq", 0);
+ splx(s);
if (xfer->resp != 0)
err = xfer->resp;
} else {
@@ -376,13 +385,16 @@ fwmem_write (dev_t dev, struct uio *uio, int ioflag)
err = uiomove(data, len, uio);
if (err)
break;
+ s = splfw();
xfer = fwmem_write_block(fwdev, NULL, fwmem_speed,
dst_hi, dst_lo, len, data, fw_asy_callback);
if (xfer == NULL) {
err = EINVAL;
+ splx(s);
break;
}
err = tsleep((caddr_t)xfer, FWPRI, "fwmwb", 0);
+ splx(s);
if (xfer->resp != 0)
err = xfer->resp;
}
OpenPOWER on IntegriCloud