openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

linux_dma.c (30318B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * Linux Kernel BDE DMA memory allocation
      8  *
      9  *
     10  * DMA memory allocation modes
     11  * ===========================
     12  *
     13  * 1. Using private pool in kernel memory
     14  * --------------------------------------
     15  * In this mode the BDE module will try to assemble a physically contiguous
     16  * of memory using the kernel page allocator. This memory block is then
     17  * administered by the mpool allocation functions. Note that once a system
     18  * has been running for a while, the memory fragmentation may prevent the
     19  * allocator from assembling a contiguous memory block, however, if the
     20  * module is loaded shortly after system startup, it is very unlikely to
     21  * fail.
     22  *
     23  * This allocation method is used by default.
     24  *
     25  * 2. Using private pool in high memory
     26  * ------------------------------------
     27  * In this mode the BDE module will assume that unused physical memory is
     28  * present at the high_memory address, i.e. memory not managed by the Linux
     29  * memory manager. This memory block is mapped into kernel space and
     30  * administered by the mpool allocation functions. High memory must be
     31  * reserved using either the mem=xxx kernel parameter (recommended), or by
     32  * hardcoding the memory limit in the kernel image.
     33  *
     34  * The module parameter himem=1 enables this allocation mode.
     35  *
     36  * 3. Using kernel allocators (kmalloc, __get_free_pages)
     37  * ------------------------------------------------------
     38  * In this mode all DMA memory is allocated from the kernel on the fly, i.e.
     39  * no private DMA memory pool will be created. If large memory blocks are
     40  * only allocated at system startup (or not at all), this allocation method
     41  * is the most flexible and memory-efficient, however, it is not recommended
     42  * for non-coherent memory platforms due to an overall system performance
     43  * degradation arising from the use of cache flush/invalidate instructions.
     44  *
     45  * The module parameter dmasize=0M enables this allocation mode, however if
     46  * DMA memory is requested from a user mode application, a private memory
     47  * pool will be created and used irrespectively.
     48  */
     49 
     50 #include <gmodule.h>
     51 #include <linux-bde.h>
     52 #include <linux_dma.h>
     53 #include <mpool.h>
     54 #include <sdk_config.h>
     55 
     56 #ifdef BCM_PLX9656_LOCAL_BUS
     57 #include <asm/cacheflush.h>
     58 #endif
     59 
     60 /* allocation types/methods for the DMA memory pool */
     61 #define ALLOC_TYPE_CHUNK 0 /* use small allocations and join them */
     62 #define ALLOC_TYPE_API 1 /* use one allocation */
     63 #if _SIMPLE_MEMORY_ALLOCATION_
     64 #include <linux/dma-mapping.h>
     65 #if defined(IPROC_CMICD) && defined(CONFIG_CMA) && defined(CONFIG_CMA_SIZE_MBYTES)
     66 #define DMA_MAX_ALLOC_SIZE (CONFIG_CMA_SIZE_MBYTES * 1024 * 1024)
     67 #else
     68 #define DMA_MAX_ALLOC_SIZE (1 << (MAX_ORDER - 1 + PAGE_SHIFT)) /* Maximum size the kernel can allocate in one allocation */
     69 #endif
     70 #endif /* _SIMPLE_MEMORY_ALLOCATION_ */
     71 
     72 #if _SIMPLE_MEMORY_ALLOCATION_ == 1
     73 #define ALLOC_METHOD_DEFAULT ALLOC_TYPE_API
     74 #if defined(__arm__)
     75 #define USE_DMA_MMAP_COHERENT
     76 #define _PGPROT_NONCACHED(x) x = pgprot_noncached((x))
     77 #elif defined(__aarch64__ )
     78 #define USE_DMA_MMAP_COHERENT
     79 #define _PGPROT_NONCACHED(x) x = pgprot_writecombine((x))
     80 #endif
     81 #else
     82 #define ALLOC_METHOD_DEFAULT ALLOC_TYPE_CHUNK
     83 #endif
     84 
     85 #ifndef _PGPROT_NONCACHED
     86 #ifdef REMAP_DMA_NONCACHED
     87 #define _PGPROT_NONCACHED(x) x = pgprot_noncached((x))
     88 #else
     89 #define _PGPROT_NONCACHED(x)
     90 #endif
     91 #endif
     92 
     93 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
     94 #include <linux/slab.h>
     95 #define virt_to_bus virt_to_phys
     96 #define bus_to_virt phys_to_virt
     97 #endif
     98 
     99 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
    100 #define VIRT_TO_PAGE(p)     virt_to_page((void*)(p))
    101 #else
    102 #define VIRT_TO_PAGE(p)     virt_to_page((p))
    103 #endif
    104 
    105 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
    106 #define DMA_MAPPING_ERROR(d, p)     dma_mapping_error((d),(p))
    107 #else
    108 #define DMA_MAPPING_ERROR(d, p)     dma_mapping_error((p))
    109 #endif
    110 
    111 #ifndef KMALLOC_MAX_SIZE
    112 #define KMALLOC_MAX_SIZE (1UL << (MAX_ORDER - 1 + PAGE_SHIFT))
    113 #endif
    114 
    115 /* Compatibility */
    116 #ifdef LKM_2_4
    117 #define MEM_MAP_RESERVE mem_map_reserve
    118 #define MEM_MAP_UNRESERVE mem_map_unreserve
    119 #else /* LKM_2_6 */
    120 #define MEM_MAP_RESERVE SetPageReserved
    121 #define MEM_MAP_UNRESERVE ClearPageReserved
    122 #endif /* LKM_2_x */
    123 
    124 #ifndef GFP_DMA32
    125 #define GFP_DMA32 0
    126 #endif
    127 
    128 /* Flags for memory allocations */
    129 #ifdef SAL_BDE_XLP
    130 static int mem_flags = GFP_ATOMIC | GFP_KERNEL | GFP_DMA;
    131 #else
    132 #if defined(CONFIG_ZONE_DMA32)
    133 static int mem_flags = GFP_ATOMIC | GFP_DMA32;
    134 #else
    135 static int mem_flags = GFP_ATOMIC | GFP_DMA;
    136 #endif
    137 #endif
    138 
    139 /* Debug output */
    140 static int dma_debug = 0;
    141 module_param(dma_debug, int, 0);
    142 MODULE_PARM_DESC(dma_debug,
    143 "DMA debug output enable (default 0).");
    144 
    145 /* DMA memory pool size */
    146 static char *dmasize;
    147 LKM_MOD_PARAM(dmasize, "s", charp, 0);
    148 MODULE_PARM_DESC(dmasize,
    149 "Specify DMA memory size (default 4MB)");
    150 
    151 /* Select DMA memory pool allocation method */
    152 static int dmaalloc = ALLOC_METHOD_DEFAULT;
    153 LKM_MOD_PARAM(dmaalloc, "i", int, 0);
    154 MODULE_PARM_DESC(dmaalloc, "Select DMA memory allocation method");
    155 
    156 /* Use high memory for DMA */
    157 static char *himem;
    158 LKM_MOD_PARAM(himem, "s", charp, 0);
    159 MODULE_PARM_DESC(himem,
    160 "Use high memory for DMA (default no)");
    161 
    162 /* Physical high memory address to use for DMA */
    163 static char *himemaddr = 0;
    164 LKM_MOD_PARAM(himemaddr, "s", charp, 0);
    165 MODULE_PARM_DESC(himemaddr,
    166 "Physical address to use for high memory DMA");
    167 
    168 /* DMA memory allocation */
    169 
    170 #define ONE_KB 1024
    171 #define ONE_MB (1024*1024)
    172 #define ONE_GB (1024*1024*1024)
    173 
    174 /* Default DMA memory size */
    175 #ifdef SAL_BDE_DMA_MEM_DEFAULT
    176 #define DMA_MEM_DEFAULT (SAL_BDE_DMA_MEM_DEFAULT * ONE_MB)
    177 #else
    178 #define DMA_MEM_DEFAULT (8 * ONE_MB)
    179 #endif
    180 
    181 /* We try to assemble a contiguous segment from chunks of this size */
    182 #define DMA_BLOCK_SIZE (512 * ONE_KB)
    183 
    184 typedef struct _dma_segment {
    185     struct list_head list;
    186     unsigned long req_size;     /* Requested DMA segment size */
    187     unsigned long blk_size;     /* DMA block size */
    188     unsigned long blk_order;    /* DMA block size in alternate format */
    189     unsigned long seg_size;     /* Current DMA segment size */
    190     unsigned long seg_begin;    /* Logical address of segment */
    191     unsigned long seg_end;      /* Logical end address of segment */
    192     unsigned long *blk_ptr;     /* Array of logical DMA block addresses */
    193     int blk_cnt_max;            /* Maximum number of block to allocate */
    194     int blk_cnt;                /* Current number of blocks allocated */
    195 } dma_segment_t;
    196 
    197 static unsigned int _dma_mem_size = DMA_MEM_DEFAULT;
    198 static mpool_handle_t _dma_pool = NULL;
    199 static void __iomem *_dma_vbase = NULL;
    200 /* cpu physical address for mmap */
    201 static phys_addr_t _cpu_pbase = 0;
    202 /*
    203  * DMA bus address, it is either identical to cpu physical address
    204  * or another address(IOVA) translated by IOMMU.
    205  */
    206 static phys_addr_t _dma_pbase = 0;
    207 static int _use_himem = 0;
    208 static unsigned long _himemaddr = 0;
    209 static int _use_dma_mapping = 0;
    210 static LIST_HEAD(_dma_seg);
    211 
    212 #define DMA_DEV_INDEX      0    /* Device index to allocate memory pool */
    213 #define DMA_DEV(n)         lkbde_get_dma_dev(n)
    214 #define BDE_NUM_DEVICES(t) lkbde_get_num_devices(t)
    215 
    216 /*
    217  * Function: _find_largest_segment
    218  *
    219  * Purpose:
    220  *    Find largest contiguous segment from a pool of DMA blocks.
    221  * Parameters:
    222  *    dseg - DMA segment descriptor
    223  * Returns:
    224  *    0 on success, < 0 on error.
    225  * Notes:
    226  *    Assembly stops if a segment of the requested segment size
    227  *    has been obtained.
    228  *
    229  *    Lower address bits of the DMA blocks are used as follows:
    230  *       0: Untagged
    231  *       1: Discarded block
    232  *       2: Part of largest contiguous segment
    233  *       3: Part of current contiguous segment
    234  */
    235 static int
    236 _find_largest_segment(dma_segment_t *dseg)
    237 {
    238     int i, j, blks, found;
    239     unsigned long b, e, a;
    240 
    241     blks = dseg->blk_cnt;
    242     /* Clear all block tags */
    243     for (i = 0; i < blks; i++) {
    244         dseg->blk_ptr[i] &= ~3;
    245     }
    246     for (i = 0; i < blks && dseg->seg_size < dseg->req_size; i++) {
    247         /* First block must be an untagged block */
    248         if ((dseg->blk_ptr[i] & 3) == 0) {
    249             /* Initial segment size is the block size */
    250             b = dseg->blk_ptr[i];
    251             e = b + dseg->blk_size;
    252             dseg->blk_ptr[i] |= 3;
    253             /* Loop looking for adjacent blocks */
    254             do {
    255                 found = 0;
    256                 for (j = i + 1; j < blks && (e - b) < dseg->req_size; j++) {
    257                     a = dseg->blk_ptr[j];
    258                     /* Check untagged blocks only */
    259                     if ((a & 3) == 0) {
    260                         if (a == (b - dseg->blk_size)) {
    261                             /* Found adjacent block below current segment */
    262                             dseg->blk_ptr[j] |= 3;
    263                             b = a;
    264                             found = 1;
    265                         } else if (a == e) {
    266                             /* Found adjacent block above current segment */
    267                             dseg->blk_ptr[j] |= 3;
    268                             e += dseg->blk_size;
    269                             found = 1;
    270                         }
    271                     }
    272                 }
    273             } while (found);
    274             if ((e - b) > dseg->seg_size) {
    275                 /* The current block is largest so far */
    276                 dseg->seg_begin = b;
    277                 dseg->seg_end = e;
    278                 dseg->seg_size = e - b;
    279                 /* Re-tag current and previous largest segment */
    280                 for (j = 0; j < blks; j++) {
    281                     if ((dseg->blk_ptr[j] & 3) == 3) {
    282                         /* Tag current segment as the largest */
    283                         dseg->blk_ptr[j] &= ~1;
    284                     } else if ((dseg->blk_ptr[j] & 3) == 2) {
    285                         /* Discard previous largest segment */
    286                         dseg->blk_ptr[j] ^= 3;
    287                     }
    288                 }
    289             } else {
    290                 /* Discard all blocks in current segment */
    291                 for (j = 0; j < blks; j++) {
    292                     if ((dseg->blk_ptr[j] & 3) == 3) {
    293                         dseg->blk_ptr[j] &= ~2;
    294                     }
    295                 }
    296             }
    297         }
    298     }
    299     return 0;
    300 }
    301 
    302 /*
    303  * Function: _alloc_dma_blocks
    304  *
    305  * Purpose:
    306  *    Allocate DMA blocks and add them to the pool.
    307  * Parameters:
    308  *    dseg - DMA segment descriptor
    309  *    blks - number of DMA blocks to allocate
    310  * Returns:
    311  *    0 on success, < 0 on error.
    312  * Notes:
    313  *    DMA blocks are allocated using the page allocator.
    314  */
    315 static int
    316 _alloc_dma_blocks(dma_segment_t *dseg, int blks)
    317 {
    318     int i, start;
    319     unsigned long addr;
    320 
    321     if (dseg->blk_cnt + blks > dseg->blk_cnt_max) {
    322         gprintk("No more DMA blocks\n");
    323         return -1;
    324     }
    325     start = dseg->blk_cnt;
    326     for (i = 0; i < blks; i++) {
    327         /*
    328          * Note that we cannot use pci_alloc_consistent when we
    329          * want to be able to map DMA memory to user space.
    330          *
    331          * The GFP_DMA flag is omitted as this imposes the ISA
    332          * addressing limitations on x86 platforms. As long as
    333          * we have less than 1GB of memory, we can do PCI DMA
    334          * to all physical RAM locations.
    335          */
    336         addr = __get_free_pages(mem_flags, dseg->blk_order);
    337         if (addr) {
    338             dseg->blk_ptr[start + i] = addr;
    339             ++dseg->blk_cnt;
    340         } else {
    341             gprintk("DMA allocation failed: allocated %d of %d "
    342                     "requested blocks\n", i, blks);
    343             return -1;
    344         }
    345     }
    346     return 0;
    347 }
    348 
    349 /*
    350  * Function: _dma_segment_alloc
    351  *
    352  * Purpose:
    353  *    Allocate large physically contiguous DMA segment.
    354  * Parameters:
    355  *    size - requested DMA segment size
    356  *    blk_size - assemble segment from blocks of this size
    357  * Returns:
    358  *    DMA segment descriptor.
    359  * Notes:
    360  *    Since we cannot allocate large blocks of contiguous
    361  *    memory from the kernel, we simply keep allocating
    362  *    smaller chunks until we can assemble a contiguous
    363  *    block of the desired size.
    364  *
    365  *    When system allowed maximum bytes of memory has been allocated
    366  *    without a successful assembly of a contiguous DMA
    367  *    segment, the allocation function will return the
    368  *    largest contiguous segment found so far. It is up
    369  *    to the calling function to decide whether this
    370  *    amount is sufficient to proceed.
    371  */
    372 static dma_segment_t *
    373 _dma_segment_alloc(size_t size, size_t blk_size)
    374 {
    375     dma_segment_t *dseg;
    376     int i, blk_ptr_size;
    377     unsigned long page_addr;
    378     struct sysinfo si;
    379 
    380     /* Sanity check */
    381     if (size == 0 || blk_size == 0) {
    382         return NULL;
    383     }
    384     /* Allocate an initialize DMA segment descriptor */
    385     if ((dseg = kmalloc(sizeof(dma_segment_t), GFP_KERNEL)) == NULL) {
    386         return NULL;
    387     }
    388     memset(dseg, 0, sizeof(dma_segment_t));
    389     dseg->req_size = size;
    390     dseg->blk_size = PAGE_ALIGN(blk_size);
    391     while ((PAGE_SIZE << dseg->blk_order) < dseg->blk_size) {
    392         dseg->blk_order++;
    393     }
    394 
    395     si_meminfo(&si);
    396     dseg->blk_cnt_max = (si.totalram << PAGE_SHIFT) / dseg->blk_size;
    397     blk_ptr_size = dseg->blk_cnt_max * sizeof(unsigned long);
    398     if (blk_ptr_size > KMALLOC_MAX_SIZE) {
    399         blk_ptr_size = KMALLOC_MAX_SIZE;
    400         dseg->blk_cnt_max = KMALLOC_MAX_SIZE / sizeof(unsigned long);
    401     }
    402     /* Allocate an initialize DMA block pool */
    403     dseg->blk_ptr = KMALLOC(blk_ptr_size, GFP_KERNEL);
    404     if (dseg->blk_ptr == NULL) {
    405         kfree(dseg);
    406         return NULL;
    407     }
    408     memset(dseg->blk_ptr, 0, blk_ptr_size);
    409     /* Allocate minimum number of blocks */
    410     if (_alloc_dma_blocks(dseg, dseg->req_size / dseg->blk_size) != 0) {
    411         gprintk("Failed to allocate minimum number of DMA blocks\n");
    412         /*
    413          * _alloc_dma_blocks() returns -1 if it fails to allocate the requested
    414          * number of blocks, but it may still have allocated something.  Fall
    415          * through and return dseg filled in with as much memory as we could
    416          * allocate.
    417          */
    418     }
    419     /* Allocate more blocks until we have a complete segment */
    420     do {
    421         _find_largest_segment(dseg);
    422         if (dseg->seg_size >= dseg->req_size) {
    423             break;
    424         }
    425     } while (_alloc_dma_blocks(dseg, 8) == 0);
    426     /* Reserve all pages in the DMA segment and free unused blocks */
    427     for (i = 0; i < dseg->blk_cnt; i++) {
    428         if ((dseg->blk_ptr[i] & 3) == 2) {
    429             dseg->blk_ptr[i] &= ~3;
    430             for (page_addr = dseg->blk_ptr[i];
    431                  page_addr < dseg->blk_ptr[i] + dseg->blk_size;
    432                  page_addr += PAGE_SIZE) {
    433                 MEM_MAP_RESERVE(VIRT_TO_PAGE(page_addr));
    434             }
    435         } else if (dseg->blk_ptr[i]) {
    436             dseg->blk_ptr[i] &= ~3;
    437             free_pages(dseg->blk_ptr[i], dseg->blk_order);
    438             dseg->blk_ptr[i] = 0;
    439         }
    440     }
    441     return dseg;
    442 }
    443 
    444 /*
    445  * Function: _dma_segment_free
    446  *
    447  * Purpose:
    448  *    Release resources used by DMA segment.
    449  * Parameters:
    450  *    dseg - DMA segment descriptor
    451  * Returns:
    452  *    Nothing.
    453  */
    454 static void
    455 _dma_segment_free(dma_segment_t *dseg)
    456 {
    457     int i;
    458     unsigned long page_addr;
    459 
    460     if (dseg->blk_ptr) {
    461         for (i = 0; i < dseg->blk_cnt; i++) {
    462             if (dseg->blk_ptr[i]) {
    463                 for (page_addr = dseg->blk_ptr[i];
    464                      page_addr < dseg->blk_ptr[i] + dseg->blk_size;
    465                      page_addr += PAGE_SIZE) {
    466                     MEM_MAP_UNRESERVE(VIRT_TO_PAGE(page_addr));
    467                 }
    468                 free_pages(dseg->blk_ptr[i], dseg->blk_order);
    469             }
    470         }
    471         kfree(dseg->blk_ptr);
    472         kfree(dseg);
    473     }
    474 }
    475 
    476 /*
    477  * Function: _pgalloc
    478  *
    479  * Purpose:
    480  *    Allocate DMA memory using page allocator
    481  * Parameters:
    482  *    size - number of bytes to allocate
    483  * Returns:
    484  *    Pointer to allocated DMA memory or NULL if failure.
    485  * Notes:
    486  *    For any sizes less than DMA_BLOCK_SIZE, we ask the page
    487  *    allocator for the entire memory block, otherwise we try
    488  *    to assemble a contiguous segment ourselves.
    489  */
    490 static void *
    491 _pgalloc(size_t size)
    492 {
    493     dma_segment_t *dseg;
    494     size_t blk_size;
    495 
    496     blk_size = (size < DMA_BLOCK_SIZE) ? size : DMA_BLOCK_SIZE;
    497     if ((dseg = _dma_segment_alloc(size, blk_size)) == NULL) {
    498         return NULL;
    499     }
    500     if (dseg->seg_size < size) {
    501         /* If we didn't get the full size then forget it */
    502         gprintk("_pgalloc() failed to get requested size %zu: "
    503                 "only got %lu contiguous across %d blocks\n",
    504                 size, dseg->seg_size, dseg->blk_cnt);
    505         _dma_segment_free(dseg);
    506         return NULL;
    507     }
    508     list_add(&dseg->list, &_dma_seg);
    509     return (void *)dseg->seg_begin;
    510 }
    511 
    512 /*
    513  * Function: _pgfree
    514  *
    515  * Purpose:
    516  *    Free memory allocated by _pgalloc
    517  * Parameters:
    518  *    ptr - pointer returned by _pgalloc
    519  * Returns:
    520  *    0 if succesfully freed, otherwise -1.
    521  */
    522 static int
    523 _pgfree(void *ptr)
    524 {
    525     struct list_head *pos;
    526     list_for_each(pos, &_dma_seg) {
    527         dma_segment_t *dseg = list_entry(pos, dma_segment_t, list);
    528         if (ptr == (void *)dseg->seg_begin) {
    529             list_del(&dseg->list);
    530             _dma_segment_free(dseg);
    531             return 0;
    532         }
    533     }
    534     return -1;
    535 }
    536 
    537 /*
    538  * Function: _pgcleanup
    539  *
    540  * Purpose:
    541  *    Free all memory allocated by _pgalloc
    542  * Parameters:
    543  *    None
    544  * Returns:
    545  *    Nothing.
    546  */
    547 static void
    548 _pgcleanup(void)
    549 {
    550     switch (dmaalloc) {
    551 #if _SIMPLE_MEMORY_ALLOCATION_
    552       case ALLOC_TYPE_API:
    553         if (_dma_vbase) {
    554             if (dma_debug >= 1) gprintk("freeing v=%p p=0x%lx size=0x%lx\n", _dma_vbase,(unsigned long) _dma_pbase, (unsigned long)_dma_mem_size);
    555             dma_free_coherent(DMA_DEV(DMA_DEV_INDEX), _dma_mem_size, _dma_vbase, _dma_pbase);
    556         }
    557         break;
    558 #endif /* _SIMPLE_MEMORY_ALLOCATION_ */
    559 
    560       case ALLOC_TYPE_CHUNK: {
    561         struct list_head *pos, *tmp;
    562         int i, ndevices;
    563         if (_use_dma_mapping) {
    564             ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES);
    565             for (i = 0; i < ndevices && DMA_DEV(i); i ++) {
    566                 dma_unmap_single(DMA_DEV(i), (dma_addr_t)_dma_pbase, _dma_mem_size, DMA_BIDIRECTIONAL);
    567             }
    568             _use_dma_mapping = 0;
    569         }
    570         list_for_each_safe(pos, tmp, &_dma_seg) {
    571             dma_segment_t *dseg = list_entry(pos, dma_segment_t, list);
    572             list_del(&dseg->list);
    573             _dma_segment_free(dseg);
    574         }
    575         break;
    576       }
    577 
    578       default:
    579         gprintk("DMA memory allocation method dmaalloc=%d is not supported\n", dmaalloc);
    580     }
    581 }
    582 
    583 /*
    584  * Function: _alloc_mpool
    585  *
    586  * Purpose:
    587  *    Allocate DMA memory pool
    588  * Parameters:
    589  *    size - size of DMA memory pool
    590  * Returns:
    591  *    Nothing.
    592  * Notes:
    593  *    If set up to use high memory, we simply map the memory into
    594  *    kernel space.
    595  *    It is assumed there is only one pool.
    596  */
    597 static void
    598 _alloc_mpool(size_t size)
    599 {
    600     unsigned long pbase = 0;
    601 #if defined(__arm__) && !defined(CONFIG_HIGHMEM)
    602     if (_use_himem) {
    603         gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n");
    604         return;
    605     }
    606 #endif
    607 
    608     if (_use_himem) {
    609         /* Use high memory for DMA */
    610         if (_himemaddr) {
    611             pbase = _himemaddr;
    612         } else {
    613             pbase = virt_to_bus(high_memory);
    614         }
    615         if (((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) {
    616             gprintk("DMA in high memory at 0x%lx size 0x%lx is beyond the 4GB limit and not supported.\n", pbase, (unsigned long)size);
    617             return;
    618         }
    619         _cpu_pbase = _dma_pbase = pbase;
    620         _dma_vbase = IOREMAP(_dma_pbase, size);
    621     } else {
    622         /* Get DMA memory from kernel */
    623         if (dma_debug >= 1) {
    624             gprintk("Allocating DMA memory using method dmaalloc=%d\n", dmaalloc);
    625         }
    626         switch (dmaalloc) {
    627 #if _SIMPLE_MEMORY_ALLOCATION_
    628           case ALLOC_TYPE_API: {
    629             size_t alloc_size = size; /* size of memory allocated in current iteration */
    630             if (alloc_size > DMA_MAX_ALLOC_SIZE) {
    631                 alloc_size = DMA_MAX_ALLOC_SIZE;
    632             }
    633             /* get a memory allocation from the kernel */
    634             {
    635                 dma_addr_t dma_handle;
    636                 if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(DMA_DEV_INDEX),
    637                         alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) {
    638                     gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size);
    639                     return;
    640                 }
    641                 _cpu_pbase = pbase = dma_handle;
    642             }
    643 
    644             if (alloc_size != size) {
    645                 gprintk("allocated 0x%lx bytes instead of 0x%lx bytes.\n",
    646                         (unsigned long)alloc_size, (unsigned long)size);
    647             }
    648             size = _dma_mem_size = alloc_size;
    649             break;
    650           }
    651 #endif /* _SIMPLE_MEMORY_ALLOCATION_ */
    652 
    653           case ALLOC_TYPE_CHUNK:
    654             _dma_vbase = _pgalloc(size);
    655             if (!_dma_vbase) {
    656                 gprintk("Failed to allocate memory pool of size 0x%lx\n", (unsigned long)size);
    657                 return;
    658             }
    659             _cpu_pbase = virt_to_bus(_dma_vbase);
    660             /* Use dma_map_single to obtain DMA bus address or IOVA if iommu is present. */
    661             if (DMA_DEV(DMA_DEV_INDEX)) {
    662                 pbase = dma_map_single(DMA_DEV(DMA_DEV_INDEX), _dma_vbase, size, DMA_BIDIRECTIONAL);
    663                 if (DMA_MAPPING_ERROR(DMA_DEV(DMA_DEV_INDEX), pbase)) {
    664                     gprintk("Failed to map memory at %p\n", _dma_vbase);
    665                     _pgcleanup();
    666                     _dma_vbase = NULL;
    667                     return;
    668                 }
    669                 _use_dma_mapping = 1;
    670             } else {
    671                 pbase = _cpu_pbase;
    672             }
    673             break;
    674           default:
    675             _dma_vbase = NULL;
    676             gprintk("DMA memory allocation method dmaalloc=%d is not supported\n", dmaalloc);
    677             return;
    678         }
    679 
    680         if (((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) {
    681             gprintk("DMA memory allocated at 0x%lx size 0x%lx is beyond the 4GB limit and not supported.\n", pbase, (unsigned long)size);
    682             _pgcleanup();
    683             _dma_vbase = NULL;
    684             _dma_pbase = 0;
    685             return;
    686         }
    687 
    688         _dma_pbase = pbase;
    689 #ifdef REMAP_DMA_NONCACHED
    690         _dma_vbase = IOREMAP(_dma_pbase, size);
    691 #endif
    692         if (dma_debug >= 1) {
    693             gprintk("_use_dma_mapping:%d _dma_vbase:%p _dma_pbase:%lx _cpu_pbase:%lx allocated:%lx dmaalloc:%d\n",
    694                      _use_dma_mapping, _dma_vbase, (unsigned long)_dma_pbase,
    695                      (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc);
    696         }
    697     }
    698 }
    699 
    700 /*
    701  * Function: _dma_cleanup
    702  *
    703  * Purpose:
    704  *    DMA cleanup function.
    705  * Parameters:
    706  *    None
    707  * Returns:
    708  *    Always 0
    709  */
    710 int
    711 _dma_cleanup(void)
    712 {
    713     if (_dma_vbase) {
    714         mpool_destroy(_dma_pool);
    715         if (_use_himem) {
    716             iounmap(_dma_vbase);
    717         } else {
    718 #ifdef REMAP_DMA_NONCACHED
    719             iounmap(_dma_vbase);
    720 #endif
    721             _pgcleanup();
    722         }
    723         _dma_vbase = NULL;
    724         _dma_pbase = 0;
    725         _cpu_pbase = 0;
    726     }
    727     return 0;
    728 }
    729 
    730 void _dma_init(int dev_index)
    731 {
    732     unsigned long pbase;
    733 
    734     if (dev_index > DMA_DEV_INDEX) {
    735         if (_use_dma_mapping && DMA_DEV(dev_index) && _dma_vbase) {
    736             pbase = dma_map_single(DMA_DEV(dev_index), _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL);
    737             if (DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) {
    738                 gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase);
    739                 return;
    740             }
    741             if (pbase != (unsigned long)_dma_pbase) {
    742                 /* Bus address/IOVA must be identical for all devices. */
    743                 gprintk("Device %d has different pbase: %lx (should be %lx)\n",
    744                         dev_index, pbase, (unsigned long)_dma_pbase);
    745             }
    746         }
    747         return;
    748     }
    749 
    750     /* DMA Setup */
    751     if (dmasize) {
    752         if ((dmasize[strlen(dmasize)-1] & ~0x20) == 'M') {
    753             _dma_mem_size = simple_strtoul(dmasize, NULL, 0);
    754             _dma_mem_size *= ONE_MB;
    755         } else {
    756             gprintk("DMA memory size must be specified as e.g. dmasize=8M\n");
    757         }
    758         if (_dma_mem_size & (_dma_mem_size-1)) {
    759             gprintk("dmasize must be a power of 2 (1M, 2M, 4M, 8M etc.)\n");
    760             _dma_mem_size = 0;
    761         }
    762     }
    763 
    764     if (himem) {
    765         if ((himem[0] & ~0x20) == 'Y' || himem[0] == '1') {
    766             _use_himem = 1;
    767         } else if ((himem[0] & ~0x20) == 'N' || himem[0] == '0') {
    768             _use_himem = 0;
    769         }
    770     }
    771 
    772     if (himemaddr && strlen(himemaddr) > 0) {
    773         char suffix = (himemaddr[strlen(himemaddr)-1] & ~0x20);
    774         _himemaddr = simple_strtoul(himemaddr, NULL, 0);
    775         if (suffix == 'M') {
    776             _himemaddr *= ONE_MB;
    777         } else if (suffix == 'G') {
    778             _himemaddr *= ONE_GB;
    779         } else {
    780             gprintk("DMA high memory address must be specified as e.g. himemaddr=8[MG]\n");
    781         }
    782     }
    783 
    784     if (_dma_mem_size) {
    785         _alloc_mpool(_dma_mem_size);
    786         if (_dma_vbase == NULL) {
    787             gprintk("no DMA memory available\n");
    788         } else {
    789             mpool_init();
    790             _dma_pool = mpool_create(_dma_vbase, _dma_mem_size);
    791         }
    792     }
    793 }
    794 
    795 /*
    796  * Some kernels are configured to prevent mapping of kernel RAM memory
    797  * into user space via the /dev/mem device.
    798  *
    799  * The function below provides a backdoor to mapping the DMA pool to
    800  * user space via the BDE device file.
    801  */
    802 int _dma_mmap(struct file *filp, struct vm_area_struct *vma)
    803 {
    804     unsigned long phys_addr = vma->vm_pgoff << PAGE_SHIFT;
    805     unsigned long size = vma->vm_end - vma->vm_start;
    806 
    807     if (phys_addr < (unsigned long )_cpu_pbase ||
    808         (phys_addr + size) > ((unsigned long )_cpu_pbase + _dma_mem_size)) {
    809         gprintk("range 0x%lx-0x%lx outside DMA pool 0x%lx-0x%lx\n",
    810                 phys_addr, phys_addr + size, (unsigned long )_cpu_pbase,
    811                 (unsigned long )_cpu_pbase + _dma_mem_size);
    812         return -EINVAL;
    813     }
    814 
    815 #ifdef USE_DMA_MMAP_COHERENT
    816     if (dmaalloc == ALLOC_TYPE_API) {
    817         vma->vm_pgoff = 0;
    818         return dma_mmap_coherent(DMA_DEV(DMA_DEV_INDEX), vma, (void *)_dma_vbase, phys_addr, size);
    819     }
    820 #endif
    821 
    822     _PGPROT_NONCACHED(vma->vm_page_prot);
    823 
    824     if (remap_pfn_range(vma,
    825                         vma->vm_start,
    826                         vma->vm_pgoff,
    827                         size,
    828                         vma->vm_page_prot)) {
    829         gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n",
    830                 phys_addr, phys_addr + size, vma->vm_start,vma->vm_end);
    831         return -EAGAIN;
    832     }
    833     return 0;
    834 }
    835 
    836 /*
    837  * Function: _dma_pool_allocated
    838  *
    839  * Purpose:
    840  *    Check if DMA pool has been allocated.
    841  * Parameters:
    842  *    None
    843  * Returns:
    844  *    0 : not allocated
    845  *    1 : allocated
    846  */
    847 int
    848 _dma_pool_allocated(void)
    849 {
    850     return (_dma_vbase) ? 1 : 0;
    851 }
    852 
    853 sal_paddr_t
    854 _l2p(int d, void *vaddr)
    855 {
    856     if (_dma_mem_size) {
    857         /* dma memory is a contiguous block */
    858         if (vaddr) {
    859             return _dma_pbase + (PTR_TO_UINTPTR(vaddr) - PTR_TO_UINTPTR(_dma_vbase));
    860         }
    861         return 0;
    862     }
    863     return ((sal_paddr_t)virt_to_bus(vaddr));
    864 }
    865 
    866 void *
    867 _p2l(int d, sal_paddr_t paddr)
    868 {
    869     sal_vaddr_t vaddr = (sal_vaddr_t)_dma_vbase;
    870 
    871     if (_dma_mem_size) {
    872         /* DMA memory is a contiguous block */
    873         if (paddr == 0) {
    874             return NULL;
    875         }
    876         return (void *)(vaddr + (sal_vaddr_t)(paddr - _dma_pbase));
    877     }
    878     return bus_to_virt(paddr);
    879 }
    880 
    881 /*
    882  * Some of the driver malloc's are too large for
    883  * kmalloc(), so 'sal_alloc' and 'sal_free' in the
    884  * linux kernel sal cannot be implemented with kmalloc().
    885  *
    886  * Instead, they expect someone to provide an allocator
    887  * that can handle the gimongous size of some of the
    888  * allocations, and we provide it here, by allocating
    889  * this memory out of the boot-time dma pool.
    890  *
    891  * These are the functions in question:
    892  */
    893 
    894 void* kmalloc_giant(int sz)
    895 {
    896     return mpool_alloc(_dma_pool, sz);
    897 }
    898 
    899 void kfree_giant(void* ptr)
    900 {
    901     return mpool_free(_dma_pool, ptr);
    902 }
    903 
    904 uint32_t *
    905 _salloc(int d, int size, const char *name)
    906 {
    907     void *ptr;
    908 
    909     if (_dma_mem_size) {
    910         return mpool_alloc(_dma_pool, size);
    911     }
    912     if ((ptr = kmalloc(size, mem_flags)) == NULL) {
    913         ptr = _pgalloc(size);
    914     }
    915     return ptr;
    916 }
    917 
    918 void
    919 _sfree(int d, void *ptr)
    920 {
    921     if (_dma_mem_size) {
    922         return mpool_free(_dma_pool, ptr);
    923     }
    924     if (_pgfree(ptr) < 0) {
    925         kfree(ptr);
    926     }
    927 }
    928 
    929 int
    930 _sinval(int d, void *ptr, int length)
    931 {
    932 #if defined(dma_cache_wback_inv)
    933      dma_cache_wback_inv((unsigned long)ptr, length);
    934 #else
    935 #if defined(IPROC_CMICD) || defined(BCM958525)
    936     
    937     dma_sync_single_for_cpu(NULL, (unsigned long)ptr, length, DMA_BIDIRECTIONAL);
    938 #else
    939     dma_cache_sync(NULL, ptr, length, DMA_BIDIRECTIONAL);
    940 #endif
    941 #endif
    942     return 0;
    943 }
    944 
    945 int
    946 _sflush(int d, void *ptr, int length)
    947 {
    948 #if defined(dma_cache_wback_inv)
    949     dma_cache_wback_inv((unsigned long)ptr, length);
    950 #else
    951 #if defined(IPROC_CMICD) || defined(BCM958525)
    952     
    953     dma_sync_single_for_cpu(NULL, (unsigned long)ptr, length, DMA_BIDIRECTIONAL);
    954 #else
    955     dma_cache_sync(NULL, ptr, length, DMA_BIDIRECTIONAL);
    956 #endif
    957 #endif
    958 
    959     return 0;
    960 }
    961 
    962 int
    963 lkbde_get_dma_info(phys_addr_t* cpu_pbase, phys_addr_t* dma_pbase, ssize_t* size)
    964 {
    965     if (_dma_vbase == NULL) {
    966         if (_dma_mem_size == 0) {
    967             _dma_mem_size = DMA_MEM_DEFAULT;
    968         }
    969         _alloc_mpool(_dma_mem_size);
    970     }
    971     *cpu_pbase = _cpu_pbase;
    972     *dma_pbase = _dma_pbase;
    973     *size = (_dma_vbase) ? _dma_mem_size : 0;
    974     return 0;
    975 }
    976 
    977 void
    978 _dma_pprint(void)
    979 {
    980     pprintf("DMA Memory (%s): %d bytes, %d used, %d free%s\n",
    981             (_use_himem) ? "high" : "kernel",
    982             (_dma_vbase) ? _dma_mem_size : 0,
    983             (_dma_vbase) ? mpool_usage(_dma_pool) : 0,
    984             (_dma_vbase) ? _dma_mem_size - mpool_usage(_dma_pool) : 0,
    985             USE_LINUX_BDE_MMAP ? ", local mmap" : "");
    986 }
    987 
    988 /*
    989  * Export functions
    990  */
    991 LKM_EXPORT_SYM(kmalloc_giant);
    992 LKM_EXPORT_SYM(kfree_giant);
    993 LKM_EXPORT_SYM(lkbde_get_dma_info);