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

Cache object: 94d3993b9da88f665cc519b01657c92b


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