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 (30972B)


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