summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/drmP.h97
-rw-r--r--linux/drm_agp.h95
-rw-r--r--linux/drm_agp_tmp.h (renamed from linux/drm_agpsupport.h)346
-rw-r--r--linux/drm_bufs.h3
-rw-r--r--linux/drm_drv.h68
-rw-r--r--linux/drm_memory.h12
-rw-r--r--linux/drm_memory_debug.h8
-rw-r--r--linux/drm_sg.h65
-rw-r--r--linux/drm_sg_tmp.h (renamed from linux/drm_scatter.h)164
-rw-r--r--linux/gamma_drv.c2
-rw-r--r--linux/i810_drv.c2
-rw-r--r--linux/i830_drv.c2
-rw-r--r--linux/mga_drv.c2
-rw-r--r--linux/r128_drv.c4
-rw-r--r--linux/radeon_drv.c4
-rw-r--r--linux/sis_drv.c2
16 files changed, 565 insertions, 311 deletions
diff --git a/linux/drmP.h b/linux/drmP.h
index 5626e4ff..d927e890 100644
--- a/linux/drmP.h
+++ b/linux/drmP.h
@@ -86,7 +86,6 @@
#include "drm_os_linux.h"
-
/***********************************************************************/
/** \name DRM template customization defaults */
/*@{*/
@@ -121,6 +120,12 @@
/*@}*/
+typedef struct drm_device drm_device_t;
+
+#include "drm_agp.h"
+#include "drm_sg.h"
+
+
/***********************************************************************/
/** \name Begin the DRM... */
/*@{*/
@@ -575,48 +580,6 @@ typedef struct drm_device_dma {
/*@}*/
} drm_device_dma_t;
-#if __REALLY_HAVE_AGP
-/**
- * AGP memory entry. Stored as a doubly linked list.
- */
-typedef struct drm_agp_mem {
- unsigned long handle; /**< handle */
- agp_memory *memory;
- unsigned long bound; /**< address */
- int pages;
- struct drm_agp_mem *prev; /**< previous entry */
- struct drm_agp_mem *next; /**< next entry */
-} drm_agp_mem_t;
-
-/**
- * AGP data.
- *
- * \sa DRM(agp_init)() and drm_device::agp.
- */
-typedef struct drm_agp_head {
- agp_kern_info agp_info; /**< AGP device information */
- drm_agp_mem_t *memory; /**< memory entries */
- unsigned long mode; /**< AGP mode */
- int enabled; /**< whether the AGP bus as been enabled */
- int acquired; /**< whether the AGP device has been acquired */
- unsigned long base;
- int agp_mtrr;
- int cant_use_aperture;
- unsigned long page_mask;
-} drm_agp_head_t;
-#endif
-
-/**
- * Scatter-gather memory.
- */
-typedef struct drm_sg_mem {
- unsigned long handle;
- void *virtual;
- int pages;
- struct page **pagelist;
- dma_addr_t *busaddr;
-} drm_sg_mem_t;
-
typedef struct drm_sigdata {
int context;
drm_hw_lock_t *lock;
@@ -646,7 +609,7 @@ typedef struct drm_vbl_sig {
/**
* DRM device structure.
*/
-typedef struct drm_device {
+struct drm_device {
const char *name; /**< Simple driver name */
char *unique; /**< Unique identifier: e.g., busid */
int unique_len; /**< Length of unique field */
@@ -757,11 +720,12 @@ typedef struct drm_device {
#endif
#endif
drm_sg_mem_t *sg; /**< Scatter gather memory */
+
unsigned long *ctx_bitmap; /**< context bitmap */
void *dev_private; /**< device private data */
drm_sigdata_t sigdata; /**< For block_all_signals */
sigset_t sigmask;
-} drm_device_t;
+};
/******************************************************************/
@@ -830,10 +794,10 @@ extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size,
extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
#if __REALLY_HAVE_AGP
-extern agp_memory *DRM(alloc_agp)(int pages, u32 type);
-extern int DRM(free_agp)(agp_memory *handle, int pages);
-extern int DRM(bind_agp)(agp_memory *handle, unsigned int start);
-extern int DRM(unbind_agp)(agp_memory *handle);
+extern agp_memory *DRM(agp_alloc)(int pages, u32 type);
+extern int DRM(agp_free)(agp_memory *handle, int pages);
+extern int DRM(agp_bind)(agp_memory *handle, unsigned int start);
+extern int DRM(agp_unbind)(agp_memory *handle);
#endif
/* Misc. IOCTL support (drm_ioctl.h) */
@@ -956,32 +920,6 @@ extern void DRM(dma_immediate_bh)( void *dev );
#endif /* __HAVE_DMA */
-#if __REALLY_HAVE_AGP
- /* AGP/GART support (drm_agpsupport.h) */
-extern drm_agp_head_t *DRM(agp_init)(void);
-extern void DRM(agp_uninit)(void);
-extern int DRM(agp_acquire)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern void DRM(agp_do_release)(void);
-extern int DRM(agp_release)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(agp_enable)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(agp_info)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(agp_alloc)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(agp_free)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(agp_unbind)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(agp_bind)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
-extern int DRM(agp_free_memory)(agp_memory *handle);
-extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start);
-extern int DRM(agp_unbind_memory)(agp_memory *handle);
-#endif
/* Stub support (drm_stub.h) */
int DRM(stub_register)(const char *name,
@@ -998,15 +936,6 @@ extern int DRM(proc_cleanup)(int minor,
struct proc_dir_entry *root,
struct proc_dir_entry *dev_root);
-#if __HAVE_SG
- /* Scatter Gather Support (drm_scatter.h) */
-extern void DRM(sg_cleanup)(drm_sg_mem_t *entry);
-extern int DRM(sg_alloc)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int DRM(sg_free)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-#endif
-
/* ATI PCIGART support (ati_pcigart.h) */
extern int DRM(ati_pcigart_init)(drm_device_t *dev,
unsigned long *addr,
diff --git a/linux/drm_agp.h b/linux/drm_agp.h
new file mode 100644
index 00000000..27c2b29f
--- /dev/null
+++ b/linux/drm_agp.h
@@ -0,0 +1,95 @@
+/**
+ * \file drm_agp.h
+ * DRM support for AGP/GART backend
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DRM_AGP_H_
+#define _DRM_AGP_H_
+
+
+/**
+ * AGP memory entry. Stored as a doubly linked list.
+ */
+typedef struct drm_agp_mem {
+ unsigned long handle; /**< handle */
+ agp_memory *memory;
+ unsigned long bound; /**< address */
+ int pages;
+ struct drm_agp_mem *prev; /**< previous entry */
+ struct drm_agp_mem *next; /**< next entry */
+} drm_agp_mem_t;
+
+/**
+ * AGP data.
+ *
+ * \sa DRM(agp_init)() and drm_device::agp.
+ */
+typedef struct drm_agp_head {
+ agp_kern_info agp_info; /**< AGP device information */
+ drm_agp_mem_t *memory; /**< memory entries */
+ unsigned long mode; /**< AGP mode */
+ int enabled; /**< whether the AGP bus as been enabled */
+ int acquired; /**< whether the AGP device has been acquired */
+ unsigned long base;
+ int agp_mtrr;
+ int cant_use_aperture;
+ unsigned long page_mask;
+} drm_agp_head_t;
+
+
+/** \name Prototypes */
+/*@{*/
+
+extern int DRM(agp_acquire)(void);
+extern void DRM(agp_release)(void);
+extern void DRM(agp_enable)(unsigned mode);
+extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
+extern int DRM(agp_free_memory)(agp_memory *handle);
+extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start);
+extern int DRM(agp_unbind_memory)(agp_memory *handle);
+
+extern int DRM(agp_acquire_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern int DRM(agp_release_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern int DRM(agp_enable_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern int DRM(agp_info_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern int DRM(agp_alloc_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern int DRM(agp_free_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern int DRM(agp_bind_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern int DRM(agp_unbind_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+
+extern void DRM(agp_init)(void);
+extern void DRM(agp_cleanup)(void);
+extern void DRM(agp_init_dev)(drm_device_t *dev);
+extern void DRM(agp_cleanup_dev)(drm_device_t *dev);
+
+/*@}*/
+
+#endif
diff --git a/linux/drm_agpsupport.h b/linux/drm_agp_tmp.h
index 81850593..4b52ed4f 100644
--- a/linux/drm_agpsupport.h
+++ b/linux/drm_agp_tmp.h
@@ -1,5 +1,5 @@
/**
- * \file drm_agpsupport.h
+ * \file drm_agp_tmp.h
* DRM support for AGP/GART backend
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -31,62 +31,117 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+
+
+#if __REALLY_HAVE_AGP
+
#define __NO_VERSION__
#include "drmP.h"
#include <linux/module.h>
-#if __REALLY_HAVE_AGP
+/**
+ * Pointer to the drm_agp_t structure made available by the AGPGART module.
+ */
+static const drm_agp_t *drm_agp = NULL;
-#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
-#define DRM_AGP_PUT inter_module_put("drm_agp")
+
+/**********************************************************************/
+/** \name drm_agp wrappers
+ *
+ * These functions are thin wrappers around the respective methods in drm_agp
+ * which are exposed by the AGPGART module.
+ *
+ * \todo Put these in a header inline.
+ */
/**
- * Pointer to the drm_agp_t structure made available by the agpgart module.
+ * Acquire the AGP device.
*/
-static const drm_agp_t *drm_agp = NULL;
+int DRM(agp_acquire)(void)
+{
+ return drm_agp->acquire();
+}
/**
- * AGP information ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a (output) drm_agp_info structure.
- * \return zero on success or a negative number on failure.
+ * Release the AGP device.
+ */
+void DRM(agp_release)(void)
+{
+ if (drm_agp->release)
+ drm_agp->release();
+}
+
+/**
+ * Enable the AGP bus.
+ */
+void DRM(agp_enable)(unsigned mode)
+{
+ if (drm_agp->enable)
+ drm_agp->enable(mode);
+}
+
+/**
+ * Allocate AGP memory.
+ *
+ * Not meant to be called directly. Use agp_alloc() instead, which can provide
+ * some debugging features.
+ */
+agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
+{
+ if (!drm_agp->allocate_memory)
+ return NULL;
+ return drm_agp->allocate_memory(pages, type);
+}
+
+/**
+ * Free AGP memory.
+ *
+ * Not meant to be called directly. Use agp_free() instead, which can provide
+ * some debugging features.
+ */
+int DRM(agp_free_memory)(agp_memory *handle)
+{
+ if (!handle || !drm_agp->free_memory)
+ return 0;
+ drm_agp->free_memory(handle);
+ return 1;
+}
+
+/**
+ * Bind AGP memory.
*
- * Verifies the AGP device has been initialized and acquired and fills in the
- * drm_agp_info structure with the information in drm_agp_head::agp_info.
+ * Not meant to be called directly. Use agp_bind() instead, which can provide
+ * some debugging features.
*/
-int DRM(agp_info)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int DRM(agp_bind_memory)(agp_memory *handle, off_t start)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- agp_kern_info *kern;
- drm_agp_info_t info;
+ if (!handle || !drm_agp->bind_memory)
+ return -EINVAL;
+ return drm_agp->bind_memory(handle, start);
+}
- if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
+/**
+ * Bind AGP memory.
+ *
+ * Not meant to be called directly. Use agp_unbind() instead, which can provide
+ * some debugging features.
+ */
+int DRM(agp_unbind_memory)(agp_memory *handle)
+{
+ if (!handle || !drm_agp->unbind_memory)
return -EINVAL;
+ return drm_agp->unbind_memory(handle);
+}
- kern = &dev->agp->agp_info;
- info.agp_version_major = kern->version.major;
- info.agp_version_minor = kern->version.minor;
- info.mode = kern->mode;
- info.aperture_base = kern->aper_base;
- info.aperture_size = kern->aper_size * 1024 * 1024;
- info.memory_allowed = kern->max_memory << PAGE_SHIFT;
- info.memory_used = kern->current_memory << PAGE_SHIFT;
- info.id_vendor = kern->device->vendor;
- info.id_device = kern->device->device;
+/**@}*/
- if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
+
+/**********************************************************************/
+/** \name Ioctl's */
/**
- * Acquire the AGP device (ioctl).
+ * Acquire the AGP device.
*
* \param inode device inode.
* \param filp file pointer.
@@ -95,9 +150,9 @@ int DRM(agp_info)(struct inode *inode, struct file *filp,
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device hasn't been acquired before and calls
- * drm_agp->acquire().
+ * drm_acquire().
*/
-int DRM(agp_acquire)(struct inode *inode, struct file *filp,
+int DRM(agp_acquire_ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -106,13 +161,13 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
return -EINVAL;
- if ((retcode = drm_agp->acquire())) return retcode;
+ if ((retcode = DRM(agp_acquire)())) return retcode;
dev->agp->acquired = 1;
return 0;
}
/**
- * Release the AGP device (ioctl).
+ * Release the AGP device.
*
* \param inode device inode.
* \param filp file pointer.
@@ -122,7 +177,7 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
*
* Verifies the AGP device has been acquired and calls drm_agp->release().
*/
-int DRM(agp_release)(struct inode *inode, struct file *filp,
+int DRM(agp_release_ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -137,13 +192,42 @@ int DRM(agp_release)(struct inode *inode, struct file *filp,
}
/**
- * Release the AGP device.
+ * Get AGP information.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to an (output) drm_agp_info structure.
+ * \return zero on success or a negative number on failure.
*
- * Calls drm_agp->release().
+ * Verifies the AGP device has been initialized and acquired and fills in the
+ * drm_agp_info structure with the information in drm_agp_head::agp_info.
*/
-void DRM(agp_do_release)(void)
+int DRM(agp_info_ioctl)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- if (drm_agp->release) drm_agp->release();
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ agp_kern_info *kern;
+ drm_agp_info_t info;
+
+ if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
+ return -EINVAL;
+
+ kern = &dev->agp->agp_info;
+ info.agp_version_major = kern->version.major;
+ info.agp_version_minor = kern->version.minor;
+ info.mode = kern->mode;
+ info.aperture_base = kern->aper_base;
+ info.aperture_size = kern->aper_size * 1024 * 1024;
+ info.memory_allowed = kern->max_memory << PAGE_SHIFT;
+ info.memory_used = kern->current_memory << PAGE_SHIFT;
+ info.id_vendor = kern->device->vendor;
+ info.id_device = kern->device->device;
+
+ if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
}
/**
@@ -155,10 +239,10 @@ void DRM(agp_do_release)(void)
* \param arg pointer to a drm_agp_mode structure.
* \return zero on success or a negative number on failure.
*
- * Verifies the AGP device has been acquired but not enabled, and calls
- * drm_agp->enable().
+ * Verifies the AGP device has been acquired, and calls
+ * agp_enable().
*/
-int DRM(agp_enable)(struct inode *inode, struct file *filp,
+int DRM(agp_enable_ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -172,7 +256,7 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp,
return -EFAULT;
dev->agp->mode = mode.mode;
- drm_agp->enable(mode.mode);
+ DRM(agp_enable)(mode.mode);
dev->agp->base = dev->agp->agp_info.aper_base;
dev->agp->enabled = 1;
return 0;
@@ -190,7 +274,7 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp,
* 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,
+int DRM(agp_alloc_ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -212,7 +296,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
type = (u32) request.type;
- if (!(memory = DRM(alloc_agp)(pages, type))) {
+ if (!(memory = DRM(agp_alloc)(pages, type))) {
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -ENOMEM;
}
@@ -232,7 +316,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) {
dev->agp->memory = entry->next;
dev->agp->memory->prev = NULL;
- DRM(free_agp)(memory, pages);
+ DRM(agp_free)(memory, pages);
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -EFAULT;
}
@@ -260,7 +344,7 @@ static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
}
/**
- * Unbind AGP memory from the GATT (ioctl).
+ * Unbind AGP memory from the GATT.
*
* \param inode device inode.
* \param filp file pointer.
@@ -271,7 +355,7 @@ static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
* 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,
+int DRM(agp_unbind_ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -286,14 +370,14 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
if (!entry->bound) return -EINVAL;
- ret = DRM(unbind_agp)(entry->memory);
+ ret = DRM(agp_unbind)(entry->memory);
if (ret == 0)
entry->bound = 0;
return ret;
}
/**
- * Bind AGP memory into the GATT (ioctl)
+ * Bind AGP memory into the GATT
*
* \param inode device inode.
* \param filp file pointer.
@@ -305,7 +389,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
* 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,
+int DRM(agp_bind_ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -323,7 +407,7 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
return -EINVAL;
if (entry->bound) return -EINVAL;
page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
- if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode;
+ if ((retcode = DRM(agp_bind)(entry->memory, page))) return retcode;
entry->bound = dev->agp->base + (page << PAGE_SHIFT);
DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
dev->agp->base, entry->bound);
@@ -331,7 +415,7 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
}
/**
- * Free AGP memory (ioctl).
+ * Free AGP memory.
*
* \param inode device inode.
* \param filp file pointer.
@@ -344,7 +428,7 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
* 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,
+int DRM(agp_free_ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -357,95 +441,113 @@ int DRM(agp_free)(struct inode *inode, struct file *filp,
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
- if (entry->bound) DRM(unbind_agp)(entry->memory);
+ if (entry->bound) DRM(agp_unbind)(entry->memory);
if (entry->prev) entry->prev->next = entry->next;
else dev->agp->memory = entry->next;
if (entry->next) entry->next->prev = entry->prev;
- DRM(free_agp)(entry->memory, entry->pages);
+ DRM(agp_free)(entry->memory, entry->pages);
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return 0;
}
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Initialization and cleanup */
+/*@{*/
+
/**
- * Initialize the AGP resources.
- *
- * \return pointer to a drm_agp_head structure.
+ * Initialize the global AGP resources.
*
* Gets the drm_agp_t structure which is made available by the agpgart module
- * via the inter_module_* functions. Creates and initializes a drm_agp_head
- * structure.
+ * via the inter_module_* functions.
*/
-drm_agp_head_t *DRM(agp_init)(void)
+void DRM(agp_init)(void)
{
- drm_agp_head_t *head = NULL;
-
- drm_agp = DRM_AGP_GET;
- if (drm_agp) {
- if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
- return NULL;
- memset((void *)head, 0, sizeof(*head));
- drm_agp->copy_info(&head->agp_info);
- if (head->agp_info.chipset == NOT_SUPPORTED) {
- DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
- return NULL;
- }
- head->memory = NULL;
-#if LINUX_VERSION_CODE <= 0x020408
- head->cant_use_aperture = 0;
- head->page_mask = ~(0xfff);
-#else
- head->cant_use_aperture = head->agp_info.cant_use_aperture;
- head->page_mask = head->agp_info.page_mask;
-#endif
-
- DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n",
- head->agp_info.version.major,
- head->agp_info.version.minor,
- head->agp_info.aper_base,
- head->agp_info.aper_size);
- }
- return head;
+ drm_agp = (drm_agp_t *)inter_module_get("drm_agp");
}
/**
- * Free the AGP resources.
+ * Free the global AGP resources.
*
* Releases the pointer in ::drm_agp.
*/
-void DRM(agp_uninit)(void)
+void DRM(agp_cleanup)(void)
{
- DRM_AGP_PUT;
- drm_agp = NULL;
+ if (drm_agp) {
+ inter_module_put("drm_agp");
+ drm_agp = NULL;
+ }
}
-/** Calls drm_agp->allocate_memory() */
-agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
+/**
+ * Initialize the device AGP resources.
+ *
+ * Creates and initializes a drm_agp_head structure in drm_device_t::agp.
+ */
+void DRM(agp_init_dev)(drm_device_t *dev)
{
- if (!drm_agp->allocate_memory) return NULL;
- return drm_agp->allocate_memory(pages, type);
-}
+ drm_agp_head_t *head = NULL;
-/** Calls drm_agp->free_memory() */
-int DRM(agp_free_memory)(agp_memory *handle)
-{
- if (!handle || !drm_agp->free_memory) return 0;
- drm_agp->free_memory(handle);
- return 1;
-}
+ if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
+ return;
-/** Calls drm_agp->bind_memory() */
-int DRM(agp_bind_memory)(agp_memory *handle, off_t start)
-{
- if (!handle || !drm_agp->bind_memory) return -EINVAL;
- return drm_agp->bind_memory(handle, start);
+ memset((void *)head, 0, sizeof(*head));
+ drm_agp->copy_info(&head->agp_info);
+ if (head->agp_info.chipset == NOT_SUPPORTED) {
+ DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
+ }
+ head->memory = NULL;
+#if LINUX_VERSION_CODE <= 0x020408
+ head->cant_use_aperture = 0;
+ head->page_mask = ~(0xfff);
+#else
+ head->cant_use_aperture = head->agp_info.cant_use_aperture;
+ head->page_mask = head->agp_info.page_mask;
+#endif
+
+ DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n",
+ head->agp_info.version.major,
+ head->agp_info.version.minor,
+ head->agp_info.aper_base,
+ head->agp_info.aper_size);
+
+ dev->agp = head;
}
-/** Calls drm_agp->unbind_memory() */
-int DRM(agp_unbind_memory)(agp_memory *handle)
+/**
+ * Free the device AGP resources.
+ */
+void DRM(agp_cleanup_dev)(drm_device_t *dev)
{
- if (!handle || !drm_agp->unbind_memory) return -EINVAL;
- return drm_agp->unbind_memory(handle);
+ if ( dev->agp ) {
+ drm_agp_mem_t *entry;
+ drm_agp_mem_t *nexte;
+
+ /* Remove AGP resources, but leave dev->agp
+ intact until drv_cleanup is called. */
+ for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
+ nexte = entry->next;
+ if ( entry->bound ) DRM(agp_unbind)( entry->memory );
+ DRM(agp_free)( entry->memory, entry->pages );
+ DRM(free)( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
+ }
+ dev->agp->memory = NULL;
+
+ if ( dev->agp->acquired )
+ DRM(agp_release)();
+
+ dev->agp->acquired = 0;
+ dev->agp->enabled = 0;
+
+ DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+ dev->agp = NULL;
+ }
}
+/*@}*/
+
+
#endif /* __REALLY_HAVE_AGP */
diff --git a/linux/drm_bufs.h b/linux/drm_bufs.h
index 77573709..f42fabef 100644
--- a/linux/drm_bufs.h
+++ b/linux/drm_bufs.h
@@ -174,6 +174,8 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
break;
#endif
+
+#if __HAVE_SG
case _DRM_SCATTER_GATHER:
if (!dev->sg) {
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
@@ -181,6 +183,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
}
map->offset += dev->sg->handle;
break;
+#endif
default:
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
diff --git a/linux/drm_drv.h b/linux/drm_drv.h
index 90c2d18b..5a4ab36e 100644
--- a/linux/drm_drv.h
+++ b/linux/drm_drv.h
@@ -225,19 +225,19 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
#endif
#if __REALLY_HAVE_AGP
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 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_ACQUIRE)] = { DRM(agp_acquire_ioctl), 1, 1 },
+ [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_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
#if __HAVE_SG
- [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { DRM(sg_alloc), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { DRM(sg_alloc_ioctl), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free_ioctl), 1, 1 },
#endif
#if __HAVE_VBL_IRQ
@@ -416,29 +416,6 @@ static int DRM(takedown)( drm_device_t *dev )
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
}
-#if __REALLY_HAVE_AGP
- /* Clear AGP information */
- if ( dev->agp ) {
- drm_agp_mem_t *entry;
- drm_agp_mem_t *nexte;
-
- /* Remove AGP resources, but leave dev->agp
- intact until drv_cleanup is called. */
- for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
- nexte = entry->next;
- if ( entry->bound ) DRM(unbind_agp)( entry->memory );
- DRM(free_agp)( entry->memory, entry->pages );
- DRM(free)( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
- }
- dev->agp->memory = NULL;
-
- if ( dev->agp->acquired ) DRM(agp_do_release)();
-
- dev->agp->acquired = 0;
- dev->agp->enabled = 0;
- }
-#endif
-
/* Clear vma list (only built for debugging) */
if ( dev->vmalist ) {
for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
@@ -486,10 +463,7 @@ static int DRM(takedown)( drm_device_t *dev )
* isn't defined.
*/
#if __HAVE_SG
- if(dev->sg) {
- DRM(sg_cleanup)(dev->sg);
- dev->sg = NULL;
- }
+ DRM(sg_cleanup)(dev);
#endif
break;
}
@@ -618,6 +592,10 @@ static int __init drm_init( void )
DRM(mem_init)();
+#if __REALLY_HAVE_AGP
+ DRM(agp_init)();
+#endif
+
for (i = 0; i < DRM(numdevs); i++) {
dev = &(DRM(device)[i]);
memset( (void *)dev, 0, sizeof(*dev) );
@@ -630,8 +608,9 @@ static int __init drm_init( void )
dev->name = DRIVER_NAME;
#if __REALLY_HAVE_AGP
- dev->agp = DRM(agp_init)();
+ DRM(agp_init_dev)( dev );
#if __MUST_HAVE_AGP
+
if ( dev->agp == NULL ) {
DRM_ERROR( "Cannot initialize the agpgart module.\n" );
DRM(stub_unregister)(DRM(minor)[i]);
@@ -639,14 +618,12 @@ static int __init drm_init( void )
return -ENOMEM;
}
#endif
-#if __REALLY_HAVE_MTRR
if (dev->agp)
dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
dev->agp->agp_info.aper_size*1024*1024,
MTRR_TYPE_WRCOMB,
1 );
#endif
-#endif
#if __HAVE_CTX_BITMAP
retcode = DRM(ctxbitmap_init)( dev );
@@ -712,13 +689,14 @@ static void __exit drm_cleanup( void )
DRM(takedown)( dev );
#if __REALLY_HAVE_AGP
- if ( dev->agp ) {
- DRM(agp_uninit)();
- DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
- dev->agp = NULL;
- }
+ DRM(agp_cleanup_dev)( dev );
#endif
}
+
+#if __REALLY_HAVE_AGP
+ DRM(agp_cleanup)();
+#endif
+
DRIVER_POSTCLEANUP();
kfree(DRM(minor));
kfree(DRM(device));
diff --git a/linux/drm_memory.h b/linux/drm_memory.h
index 2a969fcd..9999c213 100644
--- a/linux/drm_memory.h
+++ b/linux/drm_memory.h
@@ -332,27 +332,29 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
#if __REALLY_HAVE_AGP
/** Wrapper around agp_allocate_memory() */
-agp_memory *DRM(alloc_agp)(int pages, u32 type)
+agp_memory *DRM(agp_alloc)(int pages, u32 type)
{
return DRM(agp_allocate_memory)(pages, type);
}
/** Wrapper around agp_free_memory() */
-int DRM(free_agp)(agp_memory *handle, int pages)
+int DRM(agp_free)(agp_memory *handle, int pages)
{
return DRM(agp_free_memory)(handle) ? 0 : -EINVAL;
}
/** Wrapper around agp_bind_memory() */
-int DRM(bind_agp)(agp_memory *handle, unsigned int start)
+int DRM(agp_bind)(agp_memory *handle, unsigned int start)
{
return DRM(agp_bind_memory)(handle, start);
}
/** Wrapper around agp_unbind_memory() */
-int DRM(unbind_agp)(agp_memory *handle)
+int DRM(agp_unbind)(agp_memory *handle)
{
return DRM(agp_unbind_memory)(handle);
}
-#endif /* agp */
+#endif /* __REALLY_HAVE_AGP */
+
+
#endif /* debug_memory */
diff --git a/linux/drm_memory_debug.h b/linux/drm_memory_debug.h
index 5cfff83a..860fc741 100644
--- a/linux/drm_memory_debug.h
+++ b/linux/drm_memory_debug.h
@@ -343,7 +343,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
#if __REALLY_HAVE_AGP
-agp_memory *DRM(alloc_agp)(int pages, u32 type)
+agp_memory *DRM(agp_alloc)(int pages, u32 type)
{
agp_memory *handle;
@@ -366,7 +366,7 @@ agp_memory *DRM(alloc_agp)(int pages, u32 type)
return NULL;
}
-int DRM(free_agp)(agp_memory *handle, int pages)
+int DRM(agp_free)(agp_memory *handle, int pages)
{
int alloc_count;
int free_count;
@@ -395,7 +395,7 @@ int DRM(free_agp)(agp_memory *handle, int pages)
return retval;
}
-int DRM(bind_agp)(agp_memory *handle, unsigned int start)
+int DRM(agp_bind)(agp_memory *handle, unsigned int start)
{
int retcode = -EINVAL;
@@ -419,7 +419,7 @@ int DRM(bind_agp)(agp_memory *handle, unsigned int start)
return retcode;
}
-int DRM(unbind_agp)(agp_memory *handle)
+int DRM(agp_unbind)(agp_memory *handle)
{
int alloc_count;
int free_count;
diff --git a/linux/drm_sg.h b/linux/drm_sg.h
new file mode 100644
index 00000000..afd80ef0
--- /dev/null
+++ b/linux/drm_sg.h
@@ -0,0 +1,65 @@
+/**
+ * \file drm_sg.h
+ * IOCTLs to manage scatter/gather memory
+ *
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _DRM_SCATTER_H_
+#define _DRM_SCATTER_H_
+
+
+/**
+ * Scatter/gather memory entry.
+ *
+ * This structure is used by sg_alloc() sg_free() to store all the necessary
+ * information about a scatter/gather memory block.
+ *
+ * Also one instance of this structure is used to hold the user-space
+ * allocation done via the sg_alloc_ioctl() and sg_free_ioctl() ioctl's.
+ */
+typedef struct drm_sg_mem {
+ unsigned long handle;
+ void *virtual; /**< virtual address */
+ int pages;
+ struct page **pagelist;
+ dma_addr_t *busaddr; /**< bus address */
+} drm_sg_mem_t;
+
+
+/** \name Prototypes */
+/*@{*/
+extern void DRM(sg_free)( drm_sg_mem_t *entry );
+extern drm_sg_mem_t * DRM(sg_alloc)( unsigned long size );
+extern int DRM(sg_alloc_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern int DRM(sg_free_ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+extern void DRM(sg_cleanup)(drm_device_t *dev);
+/*@}*/
+
+
+#endif
diff --git a/linux/drm_scatter.h b/linux/drm_sg_tmp.h
index 45a30fc3..95cb1fc7 100644
--- a/linux/drm_scatter.h
+++ b/linux/drm_sg_tmp.h
@@ -1,13 +1,11 @@
/**
- * \file drm_scatter.h
+ * \file drm_sg_tmp.h
* IOCTLs to manage scatter/gather memory
*
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
- * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
- *
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
@@ -31,14 +29,29 @@
* DEALINGS IN THE SOFTWARE.
*/
+
+#if __HAVE_SG
+
+
#define __NO_VERSION__
#include <linux/config.h>
#include <linux/vmalloc.h>
#include "drmP.h"
+
+/**
+ * Define to non-zero to verify that each page points to its virtual address,
+ * and vice versa, in sg_alloc().
+ */
#define DEBUG_SCATTER 0
-void DRM(sg_cleanup)( drm_sg_mem_t *entry )
+
+/**
+ * Free scatter/gather memory.
+ *
+ * \param entry scatter/gather memory entry to free, as returned by sg_alloc().
+ */
+void DRM(sg_free)( drm_sg_mem_t *entry )
{
struct page *page;
int i;
@@ -62,40 +75,34 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry )
DRM_MEM_SGLISTS );
}
-int DRM(sg_alloc)( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+/**
+ * Allocate scatter/gather memory.
+ *
+ * \param size size of memory to allocate.
+ * \return pointer to a drm_sg_mem structure on success or NULL on failure.
+ */
+drm_sg_mem_t * DRM(sg_alloc)( unsigned long size )
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_scatter_gather_t request;
drm_sg_mem_t *entry;
unsigned long pages, i, j;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( dev->sg )
- return -EINVAL;
-
- if ( copy_from_user( &request,
- (drm_scatter_gather_t *)arg,
- sizeof(request) ) )
- return -EFAULT;
-
entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS );
if ( !entry )
- return -ENOMEM;
+ return NULL;
memset( entry, 0, sizeof(*entry) );
- pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
- DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
+ pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+ DRM_DEBUG( "sg size=%ld pages=%ld\n", size, pages );
entry->pages = pages;
entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist),
DRM_MEM_PAGES );
if ( !entry->pagelist ) {
DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
- return -ENOMEM;
+ return NULL;
}
memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
@@ -109,7 +116,7 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
DRM(free)( entry,
sizeof(*entry),
DRM_MEM_SGLISTS );
- return -ENOMEM;
+ return NULL;
}
memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
@@ -124,7 +131,7 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
DRM(free)( entry,
sizeof(*entry),
DRM_MEM_SGLISTS );
- return -ENOMEM;
+ return NULL;
}
/* This also forces the mapping of COW pages, so our page list
@@ -144,21 +151,7 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
SetPageReserved(entry->pagelist[j]);
}
- request.handle = entry->handle;
-
- if ( copy_to_user( (drm_scatter_gather_t *)arg,
- &request,
- sizeof(request) ) ) {
- DRM(sg_cleanup)( entry );
- return -EFAULT;
- }
-
- dev->sg = entry;
-
#if DEBUG_SCATTER
- /* Verify that each page points to its virtual address, and vice
- * versa.
- */
{
int error = 0;
@@ -195,14 +188,83 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
}
#endif
- return 0;
+ return entry;
failed:
- DRM(sg_cleanup)( entry );
- return -ENOMEM;
+ DRM(sg_free)( entry );
+ return NULL;
}
-int DRM(sg_free)( struct inode *inode, struct file *filp,
+
+/**********************************************************************/
+/** \name Ioctl's
+ *
+ * These expose the scatter/gather memory functions to user-space,
+ * doing the necessary parameter verification and book-keeping to avoid memory
+ * leaks.
+ *
+ * In the current implementation only one scatter/gather memory block can be
+ * allocated per device at a given instance.
+ *
+ * The information about the currently allocated scatter/gather memory block is
+ * stored in drm_device_t::sg.
+ */
+/*@{*/
+
+/**
+ * Wrapper ioctl around sg_alloc().
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_scatter_gather structure.
+ * \return zero on success or a negative number on failure.
+ */
+int DRM(sg_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->dev;
+ drm_scatter_gather_t request;
+ drm_sg_mem_t *entry;
+
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ if ( dev->sg )
+ return -EINVAL;
+
+ if ( copy_from_user( &request,
+ (drm_scatter_gather_t *)arg,
+ sizeof(request) ) )
+ return -EFAULT;
+
+ entry = DRM(sg_alloc)( request.size );
+ if ( !entry )
+ return -ENOMEM;
+
+ request.handle = entry->handle;
+
+ if ( copy_to_user( (drm_scatter_gather_t *)arg,
+ &request,
+ sizeof(request) ) ) {
+ DRM(sg_free)( entry );
+ return -EFAULT;
+ }
+
+ dev->sg = entry;
+
+ return 0;
+}
+
+/** Wrapper around sg_free().
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_scatter_gather structure.
+ * \return zero on success or a negative number on failure.
+ */
+int DRM(sg_free_ioctl)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
@@ -223,7 +285,25 @@ int DRM(sg_free)( struct inode *inode, struct file *filp,
DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
- DRM(sg_cleanup)( entry );
+ DRM(sg_free)( entry );
return 0;
}
+
+/*@}*/
+
+
+/**
+ * Called by takedown() to free the scatter/gather memory resources associated
+ * with a given device, i.e., to free drm_device_t::sg.
+ */
+void DRM(sg_cleanup)(drm_device_t *dev)
+{
+ if ( dev->sg ) {
+ DRM(sg_free)( dev->sg );
+ dev->sg = NULL;
+ }
+}
+
+
+#endif
diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c
index f1b8b205..1313418e 100644
--- a/linux/gamma_drv.c
+++ b/linux/gamma_drv.c
@@ -37,7 +37,7 @@
#include "gamma_drv.h"
#include "drm_auth.h"
-#include "drm_agpsupport.h"
+#include "drm_agp_tmp.h"
#include "drm_bufs.h"
#include "gamma_context.h" /* NOTE! */
#include "drm_dma.h"
diff --git a/linux/i810_drv.c b/linux/i810_drv.c
index 0bc79386..2b816fbf 100644
--- a/linux/i810_drv.c
+++ b/linux/i810_drv.c
@@ -37,7 +37,7 @@
#include "i810_drm.h"
#include "i810_drv.h"
-#include "drm_agpsupport.h"
+#include "drm_agp_tmp.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
diff --git a/linux/i830_drv.c b/linux/i830_drv.c
index 0735c94d..496c41ee 100644
--- a/linux/i830_drv.c
+++ b/linux/i830_drv.c
@@ -39,7 +39,7 @@
#include "i830_drm.h"
#include "i830_drv.h"
-#include "drm_agpsupport.h"
+#include "drm_agp_tmp.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
diff --git a/linux/mga_drv.c b/linux/mga_drv.c
index f0d4935d..f438660c 100644
--- a/linux/mga_drv.c
+++ b/linux/mga_drv.c
@@ -35,7 +35,7 @@
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h"
-#include "drm_agpsupport.h"
+#include "drm_agp_tmp.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
diff --git a/linux/r128_drv.c b/linux/r128_drv.c
index e2e42690..474c1418 100644
--- a/linux/r128_drv.c
+++ b/linux/r128_drv.c
@@ -37,7 +37,7 @@
#include "r128_drv.h"
#include "ati_pcigart.h"
-#include "drm_agpsupport.h"
+#include "drm_agp_tmp.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
@@ -52,4 +52,4 @@
#include "drm_proc.h"
#include "drm_vm.h"
#include "drm_stub.h"
-#include "drm_scatter.h"
+#include "drm_sg_tmp.h"
diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c
index 6152b8a5..1473e2ee 100644
--- a/linux/radeon_drv.c
+++ b/linux/radeon_drv.c
@@ -38,7 +38,7 @@
#include "radeon_drv.h"
#include "ati_pcigart.h"
-#include "drm_agpsupport.h"
+#include "drm_agp_tmp.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
@@ -53,4 +53,4 @@
#include "drm_proc.h"
#include "drm_vm.h"
#include "drm_stub.h"
-#include "drm_scatter.h"
+#include "drm_sg_tmp.h"
diff --git a/linux/sis_drv.c b/linux/sis_drv.c
index 3dd075d3..64d0754f 100644
--- a/linux/sis_drv.c
+++ b/linux/sis_drv.c
@@ -32,7 +32,7 @@
#include "sis_drv.h"
#include "drm_auth.h"
-#include "drm_agpsupport.h"
+#include "drm_agp_tmp.h"
#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"