sys/dev/sound/pcm/sound.c
int
pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction,
		pid_t pid, int chnum)
{
	struct pcm_channel *c;
	struct snddev_channel *sce;
	int err;

	err = ENODEV;
	/* scan for a free channel */
	SLIST_FOREACH(sce, &d->channels, link) {
		c = sce->channel;
		CHN_LOCK(c);
		if (c->direction == direction && !(c->flags & CHN_F_BUSY)) {
			if (chnum < 0 || sce->chan_num == chnum) {
				c->flags |= CHN_F_BUSY;
				c->pid = pid;
				*ch = c;
				return 0;
			}
		}
		if (sce->chan_num == chnum) {
			if (c->direction != direction)
				err = EOPNOTSUPP;
			else if (c->flags & CHN_F_BUSY)
				err = EBUSY;
			else
				err = EINVAL;
			CHN_UNLOCK(c);
			return err;
		} else if (c->direction == direction && (c->flags & CHN_F_BUSY))
			err = EBUSY;
		CHN_UNLOCK(c);
	}

	return err;
}
/* return error status and a locked channel */
return error status and a locked channel
return error status and a locked channel
int
pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction,
		pid_t pid, int chnum)
{
	struct pcm_channel *c;
	struct snddev_channel *sce;
	int err;
	err = ENODEV;
	SLIST_FOREACH(sce, &d->channels, link) {
		c = sce->channel;
		CHN_LOCK(c);
		if (c->direction == direction && !(c->flags & CHN_F_BUSY)) {
			if (chnum < 0 || sce->chan_num == chnum) {
				c->flags |= CHN_F_BUSY;
				c->pid = pid;
				*ch = c;
				return 0;
			}
		}
		if (sce->chan_num == chnum) {
			if (c->direction != direction)
				err = EOPNOTSUPP;
			else if (c->flags & CHN_F_BUSY)
				err = EBUSY;
			else
				err = EINVAL;
			CHN_UNLOCK(c);
			return err;
		} else if (c->direction == direction && (c->flags & CHN_F_BUSY))
			err = EBUSY;
		CHN_UNLOCK(c);
	}
	return err;
}
int pcm_chnalloc ( struct snddev_info * d , struct pcm_channel * * ch , int direction , pid_t pid , int chnum ) { struct pcm_channel * c ; struct snddev_channel * sce ; int err ; err = ENODEV ; SLIST_FOREACH ( sce , & d -> channels , link ) { c = sce -> channel ; CHN_LOCK ( c ) ; if ( c -> direction == direction && ! ( c -> flags & CHN_F_BUSY ) ) { if ( chnum < 0 || sce -> chan_num == chnum ) { c -> flags |= CHN_F_BUSY ; c -> pid = pid ; * ch = c ; return 0 ; } } if ( sce -> chan_num == chnum ) { if ( c -> direction != direction ) err = EOPNOTSUPP ; else if ( c -> flags & CHN_F_BUSY ) err = EBUSY ; else err = EINVAL ; CHN_UNLOCK ( c ) ; return err ; } else if ( c -> direction == direction && ( c -> flags & CHN_F_BUSY ) ) err = EBUSY ; CHN_UNLOCK ( c ) ; } return err ; }
return error status and a locked channel
return error status and a locked channel
/* scan for a free channel */