The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/netif/oce/oce_util.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (C) 2013 Emulex
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions are met:
    7  *
    8  * 1. Redistributions of source code must retain the above copyright notice,
    9  *    this list of conditions and the following disclaimer.
   10  *
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * 3. Neither the name of the Emulex Corporation nor the names of its
   16  *    contributors may be used to endorse or promote products derived from
   17  *    this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  *
   31  * Contact Information:
   32  * freebsd-drivers@emulex.com
   33  *
   34  * Emulex
   35  * 3333 Susan Street
   36  * Costa Mesa, CA 92626
   37  */
   38 
   39 
   40 /* $FreeBSD: src/sys/dev/oce/oce_util.c,v 1.5 2013/07/07 00:30:13 svnexp Exp $ */
   41 
   42 
   43 #include "oce_if.h"
   44 
   45 static void oce_dma_map_ring(void *arg,
   46                              bus_dma_segment_t *segs,
   47                              int nseg,
   48                              int error);
   49 
   50 /**
   51  * @brief               Allocate DMA memory
   52  * @param sc            software handle to the device
   53  * @param size          bus size
   54  * @param dma           dma memory area
   55  * @param flags         creation flags
   56  * @returns             0 on success, error otherwize
   57  */
   58 int
   59 oce_dma_alloc(POCE_SOFTC sc, bus_size_t size, POCE_DMA_MEM dma, int flags)
   60 {
   61         int rc;
   62 
   63 
   64         memset(dma, 0, sizeof(OCE_DMA_MEM));
   65 
   66         rc = bus_dma_tag_create(NULL,
   67                                 8, 0,
   68                                 BUS_SPACE_MAXADDR,
   69                                 BUS_SPACE_MAXADDR,
   70                                 NULL, NULL,
   71                                 size, 1, size, 0, &dma->tag);
   72 
   73         if (rc == 0) {
   74                 rc = bus_dmamem_alloc(dma->tag,
   75                                       &dma->ptr,
   76                                       BUS_DMA_NOWAIT | BUS_DMA_COHERENT |
   77                                         BUS_DMA_ZERO,
   78                                       &dma->map);
   79         }
   80 
   81         dma->paddr = 0;
   82         if (rc == 0) {
   83                 rc = bus_dmamap_load(dma->tag,
   84                                      dma->map,
   85                                      dma->ptr,
   86                                      size,
   87                                      oce_dma_map_addr,
   88                                      &dma->paddr, flags | BUS_DMA_NOWAIT);
   89                 if (dma->paddr == 0)
   90                         rc = ENXIO;
   91         }
   92 
   93         if (rc != 0)
   94                 oce_dma_free(sc, dma);
   95 
   96         return rc;
   97 }
   98 
   99 /**
  100  * @brief               Free DMA memory
  101  * @param sc            software handle to the device
  102  * @param dma           dma area to free
  103  */
  104 void
  105 oce_dma_free(POCE_SOFTC sc, POCE_DMA_MEM dma)
  106 {
  107         if (dma->tag == NULL)
  108                 return;
  109 
  110         if (dma->map != NULL) {
  111                 bus_dmamap_sync(dma->tag, dma->map,
  112                                 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  113                 bus_dmamap_unload(dma->tag, dma->map);
  114         }
  115 
  116         if (dma->ptr != NULL) {
  117                 bus_dmamem_free(dma->tag, dma->ptr, dma->map);
  118                 dma->map = NULL;
  119                 dma->ptr = NULL;
  120         }
  121 
  122         bus_dma_tag_destroy(dma->tag);
  123         dma->tag = NULL;
  124 
  125         return;
  126 }
  127 
  128 
  129 
  130 /**
  131  * @brief               Map DMA memory segment addresses
  132  * @param arg           physical address pointer
  133  * @param segs          dma memory segments
  134  * @param nseg          number of dma memory segments
  135  * @param error         if error, zeroes the physical address
  136  */
  137 void
  138 oce_dma_map_addr(void *arg, bus_dma_segment_t * segs, int nseg, int error)
  139 {
  140         bus_addr_t *paddr = arg;
  141 
  142         if (error)
  143                 *paddr = 0;
  144         else
  145                 *paddr = segs->ds_addr;
  146 }
  147 
  148 
  149 
  150 /**
  151  * @brief               Destroy a ring buffer
  152  * @param sc            software handle to the device
  153  * @param ring          ring buffer
  154  */
  155 
  156 void
  157 oce_destroy_ring_buffer(POCE_SOFTC sc, oce_ring_buffer_t *ring)
  158 {
  159         oce_dma_free(sc, &ring->dma);
  160         kfree(ring, M_DEVBUF);
  161 }
  162 
  163 
  164 
  165 oce_ring_buffer_t *
  166 oce_create_ring_buffer(POCE_SOFTC sc,
  167                 uint32_t q_len, uint32_t item_size)
  168 {
  169         uint32_t size = q_len * item_size;
  170         int rc;
  171         oce_ring_buffer_t *ring;
  172 
  173 
  174         ring = kmalloc(sizeof(oce_ring_buffer_t), M_DEVBUF, M_NOWAIT | M_ZERO);
  175         if (ring == NULL)
  176                 return NULL;
  177 
  178         ring->item_size = item_size;
  179         ring->num_items = q_len;
  180 
  181         rc = bus_dma_tag_create(NULL,
  182                                 4096, 0,
  183                                 BUS_SPACE_MAXADDR,
  184                                 BUS_SPACE_MAXADDR,
  185                                 NULL, NULL,
  186                                 size, 8, 4096, 0, &ring->dma.tag);
  187         if (rc)
  188                 goto fail;
  189 
  190 
  191         rc = bus_dmamem_alloc(ring->dma.tag,
  192                                 &ring->dma.ptr,
  193                                 BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
  194                                 &ring->dma.map);
  195         if (rc)
  196                 goto fail;
  197 
  198         bzero(ring->dma.ptr, size);
  199         bus_dmamap_sync(ring->dma.tag, ring->dma.map,
  200                         BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  201         ring->dma.paddr = 0;
  202 
  203         return ring;
  204 
  205 fail:
  206         oce_dma_free(sc, &ring->dma);
  207         kfree(ring, M_DEVBUF);
  208         ring = NULL;
  209         return NULL;
  210 }
  211 
  212 
  213 
  214 struct _oce_dmamap_paddr_table {
  215         uint32_t max_entries;
  216         uint32_t num_entries;
  217         struct phys_addr *paddrs;
  218 };
  219 
  220 
  221 
  222 /**
  223  * @brief               Map ring buffer
  224  * @param arg           dma map phyical address table pointer
  225  * @param segs          dma memory segments
  226  * @param nseg          number of dma memory segments
  227  * @param error         maps only if error is 0
  228  */
  229 static void
  230 oce_dma_map_ring(void *arg, bus_dma_segment_t * segs, int nseg, int error)
  231 {
  232         int i;
  233         struct _oce_dmamap_paddr_table *dpt =
  234             (struct _oce_dmamap_paddr_table *)arg;
  235 
  236         if (error == 0) {
  237                 if (nseg <= dpt->max_entries) {
  238                         for (i = 0; i < nseg; i++) {
  239                                 dpt->paddrs[i].lo = ADDR_LO(segs[i].ds_addr);
  240                                 dpt->paddrs[i].hi = ADDR_HI(segs[i].ds_addr);
  241                         }
  242                         dpt->num_entries = nseg;
  243                 }
  244         }
  245 }
  246 
  247 
  248 
  249 /**
  250  * @brief               Load bus dma map for a ring buffer
  251  * @param ring          ring buffer pointer
  252  * @param pa_list       physical address list
  253  * @returns             number entries
  254  */
  255 uint32_t
  256 oce_page_list(oce_ring_buffer_t *ring, struct phys_addr *pa_list)
  257 {
  258         struct _oce_dmamap_paddr_table dpt;
  259 
  260         dpt.max_entries = 8;
  261         dpt.num_entries = 0;
  262         dpt.paddrs = pa_list;
  263 
  264         bus_dmamap_load(ring->dma.tag,
  265                         ring->dma.map,
  266                         ring->dma.ptr,
  267                         ring->item_size * ring->num_items,
  268                         oce_dma_map_ring, &dpt, BUS_DMA_NOWAIT);
  269 
  270         return dpt.num_entries;
  271 }

Cache object: ccd4d27ca50588ab1592f64e5e52f530


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.