drm: add in-kernel entry points for rest of AGP ioctls

Allow DRM modules to call AGP internally in the kernel.

From: Ian Romanick <idr@us.ibm.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index e9ede8d..6681429 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -925,13 +925,17 @@
 extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info);
 extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
 			      unsigned int cmd, unsigned long arg);
-extern int drm_agp_alloc(struct inode *inode, struct file *filp,
+extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request);
+extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
 			 unsigned int cmd, unsigned long arg);
-extern int drm_agp_free(struct inode *inode, struct file *filp,
+extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request);
+extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
 			unsigned int cmd, unsigned long arg);
-extern int drm_agp_unbind(struct inode *inode, struct file *filp,
+extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
+extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
 			  unsigned int cmd, unsigned long arg);
-extern int drm_agp_bind(struct inode *inode, struct file *filp,
+extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request);
+extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
 			unsigned int cmd, unsigned long arg);
 extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge,
 					    size_t pages, u32 type);
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
index 2b6453a..b80e61a 100644
--- a/drivers/char/drm/drm_agpsupport.c
+++ b/drivers/char/drm/drm_agpsupport.c
@@ -208,30 +208,22 @@
  * Verifies the AGP device is present and has been acquired, allocates the
  * memory via alloc_agp() and creates a drm_agp_mem entry for it.
  */
-int drm_agp_alloc(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
+int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->head->dev;
-	drm_agp_buffer_t request;
 	drm_agp_mem_t *entry;
 	DRM_AGP_MEM *memory;
 	unsigned long pages;
 	u32 type;
-	drm_agp_buffer_t __user *argp = (void __user *)arg;
 
 	if (!dev->agp || !dev->agp->acquired)
 		return -EINVAL;
-	if (copy_from_user(&request, argp, sizeof(request)))
-		return -EFAULT;
 	if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
 		return -ENOMEM;
 
 	memset(entry, 0, sizeof(*entry));
 
-	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
-	type = (u32) request.type;
-
+	pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
+	type = (u32) request->type;
 	if (!(memory = drm_alloc_agp(dev, pages, type))) {
 		drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
 		return -ENOMEM;
@@ -247,16 +239,39 @@
 		dev->agp->memory->prev = entry;
 	dev->agp->memory = entry;
 
-	request.handle = entry->handle;
-	request.physical = memory->physical;
+	request->handle = entry->handle;
+	request->physical = memory->physical;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_agp_alloc);
+
+int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->head->dev;
+	drm_agp_buffer_t request;
+	drm_agp_buffer_t __user *argp = (void __user *)arg;
+	int err;
+
+	if (copy_from_user(&request, argp, sizeof(request)))
+		return -EFAULT;
+
+	err = drm_agp_alloc(dev, &request);
+	if (err)
+		return err;
 
 	if (copy_to_user(argp, &request, sizeof(request))) {
+		drm_agp_mem_t *entry = dev->agp->memory;
+
 		dev->agp->memory = entry->next;
 		dev->agp->memory->prev = NULL;
-		drm_free_agp(memory, pages);
+		drm_free_agp(entry->memory, entry->pages);
 		drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
 		return -EFAULT;
 	}
+
 	return 0;
 }
 
@@ -293,21 +308,14 @@
  * Verifies the AGP device is present and acquired, looks-up the AGP memory
  * entry and passes it to the unbind_agp() function.
  */
-int drm_agp_unbind(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
+int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->head->dev;
-	drm_agp_binding_t request;
 	drm_agp_mem_t *entry;
 	int ret;
 
 	if (!dev->agp || !dev->agp->acquired)
 		return -EINVAL;
-	if (copy_from_user
-	    (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+	if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
 		return -EINVAL;
 	if (!entry->bound)
 		return -EINVAL;
@@ -316,6 +324,21 @@
 		entry->bound = 0;
 	return ret;
 }
+EXPORT_SYMBOL(drm_agp_unbind);
+
+int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
+			 unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->head->dev;
+	drm_agp_binding_t request;
+
+	if (copy_from_user
+	    (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
+		return -EFAULT;
+
+	return drm_agp_unbind(dev, &request);
+}
 
 /**
  * Bind AGP memory into the GATT (ioctl)
@@ -330,26 +353,19 @@
  * is currently bound into the GATT. Looks-up the AGP memory entry and passes
  * it to bind_agp() function.
  */
-int drm_agp_bind(struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg)
+int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->head->dev;
-	drm_agp_binding_t request;
 	drm_agp_mem_t *entry;
 	int retcode;
 	int page;
 
 	if (!dev->agp || !dev->agp->acquired)
 		return -EINVAL;
-	if (copy_from_user
-	    (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+	if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
 		return -EINVAL;
 	if (entry->bound)
 		return -EINVAL;
-	page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
+	page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE;
 	if ((retcode = drm_bind_agp(entry->memory, page)))
 		return retcode;
 	entry->bound = dev->agp->base + (page << PAGE_SHIFT);
@@ -357,6 +373,21 @@
 		  dev->agp->base, entry->bound);
 	return 0;
 }
+EXPORT_SYMBOL(drm_agp_bind);
+
+int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
+		       unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->head->dev;
+	drm_agp_binding_t request;
+
+	if (copy_from_user
+	    (&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
+		return -EFAULT;
+
+	return drm_agp_bind(dev, &request);
+}
 
 /**
  * Free AGP memory (ioctl).
@@ -372,20 +403,13 @@
  * unbind_agp(). Frees it via free_agp() as well as the entry itself
  * and unlinks from the doubly linked list it's inserted in.
  */
-int drm_agp_free(struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg)
+int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->head->dev;
-	drm_agp_buffer_t request;
 	drm_agp_mem_t *entry;
 
 	if (!dev->agp || !dev->agp->acquired)
 		return -EINVAL;
-	if (copy_from_user
-	    (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+	if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
 		return -EINVAL;
 	if (entry->bound)
 		drm_unbind_agp(entry->memory);
@@ -402,6 +426,21 @@
 	drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
 	return 0;
 }
+EXPORT_SYMBOL(drm_agp_free);
+
+int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
+		       unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->head->dev;
+	drm_agp_buffer_t request;
+
+	if (copy_from_user
+	    (&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
+		return -EFAULT;
+
+	return drm_agp_free(dev, &request);
+}
 
 /**
  * Initialize the AGP resources.
diff --git a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h
index cc97bb9..f4f9db6c 100644
--- a/drivers/char/drm/drm_core.h
+++ b/drivers/char/drm/drm_core.h
@@ -24,11 +24,11 @@
 
 #define CORE_NAME		"drm"
 #define CORE_DESC		"DRM shared core routines"
-#define CORE_DATE		"20040925"
+#define CORE_DATE		"20051102"
 
 #define DRM_IF_MAJOR	1
 #define DRM_IF_MINOR	2
 
 #define CORE_MAJOR	1
 #define CORE_MINOR	0
-#define CORE_PATCHLEVEL 0
+#define CORE_PATCHLEVEL 1
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index d8ff84b..222ae09 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -106,10 +106,10 @@
 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1},
 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1},
 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0},
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1},
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1},
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, 1, 1},
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, 1, 1},
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, 1, 1},
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, 1, 1},
 #endif
 
 	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1},