diff options
author | bde <bde@FreeBSD.org> | 1994-11-06 00:46:21 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1994-11-06 00:46:21 +0000 |
commit | 02630d5e4bda74529142ab916ce9f9f2d85118ad (patch) | |
tree | be61e3a266b8af762ae8a8fdd856fe1a821649fe /sys/i386/isa/pcaudio.c | |
parent | eca5256cb09025f6333a0a02f930eb01979dc4b2 (diff) | |
download | FreeBSD-src-02630d5e4bda74529142ab916ce9f9f2d85118ad.zip FreeBSD-src-02630d5e4bda74529142ab916ce9f9f2d85118ad.tar.gz |
Abort writes if a signal is received (don't ignore the value returned by
tsleep()). Try `dd if=/dev/zero of=/dev/pcaudio bs=640k count=1'. The
write takes a few hundred seconds to drain, and if it is killed by a
signal, it still takes a few hundred seconds to drain and all of those
seconds are spent busy-waiting.
Clean up includes and declarations. Remove bogus casts of args to
timeout functions.
Diffstat (limited to 'sys/i386/isa/pcaudio.c')
-rw-r--r-- | sys/i386/isa/pcaudio.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/sys/i386/isa/pcaudio.c b/sys/i386/isa/pcaudio.c index defd2fb..368c279 100644 --- a/sys/i386/isa/pcaudio.c +++ b/sys/i386/isa/pcaudio.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcaudio.c,v 1.9 1994/09/29 21:11:29 sos Exp $ + * $Id: pcaudio.c,v 1.10 1994/10/27 08:03:12 sos Exp $ */ #include "pca.h" @@ -38,10 +38,14 @@ #include <sys/file.h> #include <sys/proc.h> #include <sys/devconf.h> + +#include <machine/clock.h> #include <machine/pcaudioio.h> + #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> #include <i386/isa/timerreg.h> + #include <i386/isa/sound/ulaw.h> #define BUF_SIZE 8192 @@ -74,7 +78,7 @@ static char volume_table[256]; static int pca_sleep = 0; static int pca_initialized = 0; -void pcaintr(int regs); +void pcaintr(struct clockframe *frame); int pcaprobe(struct isa_device *dvp); int pcaattach(struct isa_device *dvp); int pcaclose(dev_t dev, int flag); @@ -195,13 +199,21 @@ pca_continue() } -static void +static int pca_wait(void) { + int error; + while (pca_status.in_use[0] || pca_status.in_use[1]) { pca_sleep = 1; - tsleep((caddr_t)&pca_sleep, PZERO|PCATCH, "pca_drain", 0); + error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_drain", 0); + pca_sleep = 0; + if (error != 0 && error != ERESTART) { + pca_stop(); + return error; + } } + return 0; } @@ -291,7 +303,7 @@ pcaclose(dev_t dev, int flag) int pcawrite(dev_t dev, struct uio *uio, int flag) { - int count, which; + int count, error, which; /* only audio device can be written */ if (minor(dev) > 0) @@ -300,7 +312,12 @@ pcawrite(dev_t dev, struct uio *uio, int flag) while ((count = min(BUF_SIZE, uio->uio_resid)) > 0) { if (pca_status.in_use[0] && pca_status.in_use[1]) { pca_sleep = 1; - tsleep((caddr_t)&pca_sleep, PZERO|PCATCH, "pca_wait",0); + error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_wait", 0); + pca_sleep = 0; + if (error != 0 && error != ERESTART) { + pca_stop(); + return error; + } } which = pca_status.in_use[0] ? 1 : 0; if (count && !pca_status.in_use[which]) { @@ -378,8 +395,7 @@ pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return 0; case AUDIO_DRAIN: - pca_wait(); - return 0; + return pca_wait(); case AUDIO_FLUSH: pca_stop(); @@ -391,7 +407,7 @@ pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) void -pcaintr(int regs) +pcaintr(struct clockframe *frame) { if (pca_status.index < pca_status.in_use[pca_status.current]) { disable_intr(); @@ -413,7 +429,7 @@ pcaintr(int regs) pca_status.current ^= 1; pca_status.buffer = pca_status.buf[pca_status.current]; if (pca_sleep) { - wakeup((caddr_t)&pca_sleep); + wakeup(&pca_sleep); pca_sleep = 0; } if (pca_status.wsel.si_pid) { |