A few steps down the yellow brick road toward bus_dma-ification:
- Add drm_dmamem_alloc/drm_dmamem_free to drm_memory.c to nicely wrap up the bus_dma API. - Start using the above in drm_pci.c. - Add DRM_NETBSD_DMA_ADDR/DRM_NETBSD_DMA_VADDR macros. Locking: - Use IPL_NONE for all locks except the IRQ lock, which runs at IPL_VM. - Use IPL_VM instead of IPL_TTY with pci_intr_establish() for consistency's sake. These two changes seem to eliminate the presistent lockups I was having (NetBSD-current/amd64 r300). - Start getting rid of DRM_SPININIT/DRM_SPINUNINIT and DRM_SPINLOCK/ DRM_SPINUNLOCK ... these annoy me to no end--not to mention that they locks may or may not be spinlocks! It's a linux frob, really. We're way beyond merging any useful bsd-core code on a large scale, which was the only good reason to keep them around. Memory allocation: - Change drm_memory.c so that it contains generally useful, memory allocation functions using kmem(9) (mostly used by the drivers themselves). However, I expect to use this more in the future in the "bsd core". These functions always use KM_NOSLEEP. The new drm_dmamem_alloc function has a wait argument which takes DRM_DMA_WAIT/DRM_DMA_NOWAIT (defined as their bus_dma counterparts), and honors this hint in its calls to kmem(9) and bus_dma(9) functions. - Got rid of these functions' "area" argument--it's been deprecated for ages. Provide macros in drmP.h to deal with the os-independent code. - Declare these functions inline -- I believe they're used enough by the i915 and radeon drivers to justify it. Please let me know if I am mistaken. NOTE: With these changes, a glxgears score which was previously ~3900fps is now ~4400fps (same setup as mentioned above). I realize that using kmem(9) could cause problems, but I can't seem to run into any with my test setup. If anyone smells regression, please let me know.
This commit is contained in:
parent
c63ddfd726
commit
a65a4adb77
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: drmP.h,v 1.20 2008/05/05 14:00:10 jmcneill Exp $ */
|
||||
/* $NetBSD: drmP.h,v 1.21 2008/05/06 01:26:14 bjs Exp $ */
|
||||
|
||||
/* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*-
|
||||
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
|
||||
|
@ -56,6 +56,7 @@ typedef struct drm_file drm_file_t;
|
|||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kernel.h>
|
||||
#ifdef __FreeBSD__
|
||||
|
@ -230,7 +231,7 @@ MALLOC_DECLARE(M_DRM);
|
|||
#define DRM_STRUCTPROC struct proc
|
||||
#define DRM_STRUCTCDEVPROC struct lwp
|
||||
#define DRM_SPINTYPE kmutex_t
|
||||
#define DRM_SPININIT(l,name) mutex_init(l, MUTEX_DEFAULT, IPL_VM)
|
||||
#define DRM_SPININIT(l,name) mutex_init(l, MUTEX_DEFAULT, IPL_NONE)
|
||||
#define DRM_SPINUNINIT(l) mutex_destroy(l)
|
||||
#define DRM_SPINLOCK(l) mutex_enter(l)
|
||||
#define DRM_SPINUNLOCK(u) mutex_exit(u)
|
||||
|
@ -257,6 +258,7 @@ MALLOC_DECLARE(M_DRM);
|
|||
#endif /* __NetBSD__ */
|
||||
#endif /* __NetBSD__ || __OpenBSD__ */
|
||||
|
||||
|
||||
/* Currently our DRMFILE (filp) is a void * which is actually the pid
|
||||
* of the current process. It should be a per-open unique pointer, but
|
||||
* code for that is not yet written */
|
||||
|
@ -312,6 +314,11 @@ extern drm_device_t *drm_units[];
|
|||
#define DRM_NETBSD_ADDR2HANDLE(addr) (addr)
|
||||
#define DRM_NETBSD_HANDLE2ADDR(handle) (handle)
|
||||
#endif
|
||||
/* see struct drm_dmamem */
|
||||
#define DRM_NETBSD_DMA_VADDR(p) ((p)->dm_kva)
|
||||
#define DRM_NETBSD_DMA_ADDR(p) ((p)->dm_segs[0].ds_addr)
|
||||
#define DRM_DMA_WAITOK BUS_DMA_WAITOK
|
||||
#define DRM_DMA_NOWAIT BUS_DMA_NOWAIT
|
||||
#elif defined(__OpenBSD__)
|
||||
#define DRM_DEVICE \
|
||||
#define DRM_SUSER(p) (suser(p->p_ucred, &p->p_acflag) == 0)
|
||||
|
@ -603,16 +610,21 @@ typedef struct drm_freelist {
|
|||
int high_mark; /* High water mark */
|
||||
} drm_freelist_t;
|
||||
|
||||
struct drm_dmamem {
|
||||
bus_dma_tag_t dm_tag;
|
||||
bus_dmamap_t dm_map;
|
||||
bus_dma_segment_t *dm_segs;
|
||||
int dm_nsegs;
|
||||
size_t dm_size;
|
||||
void *dm_kva;
|
||||
};
|
||||
|
||||
typedef struct drm_dma_handle {
|
||||
void *vaddr;
|
||||
bus_addr_t busaddr;
|
||||
bus_dma_tag_t dmat;
|
||||
bus_dmamap_t map;
|
||||
bus_dma_segment_t segs[1];
|
||||
size_t size;
|
||||
void *addr;
|
||||
struct drm_dmamem *dmam;
|
||||
} drm_dma_handle_t;
|
||||
#define DRM_PCI_DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
|
||||
|
||||
typedef struct drm_buf_entry {
|
||||
int buf_size;
|
||||
|
@ -695,6 +707,7 @@ typedef struct drm_sg_mem {
|
|||
int pages;
|
||||
dma_addr_t *busaddr;
|
||||
drm_dma_handle_t *dmah; /* Handle to PCI memory for ATI PCIGART table */
|
||||
struct drm_dmamem *dmam;
|
||||
} drm_sg_mem_t;
|
||||
|
||||
typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t;
|
||||
|
@ -970,16 +983,29 @@ extern drm_file_t *drm_find_file_by_proc(drm_device_t *dev,
|
|||
DRM_STRUCTPROC *p);
|
||||
#endif /* __NetBSD__ || __OpenBSD__ */
|
||||
|
||||
/* Memory management support (drm_memory.c) */
|
||||
void drm_mem_init(void);
|
||||
void drm_mem_uninit(void);
|
||||
void *drm_alloc(size_t size, int area);
|
||||
void *drm_calloc(size_t nmemb, size_t size, int area);
|
||||
void *drm_realloc(void *oldpt, size_t oldsize, size_t size,
|
||||
int area);
|
||||
void drm_free(void *pt, size_t size, int area);
|
||||
void drm_mem_init(void); /* XXX unused */
|
||||
void drm_mem_uninit(void); /* XXX unused */
|
||||
|
||||
/* NetBSD-specific memory allocation functions */
|
||||
inline void *drm_mem_alloc(size_t size);
|
||||
inline void *drm_mem_zalloc(size_t size);
|
||||
inline void *drm_mem_calloc(size_t nmemb, size_t size);
|
||||
inline void *drm_mem_realloc(void *oldpt, size_t oldsize, size_t size);
|
||||
inline void drm_mem_free(void *pt, size_t size);
|
||||
|
||||
/* NetBSD-specific DMA memory management */
|
||||
inline struct drm_dmamem *drm_dmamem_alloc(bus_dma_tag_t tag, size_t size, int wait);
|
||||
inline void drm_dmamem_free(struct drm_dmamem *dmam);
|
||||
|
||||
/* macros for os-independent code (discards deprecated 'area' argument) */
|
||||
#define drm_alloc(sz, a) drm_mem_alloc(sz)
|
||||
#define drm_calloc(sz, a) drm_mem_zalloc(sz)
|
||||
#define drm_realloc(old, oldsz, sz, a) drm_mem_realloc(old, oldsz, sz)
|
||||
#define drm_free(p, sz, a) drm_mem_free(p, sz)
|
||||
|
||||
void *drm_ioremap(drm_device_t *dev, drm_local_map_t *map);
|
||||
void drm_ioremapfree(drm_local_map_t *map);
|
||||
|
||||
int drm_mtrr_add(unsigned long offset, size_t size, int flags);
|
||||
int drm_mtrr_del(int handle, unsigned long offset, size_t size, int flags);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: drm_irq.c,v 1.8 2008/04/08 07:39:11 cegger Exp $ */
|
||||
/* $NetBSD: drm_irq.c,v 1.9 2008/05/06 01:26:14 bjs Exp $ */
|
||||
|
||||
/* drm_irq.c -- IRQ IOCTL and function support
|
||||
* Created: Fri Oct 18 2003 by anholt@FreeBSD.org
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_irq.c,v 1.8 2008/04/08 07:39:11 cegger Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_irq.c,v 1.9 2008/05/06 01:26:14 bjs Exp $");
|
||||
/*
|
||||
__FBSDID("$FreeBSD: src/sys/dev/drm/drm_irq.c,v 1.2 2005/11/28 23:13:52 anholt Exp $");
|
||||
*/
|
||||
|
@ -68,9 +68,9 @@ drm_irq_handler_wrap(DRM_IRQ_ARGS)
|
|||
irqreturn_t ret;
|
||||
drm_device_t *dev = (drm_device_t *)arg;
|
||||
|
||||
DRM_SPINLOCK(&dev->irq_lock);
|
||||
mutex_enter(&dev->irq_lock);
|
||||
ret = dev->driver.irq_handler(arg);
|
||||
DRM_SPINUNLOCK(&dev->irq_lock);
|
||||
mutex_exit(&dev->irq_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ int drm_irq_install(drm_device_t *dev)
|
|||
|
||||
dev->context_flag = 0;
|
||||
|
||||
DRM_SPININIT(&dev->irq_lock, "DRM IRQ lock");
|
||||
mutex_init(&dev->irq_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
|
||||
/* Before installing handler */
|
||||
|
||||
|
@ -107,7 +107,7 @@ int drm_irq_install(drm_device_t *dev)
|
|||
goto err;
|
||||
}
|
||||
istr = pci_intr_string(dev->pa.pa_pc, ih);
|
||||
dev->irqh = pci_intr_establish(dev->pa.pa_pc, ih, IPL_TTY,
|
||||
dev->irqh = pci_intr_establish(dev->pa.pa_pc, ih, IPL_VM,
|
||||
drm_irq_handler_wrap, dev);
|
||||
if (!dev->irqh) {
|
||||
retcode = ENOENT;
|
||||
|
@ -124,7 +124,7 @@ int drm_irq_install(drm_device_t *dev)
|
|||
err:
|
||||
DRM_LOCK();
|
||||
dev->irq_enabled = 0;
|
||||
DRM_SPINUNINIT(&dev->irq_lock);
|
||||
mutex_destroy(&dev->irq_lock);
|
||||
DRM_UNLOCK();
|
||||
return retcode;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ int drm_irq_uninstall(drm_device_t *dev)
|
|||
dev->driver.irq_uninstall(dev);
|
||||
|
||||
pci_intr_disestablish(dev->pa.pa_pc, dev->irqh);
|
||||
DRM_SPINUNINIT(&dev->irq_lock);
|
||||
mutex_destroy(&dev->irq_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -209,9 +209,9 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
|||
|
||||
vblwait.reply.sequence = atomic_read(&dev->vbl_received);
|
||||
|
||||
DRM_SPINLOCK(&dev->irq_lock);
|
||||
mutex_enter(&dev->irq_lock);
|
||||
TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
|
||||
DRM_SPINUNLOCK(&dev->irq_lock);
|
||||
mutex_exit(&dev->irq_lock);
|
||||
ret = 0;
|
||||
#endif
|
||||
ret = EINVAL;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: drm_memory.c,v 1.8 2008/03/13 05:35:43 bjs Exp $ */
|
||||
/* $NetBSD: drm_memory.c,v 1.9 2008/05/06 01:26:14 bjs Exp $ */
|
||||
|
||||
/* drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*-
|
||||
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_memory.c,v 1.8 2008/03/13 05:35:43 bjs Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_memory.c,v 1.9 2008/05/06 01:26:14 bjs Exp $");
|
||||
/*
|
||||
__FBSDID("$FreeBSD: src/sys/dev/drm/drm_memory.c,v 1.2 2005/11/28 23:13:52 anholt Exp $");
|
||||
*/
|
||||
|
@ -54,42 +54,53 @@ MALLOC_DEFINE(M_DRM, "drm", "DRM Data Structures");
|
|||
|
||||
void drm_mem_init(void)
|
||||
{
|
||||
/*
|
||||
malloc_type_attach(M_DRM);
|
||||
*/
|
||||
}
|
||||
|
||||
void drm_mem_uninit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void *drm_alloc(size_t size, int area)
|
||||
inline void *drm_mem_alloc(size_t size)
|
||||
{
|
||||
return malloc(size, M_DRM, M_NOWAIT);
|
||||
return kmem_alloc(size, KM_NOSLEEP);
|
||||
}
|
||||
|
||||
void *drm_calloc(size_t nmemb, size_t size, int area)
|
||||
inline void *drm_mem_zalloc(size_t size)
|
||||
{
|
||||
return malloc(size * nmemb, M_DRM, M_NOWAIT | M_ZERO);
|
||||
return kmem_zalloc(size, KM_NOSLEEP);
|
||||
}
|
||||
|
||||
void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
|
||||
inline void *drm_mem_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
return kmem_zalloc(size * nmemb, KM_NOSLEEP);
|
||||
}
|
||||
|
||||
inline void *drm_mem_realloc(void *oldpt, size_t oldsize, size_t size)
|
||||
{
|
||||
void *pt;
|
||||
|
||||
pt = malloc(size, M_DRM, M_NOWAIT);
|
||||
pt = drm_mem_alloc(size);
|
||||
if (pt == NULL)
|
||||
return NULL;
|
||||
if (oldpt && oldsize) {
|
||||
memcpy(pt, oldpt, oldsize);
|
||||
free(oldpt, M_DRM);
|
||||
drm_mem_free(oldpt, oldsize);
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
||||
void drm_free(void *pt, size_t size, int area)
|
||||
inline void drm_mem_free(void *pt, size_t size)
|
||||
{
|
||||
free(pt, M_DRM);
|
||||
#if 0
|
||||
KASSERT(pt == NULL)
|
||||
#else
|
||||
if (pt == NULL) {
|
||||
DRM_DEBUG("drm_mem_free: told to free a null pointer!");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
kmem_free(pt, size);
|
||||
}
|
||||
|
||||
void *drm_ioremap(drm_device_t *dev, drm_local_map_t *map)
|
||||
|
@ -227,3 +238,60 @@ drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags)
|
|||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline struct drm_dmamem *
|
||||
drm_dmamem_alloc(bus_dma_tag_t tag, size_t size, int wait)
|
||||
{
|
||||
struct drm_dmamem *dma;
|
||||
int kmflag;
|
||||
|
||||
kmflag = (wait & DRM_DMA_NOWAIT) != 0 ? KM_NOSLEEP : KM_SLEEP;
|
||||
|
||||
dma = kmem_zalloc(sizeof(*dma), kmflag);
|
||||
if (dma == NULL)
|
||||
return NULL;
|
||||
|
||||
dma->dm_size = size;
|
||||
dma->dm_tag = tag;
|
||||
|
||||
if (bus_dmamap_create(dma->dm_tag, size, size / PAGE_SIZE + 1, size, 0,
|
||||
wait|BUS_DMA_ALLOCNOW, &dma->dm_map) != 0)
|
||||
goto dmafree;
|
||||
|
||||
if (bus_dmamem_alloc(dma->dm_tag, size, PAGE_SIZE, 0, dma->dm_segs,
|
||||
1, &dma->dm_nsegs, wait) != 0)
|
||||
goto destroy;
|
||||
|
||||
if (bus_dmamem_map(dma->dm_tag, dma->dm_segs, dma->dm_nsegs, size,
|
||||
&dma->dm_kva, wait|BUS_DMA_COHERENT) != 0)
|
||||
goto free;
|
||||
|
||||
if (bus_dmamap_load(dma->dm_tag, dma->dm_map, dma->dm_kva, size,
|
||||
NULL, wait) != 0)
|
||||
goto unmap;
|
||||
|
||||
return dma;
|
||||
|
||||
unmap:
|
||||
bus_dmamem_unmap(dma->dm_tag, dma->dm_kva, size);
|
||||
free:
|
||||
bus_dmamem_free(dma->dm_tag, dma->dm_segs, dma->dm_nsegs);
|
||||
destroy:
|
||||
bus_dmamap_destroy(dma->dm_tag, dma->dm_map);
|
||||
dmafree:
|
||||
kmem_free(dma, sizeof(*dma));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline void
|
||||
drm_dmamem_free(struct drm_dmamem *dma)
|
||||
{
|
||||
if (dma != NULL) {
|
||||
bus_dmamap_unload(dma->dm_tag, dma->dm_map);
|
||||
bus_dmamem_unmap(dma->dm_tag, dma->dm_kva, dma->dm_size);
|
||||
bus_dmamem_free(dma->dm_tag, dma->dm_segs, dma->dm_nsegs);
|
||||
bus_dmamap_destroy(dma->dm_tag, dma->dm_map);
|
||||
kmem_free(dma, sizeof(*dma));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: drm_pci.c,v 1.8 2008/03/02 07:12:15 bjs Exp $ */
|
||||
/* $NetBSD: drm_pci.c,v 1.9 2008/05/06 01:26:14 bjs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2003 Eric Anholt.
|
||||
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.8 2008/03/02 07:12:15 bjs Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.9 2008/05/06 01:26:14 bjs Exp $");
|
||||
/*
|
||||
__FBSDID("$FreeBSD: src/sys/dev/drm/drm_pci.c,v 1.2 2005/11/28 23:13:52 anholt Exp $");
|
||||
*/
|
||||
|
@ -34,72 +34,35 @@ __FBSDID("$FreeBSD: src/sys/dev/drm/drm_pci.c,v 1.2 2005/11/28 23:13:52 anholt E
|
|||
drm_dma_handle_t *
|
||||
drm_pci_alloc(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr)
|
||||
{
|
||||
drm_dma_handle_t *h;
|
||||
int error, nsegs;
|
||||
drm_dma_handle_t *hdl;
|
||||
struct drm_dmamem *dmam;
|
||||
|
||||
hdl = drm_mem_zalloc(sizeof(drm_dma_handle_t));
|
||||
if (hdl == NULL)
|
||||
goto err;
|
||||
|
||||
/* Need power-of-two alignment, so fail the allocation if it isn't. */
|
||||
if ((align & (align - 1)) != 0) {
|
||||
DRM_ERROR("drm_pci_alloc with non-power-of-two alignment %d\n",
|
||||
(int)align);
|
||||
return NULL;
|
||||
}
|
||||
dmam = drm_dmamem_alloc(dev->pa.pa_dmat, size, DRM_DMA_NOWAIT);
|
||||
if (dmam == NULL)
|
||||
goto free;
|
||||
|
||||
h = malloc(sizeof(drm_dma_handle_t), M_DRM, M_ZERO | M_NOWAIT);
|
||||
hdl->busaddr = DRM_NETBSD_DMA_ADDR(dmam);
|
||||
hdl->vaddr = DRM_NETBSD_DMA_VADDR(dmam);
|
||||
hdl->size = size;
|
||||
return hdl;
|
||||
|
||||
if (h == NULL)
|
||||
return NULL;
|
||||
if ((error = bus_dmamem_alloc(dev->pa.pa_dmat, size, align, 0,
|
||||
h->segs, 1, &nsegs, BUS_DMA_NOWAIT)) != 0) {
|
||||
printf("drm: Unable to allocate DMA, error %d\n", error);
|
||||
goto fail;
|
||||
}
|
||||
if ((error = bus_dmamem_map(dev->pa.pa_dmat, h->segs, nsegs, size,
|
||||
&h->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
|
||||
printf("drm: Unable to map DMA, error %d\n", error);
|
||||
goto free;
|
||||
}
|
||||
if ((error = bus_dmamap_create(dev->pa.pa_dmat, size, 1, size, 0,
|
||||
BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &h->map)) != 0) {
|
||||
printf("drm: Unable to create DMA map, error %d\n", error);
|
||||
goto unmap;
|
||||
}
|
||||
if ((error = bus_dmamap_load(dev->pa.pa_dmat, h->map, h->addr, size,
|
||||
NULL, BUS_DMA_NOWAIT)) != 0) {
|
||||
printf("drm: Unable to load DMA map, error %d\n", error);
|
||||
goto destroy;
|
||||
}
|
||||
h->busaddr = DRM_PCI_DMAADDR(h);
|
||||
h->vaddr = h->addr;
|
||||
h->size = size;
|
||||
|
||||
return h;
|
||||
|
||||
destroy:
|
||||
bus_dmamap_destroy(dev->pa.pa_dmat, h->map);
|
||||
unmap:
|
||||
bus_dmamem_unmap(dev->pa.pa_dmat, h->addr, size);
|
||||
free:
|
||||
bus_dmamem_free(dev->pa.pa_dmat, h->segs, 1);
|
||||
fail:
|
||||
free(h, M_DRM);
|
||||
drm_mem_free(hdl, sizeof(*hdl));
|
||||
err:
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a DMA-accessible consistent memory block.
|
||||
*/
|
||||
|
||||
void
|
||||
drm_pci_free(drm_device_t *dev, drm_dma_handle_t *h)
|
||||
drm_pci_free(drm_device_t *dev, drm_dma_handle_t *hdl)
|
||||
{
|
||||
if (h == NULL)
|
||||
return;
|
||||
bus_dmamap_unload(dev->pa.pa_dmat, h->map);
|
||||
bus_dmamap_destroy(dev->pa.pa_dmat, h->map);
|
||||
bus_dmamem_unmap(dev->pa.pa_dmat, h->addr, h->size);
|
||||
bus_dmamem_free(dev->pa.pa_dmat, h->segs, 1);
|
||||
|
||||
free(h, M_DRM);
|
||||
if (hdl != NULL) {
|
||||
if (hdl->dmam != NULL)
|
||||
drm_dmamem_free(hdl->dmam);
|
||||
drm_mem_free(hdl, sizeof(*hdl));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue