diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index d79d032..2a080c8 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -33,6 +33,7 @@
 
 #include <dev/sound/pcm/sound.h>
 #include <dev/sound/pcm/vchan.h>
+#include <sys/vnode.h>
 
 #include "feeder_if.h"
 
@@ -489,7 +490,7 @@ chn_wrintr(struct pcm_channel *c)
  */
 
 int
-chn_write(struct pcm_channel *c, struct uio *buf)
+chn_write(struct pcm_channel *c, struct uio *buf, int ioflags)
 {
 	struct snd_dbuf *bs = c->bufsoft;
 	void *off;
@@ -524,7 +525,8 @@ chn_write(struct pcm_channel *c, struct uio *buf)
 				if (ret != 0)
 					c->flags |= CHN_F_DEAD;
 			}
-		} else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) {
+		} else if ((ioflags & IO_NDELAY) ||
+		    (c->flags & CHN_F_NOTRIGGER)) {
 			/**
 			 * @todo Evaluate whether EAGAIN is truly desirable.
 			 * 	 4Front drivers behave like this, but I'm
@@ -619,7 +621,7 @@ chn_rdintr(struct pcm_channel *c)
  */
 
 int
-chn_read(struct pcm_channel *c, struct uio *buf)
+chn_read(struct pcm_channel *c, struct uio *buf, int ioflags)
 {
 	struct snd_dbuf *bs = c->bufsoft;
 	void *off;
@@ -657,9 +659,10 @@ chn_read(struct pcm_channel *c, struct uio *buf)
 				sndbuf_dispose(bs, NULL, t);
 			}
 			ret = 0;
-		} else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER))
+		} else if ((ioflags & IO_NDELAY) ||
+		    (c->flags & CHN_F_NOTRIGGER)) {
 			ret = EAGAIN;
-		else {
+		} else {
    			ret = chn_sleep(c, timeout);
 			if (ret == EAGAIN) {
 				ret = EINVAL;
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
index dcdc782..bb78d53 100644
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -254,8 +254,8 @@ struct pcm_channel {
 #include "channel_if.h"
 
 int chn_reinit(struct pcm_channel *c);
-int chn_write(struct pcm_channel *c, struct uio *buf);
-int chn_read(struct pcm_channel *c, struct uio *buf);
+int chn_write(struct pcm_channel *c, struct uio *buf, int ioflags);
+int chn_read(struct pcm_channel *c, struct uio *buf, int ioflags);
 u_int32_t chn_start(struct pcm_channel *c, int force);
 int chn_sync(struct pcm_channel *c, int threshold);
 int chn_flush(struct pcm_channel *c);
@@ -351,7 +351,7 @@ extern int report_soft_matrix;
 #define CHN_F_NOTRIGGER		0x00000010
 #define CHN_F_SLEEPING		0x00000020
 
-#define CHN_F_NBIO              0x00000040  /* do non-blocking i/o */
+#define CHN_F_UNUSED1           0x00000040
 #define CHN_F_MMAP		0x00000080  /* has been mmap()ed */
 
 #define CHN_F_BUSY              0x00000100  /* has been opened 	*/
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index f4ab25a..97de51e 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -589,8 +589,6 @@ dsp_open(struct dev_open_args *ap)
 				pcm_chnrelease(rdch);
 			}
 		} else {
-			if (flags & O_NONBLOCK)
-				rdch->flags |= CHN_F_NBIO;
 			if (flags & O_EXCL)
 				rdch->flags |= CHN_F_EXCLUSIVE;
 			pcm_chnref(rdch, 1);
@@ -636,8 +634,6 @@ dsp_open(struct dev_open_args *ap)
 				pcm_chnrelease(wrch);
 			}
 		} else {
-			if (flags & O_NONBLOCK)
-				wrch->flags |= CHN_F_NBIO;
 			if (flags & O_EXCL)
 				wrch->flags |= CHN_F_EXCLUSIVE;
 			pcm_chnref(wrch, 1);
@@ -834,11 +830,11 @@ dsp_close(struct dev_close_args *ap)
 }
 
 static __inline int
-dsp_io_ops(struct cdev *i_dev, struct uio *buf)
+dsp_io_ops(struct cdev *i_dev, struct uio *buf, int ioflags)
 {
 	struct snddev_info *d;
 	struct pcm_channel **ch, *rdch, *wrch;
-	int (*chn_io)(struct pcm_channel *, struct uio *);
+	int (*chn_io)(struct pcm_channel *, struct uio *, int);
 	int prio, ret;
 	pid_t runpid;
 
@@ -895,7 +891,7 @@ dsp_io_ops(struct cdev *i_dev, struct uio *buf)
 	 * someone else doesn't come along and muss up the buffer.
 	 */
 	++(*ch)->inprog;
-	ret = chn_io(*ch, buf);
+	ret = chn_io(*ch, buf, ioflags);
 	--(*ch)->inprog;
 
 	CHN_BROADCAST(&(*ch)->cv);
@@ -913,7 +909,7 @@ dsp_read(struct dev_read_args *ap)
 	struct cdev *i_dev = ap->a_head.a_dev;
 	struct uio *buf = ap->a_uio;
 
-	return (dsp_io_ops(i_dev, buf));
+	return (dsp_io_ops(i_dev, buf, ap->a_ioflag));
 }
 
 static int
@@ -922,7 +918,7 @@ dsp_write(struct dev_write_args *ap)
 	struct cdev *i_dev = ap->a_head.a_dev;
 	struct uio *buf = ap->a_uio;
 
-	return (dsp_io_ops(i_dev, buf));
+	return (dsp_io_ops(i_dev, buf, ap->a_ioflag));
 }
 
 static int
@@ -1362,24 +1358,12 @@ dsp_ioctl(struct dev_ioctl_args *ap)
 		DEB( kprintf("FIOASYNC\n") ; )
 		break;
 
-    	case SNDCTL_DSP_NONBLOCK: /* set non-blocking i/o */
     	case FIONBIO: /* set/clear non-blocking i/o */
-		if (rdch) {
-			CHN_LOCK(rdch);
-			if (cmd == SNDCTL_DSP_NONBLOCK || *arg_i)
-				rdch->flags |= CHN_F_NBIO;
-			else
-				rdch->flags &= ~CHN_F_NBIO;
-			CHN_UNLOCK(rdch);
-		}
-		if (wrch) {
-			CHN_LOCK(wrch);
-			if (cmd == SNDCTL_DSP_NONBLOCK || *arg_i)
-				wrch->flags |= CHN_F_NBIO;
-			else
-				wrch->flags &= ~CHN_F_NBIO;
-			CHN_UNLOCK(wrch);
-		}
+		DEB( kprintf("FIONBIO\n") ; )
+		break;
+
+    	case SNDCTL_DSP_NONBLOCK: /* set non-blocking i/o */
+		atomic_set_int(&ap->a_fp->f_flag, FNONBLOCK);
 		break;
 
     	/*
