2 * Copyright 2003 Eric Anholt.
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:
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
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.
26 * \brief PCI consistent, DMA-accessible memory allocation.
28 * \author Eric Anholt <anholt@FreeBSD.org>
31 #include "dev/drm/drmP.h"
33 /**********************************************************************/
34 /** \name PCI memory */
38 drm_pci_busdma_callback(void *arg
, bus_dma_segment_t
*segs
, int nsegs
, int error
)
40 drm_dma_handle_t
*dmah
= arg
;
45 KASSERT(nsegs
== 1, ("drm_pci_busdma_callback: bad dma segment count"));
46 dmah
->busaddr
= segs
[0].ds_addr
;
50 * \brief Allocate a physically contiguous DMA-accessible consistent
54 drm_pci_alloc(struct drm_device
*dev
, size_t size
,
55 size_t align
, dma_addr_t maxaddr
)
57 drm_dma_handle_t
*dmah
;
60 /* Need power-of-two alignment, so fail the allocation if it isn't. */
61 if ((align
& (align
- 1)) != 0) {
62 DRM_ERROR("drm_pci_alloc with non-power-of-two alignment %d\n",
67 dmah
= malloc(sizeof(drm_dma_handle_t
), DRM_MEM_DMA
, M_ZERO
| M_NOWAIT
);
71 #if 0 /* HT XXX XXX XXX */
72 /* Make sure we aren't holding locks here */
73 mtx_assert(&dev
->dev_lock
, MA_NOTOWNED
);
74 if (mtx_owned(&dev
->dev_lock
))
75 DRM_ERROR("called while holding dev_lock\n");
76 mtx_assert(&dev
->dma_lock
, MA_NOTOWNED
);
77 if (mtx_owned(&dev
->dma_lock
))
78 DRM_ERROR("called while holding dma_lock\n");
81 ret
= bus_dma_tag_create(NULL
, align
, 0, /* tag, align, boundary */
82 maxaddr
, BUS_SPACE_MAXADDR
, /* lowaddr, highaddr */
83 NULL
, NULL
, /* filtfunc, filtfuncargs */
84 size
, 1, size
, /* maxsize, nsegs, maxsegsize */
88 free(dmah
, DRM_MEM_DMA
);
92 /* XXX BUS_DMA_NOCACHE */
93 ret
= bus_dmamem_alloc(dmah
->tag
, &dmah
->vaddr
,
94 BUS_DMA_WAITOK
| BUS_DMA_ZERO
, &dmah
->map
);
96 bus_dma_tag_destroy(dmah
->tag
);
97 free(dmah
, DRM_MEM_DMA
);
101 ret
= bus_dmamap_load(dmah
->tag
, dmah
->map
, dmah
->vaddr
, size
,
102 drm_pci_busdma_callback
, dmah
, BUS_DMA_NOWAIT
);
104 bus_dmamem_free(dmah
->tag
, dmah
->vaddr
, dmah
->map
);
105 bus_dma_tag_destroy(dmah
->tag
);
106 free(dmah
, DRM_MEM_DMA
);
114 * \brief Free a DMA-accessible consistent memory block.
117 drm_pci_free(struct drm_device
*dev
, drm_dma_handle_t
*dmah
)
122 bus_dmamem_free(dmah
->tag
, dmah
->vaddr
, dmah
->map
);
123 bus_dma_tag_destroy(dmah
->tag
);
125 free(dmah
, DRM_MEM_DMA
);