Skip to content

Commit

Permalink
ALSA: Clean up SG-buffer helper functions and macros
Browse files Browse the repository at this point in the history
Clean up SG-buffer helper functions and macros.  Helpers take substream
as arguments now.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
Takashi Iwai authored and Jaroslav Kysela committed Aug 25, 2008
1 parent 46480b3 commit 77a23f2
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 103 deletions.
12 changes: 12 additions & 0 deletions include/sound/memalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ struct snd_dma_buffer {
/*
* Scatter-Gather generic device pages
*/
void *snd_malloc_sgbuf_pages(struct device *device,
size_t size, struct snd_dma_buffer *dmab,
size_t *res_size);
int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);

struct snd_sg_page {
void *buf;
dma_addr_t addr;
Expand Down Expand Up @@ -95,6 +100,13 @@ static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t off
return sgbuf->table[offset >> PAGE_SHIFT].addr + offset % PAGE_SIZE;
}

/*
* return the virtual address at the corresponding offset
*/
static inline void *snd_sgbuf_get_ptr(struct snd_sg_buf *sgbuf, size_t offset)
{
return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
}

/* allocate/release a buffer */
int snd_dma_alloc_pages(int type, struct device *dev, size_t size,
Expand Down
27 changes: 23 additions & 4 deletions include/sound/pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -974,10 +974,29 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);

#define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_buffer_p->private_data)
#define snd_pcm_sgbuf_pages(size) snd_sgbuf_aligned_pages(size)
#define snd_pcm_sgbuf_get_addr(sgbuf,ofs) snd_sgbuf_get_addr(sgbuf,ofs)
struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset);
/*
* SG-buffer handling
*/
#define snd_pcm_substream_sgbuf(substream) \
((substream)->runtime->dma_buffer_p->private_data)

static inline dma_addr_t
snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
{
struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
return snd_sgbuf_get_addr(sg, ofs);
}

static inline void *
snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
{
struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
return snd_sgbuf_get_ptr(sg, ofs);
}

struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
unsigned long offset);


/* handle mmap counter - PCM mmap callback should handle this counter properly */
static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
Expand Down
8 changes: 0 additions & 8 deletions sound/core/memalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,6 @@ MODULE_DESCRIPTION("Memory allocator for ALSA system.");
MODULE_LICENSE("GPL");


/*
*/

void *snd_malloc_sgbuf_pages(struct device *device,
size_t size, struct snd_dma_buffer *dmab,
size_t *res_size);
int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);

/*
*/

Expand Down
7 changes: 2 additions & 5 deletions sound/pci/au88x0/au88x0.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ typedef struct {
/* Virtual page extender stuff */
int nr_periods;
int period_bytes;
struct snd_sg_buf *sgbuf; /* DMA Scatter Gather struct */
int period_real;
int period_virt;

Expand Down Expand Up @@ -195,16 +194,14 @@ static void vortex_adb_setsrc(vortex_t * vortex, int adbdma,

/* DMA Engines. */
static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
struct snd_sg_buf * sgbuf, int size,
int count);
int size, int count);
static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie,
int dir, int fmt, int d,
u32 offset);
static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb);
#ifndef CHIP_AU8810
static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
struct snd_sg_buf * sgbuf, int size,
int count);
int size, int count);
static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */
u32 offset);
static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb);
Expand Down
38 changes: 17 additions & 21 deletions sound/pci/au88x0/au88x0_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1097,19 +1097,12 @@ static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb)

static void
vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
struct snd_sg_buf * sgbuf, int psize, int count)
int psize, int count)
{
stream_t *dma = &vortex->dma_adb[adbdma];

if (sgbuf == NULL) {
printk(KERN_INFO "vortex: FATAL: sgbuf is NULL!\n");
return;
}
//printk(KERN_INFO "vortex: page count = %d, tblcount = %d\n", count, sgbuf->tblsize);

dma->period_bytes = psize;
dma->nr_periods = count;
dma->sgbuf = sgbuf;

dma->cfg0 = 0;
dma->cfg1 = 0;
Expand All @@ -1120,26 +1113,26 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc,
snd_sgbuf_get_addr(sgbuf, psize * 3));
snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
/* 3 pages */
case 3:
dma->cfg0 |= 0x12000000;
dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8,
snd_sgbuf_get_addr(sgbuf, psize * 2));
snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
/* 2 pages */
case 2:
dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4,
snd_sgbuf_get_addr(sgbuf, psize));
snd_pcm_sgbuf_get_addr(dma->substream, psize));
/* 1 page */
case 1:
dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (adbdma << 4),
snd_sgbuf_get_addr(sgbuf, 0));
snd_pcm_sgbuf_get_addr(dma->substream, 0));
break;
}
//printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1);
Expand Down Expand Up @@ -1205,7 +1198,7 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
//hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
snd_sgbuf_get_addr(dma->sgbuf,
snd_pcm_sgbuf_get_addr(dma->substream,
dma->period_bytes * p));
/* Force write thru cache. */
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
Expand Down Expand Up @@ -1244,7 +1237,10 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
if (pp >= 4)
pp -= 4;
}
hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
hwwrite(vortex->mmio,
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
snd_pcm_sgbuf_get_addr(dma->substream,
dma->period_bytes * p));
/* Force write thru cache. */
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
}
Expand Down Expand Up @@ -1367,13 +1363,12 @@ static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb)

static void
vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
struct snd_sg_buf * sgbuf, int psize, int count)
int psize, int count)
{
stream_t *dma = &vortex->dma_wt[wtdma];

dma->period_bytes = psize;
dma->nr_periods = count;
dma->sgbuf = sgbuf;

dma->cfg0 = 0;
dma->cfg1 = 0;
Expand All @@ -1383,23 +1378,23 @@ vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
case 4:
dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
snd_sgbuf_get_addr(sgbuf, psize * 3));
snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
/* 3 pages */
case 3:
dma->cfg0 |= 0x12000000;
dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8,
snd_sgbuf_get_addr(sgbuf, psize * 2));
snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
/* 2 pages */
case 2:
dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
snd_sgbuf_get_addr(sgbuf, psize));
snd_pcm_sgbuf_get_addr(dma->substream, psize));
/* 1 page */
case 1:
dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
snd_sgbuf_get_addr(sgbuf, 0));
snd_pcm_sgbuf_get_addr(dma->substream, 0));
break;
}
hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);
Expand Down Expand Up @@ -1465,7 +1460,8 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
hwwrite(vortex->mmio,
VORTEX_WTDMA_BUFBASE +
(((wtdma << 2) + pp) << 2),
snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
snd_pcm_sgbuf_get_addr(dma->substream,
dma->period_bytes * p));
/* Force write thru cache. */
hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
(((wtdma << 2) + pp) << 2));
Expand Down
14 changes: 2 additions & 12 deletions sound/pci/au88x0/au88x0_pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
{
vortex_t *chip = snd_pcm_substream_chip(substream);
stream_t *stream = (stream_t *) (substream->runtime->private_data);
struct snd_sg_buf *sgbuf;
int err;

// Alloc buffer memory.
Expand All @@ -199,8 +198,6 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
printk(KERN_ERR "Vortex: pcm page alloc failed!\n");
return err;
}
//sgbuf = (struct snd_sg_buf *) substream->runtime->dma_private;
sgbuf = snd_pcm_substream_sgbuf(substream);
/*
printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
params_period_bytes(hw_params), params_channels(hw_params));
Expand All @@ -226,7 +223,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
stream = substream->runtime->private_data = &chip->dma_adb[dma];
stream->substream = substream;
/* Setup Buffers. */
vortex_adbdma_setbuffers(chip, dma, sgbuf,
vortex_adbdma_setbuffers(chip, dma,
params_period_bytes(hw_params),
params_periods(hw_params));
}
Expand All @@ -240,7 +237,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
&chip->dma_wt[substream->number];
stream->dma = substream->number;
stream->substream = substream;
vortex_wtdma_setbuffers(chip, substream->number, sgbuf,
vortex_wtdma_setbuffers(chip, substream->number,
params_period_bytes(hw_params),
params_periods(hw_params));
}
Expand Down Expand Up @@ -392,13 +389,6 @@ static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substr
return (bytes_to_frames(substream->runtime, current_ptr));
}

/* Page callback. */
/*
static struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) {
}
*/
/* operators */
static struct snd_pcm_ops snd_vortex_playback_ops = {
.open = snd_vortex_pcm_open,
Expand Down
5 changes: 3 additions & 2 deletions sound/pci/bt87x.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ static inline void snd_bt87x_writel(struct snd_bt87x *chip, u32 reg, u32 value)
static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substream *substream,
unsigned int periods, unsigned int period_bytes)
{
struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
unsigned int i, offset;
u32 *risc;

Expand All @@ -246,6 +245,7 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea
rest = period_bytes;
do {
u32 cmd, len;
unsigned int addr;

len = PAGE_SIZE - (offset % PAGE_SIZE);
if (len > rest)
Expand All @@ -260,7 +260,8 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea
if (len == rest)
cmd |= RISC_EOL | RISC_IRQ;
*risc++ = cpu_to_le32(cmd);
*risc++ = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, offset));
addr = snd_pcm_sgbuf_get_addr(substream, offset);
*risc++ = cpu_to_le32(addr);
offset += len;
rest -= len;
} while (rest > 0);
Expand Down
14 changes: 4 additions & 10 deletions sound/pci/echoaudio/echoaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,6 @@ static int init_engine(struct snd_pcm_substream *substream,
{
struct echoaudio *chip;
int err, per, rest, page, edge, offs;
struct snd_sg_buf *sgbuf;
struct audiopipe *pipe;

chip = snd_pcm_substream_chip(substream);
Expand Down Expand Up @@ -531,10 +530,6 @@ static int init_engine(struct snd_pcm_substream *substream,
return err;
}

sgbuf = snd_pcm_substream_sgbuf(substream);

DE_HWP(("pcm_hw_params table size=%d pages=%d\n",
sgbuf->size, sgbuf->pages));
sglist_init(chip, pipe);
edge = PAGE_SIZE;
for (offs = page = per = 0; offs < params_buffer_bytes(hw_params);
Expand All @@ -543,16 +538,15 @@ static int init_engine(struct snd_pcm_substream *substream,
if (offs + rest > params_buffer_bytes(hw_params))
rest = params_buffer_bytes(hw_params) - offs;
while (rest) {
dma_addr_t addr;
addr = snd_pcm_sgbuf_get_addr(substream, offs);
if (rest <= edge - offs) {
sglist_add_mapping(chip, pipe,
snd_sgbuf_get_addr(sgbuf, offs),
rest);
sglist_add_mapping(chip, pipe, addr, rest);
sglist_add_irq(chip, pipe);
offs += rest;
rest = 0;
} else {
sglist_add_mapping(chip, pipe,
snd_sgbuf_get_addr(sgbuf, offs),
sglist_add_mapping(chip, pipe, addr,
edge - offs);
rest -= edge - offs;
offs = edge;
Expand Down
12 changes: 2 additions & 10 deletions sound/pci/emu10k1/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ struct snd_util_memblk *
snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
struct snd_util_memhdr *hdr;
struct snd_emu10k1_memblk *blk;
int page, err, idx;
Expand All @@ -321,16 +320,9 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
*/
idx = 0;
for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
unsigned long ofs = idx << PAGE_SHIFT;
dma_addr_t addr;
#ifdef CONFIG_SND_DEBUG
if (idx >= sgbuf->pages) {
printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n",
blk->first_page, blk->last_page, sgbuf->pages);
mutex_unlock(&hdr->block_mutex);
return NULL;
}
#endif
addr = sgbuf->table[idx].addr;
addr = snd_pcm_sgbuf_get_addr(substream, ofs);
if (! is_valid_page(emu, addr)) {
printk(KERN_ERR "emu: failure page = %d\n", idx);
mutex_unlock(&hdr->block_mutex);
Expand Down
3 changes: 1 addition & 2 deletions sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,6 @@ static int setup_bdle(struct snd_pcm_substream *substream,
struct azx_dev *azx_dev, u32 **bdlp,
int ofs, int size, int with_ioc)
{
struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
u32 *bdl = *bdlp;

while (size > 0) {
Expand All @@ -1008,7 +1007,7 @@ static int setup_bdle(struct snd_pcm_substream *substream,
if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
return -EINVAL;

addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs);
addr = snd_pcm_sgbuf_get_addr(substream, ofs);
/* program the address field of the BDL entry */
bdl[0] = cpu_to_le32((u32)addr);
bdl[1] = cpu_to_le32(upper_32_bits(addr));
Expand Down
Loading

0 comments on commit 77a23f2

Please sign in to comment.