xref: /openbsd/sys/kern/dma_alloc.c (revision 3d8817e4)
1 /*	$OpenBSD: dma_alloc.c,v 1.8 2011/04/18 19:23:46 art Exp $	 */
2 /*
3  * Copyright (c) 2010 Theo de Raadt <deraadt@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/pool.h>
20 #include <uvm/uvm.h>
21 
22 static __inline int	 dma_alloc_index(size_t size);
23 
24 /* Create dma pools from objects sized 2^4 to 2^16 */
25 #define DMA_PAGE_SHIFT		16
26 #define DMA_BUCKET_OFFSET	4
27 static char dmanames[DMA_PAGE_SHIFT - DMA_BUCKET_OFFSET + 1][10];
28 struct pool dmapools[DMA_PAGE_SHIFT - DMA_BUCKET_OFFSET + 1];
29 
30 void
31 dma_alloc_init(void)
32 {
33 	int i;
34 
35 	for (i = 0; i < nitems(dmapools); i++) {
36 		snprintf(dmanames[i], sizeof(dmanames[0]), "dma%d",
37 		    1 << (i + DMA_BUCKET_OFFSET));
38 		pool_init(&dmapools[i], 1 << (i + DMA_BUCKET_OFFSET), 0, 0, 0,
39 		    dmanames[i], NULL);
40 		pool_set_constraints(&dmapools[i], &kp_dma);
41 		pool_setipl(&dmapools[i], IPL_VM);
42 		/* XXX need pool_setlowat(&dmapools[i], dmalowat); */
43 	}
44 }
45 
46 static __inline int
47 dma_alloc_index(size_t sz)
48 {
49 	int b;
50 
51 	for (b = 0; b < nitems(dmapools); b++)
52 		if (sz <= (1 << (b + DMA_BUCKET_OFFSET)))
53 			return (b);
54 #ifdef DEBUG
55 	printf("dma_alloc/free: object %d too large\n", sz);
56 #endif
57 	return (-1);
58 }
59 
60 void *
61 dma_alloc(size_t size, int prflags)
62 {
63 	int pi = dma_alloc_index(size);
64 
65 	if (pi == -1)
66 		return (NULL);
67 	return pool_get(&dmapools[pi], prflags);
68 }
69 
70 
71 void
72 dma_free(void *m, size_t size)
73 {
74 	int pi = dma_alloc_index(size);
75 
76 	if (pi == -1)
77 		return;
78 	pool_put(&dmapools[pi], m);
79 }
80