Marginally simplify dsp_open error handling by adding an early test to
determine liklihood of opening device in requested directions. Makes for simpler error handling and change should close kern/35004. PR: kern/35004.
This commit is contained in:
parent
e7413bff80
commit
47d5a0f3e5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=102525
@ -213,21 +213,27 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
|
||||
/* lock snddev so nobody else can monkey with it */
|
||||
pcm_lock(d);
|
||||
if ((dsp_get_flags(i_dev) & SD_F_SIMPLEX) && (i_dev->si_drv1 || i_dev->si_drv2)) {
|
||||
|
||||
rdch = i_dev->si_drv1;
|
||||
wrch = i_dev->si_drv2;
|
||||
|
||||
if ((dsp_get_flags(i_dev) & SD_F_SIMPLEX) && (rdch || wrch)) {
|
||||
/* simplex device, already open, exit */
|
||||
pcm_unlock(d);
|
||||
splx(s);
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
/* if we get here, the open request is valid */
|
||||
rdch = i_dev->si_drv1;
|
||||
wrch = i_dev->si_drv2;
|
||||
if (((flags & FREAD) && rdch) || ((flags & FWRITE) && wrch)) {
|
||||
/* device already open in one or both directions */
|
||||
pcm_unlock(d);
|
||||
splx(s);
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
/* if we get here, the open request is valid */
|
||||
if (flags & FREAD) {
|
||||
/* open for read */
|
||||
if (rdch == NULL) {
|
||||
/* not already open, try to get a channel */
|
||||
if (devtype == SND_DEV_DSPREC)
|
||||
rdch = pcm_chnalloc(d, PCMDIR_REC, td->td_proc->p_pid, PCMCHAN(i_dev));
|
||||
else
|
||||
@ -239,22 +245,14 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
return EBUSY;
|
||||
}
|
||||
/* got a channel, already locked for us */
|
||||
} else {
|
||||
/* already open for read, exit */
|
||||
pcm_unlock(d);
|
||||
splx(s);
|
||||
return EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FWRITE) {
|
||||
/* open for write */
|
||||
if (wrch == NULL) {
|
||||
/* not already open, try to get a channel */
|
||||
wrch = pcm_chnalloc(d, PCMDIR_PLAY, td->td_proc->p_pid, -1);
|
||||
if (!wrch) {
|
||||
/* no channel available */
|
||||
if (rdch && (flags & FREAD)) {
|
||||
if (flags & FREAD) {
|
||||
/* just opened a read channel, release it */
|
||||
pcm_chnrelease(rdch);
|
||||
}
|
||||
@ -264,17 +262,6 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
return EBUSY;
|
||||
}
|
||||
/* got a channel, already locked for us */
|
||||
} else {
|
||||
/* already open for write */
|
||||
if (rdch && (flags & FREAD)) {
|
||||
/* just opened a read channel, release it */
|
||||
pcm_chnrelease(rdch);
|
||||
}
|
||||
/* exit */
|
||||
pcm_unlock(d);
|
||||
splx(s);
|
||||
return EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
i_dev->si_drv1 = rdch;
|
||||
@ -283,7 +270,6 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
/* finished with snddev, new channels still locked */
|
||||
|
||||
/* bump refcounts, reset and unlock any channels that we just opened */
|
||||
if (rdch) {
|
||||
if (flags & FREAD) {
|
||||
if (chn_reset(rdch, fmt)) {
|
||||
pcm_lock(d);
|
||||
@ -296,28 +282,25 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
}
|
||||
if (flags & O_NONBLOCK)
|
||||
rdch->flags |= CHN_F_NBIO;
|
||||
} else
|
||||
CHN_LOCK(rdch);
|
||||
|
||||
pcm_chnref(rdch, 1);
|
||||
CHN_UNLOCK(rdch);
|
||||
}
|
||||
if (wrch) {
|
||||
if (flags & FWRITE) {
|
||||
if (chn_reset(wrch, fmt)) {
|
||||
pcm_lock(d);
|
||||
pcm_chnrelease(wrch);
|
||||
if (rdch && (flags & FREAD))
|
||||
if (flags & FREAD) {
|
||||
CHN_LOCK(rdch);
|
||||
pcm_chnref(rdch, -1);
|
||||
pcm_chnrelease(rdch);
|
||||
CHN_UNLOCK(rdch);
|
||||
}
|
||||
pcm_unlock(d);
|
||||
splx(s);
|
||||
return ENODEV;
|
||||
}
|
||||
if (flags & O_NONBLOCK)
|
||||
wrch->flags |= CHN_F_NBIO;
|
||||
} else
|
||||
CHN_LOCK(wrch);
|
||||
|
||||
pcm_chnref(wrch, 1);
|
||||
CHN_UNLOCK(wrch);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user