/* Memory management support (drm_memory.c) */
-void drm_mem_init(void);
-void drm_mem_uninit(void);
+
+/*
+ * XXX The drm_mem_init/uninit functions originally took void arguments.
+ * However, these are sensible places to create/destroy the mmap cookie
+ * extent map, and so they now take a pointer to the "drm device".
+ */
+void drm_mem_init(struct drm_device *);
+void drm_mem_uninit(struct drm_device *);
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,
@@ -1154,9 +1184,12 @@
{
drm_local_map_t *map;
+ /* NOTE: this code must be remain in harmony with related code
+ * in drm_mmap(), drm_addmap_ioctl(), and/or drm_rmmap().
+ */
DRM_SPINLOCK_ASSERT(&dev->dev_lock);
TAILQ_FOREACH(map, &dev->maplist, link) {
- if (map->offset == offset)
+ if (map->cookie == offset)
return map;
}
return NULL;
Index: dev/drm/drm_auth.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_auth.c,v
retrieving revision 1.6
diff -u -b -r1.6 drm_auth.c
--- dev/drm/drm_auth.c 29 Jun 2008 12:49:08 -0000 1.6
+++ dev/drm/drm_auth.c 10 Aug 2008 00:57:11 -0000
@@ -79,7 +79,6 @@
entry->priv = priv;
entry->next = NULL;
if (request->count < 0 || request->count > 4096)
return DRM_ERR(EINVAL);
@@ -780,6 +803,8 @@
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return DRM_ERR(EINVAL);
+ DRM_SPINLOCK(&dev->dma_lock);
+
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
@@ -802,7 +827,6 @@
{
int order, ret;
- DRM_SPINLOCK(&dev->dma_lock);
if (!DRM_SUSER(DRM_CURPROC))
return DRM_ERR(EACCES);
@@ -814,6 +838,8 @@
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return DRM_ERR(EINVAL);
+ DRM_SPINLOCK(&dev->dma_lock);
+
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
@@ -836,7 +862,6 @@
{
int order, ret;
- DRM_SPINLOCK(&dev->dma_lock);
if (!DRM_SUSER(DRM_CURPROC))
return DRM_ERR(EACCES);
@@ -848,6 +873,8 @@
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return DRM_ERR(EINVAL);
+ DRM_SPINLOCK(&dev->dma_lock);
+
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
@@ -1024,7 +1051,7 @@
struct vmspace *vms;
struct vnode *vn;
voff_t foff;
- vsize_t size, rsize;
+ vsize_t size;
vaddr_t vaddr;
void *drm_ioremap(drm_device_t *dev, drm_local_map_t *map)
Index: dev/drm/drm_netbsd.c
===================================================================
RCS file: dev/drm/drm_netbsd.c
diff -N dev/drm/drm_netbsd.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dev/drm/drm_netbsd.c 10 Aug 2008 00:57:11 -0000
@@ -0,0 +1,142 @@
+/* $NetBSD: drm_netbsd.c,v 1.1 2008/05/28 04:52:48 bjs Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Blair Sadewitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <dev/drm/drmP.h>
+#include <sys/hash.h>
+
+/* XXX Most everything the DRM wants is expressed in pages. There are possible
+ scenarios where e.g. the page size does not equal the page size of the GART,
+ but our DRM does not work on those platforms yet. */
+
+struct drm_dmamem *
+drm_dmamem_pgalloc(drm_device_t *dev, size_t pages)
+{
+ struct drm_dmamem *mem = NULL;
+ size_t size = pages << PAGE_SHIFT;
+ int ret = 0;
+
+ mem = malloc(sizeof(*mem), M_DRM, M_NOWAIT | M_ZERO);
+ if (mem == NULL)
+ return NULL;
+
+ mem->phase = DRM_DMAMEM_INIT;
+
+ mem->dd_segs = malloc(sizeof(*mem->dd_segs) * pages, M_DRM,
+ M_NOWAIT | M_ZERO);
+ if (mem->dd_segs == NULL)
+ goto error;
+
+ mem->dd_dmat = dev->pa.pa_dmat;
+ mem->dd_size = size;
+
+ if (bus_dmamap_create(dev->pa.pa_dmat, size, pages, PAGE_SIZE, 0,
+ BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mem->dd_dmam) != 0)
+ goto error;
+ mem->phase = DRM_DMAMAP_CREATE;
+
+ if ((ret = bus_dmamem_alloc(dev->pa.pa_dmat, size, PAGE_SIZE, 0,
+ mem->dd_segs, pages, &mem->dd_nsegs, BUS_DMA_NOWAIT)) != 0) {
+ goto error;
+ }
+ mem->phase = DRM_DMAMEM_ALLOC;
+
+ if (bus_dmamem_map(dev->pa.pa_dmat, mem->dd_segs, mem->dd_nsegs, size,
+ &mem->dd_kva, BUS_DMA_COHERENT|BUS_DMA_NOWAIT) != 0)
+ goto error;
+ mem->phase = DRM_DMAMEM_MAP;
+
+ if (bus_dmamap_load(dev->pa.pa_dmat, mem->dd_dmam, mem->dd_kva, size,
+ NULL, BUS_DMA_NOWAIT) != 0)
+ goto error;
+ mem->phase = DRM_DMAMAP_LOAD;
+
+ memset(mem->dd_kva, 0, size);
+
+ return mem;
+error:
+ mem->phase &= DRM_DMAMEM_FAIL;
+ drm_dmamem_free(mem);
+ return NULL;
+}
+
+void
+drm_dmamem_free(struct drm_dmamem *mem)
+{
+ if (mem == NULL)
+ return;
+
+ if (mem->phase & DRM_DMAMEM_FAIL) {
+ DRM_DEBUG("attempted allocation failed; teardown sequence follows:\n");
+ mem->phase &= ~DRM_DMAMEM_FAIL;
+ } else if (mem->phase & ~DRM_DMAMAP_LOAD) {
+ DRM_DEBUG("invoked by another function on unloaded map; teardown sequence follows:\n");
+ } else {
+ DRM_DEBUG("freeing DMA memory; teardown sequence follows:\n");
+ }
+
+
+ switch (mem->phase) {
+ case DRM_DMAMAP_LOAD:
+ DRM_DEBUG("bus_dmamap_unload: tag (%p), map (%p)\n",
+ (void *)mem->dd_dmat, (void *)mem->dd_dmam);
+ bus_dmamap_unload(mem->dd_dmat, mem->dd_dmam);
+ /* FALLTHRU */
+ case DRM_DMAMEM_MAP:
+ DRM_DEBUG("bus_dmamem_unmap: tag (%p), kva (%p), size (%zd)\n",
+ mem->dd_dmat, mem->dd_kva, mem->dd_size);
+ bus_dmamem_unmap(mem->dd_dmat, mem->dd_kva, mem->dd_size);
+ /* FALLTHRU */
+ case DRM_DMAMEM_ALLOC:
+ DRM_DEBUG("bus_dmamem_free: tag (%p), segs (%p), nsegs (%i)\n",
+ mem->dd_dmat, mem->dd_segs, mem->dd_nsegs);
+ bus_dmamem_free(mem->dd_dmat, mem->dd_segs,
+ mem->dd_nsegs);
+ /* FALLTHRU */
+ case DRM_DMAMAP_CREATE:
+ DRM_DEBUG("bus_dmamap_destroy: tag (%p), map (%p)\n",
+ (void *)mem->dd_dmat, (void *)mem->dd_dmam);
+ bus_dmamap_destroy(mem->dd_dmat, mem->dd_dmam);
+ /* FALLTHRU */
+ case DRM_DMAMEM_INIT:
+ if (mem->dd_segs != NULL) {
+ free(mem->dd_segs, M_DRM);
+ mem->dd_segs = NULL;
+ }
+ break;
+ }
+
+ free(mem, M_DRM);
+ mem = NULL;
+
+ return;
+}
Index: dev/drm/drm_netbsd.h
===================================================================
RCS file: dev/drm/drm_netbsd.h
diff -N dev/drm/drm_netbsd.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dev/drm/drm_netbsd.h 10 Aug 2008 00:57:11 -0000
@@ -0,0 +1,57 @@
+/* $NetBSD: drm_netbsd.h,v 1.1 2008/05/28 04:52:48 bjs Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Blair Sadewitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "drmP.h"
+
+#define DRM_DMAMEM_INIT 0x000
+#define DRM_DMAMAP_CREATE 0x001
+#define DRM_DMAMEM_ALLOC 0x002
+#define DRM_DMAMEM_MAP 0x004
+#define DRM_DMAMAP_LOAD 0x008
+#define DRM_DMAMEM_FAIL 0x800
+
+#define DRM_DMA_BUSADDR(__m) ((__m)->dd_dmam->dm_segs[0].ds_addr)
+#define DRM_DMA_SEGADDR(__m, __s) ((__m)->dd_dmam->dm_segs[__s].ds_addr)
+#define DRM_DMA_SEGSIZE(__m, __s) ((__m)->dd_dmam->dm_segs[__s].ds_len)
+#define DRM_DMA_KERNADDR(__m) ((__m)->dd_kva)
+
+struct drm_dmamem {
+ bus_dma_tag_t dd_dmat;
+ bus_dmamap_t dd_dmam;
+ bus_dma_segment_t *dd_segs;
+ int dd_nsegs;
+ size_t dd_size;
+ void *dd_kva;
+ u_int phase;
+};
+
+struct drm_dmamem *drm_dmamem_pgalloc(struct drm_device *, size_t);
+void drm_dmamem_free(struct drm_dmamem *);
Index: dev/drm/drm_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_pci.c,v
retrieving revision 1.13
diff -u -b -r1.13 drm_pci.c
--- dev/drm/drm_pci.c 29 Jun 2008 12:49:08 -0000 1.13
+++ dev/drm/drm_pci.c 10 Aug 2008 00:57:11 -0000
@@ -35,55 +35,22 @@
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;
-
-
- /* 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;
- }
h = malloc(sizeof(drm_dma_handle_t), M_DRM, M_ZERO | M_NOWAIT);
atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
+ DRM_WAKEUP(&(dev->vbl_queue));
drm_vbl_send_signals(dev);
return IRQ_HANDLED;
}
@@ -87,7 +87,7 @@
* by about a day rather than she wants to wait for years
* using vertical blanks...
*/
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
(((cur_vblank = atomic_read(&dev->vbl_received))
- *sequence) <= (1 << 23)));
@@ -97,7 +97,7 @@
* by about a day rather than she wants to wait for years
* using vertical blanks...
*/
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
(((cur_vblank = atomic_read(&dev->vbl_received))
- *sequence) <= (1 << 23)));
@@ -116,7 +116,7 @@
* by about a day rather than she wants to wait for years
* using fences.
*/
- DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ,
+ DRM_WAIT_ON(ret, &(dev_priv->fence_queue), 3 * DRM_HZ,
(((cur_fence = atomic_read(&dev_priv->last_fence_retired))
- *sequence) <= (1 << 23)));
return ret;
@@ -155,7 +155,7 @@
* by about a day rather than she wants to wait for years
* using vertical blanks...
*/
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+ DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
(((cur_vblank = atomic_read(&dev->vbl_received))
- *sequence) <= (1 << 23)));