Deleted Added
full compact
channel.c (168243) channel.c (170161)
1/*-
2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
3 * Portions Copyright by Luigi Rizzo - 1997-99
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 17 unchanged lines hidden (view full) ---

26 */
27
28#include "opt_isa.h"
29
30#include <dev/sound/pcm/sound.h>
31
32#include "feeder_if.h"
33
1/*-
2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
3 * Portions Copyright by Luigi Rizzo - 1997-99
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 17 unchanged lines hidden (view full) ---

26 */
27
28#include "opt_isa.h"
29
30#include <dev/sound/pcm/sound.h>
31
32#include "feeder_if.h"
33
34SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/channel.c 168243 2007-04-02 03:03:06Z ariff $");
34SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/channel.c 170161 2007-05-31 18:43:33Z ariff $");
35
36#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */
37#if 0
38#define DMA_ALIGN_THRESHOLD 4
39#define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1))
40#endif
41
42#define CHN_STARTED(c) ((c)->flags & CHN_F_TRIGGERED)

--- 122 unchanged lines hidden (view full) ---

165
166static void
167chn_lockinit(struct pcm_channel *c, int dir)
168{
169 switch(dir) {
170 case PCMDIR_PLAY:
171 c->lock = snd_mtxcreate(c->name, "pcm play channel");
172 break;
35
36#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */
37#if 0
38#define DMA_ALIGN_THRESHOLD 4
39#define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1))
40#endif
41
42#define CHN_STARTED(c) ((c)->flags & CHN_F_TRIGGERED)

--- 122 unchanged lines hidden (view full) ---

165
166static void
167chn_lockinit(struct pcm_channel *c, int dir)
168{
169 switch(dir) {
170 case PCMDIR_PLAY:
171 c->lock = snd_mtxcreate(c->name, "pcm play channel");
172 break;
173 case PCMDIR_PLAY_VIRTUAL:
174 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel");
175 break;
173 case PCMDIR_REC:
174 c->lock = snd_mtxcreate(c->name, "pcm record channel");
175 break;
176 case PCMDIR_REC:
177 c->lock = snd_mtxcreate(c->name, "pcm record channel");
178 break;
176 case PCMDIR_VIRTUAL:
177 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel");
179 case PCMDIR_REC_VIRTUAL:
180 c->lock = snd_mtxcreate(c->name, "pcm virtual record channel");
178 break;
179 case 0:
180 c->lock = snd_mtxcreate(c->name, "pcm fake channel");
181 break;
182 }
183
184 cv_init(&c->cv, c->name);
185}

--- 43 unchanged lines hidden (view full) ---

229 sndbuf_updateprevtotal(bs);
230 return 1;
231}
232
233static void
234chn_wakeup(struct pcm_channel *c)
235{
236 struct snd_dbuf *bs = c->bufsoft;
181 break;
182 case 0:
183 c->lock = snd_mtxcreate(c->name, "pcm fake channel");
184 break;
185 }
186
187 cv_init(&c->cv, c->name);
188}

--- 43 unchanged lines hidden (view full) ---

232 sndbuf_updateprevtotal(bs);
233 return 1;
234}
235
236static void
237chn_wakeup(struct pcm_channel *c)
238{
239 struct snd_dbuf *bs = c->bufsoft;
237 struct pcmchan_children *pce;
240 struct pcm_channel *ch;
238
239 CHN_LOCKASSERT(c);
241
242 CHN_LOCKASSERT(c);
240 if (SLIST_EMPTY(&c->children)) {
243 if (CHN_EMPTY(c, children)) {
241 if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
242 selwakeuppri(sndbuf_getsel(bs), PRIBIO);
244 if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
245 selwakeuppri(sndbuf_getsel(bs), PRIBIO);
243 wakeup_one(bs);
246 } else if (CHN_EMPTY(c, children.busy)) {
247 CHN_FOREACH(ch, c, children) {
248 CHN_LOCK(ch);
249 chn_wakeup(ch);
250 CHN_UNLOCK(ch);
251 }
244 } else {
252 } else {
245 SLIST_FOREACH(pce, &c->children, link) {
246 CHN_LOCK(pce->channel);
247 chn_wakeup(pce->channel);
248 CHN_UNLOCK(pce->channel);
253 CHN_FOREACH(ch, c, children.busy) {
254 CHN_LOCK(ch);
255 chn_wakeup(ch);
256 CHN_UNLOCK(ch);
249 }
250 }
257 }
258 }
259 if (c->flags & CHN_F_SLEEPING)
260 wakeup_one(bs);
251}
252
253static int
254chn_sleep(struct pcm_channel *c, char *str, int timeout)
255{
256 struct snd_dbuf *bs = c->bufsoft;
257 int ret;
258
259 CHN_LOCKASSERT(c);
261}
262
263static int
264chn_sleep(struct pcm_channel *c, char *str, int timeout)
265{
266 struct snd_dbuf *bs = c->bufsoft;
267 int ret;
268
269 CHN_LOCKASSERT(c);
270
271 c->flags |= CHN_F_SLEEPING;
260#ifdef USING_MUTEX
261 ret = msleep(bs, c->lock, PRIBIO | PCATCH, str, timeout);
262#else
263 ret = tsleep(bs, PRIBIO | PCATCH, str, timeout);
264#endif
272#ifdef USING_MUTEX
273 ret = msleep(bs, c->lock, PRIBIO | PCATCH, str, timeout);
274#else
275 ret = tsleep(bs, PRIBIO | PCATCH, str, timeout);
276#endif
277 c->flags &= ~CHN_F_SLEEPING;
265
266 return ret;
267}
268
269/*
270 * chn_dmaupdate() tracks the status of a dma transfer,
271 * updating pointers.
272 */

--- 219 unchanged lines hidden (view full) ---

492#if 0
493 amt = sndbuf_getready(b);
494 if (sndbuf_getfree(bs) < amt) {
495 c->xruns++;
496 amt = sndbuf_getfree(bs);
497 }
498#endif
499 amt = sndbuf_getfree(bs);
278
279 return ret;
280}
281
282/*
283 * chn_dmaupdate() tracks the status of a dma transfer,
284 * updating pointers.
285 */

--- 219 unchanged lines hidden (view full) ---

505#if 0
506 amt = sndbuf_getready(b);
507 if (sndbuf_getfree(bs) < amt) {
508 c->xruns++;
509 amt = sndbuf_getfree(bs);
510 }
511#endif
512 amt = sndbuf_getfree(bs);
500 ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : 0;
513 ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : ENOSPC;
501
502 amt = sndbuf_getready(b);
503 if (amt > 0) {
504 c->xruns++;
505 sndbuf_dispose(b, NULL, amt);
506 }
507
508 if (sndbuf_getready(bs) > 0)

--- 5 unchanged lines hidden (view full) ---

514void
515chn_rdupdate(struct pcm_channel *c)
516{
517 int ret;
518
519 CHN_LOCKASSERT(c);
520 KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel"));
521
514
515 amt = sndbuf_getready(b);
516 if (amt > 0) {
517 c->xruns++;
518 sndbuf_dispose(b, NULL, amt);
519 }
520
521 if (sndbuf_getready(bs) > 0)

--- 5 unchanged lines hidden (view full) ---

527void
528chn_rdupdate(struct pcm_channel *c)
529{
530 int ret;
531
532 CHN_LOCKASSERT(c);
533 KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel"));
534
522 if ((c->flags & CHN_F_MAPPED) || CHN_STOPPED(c))
535 if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c))
523 return;
524 chn_trigger(c, PCMTRIG_EMLDMARD);
525 chn_dmaupdate(c);
526 ret = chn_rdfeed(c);
527 DEB(if (ret)
528 printf("chn_rdfeed: %d\n", ret);)
529
530}

--- 109 unchanged lines hidden (view full) ---

640 } else {
641 struct snd_dbuf *pb;
642
643 pb = BUF_PARENT(c, b);
644 i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb);
645 j = sndbuf_getbps(pb);
646 }
647 }
536 return;
537 chn_trigger(c, PCMTRIG_EMLDMARD);
538 chn_dmaupdate(c);
539 ret = chn_rdfeed(c);
540 DEB(if (ret)
541 printf("chn_rdfeed: %d\n", ret);)
542
543}

--- 109 unchanged lines hidden (view full) ---

653 } else {
654 struct snd_dbuf *pb;
655
656 pb = BUF_PARENT(c, b);
657 i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb);
658 j = sndbuf_getbps(pb);
659 }
660 }
648 if (snd_verbose > 3 && SLIST_EMPTY(&c->children))
661 if (snd_verbose > 3 && CHN_EMPTY(c, children))
649 printf("%s: %s (%s) threshold i=%d j=%d\n",
650 __func__, CHN_DIRSTR(c),
651 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware",
652 i, j);
653 }
654
655 if (i >= j) {
656 c->flags |= CHN_F_TRIGGERED;

--- 432 unchanged lines hidden (view full) ---

1089
1090 if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX)
1091 chn_timeout = CHN_TIMEOUT;
1092
1093 chn_lockinit(c, dir);
1094
1095 b = NULL;
1096 bs = NULL;
662 printf("%s: %s (%s) threshold i=%d j=%d\n",
663 __func__, CHN_DIRSTR(c),
664 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware",
665 i, j);
666 }
667
668 if (i >= j) {
669 c->flags |= CHN_F_TRIGGERED;

--- 432 unchanged lines hidden (view full) ---

1102
1103 if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX)
1104 chn_timeout = CHN_TIMEOUT;
1105
1106 chn_lockinit(c, dir);
1107
1108 b = NULL;
1109 bs = NULL;
1110 CHN_INIT(c, children);
1111 CHN_INIT(c, children.busy);
1097 c->devinfo = NULL;
1098 c->feeder = NULL;
1099 c->latency = -1;
1100 c->timeout = 1;
1101
1102 ret = ENOMEM;
1103 b = sndbuf_create(c->dev, c->name, "primary", c);
1104 if (b == NULL)

--- 83 unchanged lines hidden (view full) ---

1188}
1189
1190int
1191chn_kill(struct pcm_channel *c)
1192{
1193 struct snd_dbuf *b = c->bufhard;
1194 struct snd_dbuf *bs = c->bufsoft;
1195
1112 c->devinfo = NULL;
1113 c->feeder = NULL;
1114 c->latency = -1;
1115 c->timeout = 1;
1116
1117 ret = ENOMEM;
1118 b = sndbuf_create(c->dev, c->name, "primary", c);
1119 if (b == NULL)

--- 83 unchanged lines hidden (view full) ---

1203}
1204
1205int
1206chn_kill(struct pcm_channel *c)
1207{
1208 struct snd_dbuf *b = c->bufhard;
1209 struct snd_dbuf *bs = c->bufsoft;
1210
1196 if (CHN_STARTED(c))
1211 if (CHN_STARTED(c)) {
1212 CHN_LOCK(c);
1197 chn_trigger(c, PCMTRIG_ABORT);
1213 chn_trigger(c, PCMTRIG_ABORT);
1198 while (chn_removefeeder(c) == 0);
1214 CHN_UNLOCK(c);
1215 }
1216 while (chn_removefeeder(c) == 0)
1217 ;
1199 if (CHANNEL_FREE(c->methods, c->devinfo))
1200 sndbuf_free(b);
1201 c->flags |= CHN_F_DEAD;
1202 sndbuf_destroy(bs);
1203 sndbuf_destroy(b);
1204 chn_lockdestroy(c);
1205 return 0;
1206}

--- 316 unchanged lines hidden (view full) ---

1523 CHN_UNLOCK(c);
1524 if (chn_usefrags == 0 ||
1525 CHANNEL_SETFRAGMENTS(c->methods, c->devinfo,
1526 hblksz, hblkcnt) < 1)
1527 sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods,
1528 c->devinfo, hblksz));
1529 CHN_LOCK(c);
1530
1218 if (CHANNEL_FREE(c->methods, c->devinfo))
1219 sndbuf_free(b);
1220 c->flags |= CHN_F_DEAD;
1221 sndbuf_destroy(bs);
1222 sndbuf_destroy(b);
1223 chn_lockdestroy(c);
1224 return 0;
1225}

--- 316 unchanged lines hidden (view full) ---

1542 CHN_UNLOCK(c);
1543 if (chn_usefrags == 0 ||
1544 CHANNEL_SETFRAGMENTS(c->methods, c->devinfo,
1545 hblksz, hblkcnt) < 1)
1546 sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods,
1547 c->devinfo, hblksz));
1548 CHN_LOCK(c);
1549
1531 if (!SLIST_EMPTY(&c->children)) {
1550 if (!CHN_EMPTY(c, children)) {
1532 sblksz = round_blksz(
1533 sndbuf_xbytes(sndbuf_getsize(b) >> 1, b, bs),
1534 sndbuf_getbps(bs));
1535 sblkcnt = 2;
1536 limit = 0;
1537 } else if (limit != 0)
1538 limit = sndbuf_xbytes(sndbuf_getsize(b), b, bs);
1539

--- 205 unchanged lines hidden (view full) ---

1745}
1746
1747int
1748chn_trigger(struct pcm_channel *c, int go)
1749{
1750#ifdef DEV_ISA
1751 struct snd_dbuf *b = c->bufhard;
1752#endif
1551 sblksz = round_blksz(
1552 sndbuf_xbytes(sndbuf_getsize(b) >> 1, b, bs),
1553 sndbuf_getbps(bs));
1554 sblkcnt = 2;
1555 limit = 0;
1556 } else if (limit != 0)
1557 limit = sndbuf_xbytes(sndbuf_getsize(b), b, bs);
1558

--- 205 unchanged lines hidden (view full) ---

1764}
1765
1766int
1767chn_trigger(struct pcm_channel *c, int go)
1768{
1769#ifdef DEV_ISA
1770 struct snd_dbuf *b = c->bufhard;
1771#endif
1772 struct snddev_info *d = c->parentsnddev;
1753 int ret;
1754
1755 CHN_LOCKASSERT(c);
1756#ifdef DEV_ISA
1757 if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD))
1758 sndbuf_dmabounce(b);
1759#endif
1773 int ret;
1774
1775 CHN_LOCKASSERT(c);
1776#ifdef DEV_ISA
1777 if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD))
1778 sndbuf_dmabounce(b);
1779#endif
1780 if ((go == PCMTRIG_START || go == PCMTRIG_STOP ||
1781 go == PCMTRIG_ABORT) && go == c->trigger)
1782 return 0;
1783
1760 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go);
1761
1784 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go);
1785
1786 if (ret == 0) {
1787 switch (go) {
1788 case PCMTRIG_START:
1789 if (snd_verbose > 3)
1790 device_printf(c->dev,
1791 "%s() %s: calling go=0x%08x , "
1792 "prev=0x%08x\n", __func__, c->name, go,
1793 c->trigger);
1794 if (c->trigger != PCMTRIG_START) {
1795 c->trigger = go;
1796 CHN_UNLOCK(c);
1797 pcm_lock(d);
1798 CHN_INSERT_HEAD(d, c, channels.pcm.busy);
1799 pcm_unlock(d);
1800 CHN_LOCK(c);
1801 }
1802 break;
1803 case PCMTRIG_STOP:
1804 case PCMTRIG_ABORT:
1805 if (snd_verbose > 3)
1806 device_printf(c->dev,
1807 "%s() %s: calling go=0x%08x , "
1808 "prev=0x%08x\n", __func__, c->name, go,
1809 c->trigger);
1810 if (c->trigger == PCMTRIG_START) {
1811 c->trigger = go;
1812 CHN_UNLOCK(c);
1813 pcm_lock(d);
1814 CHN_REMOVE(d, c, channels.pcm.busy);
1815 pcm_unlock(d);
1816 CHN_LOCK(c);
1817 }
1818 break;
1819 default:
1820 break;
1821 }
1822 }
1823
1762 return ret;
1763}
1764
1765/**
1766 * @brief Queries sound driver for sample-aligned hardware buffer pointer index
1767 *
1768 * This function obtains the hardware pointer location, then aligns it to
1769 * the current bytes-per-sample value before returning. (E.g., a channel

--- 65 unchanged lines hidden (view full) ---

1835
1836 CHN_LOCKASSERT(c);
1837 while (chn_removefeeder(c) == 0)
1838 ;
1839 KASSERT((c->feeder == NULL), ("feeder chain not empty"));
1840
1841 c->align = sndbuf_getalign(c->bufsoft);
1842
1824 return ret;
1825}
1826
1827/**
1828 * @brief Queries sound driver for sample-aligned hardware buffer pointer index
1829 *
1830 * This function obtains the hardware pointer location, then aligns it to
1831 * the current bytes-per-sample value before returning. (E.g., a channel

--- 65 unchanged lines hidden (view full) ---

1897
1898 CHN_LOCKASSERT(c);
1899 while (chn_removefeeder(c) == 0)
1900 ;
1901 KASSERT((c->feeder == NULL), ("feeder chain not empty"));
1902
1903 c->align = sndbuf_getalign(c->bufsoft);
1904
1843 if (SLIST_EMPTY(&c->children)) {
1905 if (CHN_EMPTY(c, children) || c->direction == PCMDIR_REC) {
1906 /*
1907 * Virtual rec need this.
1908 */
1844 fc = feeder_getclass(NULL);
1845 KASSERT(fc != NULL, ("can't find root feeder"));
1846
1847 err = chn_addfeeder(c, fc, NULL);
1848 if (err) {
1849 DEB(printf("can't add root feeder, err %d\n", err));
1850
1851 return err;
1852 }
1853 c->feeder->desc->out = c->format;
1909 fc = feeder_getclass(NULL);
1910 KASSERT(fc != NULL, ("can't find root feeder"));
1911
1912 err = chn_addfeeder(c, fc, NULL);
1913 if (err) {
1914 DEB(printf("can't add root feeder, err %d\n", err));
1915
1916 return err;
1917 }
1918 c->feeder->desc->out = c->format;
1854 } else {
1919 } else if (c->direction == PCMDIR_PLAY) {
1855 if (c->flags & CHN_F_HAS_VCHAN) {
1856 desc.type = FEEDER_MIXER;
1857 desc.in = c->format;
1858 } else {
1859 DEB(printf("can't decide which feeder type to use!\n"));
1860 return EOPNOTSUPP;
1861 }
1862 desc.out = c->format;

--- 6 unchanged lines hidden (view full) ---

1869 }
1870
1871 err = chn_addfeeder(c, fc, &desc);
1872 if (err) {
1873 DEB(printf("can't add vchan feeder, err %d\n", err));
1874
1875 return err;
1876 }
1920 if (c->flags & CHN_F_HAS_VCHAN) {
1921 desc.type = FEEDER_MIXER;
1922 desc.in = c->format;
1923 } else {
1924 DEB(printf("can't decide which feeder type to use!\n"));
1925 return EOPNOTSUPP;
1926 }
1927 desc.out = c->format;

--- 6 unchanged lines hidden (view full) ---

1934 }
1935
1936 err = chn_addfeeder(c, fc, &desc);
1937 if (err) {
1938 DEB(printf("can't add vchan feeder, err %d\n", err));
1939
1940 return err;
1941 }
1877 }
1942 } else
1943 return EOPNOTSUPP;
1944
1878 c->feederflags &= ~(1 << FEEDER_VOLUME);
1879 if (c->direction == PCMDIR_PLAY &&
1880 !(c->flags & CHN_F_VIRTUAL) && c->parentsnddev &&
1881 (c->parentsnddev->flags & SD_F_SOFTPCMVOL) &&
1882 c->parentsnddev->mixer_dev)
1883 c->feederflags |= 1 << FEEDER_VOLUME;
1884 if (!(c->flags & CHN_F_VIRTUAL) && c->parentsnddev &&
1885 ((c->direction == PCMDIR_PLAY &&

--- 83 unchanged lines hidden (view full) ---

1969 tmp[1] = 0;
1970 hwfmt = chn_fmtchain(c, tmp);
1971 } else
1972 hwfmt = chn_fmtchain(c, fmtlist);
1973
1974 if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) {
1975 DEB(printf("Invalid hardware format: 0x%08x\n", hwfmt));
1976 return ENODEV;
1945 c->feederflags &= ~(1 << FEEDER_VOLUME);
1946 if (c->direction == PCMDIR_PLAY &&
1947 !(c->flags & CHN_F_VIRTUAL) && c->parentsnddev &&
1948 (c->parentsnddev->flags & SD_F_SOFTPCMVOL) &&
1949 c->parentsnddev->mixer_dev)
1950 c->feederflags |= 1 << FEEDER_VOLUME;
1951 if (!(c->flags & CHN_F_VIRTUAL) && c->parentsnddev &&
1952 ((c->direction == PCMDIR_PLAY &&

--- 83 unchanged lines hidden (view full) ---

2036 tmp[1] = 0;
2037 hwfmt = chn_fmtchain(c, tmp);
2038 } else
2039 hwfmt = chn_fmtchain(c, fmtlist);
2040
2041 if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) {
2042 DEB(printf("Invalid hardware format: 0x%08x\n", hwfmt));
2043 return ENODEV;
2044 } else if (c->direction == PCMDIR_REC && !CHN_EMPTY(c, children)) {
2045 /*
2046 * Kind of awkward. This whole "MIXER" concept need a
2047 * rethinking, I guess :) . Recording is the inverse
2048 * of Playback, which is why we push mixer vchan down here.
2049 */
2050 if (c->flags & CHN_F_HAS_VCHAN) {
2051 desc.type = FEEDER_MIXER;
2052 desc.in = c->format;
2053 } else
2054 return EOPNOTSUPP;
2055 desc.out = c->format;
2056 desc.flags = 0;
2057 fc = feeder_getclass(&desc);
2058 if (fc == NULL)
2059 return EOPNOTSUPP;
2060
2061 err = chn_addfeeder(c, fc, &desc);
2062 if (err != 0)
2063 return err;
1977 }
1978
1979 sndbuf_setfmt(c->bufhard, hwfmt);
1980
1981 if ((flags & (1 << FEEDER_VOLUME))) {
1982 u_int32_t parent = SOUND_MIXER_NONE;
1983 int vol, left, right;
1984

--- 30 unchanged lines hidden (view full) ---

2015 }
2016
2017 return 0;
2018}
2019
2020int
2021chn_notify(struct pcm_channel *c, u_int32_t flags)
2022{
2064 }
2065
2066 sndbuf_setfmt(c->bufhard, hwfmt);
2067
2068 if ((flags & (1 << FEEDER_VOLUME))) {
2069 u_int32_t parent = SOUND_MIXER_NONE;
2070 int vol, left, right;
2071

--- 30 unchanged lines hidden (view full) ---

2102 }
2103
2104 return 0;
2105}
2106
2107int
2108chn_notify(struct pcm_channel *c, u_int32_t flags)
2109{
2023 struct pcmchan_children *pce;
2024 struct pcm_channel *child;
2025 int run;
2026
2027 CHN_LOCK(c);
2028
2110 int run;
2111
2112 CHN_LOCK(c);
2113
2029 if (SLIST_EMPTY(&c->children)) {
2114 if (CHN_EMPTY(c, children)) {
2030 CHN_UNLOCK(c);
2031 return ENODEV;
2032 }
2033
2034 run = (CHN_STARTED(c)) ? 1 : 0;
2035 /*
2036 * if the hwchan is running, we can't change its rate, format or
2037 * blocksize

--- 21 unchanged lines hidden (view full) ---

2059 if (flags & CHN_N_BLOCKSIZE) {
2060 /*
2061 * Set to default latency profile
2062 */
2063 chn_setlatency(c, chn_latency);
2064 }
2065 if (flags & CHN_N_TRIGGER) {
2066 int nrun;
2115 CHN_UNLOCK(c);
2116 return ENODEV;
2117 }
2118
2119 run = (CHN_STARTED(c)) ? 1 : 0;
2120 /*
2121 * if the hwchan is running, we can't change its rate, format or
2122 * blocksize

--- 21 unchanged lines hidden (view full) ---

2144 if (flags & CHN_N_BLOCKSIZE) {
2145 /*
2146 * Set to default latency profile
2147 */
2148 chn_setlatency(c, chn_latency);
2149 }
2150 if (flags & CHN_N_TRIGGER) {
2151 int nrun;
2067 /*
2068 * scan the children, and figure out if any are running
2069 * if so, we need to be running, otherwise we need to be stopped
2070 * if we aren't in our target sstate, move to it
2071 */
2072 nrun = 0;
2073 SLIST_FOREACH(pce, &c->children, link) {
2074 child = pce->channel;
2075 CHN_LOCK(child);
2076 nrun = CHN_STARTED(child);
2077 CHN_UNLOCK(child);
2078 if (nrun)
2079 break;
2080 }
2152
2153 nrun = CHN_EMPTY(c, children.busy) ? 0 : 1;
2081 if (nrun && !run)
2082 chn_start(c, 1);
2083 if (!nrun && run)
2084 chn_abort(c);
2085 }
2086 CHN_UNLOCK(c);
2087 return 0;
2088}

--- 92 unchanged lines hidden ---
2154 if (nrun && !run)
2155 chn_start(c, 1);
2156 if (!nrun && run)
2157 chn_abort(c);
2158 }
2159 CHN_UNLOCK(c);
2160 return 0;
2161}

--- 92 unchanged lines hidden ---