30 #include <sys/cdefs.h>
33 #include <sys/param.h>
35 #include <sys/mutex.h>
36 #include <sys/kernel.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <sys/module.h>
41 #include <machine/bus.h>
43 #include <sys/mbpool.h>
64 #define MBP_CARD 0x8000
65 #define MBP_USED 0x4000
66 #define MBP_PMSK 0x3fff
67 #define MBP_CMSK 0x01ff
98 #define C2T(P, C) ((struct mbtrail *)((char *)(C) + (P)->chunk_size - \
99 sizeof(struct mbtrail)))
104 #define N2C(P, PG, C) ((struct mbfree *)((char *)(PG)->va + \
105 (C) * (P)->chunk_size))
110 #define HMAKE(P, C) ((((P) & MBP_PMSK) << 16) | ((C) << 7))
111 #define HPAGE(H) (((H) >> 16) & MBP_PMSK)
112 #define HCHUNK(H) (((H) >> 7) & MBP_CMSK)
119 u_int max_pages,
size_t page_size,
size_t chunk_size)
123 if (max_pages > MBPOOL_MAX_MAXPAGES || chunk_size == 0)
126 if (nchunks == 0 || nchunks > MBPOOL_MAX_CHUNKS)
130 max_pages *
sizeof(
struct mbpage),
131 M_MBPOOL, M_WAITOK | M_ZERO);
138 (*pp)->nchunks = nchunks;
140 SLIST_INIT(&(*pp)->free_list);
141 mtx_init(&(*pp)->free_lock, name, NULL, MTX_DEF);
159 for (i = 0; i < p->npages; i++) {
162 for (b = 0; b < p->nchunks; b++) {
163 tr =
C2T(p,
N2C(p, pg, b));
165 printf(
"%s: (%s) buf still on card"
166 " %u/%u\n", __func__, p->
name, i, b);
168 printf(
"%s: (%s) sbuf still in use"
169 " %u/%u\n", __func__, p->
name, i, b);
172 bus_dmamap_unload(p->
dmat, pg->
map);
173 bus_dmamem_free(p->
dmat, pg->
va, pg->
map);
187 *(bus_addr_t *)arg = segs[0].ds_addr;
204 printf(
"%s: (%s) page limit reached %u\n", __func__,
209 pg = &p->pages[p->npages];
211 error = bus_dmamem_alloc(p->
dmat, &pg->
va, BUS_DMA_NOWAIT, &pg->
map);
218 bus_dmamem_free(p->
dmat, pg->
va, pg->
map);
222 for (i = 0; i < p->nchunks; i++) {
227 SLIST_INSERT_HEAD(&p->free_list, f, link);
243 if ((cf = SLIST_FIRST(&p->free_list)) == NULL) {
245 cf = SLIST_FIRST(&p->free_list);
251 SLIST_REMOVE_HEAD(&p->free_list, link);
275 SLIST_INSERT_HEAD(&p->free_list, (
struct mbfree *)ptr, link);
300 for (i = 0; i < p->npages; i++) {
302 for (b = 0; b < p->nchunks; b++) {
307 SLIST_INSERT_HEAD(&p->free_list, cf, link);
325 *used = *card = *free = 0;
326 for (i = 0; i < p->npages; i++) {
328 for (b = 0; b < p->nchunks; b++) {
329 tr =
C2T(p,
N2C(p, pg, b));
337 SLIST_FOREACH(cf, &p->free_list, link)
356 printf(
"%s: (%s) chunk %u page %u not on card\n", __func__,
378 printf(
"%s: (%s) chunk %u page %u not on card\n", __func__,
393 bus_dmamap_sync_size(p->
dmat, p->pages[
HPAGE(h)].map,
void mbp_destroy(struct mbpool *p)
void * mbp_get(struct mbpool *p, uint32_t h)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
void mbp_free(struct mbpool *p, void *ptr)
static MALLOC_DEFINE(M_MBPOOL,"mbpools","mbuf pools")
void * mbp_alloc(struct mbpool *p, bus_addr_t *pap, uint32_t *hp)
void mbp_sync(struct mbpool *p, uint32_t h, bus_addr_t off, bus_size_t len, u_int op)
int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, bus_size_t buflen, bus_dmamap_callback_t *callback, void *callback_arg, int flags)
void mbp_count(struct mbpool *p, u_int *used, u_int *card, u_int *free)
void free(void *addr, struct malloc_type *mtp)
int printf(const char *fmt,...)
void mbp_ext_free(void *buf, void *arg)
static void mbp_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
int mbp_create(struct mbpool **pp, const char *name, bus_dma_tag_t dmat, u_int max_pages, size_t page_size, size_t chunk_size)
void mtx_init(struct mtx *m, const char *name, const char *type, int opts)
MODULE_VERSION(libmbpool, 1)
SLIST_HEAD(et_eventtimers_list, eventtimer)
void mtx_destroy(struct mtx *m)
static void mbp_alloc_page(struct mbpool *p)
void mbp_card_free(struct mbpool *p)
void * mbp_get_keep(struct mbpool *p, uint32_t h)