Deleted Added
full compact
channel.c (74797) channel.c (75319)
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
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:

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

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
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:

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

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/sound/pcm/channel.c 74797 2001-03-25 21:43:24Z cg $
27 * $FreeBSD: head/sys/dev/sound/pcm/channel.c 75319 2001-04-08 20:20:52Z cg $
28 */
29
30#include <dev/sound/pcm/sound.h>
31
32#include "feeder_if.h"
33
34#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */
35#define DMA_ALIGN_THRESHOLD 4

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

179 DEB(
180 if (c->flags & CHN_F_CLOSING) {
181 sndbuf_dump(b, "b", 0x02);
182 sndbuf_dump(bs, "bs", 0x02);
183 })
184
185 amt = sndbuf_getfree(b);
186 ret = (amt > 0)? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC;
28 */
29
30#include <dev/sound/pcm/sound.h>
31
32#include "feeder_if.h"
33
34#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */
35#define DMA_ALIGN_THRESHOLD 4

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

179 DEB(
180 if (c->flags & CHN_F_CLOSING) {
181 sndbuf_dump(b, "b", 0x02);
182 sndbuf_dump(bs, "bs", 0x02);
183 })
184
185 amt = sndbuf_getfree(b);
186 ret = (amt > 0)? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC;
187 if (ret == 0)
187 if (ret == 0 && sndbuf_getfree(b) < amt)
188 chn_wakeup(c);
189/*
190 if (!(irqc & 63) || (ret != 0))
191 sndbuf_dump(b, "b:wrfeed", 0x03);
192*/
193 return ret;
194}
195

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

719 DEB(printf("want speed %d, ", speed));
720 if (speed <= 0)
721 return EINVAL;
722 if (CANCHANGE(c)) {
723 r = 0;
724 c->speed = speed;
725 sndbuf_setspd(bs, speed);
726 RANGE(speed, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
188 chn_wakeup(c);
189/*
190 if (!(irqc & 63) || (ret != 0))
191 sndbuf_dump(b, "b:wrfeed", 0x03);
192*/
193 return ret;
194}
195

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

719 DEB(printf("want speed %d, ", speed));
720 if (speed <= 0)
721 return EINVAL;
722 if (CANCHANGE(c)) {
723 r = 0;
724 c->speed = speed;
725 sndbuf_setspd(bs, speed);
726 RANGE(speed, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
727 sndbuf_setspd(b, speed);
728 DEB(printf("try speed %d, ", sndbuf_getspd(b)));
729 sndbuf_setspd(b, CHANNEL_SETSPEED(c->methods, c->devinfo, sndbuf_getspd(b)));
727 DEB(printf("try speed %d, ", speed));
728 sndbuf_setspd(b, CHANNEL_SETSPEED(c->methods, c->devinfo, speed));
730 DEB(printf("got speed %d, ", sndbuf_getspd(b)));
731
732 delta = sndbuf_getspd(b) - sndbuf_getspd(bs);
733 if (delta < 0)
734 delta = -delta;
735
736 c->feederflags &= ~(1 << FEEDER_RATE);
737 if (delta > 500)

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

784}
785
786static int
787chn_tryformat(struct pcm_channel *c, u_int32_t fmt)
788{
789 struct snd_dbuf *b = c->bufhard;
790 struct snd_dbuf *bs = c->bufsoft;
791 int r;
729 DEB(printf("got speed %d, ", sndbuf_getspd(b)));
730
731 delta = sndbuf_getspd(b) - sndbuf_getspd(bs);
732 if (delta < 0)
733 delta = -delta;
734
735 c->feederflags &= ~(1 << FEEDER_RATE);
736 if (delta > 500)

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

783}
784
785static int
786chn_tryformat(struct pcm_channel *c, u_int32_t fmt)
787{
788 struct snd_dbuf *b = c->bufhard;
789 struct snd_dbuf *bs = c->bufsoft;
790 int r;
792 u_int32_t hwfmt;
793
794 CHN_LOCKASSERT(c);
795 if (CANCHANGE(c)) {
796 DEB(printf("want format %d\n", fmt));
797 c->format = fmt;
791
792 CHN_LOCKASSERT(c);
793 if (CANCHANGE(c)) {
794 DEB(printf("want format %d\n", fmt));
795 c->format = fmt;
798 hwfmt = c->format;
799 c->feederflags &= ~(1 << FEEDER_FMT);
800 if (!fmtvalid(hwfmt, chn_getcaps(c)->fmtlist))
801 c->feederflags |= 1 << FEEDER_FMT;
802 r = chn_buildfeeder(c);
803 if (r == 0) {
796 r = chn_buildfeeder(c);
797 if (r == 0) {
804 hwfmt = c->feeder->desc->out;
805 sndbuf_setfmt(b, hwfmt);
798 sndbuf_setfmt(b, c->feeder->desc->out);
806 sndbuf_setfmt(bs, fmt);
807 chn_resetbuf(c);
799 sndbuf_setfmt(bs, fmt);
800 chn_resetbuf(c);
808 CHANNEL_SETFORMAT(c->methods, c->devinfo, hwfmt);
801 CHANNEL_SETFORMAT(c->methods, c->devinfo, sndbuf_getfmt(b));
809 r = chn_tryspeed(c, c->speed);
810 }
811 return r;
812 } else
813 return EINVAL;
814}
815
816int

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

953 return fmts;
954}
955
956static int
957chn_buildfeeder(struct pcm_channel *c)
958{
959 struct feeder_class *fc;
960 struct pcm_feederdesc desc;
802 r = chn_tryspeed(c, c->speed);
803 }
804 return r;
805 } else
806 return EINVAL;
807}
808
809int

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

946 return fmts;
947}
948
949static int
950chn_buildfeeder(struct pcm_channel *c)
951{
952 struct feeder_class *fc;
953 struct pcm_feederdesc desc;
961 u_int32_t tmp[2], src, dst, type, flags;
954 u_int32_t tmp[2], type, flags;
962
963 CHN_LOCKASSERT(c);
964 while (chn_removefeeder(c) == 0);
965 KASSERT((c->feeder == NULL), ("feeder chain not empty"));
955
956 CHN_LOCKASSERT(c);
957 while (chn_removefeeder(c) == 0);
958 KASSERT((c->feeder == NULL), ("feeder chain not empty"));
959
966 c->align = sndbuf_getalign(c->bufsoft);
960 c->align = sndbuf_getalign(c->bufsoft);
961
967 fc = feeder_getclass(NULL);
962 fc = feeder_getclass(NULL);
968 if (fc == NULL)
963 if (fc == NULL) {
964 DEB(printf("can't find root feeder\n"));
969 return EINVAL;
965 return EINVAL;
970 if (chn_addfeeder(c, fc, NULL))
966 }
967 if (chn_addfeeder(c, fc, NULL)) {
968 DEB(printf("can't add root feeder\n"));
971 return EINVAL;
969 return EINVAL;
970 }
972 c->feeder->desc->out = c->format;
973
974 flags = c->feederflags;
971 c->feeder->desc->out = c->format;
972
973 flags = c->feederflags;
975 src = c->feeder->desc->out;
976 if ((c->flags & CHN_F_MAPPED) && (flags != 0))
974
975 if ((c->flags & CHN_F_MAPPED) && (flags != 0)) {
976 DEB(printf("can't build feeder chain on mapped channel\n"));
977 return EINVAL;
977 return EINVAL;
978 DEB(printf("not mapped, flags %x, ", flags));
978 }
979 DEB(printf("not mapped, flags %x\n", flags));
980
979 for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) {
980 if (flags & (1 << type)) {
981 desc.type = type;
982 desc.in = 0;
983 desc.out = 0;
984 desc.flags = 0;
985 DEB(printf("find feeder type %d, ", type));
986 fc = feeder_getclass(&desc);
987 DEB(printf("got %p\n", fc));
981 for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) {
982 if (flags & (1 << type)) {
983 desc.type = type;
984 desc.in = 0;
985 desc.out = 0;
986 desc.flags = 0;
987 DEB(printf("find feeder type %d, ", type));
988 fc = feeder_getclass(&desc);
989 DEB(printf("got %p\n", fc));
988 if (fc == NULL)
990 if (fc == NULL) {
991 DEB(printf("can't find required feeder type %d\n", type));
989 return EINVAL;
992 return EINVAL;
990 dst = fc->desc->in;
991 if (src != dst) {
992 DEB(printf("build fmtchain from %x to %x: ", src, dst));
993 tmp[0] = dst;
993 }
994
995 if (c->feeder->desc->out != fc->desc->in) {
996 DEB(printf("build fmtchain from %x to %x: ", c->feeder->desc->out, fc->desc->in));
997 tmp[0] = fc->desc->in;
994 tmp[1] = 0;
998 tmp[1] = 0;
995 if (chn_fmtchain(c, tmp) == 0)
999 if (chn_fmtchain(c, tmp) == 0) {
1000 DEB(printf("failed\n"));
996 return EINVAL;
1001 return EINVAL;
1002 }
997 DEB(printf("ok\n"));
998 }
1003 DEB(printf("ok\n"));
1004 }
999 if (chn_addfeeder(c, fc, fc->desc))
1005
1006 if (chn_addfeeder(c, fc, fc->desc)) {
1007 DEB(printf("can't add feeder %p, output %x\n", fc, fc->desc->out));
1000 return EINVAL;
1008 return EINVAL;
1001 src = fc->desc->out;
1002 DEB(printf("added feeder %p, output %x\n", fc, src));
1003 dst = 0;
1004 flags &= ~(1 << type);
1009 }
1010 DEB(printf("added feeder %p, output %x\n", fc, c->feeder->desc->out));
1005 }
1006 }
1011 }
1012 }
1007 if (!fmtvalid(src, chn_getcaps(c)->fmtlist)) {
1008 if (chn_fmtchain(c, chn_getcaps(c)->fmtlist) == 0)
1013
1014 if (!fmtvalid(c->feeder->desc->out, chn_getcaps(c)->fmtlist)) {
1015 if (chn_fmtchain(c, chn_getcaps(c)->fmtlist) == 0) {
1016 DEB(printf("can't build fmtchain from %x\n", c->feeder->desc->out));
1009 return EINVAL;
1017 return EINVAL;
1010 DEB(printf("built fmtchain from %x to %x\n", src, c->feeder->desc->out));
1011 flags &= ~(1 << FEEDER_FMT);
1018 }
1019 DEB(printf("built fmtchain from %x\n", c->feeder->desc->out));
1012 }
1020 }
1021
1013 return 0;
1014}
1015
1022 return 0;
1023}
1024
1016
1017