dma_alloc.c revision 1.2
1/*	$OpenBSD: dma_alloc.c,v 1.2 2010/07/14 00:15:07 deraadt 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
22static __inline int	 dma_alloc_index(size_t size);
23
24#define DMA_BUCKET_OFFSET 4
25static char dmanames[PAGE_SHIFT - DMA_BUCKET_OFFSET][8];
26struct pool dmapools[PAGE_SHIFT - DMA_BUCKET_OFFSET];
27
28void
29dma_alloc_init(void)
30{
31	int i;
32
33	for (i = 0; i < nitems(dmapools); i++) {
34		snprintf(dmanames[i], sizeof(dmanames[0]), "dma%d",
35		    1 << (i + DMA_BUCKET_OFFSET));
36		pool_init(&dmapools[i], 1 << (i + DMA_BUCKET_OFFSET), 0, 0, 0,
37		    dmanames[i], NULL);
38		pool_set_constraints(&dmapools[i], &dma_constraint, 1);
39		/* XXX need pool_setlowat(&dmapools[i], dmalowat); */
40	}
41}
42
43static __inline int
44dma_alloc_index(size_t sz)
45{
46	int b;
47
48	for (b = 0; b < nitems(dmapools); b++)
49		if (sz <= (1 << (b + DMA_BUCKET_OFFSET)))
50			return (b);
51#ifdef DEBUG
52	printf("dma_alloc/free: object %d too large\n", sz);
53#endif
54	return (-1);
55}
56
57void *
58dma_alloc(size_t size, int prflags)
59{
60	int pi = dma_alloc_index(size);
61
62	if (pi == -1)
63		return (NULL);
64	return pool_get(&dmapools[pi], prflags);
65}
66
67
68void
69dma_free(void *m, size_t size)
70{
71	int pi = dma_alloc_index(size);
72
73	if (pi == -1)
74		return;
75	pool_put(&dmapools[pi], m);
76}
77