Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/riastradh-drm2]: src/sys/external/bsd/drm2 Add drm_limit_dma_space to li...



details:   https://anonhg.NetBSD.org/src/rev/e154206ce9db
branches:  riastradh-drm2
changeset: 788313:e154206ce9db
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Wed Jul 24 03:12:33 2013 +0000

description:
Add drm_limit_dma_space to limit the memory available for DMA.

Designed as a compatibility stub to replace dma_set_coherent_mask in
Linux.  Not exactly the same, but probably close enough for all uses
of dma_set_coherent_mask in Linux.

diffstat:

 sys/external/bsd/drm2/dist/include/drm/drmP.h |   6 ++
 sys/external/bsd/drm2/drm/drm_memory.c        |  57 ++++++++++++++++++++++++++-
 2 files changed, 61 insertions(+), 2 deletions(-)

diffs (99 lines):

diff -r 261e2e39fc72 -r e154206ce9db sys/external/bsd/drm2/dist/include/drm/drmP.h
--- a/sys/external/bsd/drm2/dist/include/drm/drmP.h     Wed Jul 24 03:12:15 2013 +0000
+++ b/sys/external/bsd/drm2/dist/include/drm/drmP.h     Wed Jul 24 03:12:33 2013 +0000
@@ -1359,7 +1359,11 @@
        /* XXX What does this have to do with AGP?  */
        struct drm_bus_map *agp_maps;
        size_t agp_nmaps;
+       bus_dma_tag_t bus_dmat;
        bus_dma_tag_t dmat;
+       bool dmat_subregion_p;
+       bus_addr_t dmat_subregion_min;
+       bus_addr_t dmat_subregion_max;
 #endif
 
        struct drm_sg_mem *sg;  /**< Scatter gather memory */
@@ -1526,6 +1530,8 @@
 #ifdef __NetBSD__
 extern void *drm_ioremap(struct drm_device *dev, struct drm_local_map *map);
 extern void drm_iounmap(struct drm_device *dev, struct drm_local_map *map);
+extern int drm_limit_dma_space(struct drm_device *, resource_size_t,
+    resource_size_t);
 #endif
 
                                /* Misc. IOCTL support (drm_ioctl.h) */
diff -r 261e2e39fc72 -r e154206ce9db sys/external/bsd/drm2/drm/drm_memory.c
--- a/sys/external/bsd/drm2/drm/drm_memory.c    Wed Jul 24 03:12:15 2013 +0000
+++ b/sys/external/bsd/drm2/drm/drm_memory.c    Wed Jul 24 03:12:33 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: drm_memory.c,v 1.1.2.5 2013/07/24 03:02:21 riastradh Exp $     */
+/*     $NetBSD: drm_memory.c,v 1.1.2.6 2013/07/24 03:12:33 riastradh Exp $     */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_memory.c,v 1.1.2.5 2013/07/24 03:02:21 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_memory.c,v 1.1.2.6 2013/07/24 03:12:33 riastradh Exp $");
 
 /* XXX Cargo-culted from the old drm_memory.c.  */
 
@@ -331,3 +331,56 @@
        dmah->dmah_tag = NULL;  /* XXX paranoia */
        kmem_free(dmah, sizeof(*dmah));
 }
+
+/*
+ * Make sure the DMA-safe memory allocated for dev lies between
+ * min_addr and max_addr.  Can be used multiple times to restrict the
+ * bounds further, but never to expand the bounds again.
+ *
+ * XXX Caller must guarantee nobody has used the tag yet,
+ * i.e. allocated any DMA memory.
+ */
+int
+drm_limit_dma_space(struct drm_device *dev, resource_size_t min_addr,
+    resource_size_t max_addr)
+{
+       int error;
+
+       KASSERT(min_addr <= max_addr);
+
+       /*
+        * Limit it further if we have already limited it, and destroy
+        * the old subregion DMA tag.
+        */
+       if (dev->dmat_subregion_p) {
+               min_addr = MAX(min_addr, dev->dmat_subregion_min);
+               max_addr = MIN(max_addr, dev->dmat_subregion_max);
+               bus_dmatag_destroy(dev->dmat);
+       }
+
+       /*
+        * Create a DMA tag for a subregion from the bus's DMA tag.  If
+        * that fails, restore dev->dmat to the whole region so that we
+        * need not worry about dev->dmat being uninitialized (not that
+        * the caller should try to allocate DMA-safe memory on failure
+        * anyway, but...paranoia).
+        */
+       error = bus_dmatag_subregion(dev->bus_dmat, min_addr, max_addr,
+           &dev->dmat, BUS_DMA_WAITOK);
+       if (error) {
+               dev->dmat = dev->bus_dmat;
+               return error;
+       }
+
+       /*
+        * Remember that we have a subregion tag so that we know to
+        * destroy it later, and record the bounds in case we need to
+        * limit them again.
+        */
+       dev->dmat_subregion_p = true;
+       dev->dmat_subregion_min = min_addr;
+       dev->dmat_subregion_max = max_addr;
+
+       /* Success!  */
+       return 0;
+}



Home | Main Index | Thread Index | Old Index