diff options
author | simokawa <simokawa@FreeBSD.org> | 2003-07-01 12:03:54 +0000 |
---|---|---|
committer | simokawa <simokawa@FreeBSD.org> | 2003-07-01 12:03:54 +0000 |
commit | 7c05940afff0eb863d9007f54f42ed5046a3b086 (patch) | |
tree | f053dec36922acd85d86435e685681e0563b12dd | |
parent | a8a0d26127c8062c4cd673666e9c6f3b6362aaba (diff) | |
download | FreeBSD-src-7c05940afff0eb863d9007f54f42ed5046a3b086.zip FreeBSD-src-7c05940afff0eb863d9007f54f42ed5046a3b086.tar.gz |
Fix tsleep/wakup race on FreeBSD-4.
-rw-r--r-- | sys/dev/firewire/fwmem.c | 16 |
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; } |