From nobody Wed Oct 14 16:02:56 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4j4bZm59QMz6vm0y for ; Wed, 14 Oct 2026 16:02:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j4bZm3Qx5z4Xvy for ; Wed, 14 Oct 2026 16:02:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791993776; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qKFEyQH++fmgLWYixqxJvW1RFsYLi5QIyNwyLQUbIMQ=; b=Nq4fGOH8ce5cE6LLoEbMiBn5KJSR4IHecTGlpeOy/o+qApCuWVI7/Qsyk7J8YxJCclaSFm F46VPALhrZe3v56o5Td1oXwKTLG4Ma58+scjOFUwbmSNEOo3SWvkcj1grj48dt/ng+ElWU x1LBGSub5e39FBrycyW5aRklwWven07V3ThmUbVbDTW/D6BKNw7vlo081gjo8xj/WiBFPn VxK1/rpyW+yO14MHVvDtxXY/UXRCkuXDBZJdUrKy5HC29u6y0NhPqMmw4iUe7IHuAhTItS jXENMqv5dFKRhsyN8jdBrUKBYIiU1R5yrkxVQQVPir7VGpEiyxKNgzN2/OwPrg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791993776; b=IVXYhzHIB5ANOTTXJJi+jz+CAbA7WjvNsTjbXs5GWhLBkxCkskZjHcv9ABNVePlOP9z6DH 2V2y182gBSq92aOaV5UYqJ7vognf1KEOY0zWX+Rh7FeCJemRBjtfo1FgCK+rmzSScFfpBi DR9mF/UngFvruJbACpBnlrB3kQR8poZKBXuaTtPzDzlACKGSMSfDZRPnilnlpsgH6ZSc1b rfZwMyRgXrnI9xHj43/IYmtSwS7ADSBKZLlms/cH4CZEjx5aEqubry6Lv1xXvrIzfXHNUC 4tuLDCanpBW3fplltgXYs027gmaecIOze1XObSKLsGgsA+vAkeewpP6KhXtaSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791993776; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qKFEyQH++fmgLWYixqxJvW1RFsYLi5QIyNwyLQUbIMQ=; b=S0SZ+32GqNdctvwEYyX/d26BcXvQJEVx5u/YM7OYUoMcZBNkUFe+4iBAqtYoEVqEcbJs72 fPZJ2GS97MfKA3cbfaCYdRaSwZ8za2AKldWdXJ4NCrO6sBRW4ByYXXCyLUf2gCuB8PKYGn ujz+V4ZjhgH1hwEAOhZ6kJWu870ck2RuzUaOmjMIB+6ejtW+hG1ITygt5uTIqDu/6pC/XU ZQjTumS/nKphKzhQEg2Wwu7bGn3bBrRhnAg+i/XvIkw7DL50MpV4gedvUu/nPmIU034icF Vrr3BNvtumqg3qHuYkJcLhjFwMls9Ia1j7F83YdUHT+1mKvBniSctZ7p7odzkg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4j4bZm2RK6z189J for ; Wed, 14 Oct 2026 16:02:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 304f3 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 14 Oct 2026 16:02:56 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 820fb570ebf1 - stable/15 - sound: Check for errors from sndbuf_resize() List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: Commit messages for all branches of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 820fb570ebf19ea25131edff2cbf349d1f8cc3c0 Auto-Submitted: auto-generated Date: Wed, 14 Oct 2026 16:02:56 +0000 Message-Id: <6acfa7b0.304f3.3394499c@gitrepo.freebsd.org> The branch stable/15 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=820fb570ebf19ea25131edff2cbf349d1f8cc3c0 commit 820fb570ebf19ea25131edff2cbf349d1f8cc3c0 Author: Mark Johnston AuthorDate: 2026-10-13 15:53:39 +0000 Commit: Mark Johnston CommitDate: 2026-10-14 16:00:47 +0000 sound: Check for errors from sndbuf_resize() Most implementations of CHANNEL_SETBLOCKSIZE and CHANNEL_SETFRAGMENTS were not checking this. This is probably not a big problem: it's unlikely for sndbuf_resize() to fail due to the refcount check in this case since it's operating on the hardware buffer, which doesn't get mmaped. But, I will add more reasons for it to fail in the next patch, so let's be more careful. This change modifies various CHANNEL_SETBLOCKSIZE implementations to check for errors. In some cases I reordered things to avoid updating driver state until after sndbuf_resize() succeeds. Return 0 from CHANNEL_SETBLOCKSIZE to indicate an error, as it otherwise returns the new block size. We could change the interface to return both an error number and a block size, but that would break at least one out-of-tree driver and I wish to avoid that here. Make sure that errors from CHANNEL_SETFRAGMENTS are returned to userspace. Approved by: so Security: FreeBSD-SA-26:71.sound Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D60553 --- sys/arm/freescale/imx/imx6_ssi.c | 3 ++- sys/arm/freescale/vybrid/vf_sai.c | 3 ++- sys/dev/sound/pci/als4000.c | 3 ++- sys/dev/sound/pci/atiixp.c | 8 ++++++-- sys/dev/sound/pci/cmi.c | 3 ++- sys/dev/sound/pci/cs4281.c | 10 ++++++---- sys/dev/sound/pci/emu10kx-pcm.c | 2 +- sys/dev/sound/pci/envy24.c | 16 +++++++++------- sys/dev/sound/pci/envy24ht.c | 16 +++++++++------- sys/dev/sound/pci/es137x.c | 12 ++++++++---- sys/dev/sound/pci/hda/hdaa.c | 12 ++++++++---- sys/dev/sound/pci/hdsp-pcm.c | 7 ++++--- sys/dev/sound/pci/hdspe-pcm.c | 8 +++++--- sys/dev/sound/pci/ich.c | 23 +++++++++++++---------- sys/dev/sound/pci/t4dwave.c | 7 ++++--- sys/dev/sound/pci/via8233.c | 8 ++++++-- sys/dev/sound/pci/via82c686.c | 3 ++- sys/dev/sound/pci/vibes.c | 3 ++- sys/dev/sound/pcm/channel.c | 37 ++++++++++++++++++++++++++++--------- sys/dev/sound/usb/uaudio.c | 14 +++++--------- sys/dev/sound/usb/uaudio.h | 2 -- sys/dev/sound/usb/uaudio_pcm.c | 7 ------- 22 files changed, 124 insertions(+), 83 deletions(-) diff --git a/sys/arm/freescale/imx/imx6_ssi.c b/sys/arm/freescale/imx/imx6_ssi.c index f4ef955761b4..30fb8bdc07dd 100644 --- a/sys/arm/freescale/imx/imx6_ssi.c +++ b/sys/arm/freescale/imx/imx6_ssi.c @@ -394,7 +394,8 @@ ssichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) struct sc_pcminfo *scp = ch->parent; struct sc_info *sc = scp->sc; - sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize); + if (sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize) != 0) + return (0); setup_dma(scp); diff --git a/sys/arm/freescale/vybrid/vf_sai.c b/sys/arm/freescale/vybrid/vf_sai.c index d3a3ab93fe80..df42784c8563 100644 --- a/sys/arm/freescale/vybrid/vf_sai.c +++ b/sys/arm/freescale/vybrid/vf_sai.c @@ -367,7 +367,8 @@ saichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) struct sc_pcminfo *scp = ch->parent; struct sc_info *sc = scp->sc; - sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize); + if (sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize) != 0) + return (0); sc->period = ch->buffer->blksz; return (sc->period); diff --git a/sys/dev/sound/pci/als4000.c b/sys/dev/sound/pci/als4000.c index 0613f3ec2b97..2bb8aff48a79 100644 --- a/sys/dev/sound/pci/als4000.c +++ b/sys/dev/sound/pci/als4000.c @@ -267,7 +267,8 @@ alschan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) if (blocksize > sc->bufsz / 2) { blocksize = sc->bufsz / 2; } - sndbuf_resize(ch->buffer, 2, blocksize); + if (sndbuf_resize(ch->buffer, 2, blocksize) != 0) + return 0; return blocksize; } diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c index 39ef2f375328..8a99813221af 100644 --- a/sys/dev/sound/pci/atiixp.c +++ b/sys/dev/sound/pci/atiixp.c @@ -532,6 +532,7 @@ atiixp_chan_setfragments(kobj_t obj, void *data, { struct atiixp_chinfo *ch = data; struct atiixp_info *sc = ch->parent; + int error; blksz &= ATI_IXP_BLK_ALIGN; @@ -555,9 +556,11 @@ atiixp_chan_setfragments(kobj_t obj, void *data, if ((ch->buffer->blksz != blksz || ch->buffer->blkcnt != blkcnt) && - sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) + (error = sndbuf_resize(ch->buffer, blkcnt, blksz)) != 0) { device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, blksz, blkcnt); + return (error); + } ch->blksz = ch->buffer->blksz; ch->blkcnt = ch->buffer->blkcnt; @@ -571,7 +574,8 @@ atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz) struct atiixp_chinfo *ch = data; struct atiixp_info *sc = ch->parent; - atiixp_chan_setfragments(obj, data, blksz, sc->blkcnt); + if (atiixp_chan_setfragments(obj, data, blksz, sc->blkcnt) != 0) + return (0); return (ch->blksz); } diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c index 58ab961b74e1..264cf2b176d3 100644 --- a/sys/dev/sound/pci/cmi.c +++ b/sys/dev/sound/pci/cmi.c @@ -470,7 +470,8 @@ cmichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) if (blocksize > sc->bufsz / CMI_INTR_PER_BUFFER) { blocksize = sc->bufsz / CMI_INTR_PER_BUFFER; } - sndbuf_resize(ch->buffer, CMI_INTR_PER_BUFFER, blocksize); + if (sndbuf_resize(ch->buffer, CMI_INTR_PER_BUFFER, blocksize) != 0) + return 0; return blocksize; } diff --git a/sys/dev/sound/pci/cs4281.c b/sys/dev/sound/pci/cs4281.c index ef5183331331..67ae20bc4bde 100644 --- a/sys/dev/sound/pci/cs4281.c +++ b/sys/dev/sound/pci/cs4281.c @@ -346,12 +346,14 @@ cs4281chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) struct sc_info *sc = ch->parent; uint32_t go; - go = adcdac_go(ch, 0); - /* 2 interrupts are possible and used in buffer (half-empty,empty), * hence factor of 2. */ - ch->blksz = min(blocksize, sc->bufsz / 2); - sndbuf_resize(ch->buffer, 2, ch->blksz); + blocksize = min(blocksize, sc->bufsz / 2); + if (sndbuf_resize(ch->buffer, 2, blocksize) != 0) + return 0; + ch->blksz = blocksize; + + go = adcdac_go(ch, 0); ch->dma_setup = 0; adcdac_prog(ch); adcdac_go(ch, go); diff --git a/sys/dev/sound/pci/emu10kx-pcm.c b/sys/dev/sound/pci/emu10kx-pcm.c index 0a15b8ba3448..33595b646788 100644 --- a/sys/dev/sound/pci/emu10kx-pcm.c +++ b/sys/dev/sound/pci/emu10kx-pcm.c @@ -785,7 +785,7 @@ emupchan_setblocksize(kobj_t obj __unused, void *c_devinfo, uint32_t blocksize) blocksize = EMU_PLAY_BUFSZ / blkcnt; if (sndbuf_resize(ch->buffer, blkcnt, blocksize) != 0) - return (ch->blksz); + return (0); mtx_lock(&sc->lock); ch->blksz = blocksize; diff --git a/sys/dev/sound/pci/envy24.c b/sys/dev/sound/pci/envy24.c index df9c680b9414..65144aad65a6 100644 --- a/sys/dev/sound/pci/envy24.c +++ b/sys/dev/sound/pci/envy24.c @@ -1714,7 +1714,7 @@ envy24chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) { struct sc_chinfo *ch = data; /* struct sc_info *sc = ch->parent; */ - uint32_t size, prev; + uint32_t blk, size, prev; unsigned int bcnt, bsize; #if(0) @@ -1729,20 +1729,22 @@ envy24chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) break; } - ch->blk = prev / ch->unit; + blk = prev / ch->unit; if (ch->dir == PCMDIR_PLAY) - ch->blk *= ENVY24_PLAY_BUFUNIT / 4; + blk *= ENVY24_PLAY_BUFUNIT / 4; else - ch->blk *= ENVY24_REC_BUFUNIT / 4; + blk *= ENVY24_REC_BUFUNIT / 4; /* set channel buffer information */ /* ch->size = ch->unit * ENVY24_SAMPLE_NUM; */ if (ch->dir == PCMDIR_PLAY) - bsize = ch->blk * 4 / ENVY24_PLAY_BUFUNIT; + bsize = blk * 4 / ENVY24_PLAY_BUFUNIT; else - bsize = ch->blk * 4 / ENVY24_REC_BUFUNIT; + bsize = blk * 4 / ENVY24_REC_BUFUNIT; bsize *= ch->unit; bcnt = ch->size / bsize; - sndbuf_resize(ch->buffer, bcnt, bsize); + if (sndbuf_resize(ch->buffer, bcnt, bsize) != 0) + return 0; + ch->blk = blk; /* mtx_unlock(&sc->lock); */ #if(0) diff --git a/sys/dev/sound/pci/envy24ht.c b/sys/dev/sound/pci/envy24ht.c index 19a4ee39eacd..29dd4b170bbe 100644 --- a/sys/dev/sound/pci/envy24ht.c +++ b/sys/dev/sound/pci/envy24ht.c @@ -1625,7 +1625,7 @@ envy24htchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) { struct sc_chinfo *ch = data; /* struct sc_info *sc = ch->parent; */ - uint32_t size, prev; + uint32_t blk, size, prev; unsigned int bcnt, bsize; #if(0) @@ -1640,20 +1640,22 @@ envy24htchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) break; } - ch->blk = prev / ch->unit; + blk = prev / ch->unit; if (ch->dir == PCMDIR_PLAY) - ch->blk *= ENVY24HT_PLAY_BUFUNIT / 4; + blk *= ENVY24HT_PLAY_BUFUNIT / 4; else - ch->blk *= ENVY24HT_REC_BUFUNIT / 4; + blk *= ENVY24HT_REC_BUFUNIT / 4; /* set channel buffer information */ /* ch->size = ch->unit * ENVY24HT_SAMPLE_NUM; */ if (ch->dir == PCMDIR_PLAY) - bsize = ch->blk * 4 / ENVY24HT_PLAY_BUFUNIT; + bsize = blk * 4 / ENVY24HT_PLAY_BUFUNIT; else - bsize = ch->blk * 4 / ENVY24HT_REC_BUFUNIT; + bsize = blk * 4 / ENVY24HT_REC_BUFUNIT; bsize *= ch->unit; bcnt = ch->size / bsize; - sndbuf_resize(ch->buffer, bcnt, bsize); + if (sndbuf_resize(ch->buffer, bcnt, bsize) != 0) + return 0; + ch->blk = blk; /* mtx_unlock(&sc->lock); */ #if(0) diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c index ab8a6db74640..fd7a97fffdfb 100644 --- a/sys/dev/sound/pci/es137x.c +++ b/sys/dev/sound/pci/es137x.c @@ -632,8 +632,9 @@ eschan1371_setspeed(kobj_t obj, void *data, uint32_t speed) 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; + struct es_chinfo *ch = data; + struct es_info *es = ch->parent; + int error; blksz &= ES_BLK_ALIGN; @@ -657,9 +658,11 @@ eschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) if ((ch->buffer->blksz != blksz || ch->buffer->blkcnt != blkcnt) && - sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) + (error = sndbuf_resize(ch->buffer, blkcnt, blksz)) != 0) { device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, blksz, blkcnt); + return (error); + } ch->bufsz = ch->buffer->bufsize; ch->blksz = ch->buffer->blksz; @@ -674,7 +677,8 @@ eschan_setblocksize(kobj_t obj, void *data, uint32_t blksz) struct es_chinfo *ch = data; struct es_info *es = ch->parent; - eschan_setfragments(obj, data, blksz, es->blkcnt); + if (eschan_setfragments(obj, data, blksz, es->blkcnt) != 0) + return (0); return (ch->blksz); } diff --git a/sys/dev/sound/pci/hda/hdaa.c b/sys/dev/sound/pci/hda/hdaa.c index 44cca506751f..ea3e65da7337 100644 --- a/sys/dev/sound/pci/hda/hdaa.c +++ b/sys/dev/sound/pci/hda/hdaa.c @@ -2080,6 +2080,7 @@ hdaa_channel_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) { struct hdaa_chan *ch = data; + int error; blksz -= blksz % lcm(HDA_DMA_ALIGNMENT, ch->b->align); @@ -2101,11 +2102,12 @@ hdaa_channel_setfragments(kobj_t obj, void *data, break; } - if ((ch->b->blksz != blksz || - ch->b->blkcnt != blkcnt) && - sndbuf_resize(ch->b, blkcnt, blksz) != 0) + if ((ch->b->blksz != blksz || ch->b->blkcnt != blkcnt) && + (error = sndbuf_resize(ch->b, blkcnt, blksz)) != 0) { device_printf(ch->devinfo->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, blksz, blkcnt); + return (error); + } ch->blksz = ch->b->blksz; ch->blkcnt = ch->b->blkcnt; @@ -2118,7 +2120,9 @@ hdaa_channel_setblocksize(kobj_t obj, void *data, uint32_t blksz) { struct hdaa_chan *ch = data; - hdaa_channel_setfragments(obj, data, blksz, ch->pdevinfo->chan_blkcnt); + if (hdaa_channel_setfragments(obj, data, blksz, + ch->pdevinfo->chan_blkcnt) != 0) + return (0); return (ch->blksz); } diff --git a/sys/dev/sound/pci/hdsp-pcm.c b/sys/dev/sound/pci/hdsp-pcm.c index 7f4f7dc76557..ca5266e9d7a2 100644 --- a/sys/dev/sound/pci/hdsp-pcm.c +++ b/sys/dev/sound/pci/hdsp-pcm.c @@ -943,6 +943,10 @@ hdspchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) } } + if (sndbuf_resize(ch->buffer, 2, + (hl->period * AFMT_CHANNEL(ch->format) * sizeof(uint32_t))) != 0) + return (0); + mtx_lock(&sc->lock); sc->ctrl_register &= ~HDSP_LAT_MASK; sc->ctrl_register |= hdsp_encode_latency(hl->n); @@ -954,9 +958,6 @@ hdspchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) device_printf(scp->dev, "New period=%d\n", sc->period); #endif - sndbuf_resize(ch->buffer, 2, - (sc->period * AFMT_CHANNEL(ch->format) * sizeof(uint32_t))); - /* Reset pointer, rewrite frequency (same register) for 9632. */ hdsp_write_4(sc, HDSP_RESET_POINTER, 0); if (sc->type == HDSP_9632) diff --git a/sys/dev/sound/pci/hdspe-pcm.c b/sys/dev/sound/pci/hdspe-pcm.c index a814c80127b1..135f7af29a95 100644 --- a/sys/dev/sound/pci/hdspe-pcm.c +++ b/sys/dev/sound/pci/hdspe-pcm.c @@ -941,6 +941,11 @@ hdspechan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) } } + if (sndbuf_resize(ch->buffer, + (HDSPE_CHANBUF_SIZE * AFMT_CHANNEL(ch->format)) / (hl->period * 4), + (hl->period * 4)) != 0) + return (0); + mtx_lock(&sc->lock); sc->ctrl_register &= ~HDSPE_LAT_MASK; sc->ctrl_register |= hdspe_encode_latency(hl->n); @@ -952,9 +957,6 @@ hdspechan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) device_printf(scp->dev, "New period=%d\n", sc->period); #endif - sndbuf_resize(ch->buffer, - (HDSPE_CHANBUF_SIZE * AFMT_CHANNEL(ch->format)) / (sc->period * 4), - (sc->period * 4)); end: return (ch->buffer->blksz); diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c index 1295e7eb5bc1..56ac2e67ffdf 100644 --- a/sys/dev/sound/pci/ich.c +++ b/sys/dev/sound/pci/ich.c @@ -294,21 +294,23 @@ AC97_DECLARE(ich_ac97); /* -------------------------------------------------------------------- */ /* common routines */ -static void -ich_filldtbl(struct sc_chinfo *ch) +static int +ich_filldtbl(struct sc_chinfo *ch, uint32_t blksz) { struct sc_info *sc = ch->parent; uint32_t base; - int i; + int error, i; base = ch->buffer->buf_addr; - if ((ch->blksz * ch->blkcnt) > ch->buffer->maxsize) - ch->blksz = ch->buffer->maxsize / ch->blkcnt; - if ((ch->buffer->blksz != ch->blksz || + if (blksz * ch->blkcnt > ch->buffer->maxsize) + blksz = ch->buffer->maxsize / ch->blkcnt; + if ((ch->buffer->blksz != blksz || ch->buffer->blkcnt != ch->blkcnt) && - sndbuf_resize(ch->buffer, ch->blkcnt, ch->blksz) != 0) + (error = sndbuf_resize(ch->buffer, ch->blkcnt, blksz)) != 0) { device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", - __func__, ch->blksz, ch->blkcnt); + __func__, blksz, ch->blkcnt); + return (error); + } ch->blksz = ch->buffer->blksz; for (i = 0; i < ICH_DTBL_LENGTH; i++) { @@ -316,6 +318,7 @@ ich_filldtbl(struct sc_chinfo *ch) ch->dtbl[i].length = ICH_BDC_IOC | (ch->blksz / ch->parent->sample_size); } + return (0); } static int @@ -496,8 +499,8 @@ ichchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) if (blocksize < ICH_MIN_BLKSZ) blocksize = ICH_MIN_BLKSZ; blocksize &= ~(ICH_MIN_BLKSZ - 1); - ch->blksz = blocksize; - ich_filldtbl(ch); + if (ich_filldtbl(ch, blocksize) != 0) + return (0); ICH_LOCK(sc); ich_wr(sc, ch->regbase + ICH_REG_X_LVI, ch->blkcnt - 1, 1); ICH_UNLOCK(sc); diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c index d4650cfa07e2..890bd70c6689 100644 --- a/sys/dev/sound/pci/t4dwave.c +++ b/sys/dev/sound/pci/t4dwave.c @@ -538,7 +538,8 @@ trpchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) { struct tr_chinfo *ch = data; - sndbuf_resize(ch->buffer, 2, blocksize); + if (sndbuf_resize(ch->buffer, 2, blocksize) != 0) + return 0; return blocksize; } @@ -659,8 +660,8 @@ trrchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) { struct tr_rchinfo *ch = data; - sndbuf_resize(ch->buffer, 2, blocksize); - + if (sndbuf_resize(ch->buffer, 2, blocksize) != 0) + return 0; return blocksize; } diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c index 90e966b864e3..10af3281cef3 100644 --- a/sys/dev/sound/pci/via8233.c +++ b/sys/dev/sound/pci/via8233.c @@ -565,6 +565,7 @@ via8233chan_setfragments(kobj_t obj, void *data, { struct via_chinfo *ch = data; struct via_info *via = ch->parent; + int error; blksz &= VIA_BLK_ALIGN; @@ -588,9 +589,11 @@ via8233chan_setfragments(kobj_t obj, void *data, if ((ch->buffer->blksz != blksz || ch->buffer->blkcnt != blkcnt) && - sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) + (error = sndbuf_resize(ch->buffer, blkcnt, blksz)) != 0) { device_printf(via->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, blksz, blkcnt); + return (error); + } ch->blksz = ch->buffer->blksz; ch->blkcnt = ch->buffer->blkcnt; @@ -604,7 +607,8 @@ via8233chan_setblocksize(kobj_t obj, void *data, uint32_t blksz) struct via_chinfo *ch = data; struct via_info *via = ch->parent; - via8233chan_setfragments(obj, data, blksz, via->blkcnt); + if (via8233chan_setfragments(obj, data, blksz, via->blkcnt) != 0) + return (0); return (ch->blksz); } diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c index 85356cc64145..35c301c045b3 100644 --- a/sys/dev/sound/pci/via82c686.c +++ b/sys/dev/sound/pci/via82c686.c @@ -328,8 +328,9 @@ viachan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) { struct via_chinfo *ch = data; + if (sndbuf_resize(ch->buffer, SEGS_PER_CHAN, blocksize) != 0) + return 0; ch->blksz = blocksize; - sndbuf_resize(ch->buffer, SEGS_PER_CHAN, ch->blksz); return ch->blksz; } diff --git a/sys/dev/sound/pci/vibes.c b/sys/dev/sound/pci/vibes.c index 08ba83a54d2a..6533bcb3c906 100644 --- a/sys/dev/sound/pci/vibes.c +++ b/sys/dev/sound/pci/vibes.c @@ -224,7 +224,8 @@ svchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) /* user has requested interrupts every blocksize bytes */ RANGE(blocksize, SV_MIN_BLKSZ, sc->bufsz / SV_INTR_PER_BUFFER); - sndbuf_resize(ch->buffer, SV_INTR_PER_BUFFER, blocksize); + if (sndbuf_resize(ch->buffer, SV_INTR_PER_BUFFER, blocksize) != 0) + return 0; DEB(printf("svchan_setblocksize: %d\n", blocksize)); return blocksize; } diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index 531154628ada..681bcde39d15 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -1837,7 +1837,6 @@ chn_resizebuf(struct pcm_channel *c, int latency, { struct snd_dbuf *b, *bs, *pb; int sblksz, sblkcnt, hblksz, hblkcnt, limit = 0, nsblksz, nsblkcnt; - int ret; u_int32_t maxsize; CHN_LOCKASSERT(c); @@ -1909,6 +1908,8 @@ chn_resizebuf(struct pcm_channel *c, int latency, sndbuf_xbytes(pb->blksz, pb, bs) * 2 : 0; } } else { + int error; + /* * The byte-rate-scaled cap applies to the secondary buffer * only. It exists to absorb userland scheduling latency, @@ -1942,11 +1943,27 @@ chn_resizebuf(struct pcm_channel *c, int latency, hblksz -= hblksz % b->align; CHN_UNLOCK(c); - if (chn_usefrags == 0 || - CHANNEL_SETFRAGMENTS(c->methods, c->devinfo, - hblksz, hblkcnt) != 0) - b->blksz = CHANNEL_SETBLOCKSIZE(c->methods, - c->devinfo, hblksz); + error = ENOTSUP; + if (chn_usefrags) { + error = CHANNEL_SETFRAGMENTS(c->methods, c->devinfo, + hblksz, hblkcnt); + /* The default implementation returns ENOTSUP. */ + if (error != 0 && error != ENOTSUP) { + CHN_LOCK(c); + return error; + } + } + if (error == ENOTSUP) { + uint32_t nblksz; + + nblksz = CHANNEL_SETBLOCKSIZE(c->methods, c->devinfo, + hblksz); + if (nblksz == 0) { + CHN_LOCK(c); + return EINVAL; + } + b->blksz = nblksz; + } CHN_LOCK(c); if (!CHN_EMPTY(c, children)) { @@ -1985,11 +2002,13 @@ chn_resizebuf(struct pcm_channel *c, int latency, if (bs->blkcnt != sblkcnt || bs->blksz != sblksz || bs->bufsize != (sblkcnt * sblksz)) { - ret = sndbuf_remalloc(bs, sblkcnt, sblksz); - if (ret != 0) { + int error; + + error = sndbuf_remalloc(bs, sblkcnt, sblksz); + if (error != 0) { device_printf(c->dev, "%s(): Failed: %d %d\n", __func__, sblkcnt, sblksz); - return ret; + return error; } } diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 110afc66b961..e1b394115ac2 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -2782,16 +2782,12 @@ uaudio_chan_free(struct uaudio_chan *ch) int uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize) { - uint32_t temp = 2 * uaudio_get_buffer_size(ch, ch->set_alt); - sndbuf_setup(ch->pcm_buf, ch->buf, temp); - return (temp / 2); -} + uint32_t temp; -int -uaudio_chan_set_param_fragments(struct uaudio_chan *ch, uint32_t blocksize, - uint32_t blockcount) -{ - return (1); + temp = 2 * uaudio_get_buffer_size(ch, ch->set_alt); + if (sndbuf_setup(ch->pcm_buf, ch->buf, temp) != 0) + return (0); + return (temp / 2); } int diff --git a/sys/dev/sound/usb/uaudio.h b/sys/dev/sound/usb/uaudio.h index 05858473eb00..3673fd9617ea 100644 --- a/sys/dev/sound/usb/uaudio.h +++ b/sys/dev/sound/usb/uaudio.h @@ -43,8 +43,6 @@ extern void *uaudio_chan_init(struct uaudio_chan *ch, struct snd_dbuf *b, extern int uaudio_chan_free(struct uaudio_chan *ch); extern int uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize); -extern int uaudio_chan_set_param_fragments(struct uaudio_chan *ch, - uint32_t blocksize, uint32_t blockcount); extern int uaudio_chan_set_param_speed(struct uaudio_chan *ch, uint32_t speed); extern int uaudio_chan_getptr(struct uaudio_chan *ch); diff --git a/sys/dev/sound/usb/uaudio_pcm.c b/sys/dev/sound/usb/uaudio_pcm.c index 4b1762cfc3ec..1f54022576e7 100644 --- a/sys/dev/sound/usb/uaudio_pcm.c +++ b/sys/dev/sound/usb/uaudio_pcm.c @@ -71,12 +71,6 @@ ua_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) return (uaudio_chan_set_param_blocksize(data, blocksize)); } -static int -ua_chan_setfragments(kobj_t obj, void *data, uint32_t blocksize, uint32_t blockcount) -{ - return (uaudio_chan_set_param_fragments(data, blocksize, blockcount)); -} - static int ua_chan_trigger(kobj_t obj, void *data, int go) { @@ -114,7 +108,6 @@ static kobj_method_t ua_chan_methods[] = { KOBJMETHOD(channel_setformat, ua_chan_setformat), KOBJMETHOD(channel_setspeed, ua_chan_setspeed), KOBJMETHOD(channel_setblocksize, ua_chan_setblocksize), - KOBJMETHOD(channel_setfragments, ua_chan_setfragments), KOBJMETHOD(channel_trigger, ua_chan_trigger), KOBJMETHOD(channel_getptr, ua_chan_getptr), KOBJMETHOD(channel_getcaps, ua_chan_getcaps),