Deleted Added
full compact
34c34
< SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/channel.c 168243 2007-04-02 03:03:06Z ariff $");
---
> SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/channel.c 170161 2007-05-31 18:43:33Z ariff $");
172a173,175
> case PCMDIR_PLAY_VIRTUAL:
> c->lock = snd_mtxcreate(c->name, "pcm virtual play channel");
> break;
176,177c179,180
< case PCMDIR_VIRTUAL:
< c->lock = snd_mtxcreate(c->name, "pcm virtual play channel");
---
> case PCMDIR_REC_VIRTUAL:
> c->lock = snd_mtxcreate(c->name, "pcm virtual record channel");
237c240
< struct pcmchan_children *pce;
---
> struct pcm_channel *ch;
240c243
< if (SLIST_EMPTY(&c->children)) {
---
> if (CHN_EMPTY(c, children)) {
243c246,251
< wakeup_one(bs);
---
> } else if (CHN_EMPTY(c, children.busy)) {
> CHN_FOREACH(ch, c, children) {
> CHN_LOCK(ch);
> chn_wakeup(ch);
> CHN_UNLOCK(ch);
> }
245,248c253,256
< SLIST_FOREACH(pce, &c->children, link) {
< CHN_LOCK(pce->channel);
< chn_wakeup(pce->channel);
< CHN_UNLOCK(pce->channel);
---
> CHN_FOREACH(ch, c, children.busy) {
> CHN_LOCK(ch);
> chn_wakeup(ch);
> CHN_UNLOCK(ch);
250a259,260
> if (c->flags & CHN_F_SLEEPING)
> wakeup_one(bs);
259a270,271
>
> c->flags |= CHN_F_SLEEPING;
264a277
> c->flags &= ~CHN_F_SLEEPING;
500c513
< ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : 0;
---
> ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : ENOSPC;
522c535
< if ((c->flags & CHN_F_MAPPED) || CHN_STOPPED(c))
---
> if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c))
648c661
< if (snd_verbose > 3 && SLIST_EMPTY(&c->children))
---
> if (snd_verbose > 3 && CHN_EMPTY(c, children))
1096a1110,1111
> CHN_INIT(c, children);
> CHN_INIT(c, children.busy);
1196c1211,1212
< if (CHN_STARTED(c))
---
> if (CHN_STARTED(c)) {
> CHN_LOCK(c);
1198c1214,1217
< while (chn_removefeeder(c) == 0);
---
> CHN_UNLOCK(c);
> }
> while (chn_removefeeder(c) == 0)
> ;
1531c1550
< if (!SLIST_EMPTY(&c->children)) {
---
> if (!CHN_EMPTY(c, children)) {
1752a1772
> struct snddev_info *d = c->parentsnddev;
1759a1780,1783
> if ((go == PCMTRIG_START || go == PCMTRIG_STOP ||
> go == PCMTRIG_ABORT) && go == c->trigger)
> return 0;
>
1761a1786,1823
> if (ret == 0) {
> switch (go) {
> case PCMTRIG_START:
> if (snd_verbose > 3)
> device_printf(c->dev,
> "%s() %s: calling go=0x%08x , "
> "prev=0x%08x\n", __func__, c->name, go,
> c->trigger);
> if (c->trigger != PCMTRIG_START) {
> c->trigger = go;
> CHN_UNLOCK(c);
> pcm_lock(d);
> CHN_INSERT_HEAD(d, c, channels.pcm.busy);
> pcm_unlock(d);
> CHN_LOCK(c);
> }
> break;
> case PCMTRIG_STOP:
> case PCMTRIG_ABORT:
> if (snd_verbose > 3)
> device_printf(c->dev,
> "%s() %s: calling go=0x%08x , "
> "prev=0x%08x\n", __func__, c->name, go,
> c->trigger);
> if (c->trigger == PCMTRIG_START) {
> c->trigger = go;
> CHN_UNLOCK(c);
> pcm_lock(d);
> CHN_REMOVE(d, c, channels.pcm.busy);
> pcm_unlock(d);
> CHN_LOCK(c);
> }
> break;
> default:
> break;
> }
> }
>
1843c1905,1908
< if (SLIST_EMPTY(&c->children)) {
---
> if (CHN_EMPTY(c, children) || c->direction == PCMDIR_REC) {
> /*
> * Virtual rec need this.
> */
1854c1919
< } else {
---
> } else if (c->direction == PCMDIR_PLAY) {
1877c1942,1944
< }
---
> } else
> return EOPNOTSUPP;
>
1976a2044,2063
> } else if (c->direction == PCMDIR_REC && !CHN_EMPTY(c, children)) {
> /*
> * Kind of awkward. This whole "MIXER" concept need a
> * rethinking, I guess :) . Recording is the inverse
> * of Playback, which is why we push mixer vchan down here.
> */
> if (c->flags & CHN_F_HAS_VCHAN) {
> desc.type = FEEDER_MIXER;
> desc.in = c->format;
> } else
> return EOPNOTSUPP;
> desc.out = c->format;
> desc.flags = 0;
> fc = feeder_getclass(&desc);
> if (fc == NULL)
> return EOPNOTSUPP;
>
> err = chn_addfeeder(c, fc, &desc);
> if (err != 0)
> return err;
2023,2024d2109
< struct pcmchan_children *pce;
< struct pcm_channel *child;
2029c2114
< if (SLIST_EMPTY(&c->children)) {
---
> if (CHN_EMPTY(c, children)) {
2067,2080c2152,2153
< /*
< * scan the children, and figure out if any are running
< * if so, we need to be running, otherwise we need to be stopped
< * if we aren't in our target sstate, move to it
< */
< nrun = 0;
< SLIST_FOREACH(pce, &c->children, link) {
< child = pce->channel;
< CHN_LOCK(child);
< nrun = CHN_STARTED(child);
< CHN_UNLOCK(child);
< if (nrun)
< break;
< }
---
>
> nrun = CHN_EMPTY(c, children.busy) ? 0 : 1;