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