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/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 /* $FreeBSD$ */
   40 
   41 #include "oce_if.h"
   42 
   43 static void oce_dma_map_ring(void *arg,
   44                              bus_dma_segment_t *segs,
   45                              int nseg,
   46                              int error);
   47 
   48 /**
   49  * @brief               Allocate DMA memory
   50  * @param sc            software handle to the device
   51  * @param size          bus size
   52  * @param dma           dma memory area
   53  * @param flags         creation flags
   54  * @returns             0 on success, error otherwize
   55  */
   56 int
   57 oce_dma_alloc(POCE_SOFTC sc, bus_size_t size, POCE_DMA_MEM dma, int flags)
   58 {
   59         int rc;
   60 
   61 
   62         memset(dma, 0, sizeof(OCE_DMA_MEM));
   63 
   64         rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev),
   65                                 8, 0,
   66                                 BUS_SPACE_MAXADDR,
   67                                 BUS_SPACE_MAXADDR,
   68                                 NULL, NULL,
   69                                 size, 1, size, 0, NULL, NULL, &dma->tag);
   70 
   71         if (rc == 0) {
   72                 rc = bus_dmamem_alloc(dma->tag,
   73                                       &dma->ptr,
   74                                       BUS_DMA_NOWAIT | BUS_DMA_COHERENT |
   75                                         BUS_DMA_ZERO,
   76                                       &dma->map);
   77         }
   78 
   79         dma->paddr = 0;
   80         if (rc == 0) {
   81                 rc = bus_dmamap_load(dma->tag,
   82                                      dma->map,
   83                                      dma->ptr,
   84                                      size,
   85                                      oce_dma_map_addr,
   86                                      &dma->paddr, flags | BUS_DMA_NOWAIT);
   87                 if (dma->paddr == 0)
   88                         rc = ENXIO;
   89         }
   90 
   91         if (rc != 0)
   92                 oce_dma_free(sc, dma);
   93 
   94         return rc;
   95 }
   96 
   97 /**
   98  * @brief               Free DMA memory
   99  * @param sc            software handle to the device
  100  * @param dma           dma area to free
  101  */
  102 void
  103 oce_dma_free(POCE_SOFTC sc, POCE_DMA_MEM dma)
  104 {
  105         if (dma->tag == NULL)
  106                 return;
  107 
  108         if (dma->map != NULL) {
  109                 bus_dmamap_sync(dma->tag, dma->map,
  110                                 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  111                 bus_dmamap_unload(dma->tag, dma->map);
  112         }
  113 
  114         if (dma->ptr != NULL) {
  115                 bus_dmamem_free(dma->tag, dma->ptr, dma->map);
  116                 dma->map = NULL;
  117                 dma->ptr = NULL;
  118         }
  119 
  120         bus_dma_tag_destroy(dma->tag);
  121         dma->tag = NULL;
  122         
  123         return;
  124 }
  125 
  126 
  127 
  128 /**
  129  * @brief               Map DMA memory segment addresses
  130  * @param arg           physical address pointer
  131  * @param segs          dma memory segments
  132  * @param nseg          number of dma memory segments
  133  * @param error         if error, zeroes the physical address
  134  */
  135 void
  136 oce_dma_map_addr(void *arg, bus_dma_segment_t * segs, int nseg, int error)
  137 {
  138         bus_addr_t *paddr = arg;
  139 
  140         if (error)
  141                 *paddr = 0;
  142         else
  143                 *paddr = segs->ds_addr;
  144 }
  145 
  146 
  147 
  148 /**
  149  * @brief               Destroy a ring buffer
  150  * @param sc            software handle to the device
  151  * @param ring          ring buffer
  152  */
  153 
  154 void
  155 oce_destroy_ring_buffer(POCE_SOFTC sc, oce_ring_buffer_t *ring)
  156 {
  157         oce_dma_free(sc, &ring->dma);
  158         free(ring, M_DEVBUF);
  159 }
  160 
  161 
  162 
  163 oce_ring_buffer_t *
  164 oce_create_ring_buffer(POCE_SOFTC sc,
  165                 uint32_t q_len, uint32_t item_size)
  166 {
  167         uint32_t size = q_len * item_size;
  168         int rc;
  169         oce_ring_buffer_t *ring;
  170 
  171 
  172         ring = malloc(sizeof(oce_ring_buffer_t), M_DEVBUF, M_NOWAIT | M_ZERO);
  173         if (ring == NULL) 
  174                 return NULL;
  175 
  176         ring->item_size = item_size;
  177         ring->num_items = q_len;
  178 
  179         rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev),
  180                                 4096, 0,
  181                                 BUS_SPACE_MAXADDR,
  182                                 BUS_SPACE_MAXADDR,
  183                                 NULL, NULL,
  184                                 size, 8, 4096, 0, NULL, NULL, &ring->dma.tag);
  185         if (rc)
  186                 goto fail;
  187 
  188 
  189         rc = bus_dmamem_alloc(ring->dma.tag,
  190                                 &ring->dma.ptr,
  191                                 BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
  192                                 &ring->dma.map);
  193         if (rc)
  194                 goto fail;
  195 
  196         bzero(ring->dma.ptr, size);
  197         bus_dmamap_sync(ring->dma.tag, ring->dma.map,
  198                         BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  199         ring->dma.paddr = 0;
  200         
  201         return ring;
  202         
  203 fail:
  204         oce_dma_free(sc, &ring->dma);
  205         free(ring, M_DEVBUF);
  206         ring = NULL;
  207         return NULL;
  208 }
  209 
  210 
  211 
  212 struct _oce_dmamap_paddr_table {
  213         uint32_t max_entries;
  214         uint32_t num_entries;
  215         struct phys_addr *paddrs;
  216 };
  217 
  218 
  219 
  220 /**
  221  * @brief               Map ring buffer
  222  * @param arg           dma map phyical address table pointer
  223  * @param segs          dma memory segments
  224  * @param nseg          number of dma memory segments
  225  * @param error         maps only if error is 0
  226  */
  227 static void
  228 oce_dma_map_ring(void *arg, bus_dma_segment_t * segs, int nseg, int error)
  229 {
  230         int i;
  231         struct _oce_dmamap_paddr_table *dpt =
  232             (struct _oce_dmamap_paddr_table *)arg;
  233 
  234         if (error == 0) {
  235                 if (nseg <= dpt->max_entries) {
  236                         for (i = 0; i < nseg; i++) {
  237                                 dpt->paddrs[i].lo = ADDR_LO(segs[i].ds_addr);
  238                                 dpt->paddrs[i].hi = ADDR_HI(segs[i].ds_addr);
  239                         }
  240                         dpt->num_entries = nseg;
  241                 }
  242         }
  243 }
  244 
  245 
  246 
  247 /**
  248  * @brief               Load bus dma map for a ring buffer
  249  * @param ring          ring buffer pointer
  250  * @param pa_list       physical address list
  251  * @returns             number entries
  252  */
  253 uint32_t
  254 oce_page_list(oce_ring_buffer_t *ring, struct phys_addr *pa_list)
  255 {
  256         struct _oce_dmamap_paddr_table dpt;
  257 
  258         dpt.max_entries = 8;
  259         dpt.num_entries = 0;
  260         dpt.paddrs = pa_list;
  261 
  262         bus_dmamap_load(ring->dma.tag,
  263                         ring->dma.map,
  264                         ring->dma.ptr,
  265                         ring->item_size * ring->num_items,
  266                         oce_dma_map_ring, &dpt, BUS_DMA_NOWAIT);
  267 
  268         return dpt.num_entries;
  269 }

Cache object: 3f4385f38b21b6c3ac6050d2c6692f6b


[ 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.