Submit #2804 » patch-sound_fix_nonblock.diff
| sys/dev/sound/pcm/channel.c | ||
|---|---|---|
|
*/
|
||
|
int
|
||
|
chn_write(struct pcm_channel *c, struct uio *buf)
|
||
|
chn_write(struct pcm_channel *c, struct uio *buf, int ioflag)
|
||
|
{
|
||
|
struct snd_dbuf *bs = c->bufsoft;
|
||
|
void *off;
|
||
| ... | ... | |
|
ret = 0;
|
||
|
timeout = chn_timeout * hz;
|
||
|
if (ioflag & O_NONBLOCK)
|
||
|
c->flags |= CHN_F_NBIO;
|
||
|
else
|
||
|
c->flags &= ~CHN_F_NBIO;
|
||
|
while (ret == 0 && buf->uio_resid > 0) {
|
||
|
sz = min(buf->uio_resid, sndbuf_getfree(bs));
|
||
|
if (sz > 0) {
|
||
| ... | ... | |
|
if (ret != 0)
|
||
|
c->flags |= CHN_F_DEAD;
|
||
|
}
|
||
|
} else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) {
|
||
|
} else if ((ioflag & O_NONBLOCK) || (c->flags & CHN_F_NOTRIGGER)) {
|
||
|
/**
|
||
|
* @todo Evaluate whether EAGAIN is truly desirable.
|
||
|
* 4Front drivers behave like this, but I'm
|
||
| ... | ... | |
|
*/
|
||
|
int
|
||
|
chn_read(struct pcm_channel *c, struct uio *buf)
|
||
|
chn_read(struct pcm_channel *c, struct uio *buf, int ioflag)
|
||
|
{
|
||
|
struct snd_dbuf *bs = c->bufsoft;
|
||
|
void *off;
|
||
| ... | ... | |
|
CHN_LOCKASSERT(c);
|
||
|
if (ioflag & O_NONBLOCK)
|
||
|
c->flags |= CHN_F_NBIO;
|
||
|
else
|
||
|
c->flags &= ~CHN_F_NBIO;
|
||
|
if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) {
|
||
|
ret = chn_start(c, 0);
|
||
|
if (ret != 0) {
|
||
| ... | ... | |
|
sndbuf_dispose(bs, NULL, t);
|
||
|
}
|
||
|
ret = 0;
|
||
|
} else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER))
|
||
|
} else if ((ioflag & O_NONBLOCK) || (c->flags & CHN_F_NOTRIGGER)) {
|
||
|
ret = EAGAIN;
|
||
|
else {
|
||
|
} else {
|
||
|
ret = chn_sleep(c, timeout);
|
||
|
if (ret == EAGAIN) {
|
||
|
ret = EINVAL;
|
||
| sys/dev/sound/pcm/channel.h | ||
|---|---|---|
|
#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 ioflag);
|
||
|
int chn_read(struct pcm_channel *c, struct uio *buf, int ioflag);
|
||
|
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);
|
||
| sys/dev/sound/pcm/dsp.c | ||
|---|---|---|
|
}
|
||
|
static __inline int
|
||
|
dsp_io_ops(struct cdev *i_dev, struct uio *buf)
|
||
|
dsp_io_ops(struct cdev *i_dev, struct uio *buf, int ioflag)
|
||
|
{
|
||
|
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;
|
||
| ... | ... | |
|
* someone else doesn't come along and muss up the buffer.
|
||
|
*/
|
||
|
++(*ch)->inprog;
|
||
|
ret = chn_io(*ch, buf);
|
||
|
ret = chn_io(*ch, buf, ioflag);
|
||
|
--(*ch)->inprog;
|
||
|
CHN_BROADCAST(&(*ch)->cv);
|
||
| ... | ... | |
|
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
|
||
| ... | ... | |
|
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
|
||
- « Previous
- 1
- 2
- 3
- 4
- Next »