static int via8233chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) { struct via_chinfo *ch = data; sndbuf_resize(ch->buffer, SEGS_PER_CHAN, blocksize); ch->blksz = sndbuf_getblksz(ch->buffer); return ch->blksz; }
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 > (sc->bufsz / ch->dma_segs)) blksz = sc->bufsz / ch->dma_segs; sndbuf_resize(ch->buffer, ch->dma_segs, blksz); return sndbuf_getblksz(ch->buffer); }
static void ich_filldtbl(struct sc_chinfo *ch) { struct sc_info *sc = ch->parent; uint32_t base; int i; base = sndbuf_getbufaddr(ch->buffer); if ((ch->blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer)) ch->blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt; if ((sndbuf_getblksz(ch->buffer) != ch->blksz || sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) && sndbuf_resize(ch->buffer, ch->blkcnt, ch->blksz) != 0) device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", __func__, ch->blksz, ch->blkcnt); ch->blksz = sndbuf_getblksz(ch->buffer); for (i = 0; i < ICH_DTBL_LENGTH; i++) { ch->dtbl[i].buffer = base + (ch->blksz * (i % ch->blkcnt)); ch->dtbl[i].length = ICH_BDC_IOC | (ch->blksz / ch->parent->sample_size); } }
static void atiixp_buildsgdt(struct atiixp_chinfo *ch) { uint32_t addr, blksz; int i; addr = sndbuf_getbufaddr(ch->buffer); blksz = sndbuf_getblksz(ch->buffer); for (i = 0; i < ch->dma_segs; i++) { ch->sgd_table[i].addr = htole32(addr + (i * blksz)); ch->sgd_table[i].status = htole16(0); ch->sgd_table[i].size = htole16(blksz >> 2); ch->sgd_table[i].next = htole32((uint32_t)ch->sgd_addr + (((i + 1) % ch->dma_segs) * sizeof(struct atiixp_dma_op))); } }
static int atiixp_chan_getptr(kobj_t obj, void *data) { struct atiixp_chinfo *ch = data; struct atiixp_info *sc = ch->parent; uint32_t addr, align, retry, sz; volatile uint32_t ptr; addr = sndbuf_getbufaddr(ch->buffer); align = (ch->fmt & AFMT_32BIT) ? 7 : 3; retry = 100; sz = sndbuf_getblksz(ch->buffer) * ch->dma_segs; atiixp_lock(sc); do { ptr = atiixp_rd(sc, ch->dma_dt_cur_bit); if (ptr < addr) continue; ptr -= addr; if (ptr < sz && !(ptr & align)) break; } while (--retry); atiixp_unlock(sc); #if 0 if (retry != 100) { device_printf(sc->dev, "%saligned hwptr: dir=PCMDIR_%s ptr=%u fmt=0x%08x retry=%d\n", (ptr & align) ? "un" : "", (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", ptr, ch->fmt, 100 - retry); } #endif return (retry > 0) ? ptr : 0; }