From 71f9b7357cb3d4ea7bb5b396840de3985bc13ad4 Mon Sep 17 00:00:00 2001
From: Eric Anholt <anholt@freebsd.org>
Date: Tue, 8 Nov 2005 05:29:26 +0000
Subject: Fix FreeBSD DRM for latest MGA changes to agp support, which cleans
 things     up a good bit, I think. Also, remove the agp_uninit() function
 which     has lain around as a noop for years now. The FreeBSD DRM is now all
     compiling, with the exception of via. One known sleeping-with-lock-held  
   issue remains.

---
 bsd-core/drmP.h           |  17 +++---
 bsd-core/drm_agpsupport.c | 153 ++++++++++++++++++++++++++++++++--------------
 bsd-core/drm_drv.c        |   9 ++-
 3 files changed, 119 insertions(+), 60 deletions(-)

(limited to 'bsd-core')

diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h
index dda12560..0adfef93 100644
--- a/bsd-core/drmP.h
+++ b/bsd-core/drmP.h
@@ -895,7 +895,6 @@ void	drm_vbl_send_signals(drm_device_t *dev);
 int	drm_device_is_agp(drm_device_t *dev);
 int	drm_device_is_pcie(drm_device_t *dev);
 drm_agp_head_t *drm_agp_init(void);
-void	drm_agp_uninit(void);
 int	drm_agp_acquire(drm_device_t *dev);
 int	drm_agp_release(drm_device_t *dev);
 int	drm_agp_info(drm_device_t * dev, drm_agp_info_t *info);
@@ -904,10 +903,10 @@ void	*drm_agp_allocate_memory(size_t pages, u32 type);
 int	drm_agp_free_memory(void *handle);
 int	drm_agp_bind_memory(void *handle, off_t start);
 int	drm_agp_unbind_memory(void *handle);
-#define drm_alloc_agp(dev, pages, type) drm_agp_allocate_memory(pages, type)
-#define drm_free_agp(handle, pages) drm_agp_free_memory(handle)
-#define drm_bind_agp(handle, start) drm_agp_bind_memory(handle, start)
-#define drm_unbind_agp(handle) drm_agp_unbind_memory(handle)
+int	drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request);
+int	drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request);
+int	drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request);
+int	drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
 
 /* Scatter Gather Support (drm_scatter.c) */
 void	drm_sg_cleanup(drm_sg_mem_t *entry);
@@ -979,10 +978,10 @@ int	drm_agp_acquire_ioctl(DRM_IOCTL_ARGS);
 int	drm_agp_release_ioctl(DRM_IOCTL_ARGS);
 int	drm_agp_enable_ioctl(DRM_IOCTL_ARGS);
 int	drm_agp_info_ioctl(DRM_IOCTL_ARGS);
-int	drm_agp_alloc(DRM_IOCTL_ARGS);
-int	drm_agp_free(DRM_IOCTL_ARGS);
-int	drm_agp_unbind(DRM_IOCTL_ARGS);
-int	drm_agp_bind(DRM_IOCTL_ARGS);
+int	drm_agp_alloc_ioctl(DRM_IOCTL_ARGS);
+int	drm_agp_free_ioctl(DRM_IOCTL_ARGS);
+int	drm_agp_unbind_ioctl(DRM_IOCTL_ARGS);
+int	drm_agp_bind_ioctl(DRM_IOCTL_ARGS);
 
 /* Scatter Gather Support (drm_scatter.c) */
 int	drm_sg_alloc(DRM_IOCTL_ARGS);
diff --git a/bsd-core/drm_agpsupport.c b/bsd-core/drm_agpsupport.c
index a78410a8..58293566 100644
--- a/bsd-core/drm_agpsupport.c
+++ b/bsd-core/drm_agpsupport.c
@@ -194,10 +194,8 @@ int drm_agp_enable_ioctl(DRM_IOCTL_ARGS)
 	return drm_agp_enable(dev, mode);
 }
 
-int drm_agp_alloc(DRM_IOCTL_ARGS)
+int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
 {
-	DRM_DEVICE;
-	drm_agp_buffer_t request;
 	drm_agp_mem_t    *entry;
 	void	         *handle;
 	unsigned long    pages;
@@ -207,16 +205,17 @@ int drm_agp_alloc(DRM_IOCTL_ARGS)
 	if (!dev->agp || !dev->agp->acquired)
 		return EINVAL;
 
-	request = *(drm_agp_buffer_t *) data;
-
 	entry = malloc(sizeof(*entry), M_DRM, M_NOWAIT | M_ZERO);
 	if (entry == NULL)
 		return ENOMEM;
 
-	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
-	type = (u_int32_t) request.type;
+	pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
+	type = (u_int32_t) request->type;
 
-	if (!(handle = drm_agp_allocate_memory(pages, type))) {
+	DRM_UNLOCK();
+	handle = drm_agp_allocate_memory(pages, type);
+	DRM_LOCK();
+	if (handle == NULL) {
 		free(entry, M_DRM);
 		return ENOMEM;
 	}
@@ -232,12 +231,27 @@ int drm_agp_alloc(DRM_IOCTL_ARGS)
 
 	agp_memory_info(dev->agp->agpdev, entry->handle, &info);
 
-	request.handle   = (unsigned long) entry->handle;
-        request.physical = info.ami_physical;
+	request->handle   = (unsigned long) entry->handle;
+        request->physical = info.ami_physical;
+
+	return 0;
+}
+
+int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_agp_buffer_t request;
+	int retcode;
+
+	request = *(drm_agp_buffer_t *) data;
+
+	DRM_LOCK();
+	retcode = drm_agp_alloc(dev, &request);
+	DRM_UNLOCK();
 
 	*(drm_agp_buffer_t *) data = request;
 
-	return 0;
+	return retcode;
 }
 
 static drm_agp_mem_t * drm_agp_lookup_entry(drm_device_t *dev, void *handle)
@@ -250,64 +264,94 @@ static drm_agp_mem_t * drm_agp_lookup_entry(drm_device_t *dev, void *handle)
 	return NULL;
 }
 
-int drm_agp_unbind(DRM_IOCTL_ARGS)
+int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
 {
-	DRM_DEVICE;
-	drm_agp_binding_t request;
 	drm_agp_mem_t     *entry;
 	int retcode;
 
 	if (!dev->agp || !dev->agp->acquired)
 		return EINVAL;
-	request = *(drm_agp_binding_t *) data;
-	if (!(entry = drm_agp_lookup_entry(dev, (void *)request.handle)))
+
+	entry = drm_agp_lookup_entry(dev, (void *)request->handle);
+	if (entry == NULL || !entry->bound)
 		return EINVAL;
-	if (!entry->bound) return EINVAL;
+
+	DRM_UNLOCK();
 	retcode = drm_agp_unbind_memory(entry->handle);
-	if (!retcode)
-	{
-		entry->bound=0;
-		return 0;
-	}
-	else
-		return retcode;
+	DRM_LOCK();
+
+	if (retcode == 0)
+		entry->bound = 0;
+
+	return retcode;
 }
 
-int drm_agp_bind(DRM_IOCTL_ARGS)
+int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 	drm_agp_binding_t request;
+	int retcode;
+
+	request = *(drm_agp_binding_t *) data;
+
+	DRM_LOCK();
+	retcode = drm_agp_unbind(dev, &request);
+	DRM_UNLOCK();
+
+	return retcode;
+}
+
+int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
+{
 	drm_agp_mem_t     *entry;
 	int               retcode;
 	int               page;
 	
-	DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE);
 	if (!dev->agp || !dev->agp->acquired)
 		return EINVAL;
-	request = *(drm_agp_binding_t *) data;
-	if (!(entry = drm_agp_lookup_entry(dev, (void *)request.handle)))
+
+	DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE);
+
+	entry = drm_agp_lookup_entry(dev, (void *)request->handle);
+	if (entry == NULL || entry->bound)
 		return EINVAL;
-	if (entry->bound) return EINVAL;
-	page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
-	if ((retcode = drm_agp_bind_memory(entry->handle, page)))
-		return retcode;
-	entry->bound = dev->agp->base + (page << PAGE_SHIFT);
-	return 0;
+
+	page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE;
+
+	DRM_UNLOCK();
+	retcode = drm_agp_bind_memory(entry->handle, page);
+	DRM_LOCK();
+	if (retcode == 0)
+		entry->bound = dev->agp->base + (page << PAGE_SHIFT);
+
+	return retcode;
 }
 
-int drm_agp_free(DRM_IOCTL_ARGS)
+int drm_agp_bind_ioctl(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
-	drm_agp_buffer_t request;
+	drm_agp_binding_t request;
+	int retcode;
+
+	request = *(drm_agp_binding_t *) data;
+
+	DRM_LOCK();
+	retcode = drm_agp_bind(dev, &request);
+	DRM_UNLOCK();
+
+	return retcode;
+}
+
+int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
+{
 	drm_agp_mem_t    *entry;
 	
 	if (!dev->agp || !dev->agp->acquired)
 		return EINVAL;
-	request = *(drm_agp_buffer_t *) data;
-	if (!(entry = drm_agp_lookup_entry(dev, (void*)request.handle)))
+
+	entry = drm_agp_lookup_entry(dev, (void*)request->handle);
+	if (entry == NULL)
 		return EINVAL;
-	if (entry->bound)
-		drm_agp_unbind_memory(entry->handle);
    
 	if (entry->prev)
 		entry->prev->next = entry->next;
@@ -315,9 +359,32 @@ int drm_agp_free(DRM_IOCTL_ARGS)
 		dev->agp->memory  = entry->next;
 	if (entry->next)
 		entry->next->prev = entry->prev;
+
+	DRM_UNLOCK();
+	if (entry->bound)
+		drm_agp_unbind_memory(entry->handle);
 	drm_agp_free_memory(entry->handle);
+	DRM_LOCK();
+
 	free(entry, M_DRM);
+
 	return 0;
+
+}
+
+int drm_agp_free_ioctl(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_agp_buffer_t request;
+	int retcode;
+
+	request = *(drm_agp_buffer_t *) data;
+
+	DRM_LOCK();
+	retcode = drm_agp_free(dev, &request);
+	DRM_UNLOCK();
+
+	return retcode;
 }
 
 drm_agp_head_t *drm_agp_init(void)
@@ -346,12 +413,6 @@ drm_agp_head_t *drm_agp_init(void)
 	return head;
 }
 
-void drm_agp_uninit(void)
-{
-/* FIXME: What goes here */
-}
-
-
 void *drm_agp_allocate_memory(size_t pages, u32 type)
 {
 	device_t agpdev;
diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c
index 80ef4c81..648fbf3d 100644
--- a/bsd-core/drm_drv.c
+++ b/bsd-core/drm_drv.c
@@ -108,10 +108,10 @@ static drm_ioctl_desc_t		  drm_ioctls[256] = {
 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { drm_agp_info_ioctl, DRM_AUTH },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { drm_agp_alloc,   DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { drm_agp_free,    DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { drm_agp_bind,    DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { drm_agp_unbind,  DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
 
 	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)]      = { drm_sg_alloc,    DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
 	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)]       = { drm_sg_free,     DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
@@ -590,7 +590,6 @@ static void drm_unload(drm_device_t *dev)
 	DRM_UNLOCK();
 
 	if ( dev->agp ) {
-		drm_agp_uninit();
 		free(dev->agp, M_DRM);
 		dev->agp = NULL;
 	}
-- 
cgit v1.2.3