diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c index d3e988ac8257..46cca889e5c6 100644 --- a/sys/dev/sound/pci/atiixp.c +++ b/sys/dev/sound/pci/atiixp.c @@ -65,11 +65,14 @@ SND_DECLARE_FILE("$FreeBSD$"); -#define ATI_IXP_DMA_RETRY_MAX 100 +#define ATI_IXP_DMA_RETRY_MAX 100 -#define ATI_IXP_BUFSZ_MIN 4096 -#define ATI_IXP_BUFSZ_MAX 65536 -#define ATI_IXP_BUFSZ_DEFAULT 16384 +#define ATI_IXP_BUFSZ_MIN 4096 +#define ATI_IXP_BUFSZ_MAX 65536 +#define ATI_IXP_BUFSZ_DEFAULT 16384 + +#define ATI_IXP_BLK_MIN 32 +#define ATI_IXP_BLK_ALIGN (~(ATI_IXP_BLK_MIN - 1)) struct atiixp_dma_op { volatile uint32_t addr; @@ -180,6 +183,7 @@ static void *atiixp_chan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int); static int atiixp_chan_setformat(kobj_t, void *, uint32_t); static int atiixp_chan_setspeed(kobj_t, void *, uint32_t); +static int atiixp_chan_setfragments(kobj_t, void *, uint32_t, uint32_t); static int atiixp_chan_setblocksize(kobj_t, void *, uint32_t); static void atiixp_buildsgdt(struct atiixp_chinfo *); static int atiixp_chan_trigger(kobj_t, void *, int); @@ -460,8 +464,8 @@ atiixp_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, atiixp_lock(sc); num = sc->registered_channels++; - ch->sgd_table = &sc->sgd_table[num * ch->blkcnt]; - ch->sgd_addr = sc->sgd_addr + (num * ch->blkcnt * + ch->sgd_table = &sc->sgd_table[num * ATI_IXP_DMA_CHSEGS_MAX]; + ch->sgd_addr = sc->sgd_addr + (num * ATI_IXP_DMA_CHSEGS_MAX * sizeof(struct atiixp_dma_op)); atiixp_disable_dma(ch); atiixp_unlock(sc); @@ -513,22 +517,52 @@ atiixp_chan_setspeed(kobj_t obj, void *data, uint32_t spd) return (ATI_IXP_BASE_RATE); } +static int +atiixp_chan_setfragments(kobj_t obj, void *data, + uint32_t blksz, uint32_t blkcnt) +{ + struct atiixp_chinfo *ch = data; + struct atiixp_info *sc = ch->parent; + + blksz &= ATI_IXP_BLK_ALIGN; + + if (blksz > (sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN)) + blksz = sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN; + if (blksz < ATI_IXP_BLK_MIN) + blksz = ATI_IXP_BLK_MIN; + if (blkcnt > ATI_IXP_DMA_CHSEGS_MAX) + blkcnt = ATI_IXP_DMA_CHSEGS_MAX; + if (blkcnt < ATI_IXP_DMA_CHSEGS_MIN) + blkcnt = ATI_IXP_DMA_CHSEGS_MIN; + + while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { + if ((blkcnt >> 1) >= ATI_IXP_DMA_CHSEGS_MIN) + blkcnt >>= 1; + else if ((blksz >> 1) >= ATI_IXP_BLK_MIN) + blksz >>= 1; + else + break; + } + + if ((sndbuf_getblksz(ch->buffer) != blksz || + sndbuf_getblkcnt(ch->buffer) != blkcnt) && + sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) + device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", + __func__, blksz, blkcnt); + + ch->blksz = sndbuf_getblksz(ch->buffer); + ch->blkcnt = sndbuf_getblkcnt(ch->buffer); + + return (1); +} + static int atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz) { struct atiixp_chinfo *ch = data; struct atiixp_info *sc = ch->parent; - if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer)) - blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt; - - if ((sndbuf_getblksz(ch->buffer) != blksz || - sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) && - sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0) - device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", - __func__, blksz, ch->blkcnt); - - ch->blksz = sndbuf_getblksz(ch->buffer); + atiixp_chan_setfragments(obj, data, blksz, sc->blkcnt); return (ch->blksz); } @@ -807,6 +841,7 @@ static kobj_method_t atiixp_chan_methods[] = { KOBJMETHOD(channel_setformat, atiixp_chan_setformat), KOBJMETHOD(channel_setspeed, atiixp_chan_setspeed), KOBJMETHOD(channel_setblocksize, atiixp_chan_setblocksize), + KOBJMETHOD(channel_setfragments, atiixp_chan_setfragments), KOBJMETHOD(channel_trigger, atiixp_chan_trigger), KOBJMETHOD(channel_getptr, atiixp_chan_getptr), KOBJMETHOD(channel_getcaps, atiixp_chan_getcaps), @@ -1179,6 +1214,9 @@ atiixp_pci_attach(device_t dev) */ if (resource_int_value(device_get_name(dev), device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { + i &= ATI_IXP_BLK_ALIGN; + if (i < ATI_IXP_BLK_MIN) + i = ATI_IXP_BLK_MIN; sc->blkcnt = sc->bufsz / i; i = 0; while (sc->blkcnt >> i) @@ -1212,7 +1250,7 @@ atiixp_pci_attach(device_t dev) /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/sc->blkcnt * ATI_IXP_NCHANS * + /*maxsize*/ATI_IXP_DMA_CHSEGS_MAX * ATI_IXP_NCHANS * sizeof(struct atiixp_dma_op), /*nsegments*/1, /*maxsegz*/0x3ffff, /*flags*/0, /*lockfunc*/NULL, @@ -1226,8 +1264,8 @@ atiixp_pci_attach(device_t dev) goto bad; if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table, - sc->blkcnt * ATI_IXP_NCHANS * sizeof(struct atiixp_dma_op), - atiixp_dma_cb, sc, 0)) + ATI_IXP_DMA_CHSEGS_MAX * ATI_IXP_NCHANS * + sizeof(struct atiixp_dma_op), atiixp_dma_cb, sc, 0)) goto bad; diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c index 261e9b7411e1..5bd90da04403 100644 --- a/sys/dev/sound/pci/es137x.c +++ b/sys/dev/sound/pci/es137x.c @@ -93,6 +93,11 @@ SND_DECLARE_FILE("$FreeBSD$"); #define ES_ADC 2 #define ES_NCHANS 3 +#define ES_DMA_SEGS_MIN 2 +#define ES_DMA_SEGS_MAX 256 +#define ES_BLK_MIN 64 +#define ES_BLK_ALIGN (~(ES_BLK_MIN - 1)) + #define ES1370_DAC1_MINSPEED 5512 #define ES1370_DAC1_MAXSPEED 44100 @@ -593,27 +598,52 @@ eschan1371_setspeed(kobj_t obj, void *data, uint32_t speed) return (i); } +static int +eschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) +{ + struct es_chinfo *ch = data; + struct es_info *es = ch->parent; + + blksz &= ES_BLK_ALIGN; + + if (blksz > (sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN)) + blksz = sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN; + if (blksz < ES_BLK_MIN) + blksz = ES_BLK_MIN; + if (blkcnt > ES_DMA_SEGS_MAX) + blkcnt = ES_DMA_SEGS_MAX; + if (blkcnt < ES_DMA_SEGS_MIN) + blkcnt = ES_DMA_SEGS_MIN; + + while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { + if ((blkcnt >> 1) >= ES_DMA_SEGS_MIN) + blkcnt >>= 1; + else if ((blksz >> 1) >= ES_BLK_MIN) + blksz >>= 1; + else + break; + } + + if ((sndbuf_getblksz(ch->buffer) != blksz || + sndbuf_getblkcnt(ch->buffer) != blkcnt) && + sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) + device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n", + __func__, blksz, blkcnt); + + ch->bufsz = sndbuf_getsize(ch->buffer); + ch->blksz = sndbuf_getblksz(ch->buffer); + ch->blkcnt = sndbuf_getblkcnt(ch->buffer); + + return (1); +} + static int eschan_setblocksize(kobj_t obj, void *data, uint32_t blksz) { struct es_chinfo *ch = data; struct es_info *es = ch->parent; - blksz &= ~0x3f; - if (blksz < 0x40) - blksz = 0x40; - - if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer)) - blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt; - - if ((sndbuf_getblksz(ch->buffer) != blksz || - sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) && - sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0) - device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n", - __func__, blksz, ch->blkcnt); - - ch->bufsz = sndbuf_getsize(ch->buffer); - ch->blksz = sndbuf_getblksz(ch->buffer); + eschan_setfragments(obj, data, blksz, es->blkcnt); return (ch->blksz); } @@ -813,7 +843,7 @@ eschan_getptr(kobj_t obj, void *data) } ES_UNLOCK(es); - cnt &= ~0x3f; + cnt &= ES_BLK_ALIGN; return (cnt); } @@ -831,6 +861,7 @@ static kobj_method_t eschan1370_methods[] = { KOBJMETHOD(channel_setformat, eschan_setformat), KOBJMETHOD(channel_setspeed, eschan1370_setspeed), KOBJMETHOD(channel_setblocksize, eschan_setblocksize), + KOBJMETHOD(channel_setfragments, eschan_setfragments), KOBJMETHOD(channel_trigger, eschan_trigger), KOBJMETHOD(channel_getptr, eschan_getptr), KOBJMETHOD(channel_getcaps, eschan_getcaps), @@ -843,6 +874,7 @@ static kobj_method_t eschan1371_methods[] = { KOBJMETHOD(channel_setformat, eschan_setformat), KOBJMETHOD(channel_setspeed, eschan1371_setspeed), KOBJMETHOD(channel_setblocksize, eschan_setblocksize), + KOBJMETHOD(channel_setfragments, eschan_setfragments), KOBJMETHOD(channel_trigger, eschan_trigger), KOBJMETHOD(channel_getptr, eschan_getptr), KOBJMETHOD(channel_getcaps, eschan_getcaps), @@ -1049,9 +1081,10 @@ es1371_wrcd(kobj_t obj, void *s, int addr, uint32_t data) uint32_t t, x, orig; struct es_info *es = (struct es_info*)s; - for (t = 0; t < 0x1000; t++) + for (t = 0; t < 0x1000; t++) { if (!es_rd(es, ES1371_REG_CODEC & CODEC_WIP, 4)) break; + } /* save the current state for later */ x = orig = es_rd(es, ES1371_REG_SMPRATE, 4); /* enable SRC state data in SRC mux */ @@ -1571,10 +1604,10 @@ es_init_sysctls(device_t dev) revid = pci_get_revid(dev); es = pcm_getdevinfo(dev); if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) || - (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) || - (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) || - (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) || - (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) { + (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) || + (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) || + (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) || + (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) { /* XXX: an user should be able to set this with a control tool, if not done before 7.0-RELEASE, this needs to be converted to a device specific sysctl "dev.pcm.X.yyy" via @@ -1699,18 +1732,18 @@ es_pci_attach(device_t dev) es->bufsz = pcm_getbuffersize(dev, 4096, ES_DEFAULT_BUFSZ, 65536); if (resource_int_value(device_get_name(dev), device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { - i &= ~0x3f; - if (i < 0x40) - i = 0x40; + i &= ES_BLK_ALIGN; + if (i < ES_BLK_MIN) + i = ES_BLK_MIN; es->blkcnt = es->bufsz / i; i = 0; while (es->blkcnt >> i) i++; es->blkcnt = 1 << (i - 1); - if (es->blkcnt < 2) - es->blkcnt = 2; - else if (es->blkcnt > 256) - es->blkcnt = 256; + if (es->blkcnt < ES_DMA_SEGS_MIN) + es->blkcnt = ES_DMA_SEGS_MIN; + else if (es->blkcnt > ES_DMA_SEGS_MAX) + es->blkcnt = ES_DMA_SEGS_MAX; } else es->blkcnt = 2; diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 1158eecabb66..ad0c256e139c 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -80,7 +80,7 @@ #include "mixer_if.h" -#define HDA_DRV_TEST_REV "20070316_0041" +#define HDA_DRV_TEST_REV "20070317_0042" #define HDA_WIDGET_PARSER_REV 1 SND_DECLARE_FILE("$FreeBSD$"); @@ -201,6 +201,7 @@ SND_DECLARE_FILE("$FreeBSD$"); #define ASUS_P1AH2_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x81cb) #define ASUS_A7M_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1323) #define ASUS_A7T_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x13c2) +#define ASUS_W6F_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1263) #define ASUS_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0xffff) /* IBM / Lenovo */ @@ -301,6 +302,9 @@ static const struct { #define HDA_BDL_MAX 256 #define HDA_BDL_DEFAULT HDA_BDL_MIN +#define HDA_BLK_MIN 128 +#define HDA_BLK_ALIGN (~(HDA_BLK_MIN - 1)) + #define HDA_BUFSZ_MIN 4096 #define HDA_BUFSZ_MAX 65536 #define HDA_BUFSZ_DEFAULT 16384 @@ -2763,26 +2767,52 @@ hdac_stream_setup(struct hdac_chan *ch) } } +static int +hdac_channel_setfragments(kobj_t obj, void *data, + uint32_t blksz, uint32_t blkcnt) +{ + struct hdac_chan *ch = data; + struct hdac_softc *sc = ch->devinfo->codec->sc; + + blksz &= HDA_BLK_ALIGN; + + if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN)) + blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN; + if (blksz < HDA_BLK_MIN) + blksz = HDA_BLK_MIN; + if (blkcnt > HDA_BDL_MAX) + blkcnt = HDA_BDL_MAX; + if (blkcnt < HDA_BDL_MIN) + blkcnt = HDA_BDL_MIN; + + while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->b)) { + if ((blkcnt >> 1) >= HDA_BDL_MIN) + blkcnt >>= 1; + else if ((blksz >> 1) >= HDA_BLK_MIN) + blksz >>= 1; + else + break; + } + + if ((sndbuf_getblksz(ch->b) != blksz || + sndbuf_getblkcnt(ch->b) != blkcnt) && + sndbuf_resize(ch->b, blkcnt, blksz) != 0) + device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", + __func__, blksz, blkcnt); + + ch->blksz = sndbuf_getblksz(ch->b); + ch->blkcnt = sndbuf_getblkcnt(ch->b); + + return (1); +} + static int hdac_channel_setblocksize(kobj_t obj, void *data, uint32_t blksz) { struct hdac_chan *ch = data; struct hdac_softc *sc = ch->devinfo->codec->sc; - blksz &= ~0x7f; - if (blksz < 0x80) - blksz = 0x80; - - if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->b)) - blksz = sndbuf_getmaxsize(ch->b) / ch->blkcnt; - - if ((sndbuf_getblksz(ch->b) != blksz || - sndbuf_getblkcnt(ch->b) != ch->blkcnt) && - sndbuf_resize(ch->b, ch->blkcnt, blksz) != 0) - device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", - __func__, blksz, ch->blkcnt); - - ch->blksz = sndbuf_getblksz(ch->b); + hdac_channel_setfragments(obj, data, blksz, sc->chan_blkcnt); return (ch->blksz); } @@ -2857,7 +2887,7 @@ hdac_channel_getptr(kobj_t obj, void *data) * Round to available space and force 128 bytes aligment. */ ptr %= ch->blksz * ch->blkcnt; - ptr &= ~0x7f; + ptr &= HDA_BLK_ALIGN; return (ptr); } @@ -2873,6 +2903,7 @@ static kobj_method_t hdac_channel_methods[] = { KOBJMETHOD(channel_setformat, hdac_channel_setformat), KOBJMETHOD(channel_setspeed, hdac_channel_setspeed), KOBJMETHOD(channel_setblocksize, hdac_channel_setblocksize), + KOBJMETHOD(channel_setfragments, hdac_channel_setfragments), KOBJMETHOD(channel_trigger, hdac_channel_trigger), KOBJMETHOD(channel_getptr, hdac_channel_getptr), KOBJMETHOD(channel_getcaps, hdac_channel_getcaps), @@ -3259,9 +3290,9 @@ hdac_attach(device_t dev) if (resource_int_value(device_get_name(sc->dev), device_get_unit(sc->dev), "blocksize", &i) == 0 && i > 0) { - i &= ~0x7f; - if (i < 0x80) - i = 0x80; + i &= HDA_BLK_ALIGN; + if (i < HDA_BLK_MIN) + i = HDA_BLK_MIN; sc->chan_blkcnt = sc->chan_size / i; i = 0; while (sc->chan_blkcnt >> i) diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c index eca8d11ee72c..2e0df873df5b 100644 --- a/sys/dev/sound/pci/via8233.c +++ b/sys/dev/sound/pci/via8233.c @@ -65,6 +65,8 @@ SND_DECLARE_FILE("$FreeBSD$"); #define VIA_SEGS_MIN 2 #define VIA_SEGS_MAX 64 #define VIA_SEGS_DEFAULT 2 +#define VIA_BLK_MIN 32 +#define VIA_BLK_ALIGN (~(VIA_BLK_MIN - 1)) #define VIA_DEFAULT_BUFSZ 0x1000 @@ -92,6 +94,8 @@ struct via_chinfo { }; struct via_info { + device_t dev; + bus_space_tag_t st; bus_space_handle_t sh; bus_dma_tag_t parent_dmat; @@ -312,7 +316,7 @@ via_waitready_codec(struct via_info *via) return (0); DELAY(1); } - printf("via: codec busy\n"); + device_printf(via->dev, "%s: codec busy\n", __func__); return (1); } @@ -327,7 +331,7 @@ via_waitvalid_codec(struct via_info *via) return (0); DELAY(1); } - printf("via: codec invalid\n"); + device_printf(via->dev, "%s: codec invalid\n", __func__); return (1); } @@ -555,21 +559,52 @@ via8233msgd_getcaps(kobj_t obj, void *data) /* -------------------------------------------------------------------- */ /* Common functions */ +static int +via8233chan_setfragments(kobj_t obj, void *data, + uint32_t blksz, uint32_t blkcnt) +{ + struct via_chinfo *ch = data; + struct via_info *via = ch->parent; + + blksz &= VIA_BLK_ALIGN; + + if (blksz > (sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN)) + blksz = sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN; + if (blksz < VIA_BLK_MIN) + blksz = VIA_BLK_MIN; + if (blkcnt > VIA_SEGS_MAX) + blkcnt = VIA_SEGS_MAX; + if (blkcnt < VIA_SEGS_MIN) + blkcnt = VIA_SEGS_MIN; + + while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { + if ((blkcnt >> 1) >= VIA_SEGS_MIN) + blkcnt >>= 1; + else if ((blksz >> 1) >= VIA_BLK_MIN) + blksz >>= 1; + else + break; + } + + if ((sndbuf_getblksz(ch->buffer) != blksz || + sndbuf_getblkcnt(ch->buffer) != blkcnt) && + sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) + device_printf(via->dev, "%s: failed blksz=%u blkcnt=%u\n", + __func__, blksz, blkcnt); + + ch->blksz = sndbuf_getblksz(ch->buffer); + ch->blkcnt = sndbuf_getblkcnt(ch->buffer); + + return (1); +} + static int via8233chan_setblocksize(kobj_t obj, void *data, uint32_t blksz) { struct via_chinfo *ch = data; + struct via_info *via = ch->parent; - if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer)) - blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt; - - if ((sndbuf_getblksz(ch->buffer) != blksz || - sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) && - sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0) - printf("via: %s: failed blksz=%u blkcnt=%u\n", - __func__, blksz, ch->blkcnt); - - ch->blksz = sndbuf_getblksz(ch->buffer); + via8233chan_setfragments(obj, data, blksz, via->blkcnt); return (ch->blksz); } @@ -613,8 +648,8 @@ via8233chan_reset(struct via_info *via, struct via_chinfo *ch) static void via8233chan_sgdinit(struct via_info *via, struct via_chinfo *ch, int chnum) { - ch->sgd_table = &via->sgd_table[chnum * via->blkcnt]; - ch->sgd_addr = via->sgd_addr + chnum * via->blkcnt * + ch->sgd_table = &via->sgd_table[chnum * VIA_SEGS_MAX]; + ch->sgd_addr = via->sgd_addr + chnum * VIA_SEGS_MAX * sizeof(struct via_dma_op); } @@ -716,10 +751,10 @@ via8233chan_mute(struct via_info *via, struct via_chinfo *ch, int muted) via_wr(via, ch->rbase + VIA8233_RP_DXS_RVOL, muted, 1); r = via_rd(via, ch->rbase + VIA8233_RP_DXS_LVOL, 1) & VIA8233_DXS_MUTE; - if (r != muted) { - printf("via: failed to set dxs volume " - "(dxs base 0x%02x).\n", ch->rbase); - } + if (r != muted) + device_printf(via->dev, + "%s: failed to set dxs volume " + "(dxs base 0x%02x).\n", __func__, ch->rbase); } } @@ -922,6 +957,7 @@ static kobj_method_t via8233wr_methods[] = { KOBJMETHOD(channel_setspeed, via8233wr_setspeed), KOBJMETHOD(channel_getcaps, via8233wr_getcaps), KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), + KOBJMETHOD(channel_setfragments, via8233chan_setfragments), KOBJMETHOD(channel_trigger, via8233chan_trigger), KOBJMETHOD(channel_getptr, via8233chan_getptr), { 0, 0 } @@ -934,6 +970,7 @@ static kobj_method_t via8233dxs_methods[] = { KOBJMETHOD(channel_setspeed, via8233dxs_setspeed), KOBJMETHOD(channel_getcaps, via8233dxs_getcaps), KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), + KOBJMETHOD(channel_setfragments, via8233chan_setfragments), KOBJMETHOD(channel_trigger, via8233chan_trigger), KOBJMETHOD(channel_getptr, via8233chan_getptr), { 0, 0 } @@ -946,6 +983,7 @@ static kobj_method_t via8233msgd_methods[] = { KOBJMETHOD(channel_setspeed, via8233msgd_setspeed), KOBJMETHOD(channel_getcaps, via8233msgd_getcaps), KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), + KOBJMETHOD(channel_setfragments, via8233chan_setfragments), KOBJMETHOD(channel_trigger, via8233chan_trigger), KOBJMETHOD(channel_getptr, via8233chan_getptr), { 0, 0 } @@ -1125,6 +1163,7 @@ via_attach(device_t dev) } via->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_via8233 softc"); + via->dev = dev; callout_init(&via->poll_timer, CALLOUT_MPSAFE); via->poll_ticks = 1; @@ -1161,6 +1200,9 @@ via_attach(device_t dev) via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536); if (resource_int_value(device_get_name(dev), device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { + i &= VIA_BLK_ALIGN; + if (i < VIA_BLK_MIN) + i = VIA_BLK_MIN; via->blkcnt = via->bufsz / i; i = 0; while (via->blkcnt >> i) @@ -1235,7 +1277,7 @@ via_attach(device_t dev) else via->dxs_src = 0; - nsegs = (via_dxs_chnum + via_sgd_chnum + NWRCHANS) * via->blkcnt; + nsegs = (via_dxs_chnum + via_sgd_chnum + NWRCHANS) * VIA_SEGS_MAX; /* DMA tag for buffers */ if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,