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/drm/drm_pci.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 2003 Eric Anholt.
    3  * All Rights Reserved.
    4  *
    5  * Permission is hereby granted, free of charge, to any person obtaining a
    6  * copy of this software and associated documentation files (the "Software"),
    7  * to deal in the Software without restriction, including without limitation
    8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    9  * and/or sell copies of the Software, and to permit persons to whom the
   10  * Software is furnished to do so, subject to the following conditions:
   11  *
   12  * The above copyright notice and this permission notice (including the next
   13  * paragraph) shall be included in all copies or substantial portions of the
   14  * Software.
   15  *
   16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
   19  * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
   21  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   22  */
   23 
   24 #include <sys/cdefs.h>
   25 __FBSDID("$FreeBSD$");
   26 
   27 /**
   28  * \file drm_pci.h
   29  * \brief PCI consistent, DMA-accessible memory allocation.
   30  *
   31  * \author Eric Anholt <anholt@FreeBSD.org>
   32  */
   33 
   34 #include "dev/drm/drmP.h"
   35 
   36 /**********************************************************************/
   37 /** \name PCI memory */
   38 /*@{*/
   39 
   40 static void
   41 drm_pci_busdma_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
   42 {
   43         drm_dma_handle_t *dmah = arg;
   44 
   45         if (error != 0)
   46                 return;
   47 
   48         KASSERT(nsegs == 1, ("drm_pci_busdma_callback: bad dma segment count"));
   49         dmah->busaddr = segs[0].ds_addr;
   50 }
   51 
   52 /**
   53  * \brief Allocate a physically contiguous DMA-accessible consistent 
   54  * memory block.
   55  */
   56 drm_dma_handle_t *
   57 drm_pci_alloc(struct drm_device *dev, size_t size,
   58               size_t align, dma_addr_t maxaddr)
   59 {
   60         drm_dma_handle_t *dmah;
   61         int ret;
   62 
   63         /* Need power-of-two alignment, so fail the allocation if it isn't. */
   64         if ((align & (align - 1)) != 0) {
   65                 DRM_ERROR("drm_pci_alloc with non-power-of-two alignment %d\n",
   66                     (int)align);
   67                 return NULL;
   68         }
   69 
   70         dmah = malloc(sizeof(drm_dma_handle_t), DRM_MEM_DMA, M_ZERO | M_NOWAIT);
   71         if (dmah == NULL)
   72                 return NULL;
   73 
   74         /* Make sure we aren't holding locks here */
   75         mtx_assert(&dev->dev_lock, MA_NOTOWNED);
   76         if (mtx_owned(&dev->dev_lock))
   77             DRM_ERROR("called while holding dev_lock\n");
   78         mtx_assert(&dev->dma_lock, MA_NOTOWNED);
   79         if (mtx_owned(&dev->dma_lock))
   80             DRM_ERROR("called while holding dma_lock\n");
   81 
   82         ret = bus_dma_tag_create(NULL, align, 0, /* tag, align, boundary */
   83             maxaddr, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */
   84             NULL, NULL, /* filtfunc, filtfuncargs */
   85             size, 1, size, /* maxsize, nsegs, maxsegsize */
   86             0, NULL, NULL, /* flags, lockfunc, lockfuncargs */
   87             &dmah->tag);
   88         if (ret != 0) {
   89                 free(dmah, DRM_MEM_DMA);
   90                 return NULL;
   91         }
   92 
   93         ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr,
   94             BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE, &dmah->map);
   95         if (ret != 0) {
   96                 bus_dma_tag_destroy(dmah->tag);
   97                 free(dmah, DRM_MEM_DMA);
   98                 return NULL;
   99         }
  100 
  101         ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, size,
  102             drm_pci_busdma_callback, dmah, BUS_DMA_NOWAIT);
  103         if (ret != 0) {
  104                 bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map);
  105                 bus_dma_tag_destroy(dmah->tag);
  106                 free(dmah, DRM_MEM_DMA);
  107                 return NULL;
  108         }
  109 
  110         return dmah;
  111 }
  112 
  113 /**
  114  * \brief Free a DMA-accessible consistent memory block.
  115  */
  116 void
  117 drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah)
  118 {
  119         if (dmah == NULL)
  120                 return;
  121 
  122         bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map);
  123         bus_dma_tag_destroy(dmah->tag);
  124 
  125         free(dmah, DRM_MEM_DMA);
  126 }
  127 
  128 /*@}*/

Cache object: 180b6fc9a9f5ab5fe30ad990d2c5ca8d


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