/* Create a new memory DMAable pool (when fetch failed) */ static m_pool_p ___cre_dma_pool(m_pool_ident_t dev_dmat) { m_pool_p mp = __sym_calloc(&mp0, sizeof(*mp), "MPOOL"); if (mp) { mp->dev_dmat = dev_dmat; mp->get_mem_cluster = ___get_dma_mem_cluster; #ifdef SYM_MEM_FREE_UNUSED mp->free_mem_cluster = ___free_dma_mem_cluster; #endif mp->next = mp0.next; mp0.next = mp; return mp; } return NULL; }
/* * Actual allocator for DMAable memory. */ void *__sym_calloc_dma_unlocked(m_pool_ident_t dev_dmat, int size, char *name) { m_pool_p mp; void *m = NULL; mp = ___get_dma_pool(dev_dmat); if (!mp) mp = ___cre_dma_pool(dev_dmat); if (mp) m = __sym_calloc(mp, size, name); #ifdef SYM_MEM_FREE_UNUSED if (mp && !mp->nump) ___del_dma_pool(mp); #endif return m; }
/* Get a memory cluster that matches the DMA constraints of a given pool */ static void * ___get_dma_mem_cluster(m_pool_p mp) { m_vtob_p vbp; void *vaddr; vbp = __sym_calloc(&mp0, sizeof(*vbp), "VTOB"); if (!vbp) goto out_err; vaddr = sym_m_get_dma_mem_cluster(mp, vbp); if (vaddr) { int hc = VTOB_HASH_CODE(vaddr); vbp->next = mp->vtob[hc]; mp->vtob[hc] = vbp; ++mp->nump; } return vaddr; out_err: return NULL; }
/* * Actual allocator for DMAable memory. */ void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name) { unsigned long flags; m_pool_p mp; void *m = NULL; spin_lock_irqsave(&sym53c8xx_lock, flags); mp = ___get_dma_pool(dev_dmat); if (!mp) mp = ___cre_dma_pool(dev_dmat); if (!mp) goto out; m = __sym_calloc(mp, size, name); #ifdef SYM_MEM_FREE_UNUSED if (!mp->nump) ___del_dma_pool(mp); #endif out: spin_unlock_irqrestore(&sym53c8xx_lock, flags); return m; }
/* * Actual memory allocation routine for non-DMAed memory. */ void *sym_calloc_unlocked(int size, char *name) { void *m; m = __sym_calloc(&mp0, size, name); return m; }