From nobody Mon Nov 02 16:10:40 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 4jJGrw4j3hz6xvNR for ; Mon, 02 Nov 2026 16:10:40 +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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jJGrw2fhBz4gp8 for ; Mon, 02 Nov 2026 16:10:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793635840; 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=UPhs0LxcVAP+np4tAw6VU6T9yqxsHbIj6Q3uaWZPXcE=; b=OLC2J8fqH0QvCfylmgl823I6CVUlLChYrF2A1GlUeIdobrv7ks81EFXj2TBzt9GR3YexfA SaX6VmldoYdPbGY6iJbmeSUcz+FJHgUsN2I29X9kIb6ZCb6nTwFTCe7U1LjBoGEMabMB3W +XPFwvw51BiMGlJbjTZLPG9O4obHiK+hO//K5iY3u97wMbO2Jq3z1xLkKMIgomJ6d5uWqi 8WpKI8VIuSkSmWoSt0IfV9K3vxDAbYGcSDusXpOzRr/Mei6/+r4Rm0EvhPZ8LGfANtByww H7HPMdtTnzZY22xc0bsJ27vlX5y6rOrs/sITHGNzWrRCAZAgw+e2s7ggPGANoA== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793635840; b=Sz3NyolUwcpyPM2+k7onX8gtUvNiqOH0cnjXclff0uudu6OpO8fU3YSdEySvEn6e5woccI hL0vHXWCkYPxj+9ME4OBk5JSwcB07tNy7tFpW7BdopAxqC9GQ20ojWgZ8Tgr0+DoaQlyA9 ejQBa0DPFNoSfWbAOUqwGrwSp5uceg0Nv/OuBMQloLiQrXovc6NKyiB74nVW23IPTsSCuK sa0wQdxDL/AKyG/qSYPMkvfvxnOYOKvN8+7bXXPWasTyOV372VrNWu+erLbhE+hOW5wWnR IjY/yRbxm5CjwQmCHouoU3dEVTu+1cweErQjSmKhkv5u4dtBH2VD19s0+/YW3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793635840; 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=UPhs0LxcVAP+np4tAw6VU6T9yqxsHbIj6Q3uaWZPXcE=; b=O9aQ0KjM9eBb+ZQeet8rnvMmRZY13iZY973uKVd2lhNyCcdMYlhJK0GgTbYTYdun8/FURv f0UDEWMj6HAZuERC3cS4EY9/woIkKbqduNPr0JJHuj4UGkzHyua92iSKBwJ2Qquh6jhtOm 4XTHR5BChxQJwFqkrFdF5t0s2brbVzSgBldp+mCLHOnkD46rwcFii+a7UZ6d2y/Ch7lhFg 3qZx89n9fRV0+eVjwUU8938aDxtdPb+/ZS/0l2HhRkNkTC1e2q3Ihg11gEvH6kKSX68754 hVwS+lgUkSp8PcypnT4BLsDgAKhsXFPpaUeAtlfJgDaacn9upL604ruNWqYaOw== 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 4jJGrw24b3zsF3 for ; Mon, 02 Nov 2026 16:10:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 47aab by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 02 Nov 2026 16:10:40 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 5355c97e129a - main - snd_hdsp: Use busdma for DMA buffers 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: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5355c97e129a004f013570be0b7a99c8610e1757 Auto-Submitted: auto-generated Date: Mon, 02 Nov 2026 16:10:40 +0000 Message-Id: <6ae8b600.47aab.402515fc@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=5355c97e129a004f013570be0b7a99c8610e1757 commit 5355c97e129a004f013570be0b7a99c8610e1757 Author: Kevin Bowling AuthorDate: 2026-11-02 16:09:33 +0000 Commit: Kevin Bowling CommitDate: 2026-11-02 16:09:55 +0000 snd_hdsp: Use busdma for DMA buffers Program DMA buffer registers with the bus addresses returned by busdma. Require one full-size contiguous DMA segment per direction and validate its alignment and 32-bit address range. Synchronize buffer ownership around playback, capture, clearing, and teardown. Disable channels before clearing their DMA buffers, and unwind partially allocated resources on failure. This mirrors snd_hdspe's DMA handling, adapted to HDSP's single base address per direction. MFC after: 3 days Sponsored by: BBOX.io --- sys/dev/sound/pci/hdsp-pcm.c | 24 +++++++-- sys/dev/sound/pci/hdsp.c | 113 ++++++++++++++++++++++++++++++++----------- sys/dev/sound/pci/hdsp.h | 3 ++ 3 files changed, 107 insertions(+), 33 deletions(-) diff --git a/sys/dev/sound/pci/hdsp-pcm.c b/sys/dev/sound/pci/hdsp-pcm.c index 24969f0e22b0..ad5a040398db 100644 --- a/sys/dev/sound/pci/hdsp-pcm.c +++ b/sys/dev/sound/pci/hdsp-pcm.c @@ -564,15 +564,14 @@ buffer_copy(struct sc_chinfo *ch) length -= offset; } } else { - /* Buffer position scaled down to a single channel. */ + /* Snapshot the write position before synchronizing the buffer. */ pos = sndbuf_getfreeptr(ch->buffer) / channels; - /* Get DMA buffer write position. */ dma_pos = hdsp_read_2(sc, HDSP_STATUS_REG); dma_pos &= HDSP_BUF_POSITION_MASK; dma_pos %= buffer_size; - /* Copy what is newly available. */ length = (dma_pos + buffer_size) - pos; length %= buffer_size; + bus_dmamap_sync(sc->dmat, sc->rmap, BUS_DMASYNC_POSTREAD); } /* Position and length in samples (4 bytes). */ @@ -607,6 +606,12 @@ buffer_copy(struct sc_chinfo *ch) row = hdsp_slot_first_row(slots); } + if (ch->dir == PCMDIR_PLAY && length > 0) { + bus_dmamap_sync(sc->dmat, sc->pmap, BUS_DMASYNC_PREWRITE); + } else if (ch->dir == PCMDIR_REC) { + bus_dmamap_sync(sc->dmat, sc->rmap, BUS_DMASYNC_PREREAD); + } + ch->position = ((pos + length) * 4) % buffer_size; } @@ -626,6 +631,11 @@ clean(struct sc_chinfo *ch) if (ch->dir == PCMDIR_PLAY) buf = sc->pbuf; + if (ch->dir == PCMDIR_PLAY) + bus_dmamap_sync(sc->dmat, sc->pmap, BUS_DMASYNC_POSTWRITE); + else + bus_dmamap_sync(sc->dmat, sc->rmap, BUS_DMASYNC_POSTREAD); + /* Iterate through all of the channel's slots. */ slots = hdsp_port_slot_map(ch->ports, sc->speed); slot = hdsp_slot_first(slots); @@ -638,6 +648,12 @@ clean(struct sc_chinfo *ch) slot = hdsp_slot_first(slots); } + if (ch->dir == PCMDIR_PLAY) + bus_dmamap_sync(sc->dmat, sc->pmap, BUS_DMASYNC_PREWRITE); + else + bus_dmamap_sync(sc->dmat, sc->rmap, + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + ch->position = 0; return (0); @@ -775,8 +791,8 @@ hdspchan_trigger(kobj_t obj, void *data, int go) #if 0 device_printf(scp->dev, "hdspchan_trigger(): stop or abort\n"); #endif - clean(ch); hdspchan_enable(ch, 0); + clean(ch); hdsp_stop_audio(sc); break; diff --git a/sys/dev/sound/pci/hdsp.c b/sys/dev/sound/pci/hdsp.c index b52b53231e50..3c92eb3e319a 100644 --- a/sys/dev/sound/pci/hdsp.c +++ b/sys/dev/sound/pci/hdsp.c @@ -127,17 +127,43 @@ hdsp_intr(void *p) mtx_unlock(&sc->lock); } +struct hdsp_dma_map { + uint32_t addr; + int error; +}; + static void -hdsp_dmapsetmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) +hdsp_dma_map_buffer(void *arg, bus_dma_segment_t *segs, int nseg, int error) { -#if 0 - device_printf(sc->dev, "hdsp_dmapsetmap()\n"); -#endif + struct hdsp_dma_map *map; + + map = arg; + map->error = error; + if (error != 0) + return; + + /* The hardware accepts one contiguous DMA buffer per direction. */ + if (nseg != 1 || segs[0].ds_len != HDSP_DMASEGSIZE) { + map->error = EFBIG; + return; + } + if (segs[0].ds_addr % 4 != 0 || + segs[0].ds_addr > BUS_SPACE_MAXADDR_32BIT - (HDSP_DMASEGSIZE - 1)) { + map->error = EINVAL; + return; + } + map->addr = (uint32_t)segs[0].ds_addr; } static int hdsp_alloc_resources(struct sc_info *sc) { + struct hdsp_dma_map map; + bool pmap_loaded, rmap_loaded; + int error; + + pmap_loaded = false; + rmap_loaded = false; /* Allocate resource. */ sc->csid = PCIR_BAR(0); @@ -161,10 +187,10 @@ hdsp_alloc_resources(struct sc_info *sc) bus_setup_intr(sc->dev, sc->irq, INTR_MPSAFE | INTR_TYPE_AV, NULL, hdsp_intr, sc, &sc->ih)) { device_printf(sc->dev, "Unable to alloc interrupt resource.\n"); - return (ENXIO); + goto fail; } - /* Allocate DMA resources. */ + /* Allocate one contiguous DMA segment for each direction. */ if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(sc->dev), /*alignment*/4, /*boundary*/0, @@ -172,61 +198,87 @@ hdsp_alloc_resources(struct sc_info *sc) /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/2 * HDSP_DMASEGSIZE, - /*nsegments*/2, + /*maxsize*/HDSP_DMASEGSIZE, + /*nsegments*/1, /*maxsegsz*/HDSP_DMASEGSIZE, /*flags*/0, /*lockfunc*/NULL, /*lockarg*/NULL, /*dmatag*/&sc->dmat) != 0) { device_printf(sc->dev, "Unable to create dma tag.\n"); - return (ENXIO); + goto fail; } sc->bufsize = HDSP_DMASEGSIZE; /* pbuf (play buffer). */ - if (bus_dmamem_alloc(sc->dmat, (void **)&sc->pbuf, BUS_DMA_WAITOK, - &sc->pmap)) { + if (bus_dmamem_alloc(sc->dmat, (void **)&sc->pbuf, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->pmap)) { device_printf(sc->dev, "Can't alloc pbuf.\n"); - return (ENXIO); + goto fail; } - if (bus_dmamap_load(sc->dmat, sc->pmap, sc->pbuf, sc->bufsize, - hdsp_dmapsetmap, sc, BUS_DMA_NOWAIT)) { + map.error = 0; + error = bus_dmamap_load(sc->dmat, sc->pmap, sc->pbuf, sc->bufsize, + hdsp_dma_map_buffer, &map, BUS_DMA_NOWAIT); + if (error == 0) + pmap_loaded = true; + if (error != 0 || map.error != 0) { device_printf(sc->dev, "Can't load pbuf.\n"); - return (ENXIO); + goto fail; } + sc->paddr = map.addr; /* rbuf (rec buffer). */ - if (bus_dmamem_alloc(sc->dmat, (void **)&sc->rbuf, BUS_DMA_WAITOK, - &sc->rmap)) { + if (bus_dmamem_alloc(sc->dmat, (void **)&sc->rbuf, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->rmap)) { device_printf(sc->dev, "Can't alloc rbuf.\n"); - return (ENXIO); + goto fail; } - if (bus_dmamap_load(sc->dmat, sc->rmap, sc->rbuf, sc->bufsize, - hdsp_dmapsetmap, sc, BUS_DMA_NOWAIT)) { + map.error = 0; + error = bus_dmamap_load(sc->dmat, sc->rmap, sc->rbuf, sc->bufsize, + hdsp_dma_map_buffer, &map, BUS_DMA_NOWAIT); + if (error == 0) + rmap_loaded = true; + if (error != 0 || map.error != 0) { device_printf(sc->dev, "Can't load rbuf.\n"); - return (ENXIO); + goto fail; } + sc->raddr = map.addr; - bzero(sc->pbuf, sc->bufsize); - bzero(sc->rbuf, sc->bufsize); + /* Synchronize the buffers before the first DMA cycle. */ + bus_dmamap_sync(sc->dmat, sc->pmap, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->dmat, sc->rmap, BUS_DMASYNC_PREREAD); return (0); + +fail: + if (sc->ih != NULL) + bus_teardown_intr(sc->dev, sc->irq, sc->ih); + if (rmap_loaded) + bus_dmamap_unload(sc->dmat, sc->rmap); + if (sc->rbuf != NULL) + bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap); + if (pmap_loaded) + bus_dmamap_unload(sc->dmat, sc->pmap); + if (sc->pbuf != NULL) + bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap); + if (sc->dmat != NULL) + bus_dma_tag_destroy(sc->dmat); + if (sc->irq != NULL) + bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irqid, sc->irq); + if (sc->cs != NULL) + bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->csid, sc->cs); + return (ENXIO); } static void hdsp_map_dmabuf(struct sc_info *sc) { - uint32_t paddr, raddr; - - paddr = vtophys(sc->pbuf); - raddr = vtophys(sc->rbuf); - hdsp_write_4(sc, HDSP_PAGE_ADDR_BUF_OUT, paddr); - hdsp_write_4(sc, HDSP_PAGE_ADDR_BUF_IN, raddr); + hdsp_write_4(sc, HDSP_PAGE_ADDR_BUF_OUT, sc->paddr); + hdsp_write_4(sc, HDSP_PAGE_ADDR_BUF_IN, sc->raddr); } static const char * @@ -878,6 +930,7 @@ hdsp_attach(device_t dev) err = hdsp_alloc_resources(sc); if (err) { device_printf(dev, "Unable to allocate system resources.\n"); + mtx_destroy(&sc->lock); return (ENXIO); } @@ -965,6 +1018,8 @@ static void hdsp_dmafree(struct sc_info *sc) { + bus_dmamap_sync(sc->dmat, sc->rmap, BUS_DMASYNC_POSTREAD); + bus_dmamap_sync(sc->dmat, sc->pmap, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->dmat, sc->rmap); bus_dmamap_unload(sc->dmat, sc->pmap); bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap); diff --git a/sys/dev/sound/pci/hdsp.h b/sys/dev/sound/pci/hdsp.h index 81a0be7dc1e6..b30845fb4bb9 100644 --- a/sys/dev/sound/pci/hdsp.h +++ b/sys/dev/sound/pci/hdsp.h @@ -248,6 +248,9 @@ struct sc_info { uint32_t bufsize; bus_dmamap_t pmap; bus_dmamap_t rmap; + /* DMA buffer bus addresses. */ + uint32_t paddr; + uint32_t raddr; uint32_t period; uint32_t speed; uint32_t force_period;