1*1378bae2Sdlg /* $OpenBSD: dma_alloc.c,v 1.13 2016/09/15 02:00:16 dlg Exp $ */
24bb7a4f6Smpi
372570117Sderaadt /*
472570117Sderaadt * Copyright (c) 2010 Theo de Raadt <deraadt@openbsd.org>
572570117Sderaadt *
672570117Sderaadt * Permission to use, copy, modify, and distribute this software for any
772570117Sderaadt * purpose with or without fee is hereby granted, provided that the above
872570117Sderaadt * copyright notice and this permission notice appear in all copies.
972570117Sderaadt *
1072570117Sderaadt * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1172570117Sderaadt * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1272570117Sderaadt * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1372570117Sderaadt * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1472570117Sderaadt * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1572570117Sderaadt * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1672570117Sderaadt * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1772570117Sderaadt */
1872570117Sderaadt
1972570117Sderaadt #include <sys/param.h>
20e6c6495dSderaadt #include <sys/systm.h>
2172570117Sderaadt #include <sys/pool.h>
224bb7a4f6Smpi
234bb7a4f6Smpi #include <uvm/uvm_extern.h>
2472570117Sderaadt
2572570117Sderaadt static __inline int dma_alloc_index(size_t size);
2672570117Sderaadt
278eb06826Sderaadt /* Create dma pools from objects sized 2^4 to 2^16 */
288eb06826Sderaadt #define DMA_PAGE_SHIFT 16
2972570117Sderaadt #define DMA_BUCKET_OFFSET 4
308eb06826Sderaadt static char dmanames[DMA_PAGE_SHIFT - DMA_BUCKET_OFFSET + 1][10];
318eb06826Sderaadt struct pool dmapools[DMA_PAGE_SHIFT - DMA_BUCKET_OFFSET + 1];
3272570117Sderaadt
3372570117Sderaadt void
dma_alloc_init(void)3472570117Sderaadt dma_alloc_init(void)
3572570117Sderaadt {
3672570117Sderaadt int i;
3772570117Sderaadt
3872570117Sderaadt for (i = 0; i < nitems(dmapools); i++) {
3972570117Sderaadt snprintf(dmanames[i], sizeof(dmanames[0]), "dma%d",
4072570117Sderaadt 1 << (i + DMA_BUCKET_OFFSET));
41*1378bae2Sdlg pool_init(&dmapools[i], 1 << (i + DMA_BUCKET_OFFSET), 0,
42*1378bae2Sdlg IPL_VM, 0, dmanames[i], NULL);
4312e839c5Sariane pool_set_constraints(&dmapools[i], &kp_dma_contig);
4472570117Sderaadt /* XXX need pool_setlowat(&dmapools[i], dmalowat); */
4572570117Sderaadt }
4672570117Sderaadt }
4772570117Sderaadt
4872570117Sderaadt static __inline int
dma_alloc_index(size_t sz)4972570117Sderaadt dma_alloc_index(size_t sz)
5072570117Sderaadt {
5172570117Sderaadt int b;
5272570117Sderaadt
5372570117Sderaadt for (b = 0; b < nitems(dmapools); b++)
5472570117Sderaadt if (sz <= (1 << (b + DMA_BUCKET_OFFSET)))
5572570117Sderaadt return (b);
5672570117Sderaadt #ifdef DEBUG
572f436acaSsf printf("dma_alloc/free: object %zd too large\n", sz);
5872570117Sderaadt #endif
5972570117Sderaadt return (-1);
6072570117Sderaadt }
6172570117Sderaadt
6272570117Sderaadt void *
dma_alloc(size_t size,int prflags)6372570117Sderaadt dma_alloc(size_t size, int prflags)
6472570117Sderaadt {
6572570117Sderaadt int pi = dma_alloc_index(size);
6672570117Sderaadt
6772570117Sderaadt if (pi == -1)
6872570117Sderaadt return (NULL);
6972570117Sderaadt return pool_get(&dmapools[pi], prflags);
7072570117Sderaadt }
7172570117Sderaadt
7272570117Sderaadt
7372570117Sderaadt void
dma_free(void * m,size_t size)7472570117Sderaadt dma_free(void *m, size_t size)
7572570117Sderaadt {
7672570117Sderaadt int pi = dma_alloc_index(size);
7772570117Sderaadt
7872570117Sderaadt if (pi == -1)
7972570117Sderaadt return;
8072570117Sderaadt pool_put(&dmapools[pi], m);
8172570117Sderaadt }
82