/* * try to allocate as the large pages as possible. * stores the resultant memory size in *res_size. * * the minimum size is snd_minimum_buffer. it should be power of 2. */ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size) { struct snd_dma_buffer *dmab = &substream->dma_buffer; size_t orig_size = size; int err; /* already reserved? */ if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) { if (dmab->bytes >= size) return 0; /* yes */ /* no, free the reserved block */ snd_dma_free_pages(dmab); dmab->bytes = 0; } do { if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab)) < 0) { if (err != -ENOMEM) return err; /* fatal error */ } else return 0; size >>= 1; } while (size >= snd_minimum_buffer); dmab->bytes = 0; /* tell error */ pr_warn("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n", substream->pcm->card->number, substream->pcm->device, substream->stream ? 'c' : 'p', substream->number, substream->pcm->name, orig_size); return 0; }
/* * try to allocate as the large pages as possible. * stores the resultant memory size in *res_size. * * the minimum size is snd_minimum_buffer. it should be power of 2. */ static int preallocate_pcm_pages(snd_pcm_substream_t *substream, size_t size) { struct snd_dma_buffer *dmab = &substream->dma_buffer; int err; snd_assert(size > 0, return -EINVAL); /* already reserved? */ if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) { if (dmab->bytes >= size) return 0; /* yes */ /* no, free the reserved block */ snd_dma_free_pages(dmab); dmab->bytes = 0; } do { if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab)) < 0) { if (err != -ENOMEM) return err; /* fatal error */ } else return 0; size >>= 1; } while (size >= snd_minimum_buffer); dmab->bytes = 0; /* tell error */ return 0; }