xref: /openbsd/sys/kern/dma_alloc.c (revision 1378bae2)
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