summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drmP.h106
-rw-r--r--linux-core/drm_agpsupport.c (renamed from linux/drm_agp_tmp.h)365
-rw-r--r--linux-core/drm_bufs.c3
-rw-r--r--linux-core/drm_drv.c68
-rw-r--r--linux-core/drm_memory.h12
-rw-r--r--linux-core/drm_memory_debug.h10
-rw-r--r--linux-core/drm_scatter.c (renamed from linux/drm_sg_tmp.h)164
-rw-r--r--linux-core/i810_drv.c2
-rw-r--r--linux-core/i830_drv.c2
-rw-r--r--linux-core/mga_drv.c2
-rw-r--r--linux-core/r128_drv.c4
-rw-r--r--linux-core/radeon_drv.c4
-rw-r--r--linux-core/sis_drv.c2
-rw-r--r--linux/drmP.h106
-rw-r--r--linux/drm_agp.h111
-rw-r--r--linux/drm_agpsupport.h451
-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.h10
-rw-r--r--linux/drm_scatter.h229
-rw-r--r--linux/drm_sg.h65
-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
29 files changed, 1161 insertions, 656 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 3d352a6d..5626e4ff 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -66,6 +66,10 @@
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+#include <linux/types.h>
+#include <linux/agp_backend.h>
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)
#define HAS_WORKQUEUE 0
#else
@@ -82,10 +86,14 @@
#include "drm_os_linux.h"
+
/***********************************************************************/
/** \name DRM template customization defaults */
/*@{*/
+#ifndef __HAVE_AGP
+#define __HAVE_AGP 0
+#endif
#ifndef __HAVE_MTRR
#define __HAVE_MTRR 0
#endif
@@ -105,18 +113,14 @@
#define __HAVE_DMA_FREELIST 0
#endif
+#define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \
+ defined(CONFIG_AGP_MODULE)))
#define __REALLY_HAVE_MTRR (__HAVE_MTRR && defined(CONFIG_MTRR))
#define __REALLY_HAVE_SG (__HAVE_SG)
/*@}*/
-typedef struct drm_device drm_device_t;
-
-#include "drm_agp.h"
-#include "drm_sg.h"
-
-
/***********************************************************************/
/** \name Begin the DRM... */
/*@{*/
@@ -571,6 +575,48 @@ 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;
@@ -600,7 +646,7 @@ typedef struct drm_vbl_sig {
/**
* DRM device structure.
*/
-struct drm_device {
+typedef struct drm_device {
const char *name; /**< Simple driver name */
char *unique; /**< Unique identifier: e.g., busid */
int unique_len; /**< Length of unique field */
@@ -711,12 +757,11 @@ 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;
/******************************************************************/
@@ -785,10 +830,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(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);
+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);
#endif
/* Misc. IOCTL support (drm_ioctl.h) */
@@ -911,6 +956,32 @@ 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,
@@ -927,6 +998,15 @@ 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_tmp.h b/linux-core/drm_agpsupport.c
index 8ae64b1d..81850593 100644
--- a/linux/drm_agp_tmp.h
+++ b/linux-core/drm_agpsupport.c
@@ -1,5 +1,5 @@
/**
- * \file drm_agp_tmp.h
+ * \file drm_agpsupport.h
* DRM support for AGP/GART backend
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -31,124 +31,62 @@
* 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;
-
-/**********************************************************************/
-/**
- * \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. */
-/*@{*/
-
-/**
- * Acquire the AGP device.
- */
-int DRM(agp_acquire)(void)
-{
- if (!drm_agp || !drm_agp->acquire)
- return -EINVAL;
- return drm_agp->acquire();
-}
+#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
+#define DRM_AGP_PUT inter_module_put("drm_agp")
/**
- * Release the AGP device.
+ * Pointer to the drm_agp_t structure made available by the agpgart module.
*/
-void DRM(agp_release)(void)
-{
- if (!drm_agp || !drm_agp->release)
- return;
- drm_agp->release();
-}
+static const drm_agp_t *drm_agp = NULL;
/**
- * Enable the AGP bus.
- */
-void DRM(agp_enable)(unsigned long mode)
-{
- if (!drm_agp || !drm_agp->enable)
- return;
- 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 || !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 || !drm_agp->free_memory)
- return 0;
- drm_agp->free_memory(handle);
- return 1;
-}
-
-/**
- * Bind AGP memory.
+ * AGP information ioctl.
*
- * Not meant to be called directly. Use agp_bind() instead, which can provide
- * some debugging features.
- */
-int DRM(agp_bind_memory)(agp_memory *handle, off_t start)
-{
- if (!handle || !drm_agp || !drm_agp->bind_memory)
- return -EINVAL;
- return drm_agp->bind_memory(handle, start);
-}
-
-/**
- * Bind AGP memory.
+ * \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.
*
- * Not meant to be called directly. Use agp_unbind() instead, which can provide
- * some debugging features.
+ * 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.
*/
-int DRM(agp_unbind_memory)(agp_memory *handle)
+int DRM(agp_info)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- if (!handle || !drm_agp || !drm_agp->unbind_memory)
- return -EINVAL;
- return drm_agp->unbind_memory(handle);
-}
+ 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;
-/**********************************************************************/
-/** \name Ioctl's */
-/*@{*/
+ if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+}
/**
- * Acquire the AGP device.
+ * Acquire the AGP device (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
@@ -157,9 +95,9 @@ int DRM(agp_unbind_memory)(agp_memory *handle)
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device hasn't been acquired before and calls
- * drm_acquire().
+ * drm_agp->acquire().
*/
-int DRM(agp_acquire_ioctl)(struct inode *inode, struct file *filp,
+int DRM(agp_acquire)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -168,13 +106,13 @@ int DRM(agp_acquire_ioctl)(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.
+ * Release the AGP device (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
@@ -184,7 +122,7 @@ int DRM(agp_acquire_ioctl)(struct inode *inode, struct file *filp,
*
* Verifies the AGP device has been acquired and calls drm_agp->release().
*/
-int DRM(agp_release_ioctl)(struct inode *inode, struct file *filp,
+int DRM(agp_release)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -199,42 +137,13 @@ int DRM(agp_release_ioctl)(struct inode *inode, struct file *filp,
}
/**
- * 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.
+ * Release the AGP device.
*
- * 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.
+ * Calls drm_agp->release().
*/
-int DRM(agp_info_ioctl)(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+void DRM(agp_do_release)(void)
{
- 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;
+ if (drm_agp->release) drm_agp->release();
}
/**
@@ -246,10 +155,10 @@ int DRM(agp_info_ioctl)(struct inode *inode, struct file *filp,
* \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, and calls
- * agp_enable().
+ * Verifies the AGP device has been acquired but not enabled, and calls
+ * drm_agp->enable().
*/
-int DRM(agp_enable_ioctl)(struct inode *inode, struct file *filp,
+int DRM(agp_enable)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -263,7 +172,7 @@ int DRM(agp_enable_ioctl)(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;
@@ -279,9 +188,9 @@ int DRM(agp_enable_ioctl)(struct inode *inode, struct file *filp,
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device is present and has been acquired, allocates the
- * memory via agp_alloc() and creates a drm_agp_mem entry for it.
+ * memory via alloc_agp() and creates a drm_agp_mem entry for it.
*/
-int DRM(agp_alloc_ioctl)(struct inode *inode, struct file *filp,
+int DRM(agp_alloc)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -303,7 +212,7 @@ int DRM(agp_alloc_ioctl)(struct inode *inode, struct file *filp,
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
type = (u32) request.type;
- if (!(memory = DRM(agp_alloc)(pages, type))) {
+ if (!(memory = DRM(alloc_agp)(pages, type))) {
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -ENOMEM;
}
@@ -323,7 +232,7 @@ int DRM(agp_alloc_ioctl)(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(agp_free)(memory, pages);
+ DRM(free_agp)(memory, pages);
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -EFAULT;
}
@@ -351,7 +260,7 @@ static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
}
/**
- * Unbind AGP memory from the GATT.
+ * Unbind AGP memory from the GATT (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
@@ -360,9 +269,9 @@ static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device is present and acquired, looks-up the AGP memory
- * entry and passes it to the agp_unbind() function.
+ * entry and passes it to the unbind_agp() function.
*/
-int DRM(agp_unbind_ioctl)(struct inode *inode, struct file *filp,
+int DRM(agp_unbind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -377,14 +286,14 @@ int DRM(agp_unbind_ioctl)(struct inode *inode, struct file *filp,
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
if (!entry->bound) return -EINVAL;
- ret = DRM(agp_unbind)(entry->memory);
+ ret = DRM(unbind_agp)(entry->memory);
if (ret == 0)
entry->bound = 0;
return ret;
}
/**
- * Bind AGP memory into the GATT
+ * Bind AGP memory into the GATT (ioctl)
*
* \param inode device inode.
* \param filp file pointer.
@@ -394,9 +303,9 @@ int DRM(agp_unbind_ioctl)(struct inode *inode, struct file *filp,
*
* Verifies the AGP device is present and has been acquired and that no memory
* is currently bound into the GATT. Looks-up the AGP memory entry and passes
- * it to agp_bind() function.
+ * it to bind_agp() function.
*/
-int DRM(agp_bind_ioctl)(struct inode *inode, struct file *filp,
+int DRM(agp_bind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -414,7 +323,7 @@ int DRM(agp_bind_ioctl)(struct inode *inode, struct file *filp,
return -EINVAL;
if (entry->bound) return -EINVAL;
page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
- if ((retcode = DRM(agp_bind)(entry->memory, page))) return retcode;
+ if ((retcode = DRM(bind_agp)(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);
@@ -422,7 +331,7 @@ int DRM(agp_bind_ioctl)(struct inode *inode, struct file *filp,
}
/**
- * Free AGP memory.
+ * Free AGP memory (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
@@ -432,10 +341,10 @@ int DRM(agp_bind_ioctl)(struct inode *inode, struct file *filp,
*
* Verifies the AGP device is present and has been acquired and looks up the
* AGP memory entry. If the memory it's currently bound, unbind it via
- * agp_unbind(). Frees it via agp_free() as well as the entry itself
+ * 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_ioctl)(struct inode *inode, struct file *filp,
+int DRM(agp_free)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@@ -448,117 +357,95 @@ int DRM(agp_free_ioctl)(struct inode *inode, struct file *filp,
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
- if (entry->bound) DRM(agp_unbind)(entry->memory);
+ if (entry->bound) DRM(unbind_agp)(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(agp_free)(entry->memory, entry->pages);
+ DRM(free_agp)(entry->memory, entry->pages);
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return 0;
}
-/*@}*/
-
-
-/**********************************************************************/
-/** \name Initialization and cleanup */
-/*@{*/
-
/**
- * Initialize the global AGP resources.
+ * Initialize the AGP resources.
*
- * Gets the drm_agp_t structure which is made available by the agpgart module
- * via the inter_module_* functions.
- */
-void DRM(agp_init)(void)
-{
- drm_agp = (drm_agp_t *)inter_module_get("drm_agp");
-}
-
-/**
- * Free the global AGP resources.
- *
- * Releases the pointer in ::drm_agp.
- */
-void DRM(agp_cleanup)(void)
-{
- if (drm_agp) {
- inter_module_put("drm_agp");
- drm_agp = NULL;
- }
-}
-
-/**
- * Initialize the device AGP resources.
+ * \return pointer to a drm_agp_head structure.
*
- * Creates and initializes a drm_agp_head structure in drm_device_t::agp.
+ * 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.
*/
-void DRM(agp_init_dev)(drm_device_t *dev)
+drm_agp_head_t *DRM(agp_init)(void)
{
drm_agp_head_t *head = NULL;
- if (!drm_agp)
- return;
-
- if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
- return;
-
- 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;
- }
- head->memory = 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);
+ 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;
+ 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;
+ 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;
}
/**
- * Free the device AGP resources.
+ * Free the AGP resources.
+ *
+ * Releases the pointer in ::drm_agp.
*/
-void DRM(agp_cleanup_dev)(drm_device_t *dev)
+void DRM(agp_uninit)(void)
{
- 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)();
+ DRM_AGP_PUT;
+ drm_agp = NULL;
+}
- dev->agp->acquired = 0;
- dev->agp->enabled = 0;
+/** Calls drm_agp->allocate_memory() */
+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);
+}
- DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
- dev->agp = 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;
}
-/*@}*/
+/** 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);
+}
+/** Calls drm_agp->unbind_memory() */
+int DRM(agp_unbind_memory)(agp_memory *handle)
+{
+ if (!handle || !drm_agp->unbind_memory) return -EINVAL;
+ return drm_agp->unbind_memory(handle);
+}
#endif /* __REALLY_HAVE_AGP */
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index f42fabef..77573709 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -174,8 +174,6 @@ 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);
@@ -183,7 +181,6 @@ 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-core/drm_drv.c b/linux-core/drm_drv.c
index 5a4ab36e..90c2d18b 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -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_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 },
+ [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 },
#endif
#if __HAVE_SG
- [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 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { DRM(sg_alloc), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 },
#endif
#if __HAVE_VBL_IRQ
@@ -416,6 +416,29 @@ 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 ) {
@@ -463,7 +486,10 @@ static int DRM(takedown)( drm_device_t *dev )
* isn't defined.
*/
#if __HAVE_SG
- DRM(sg_cleanup)(dev);
+ if(dev->sg) {
+ DRM(sg_cleanup)(dev->sg);
+ dev->sg = NULL;
+ }
#endif
break;
}
@@ -592,10 +618,6 @@ 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) );
@@ -608,9 +630,8 @@ static int __init drm_init( void )
dev->name = DRIVER_NAME;
#if __REALLY_HAVE_AGP
- DRM(agp_init_dev)( dev );
+ dev->agp = DRM(agp_init)();
#if __MUST_HAVE_AGP
-
if ( dev->agp == NULL ) {
DRM_ERROR( "Cannot initialize the agpgart module.\n" );
DRM(stub_unregister)(DRM(minor)[i]);
@@ -618,12 +639,14 @@ 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 );
@@ -689,14 +712,13 @@ static void __exit drm_cleanup( void )
DRM(takedown)( dev );
#if __REALLY_HAVE_AGP
- DRM(agp_cleanup_dev)( dev );
+ if ( dev->agp ) {
+ DRM(agp_uninit)();
+ DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+ dev->agp = NULL;
+ }
#endif
}
-
-#if __REALLY_HAVE_AGP
- DRM(agp_cleanup)();
-#endif
-
DRIVER_POSTCLEANUP();
kfree(DRM(minor));
kfree(DRM(device));
diff --git a/linux-core/drm_memory.h b/linux-core/drm_memory.h
index 9999c213..2a969fcd 100644
--- a/linux-core/drm_memory.h
+++ b/linux-core/drm_memory.h
@@ -332,29 +332,27 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
#if __REALLY_HAVE_AGP
/** Wrapper around agp_allocate_memory() */
-agp_memory *DRM(agp_alloc)(int pages, u32 type)
+agp_memory *DRM(alloc_agp)(int pages, u32 type)
{
return DRM(agp_allocate_memory)(pages, type);
}
/** Wrapper around agp_free_memory() */
-int DRM(agp_free)(agp_memory *handle, int pages)
+int DRM(free_agp)(agp_memory *handle, int pages)
{
return DRM(agp_free_memory)(handle) ? 0 : -EINVAL;
}
/** Wrapper around agp_bind_memory() */
-int DRM(agp_bind)(agp_memory *handle, unsigned int start)
+int DRM(bind_agp)(agp_memory *handle, unsigned int start)
{
return DRM(agp_bind_memory)(handle, start);
}
/** Wrapper around agp_unbind_memory() */
-int DRM(agp_unbind)(agp_memory *handle)
+int DRM(unbind_agp)(agp_memory *handle)
{
return DRM(agp_unbind_memory)(handle);
}
-#endif /* __REALLY_HAVE_AGP */
-
-
+#endif /* agp */
#endif /* debug_memory */
diff --git a/linux-core/drm_memory_debug.h b/linux-core/drm_memory_debug.h
index 91b42126..5cfff83a 100644
--- a/linux-core/drm_memory_debug.h
+++ b/linux-core/drm_memory_debug.h
@@ -1,5 +1,5 @@
/**
- * \file drm_memory_debug.h
+ * \file drm_memory.h
* Memory management wrappers for DRM.
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -343,7 +343,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
#if __REALLY_HAVE_AGP
-agp_memory *DRM(agp_alloc)(int pages, u32 type)
+agp_memory *DRM(alloc_agp)(int pages, u32 type)
{
agp_memory *handle;
@@ -366,7 +366,7 @@ agp_memory *DRM(agp_alloc)(int pages, u32 type)
return NULL;
}
-int DRM(agp_free)(agp_memory *handle, int pages)
+int DRM(free_agp)(agp_memory *handle, int pages)
{
int alloc_count;
int free_count;
@@ -395,7 +395,7 @@ int DRM(agp_free)(agp_memory *handle, int pages)
return retval;
}
-int DRM(agp_bind)(agp_memory *handle, unsigned int start)
+int DRM(bind_agp)(agp_memory *handle, unsigned int start)
{
int retcode = -EINVAL;
@@ -419,7 +419,7 @@ int DRM(agp_bind)(agp_memory *handle, unsigned int start)
return retcode;
}
-int DRM(agp_unbind)(agp_memory *handle)
+int DRM(unbind_agp)(agp_memory *handle)
{
int alloc_count;
int free_count;
diff --git a/linux/drm_sg_tmp.h b/linux-core/drm_scatter.c
index 95cb1fc7..45a30fc3 100644
--- a/linux/drm_sg_tmp.h
+++ b/linux-core/drm_scatter.c
@@ -1,11 +1,13 @@
/**
- * \file drm_sg_tmp.h
+ * \file drm_scatter.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.
*
@@ -29,29 +31,14 @@
* 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
-
-/**
- * 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 )
+void DRM(sg_cleanup)( drm_sg_mem_t *entry )
{
struct page *page;
int i;
@@ -75,34 +62,40 @@ void DRM(sg_free)( drm_sg_mem_t *entry )
DRM_MEM_SGLISTS );
}
-/**
- * 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 )
+int DRM(sg_alloc)( 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;
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 NULL;
+ return -ENOMEM;
memset( entry, 0, sizeof(*entry) );
- pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
- DRM_DEBUG( "sg size=%ld pages=%ld\n", size, pages );
+ pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+ DRM_DEBUG( "sg size=%ld pages=%ld\n", request.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 NULL;
+ return -ENOMEM;
}
memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
@@ -116,7 +109,7 @@ drm_sg_mem_t * DRM(sg_alloc)( unsigned long size )
DRM(free)( entry,
sizeof(*entry),
DRM_MEM_SGLISTS );
- return NULL;
+ return -ENOMEM;
}
memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
@@ -131,7 +124,7 @@ drm_sg_mem_t * DRM(sg_alloc)( unsigned long size )
DRM(free)( entry,
sizeof(*entry),
DRM_MEM_SGLISTS );
- return NULL;
+ return -ENOMEM;
}
/* This also forces the mapping of COW pages, so our page list
@@ -151,7 +144,21 @@ drm_sg_mem_t * DRM(sg_alloc)( unsigned long size )
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;
@@ -188,83 +195,14 @@ drm_sg_mem_t * DRM(sg_alloc)( unsigned long size )
}
#endif
- return entry;
+ return 0;
failed:
- DRM(sg_free)( entry );
- return NULL;
+ DRM(sg_cleanup)( entry );
+ return -ENOMEM;
}
-
-/**********************************************************************/
-/** \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,
+int DRM(sg_free)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
@@ -285,25 +223,7 @@ int DRM(sg_free_ioctl)( struct inode *inode, struct file *filp,
DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
- DRM(sg_free)( entry );
+ DRM(sg_cleanup)( 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-core/i810_drv.c b/linux-core/i810_drv.c
index 2b816fbf..0bc79386 100644
--- a/linux-core/i810_drv.c
+++ b/linux-core/i810_drv.c
@@ -37,7 +37,7 @@
#include "i810_drm.h"
#include "i810_drv.h"
-#include "drm_agp_tmp.h"
+#include "drm_agpsupport.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
diff --git a/linux-core/i830_drv.c b/linux-core/i830_drv.c
index 496c41ee..0735c94d 100644
--- a/linux-core/i830_drv.c
+++ b/linux-core/i830_drv.c
@@ -39,7 +39,7 @@
#include "i830_drm.h"
#include "i830_drv.h"
-#include "drm_agp_tmp.h"
+#include "drm_agpsupport.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c
index f438660c..f0d4935d 100644
--- a/linux-core/mga_drv.c
+++ b/linux-core/mga_drv.c
@@ -35,7 +35,7 @@
#include "drm.h"
#include "mga_drm.h"
#include "mga_drv.h"
-#include "drm_agp_tmp.h"
+#include "drm_agpsupport.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c
index 474c1418..e2e42690 100644
--- a/linux-core/r128_drv.c
+++ b/linux-core/r128_drv.c
@@ -37,7 +37,7 @@
#include "r128_drv.h"
#include "ati_pcigart.h"
-#include "drm_agp_tmp.h"
+#include "drm_agpsupport.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_sg_tmp.h"
+#include "drm_scatter.h"
diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c
index 1473e2ee..6152b8a5 100644
--- a/linux-core/radeon_drv.c
+++ b/linux-core/radeon_drv.c
@@ -38,7 +38,7 @@
#include "radeon_drv.h"
#include "ati_pcigart.h"
-#include "drm_agp_tmp.h"
+#include "drm_agpsupport.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_sg_tmp.h"
+#include "drm_scatter.h"
diff --git a/linux-core/sis_drv.c b/linux-core/sis_drv.c
index 64d0754f..3dd075d3 100644
--- a/linux-core/sis_drv.c
+++ b/linux-core/sis_drv.c
@@ -32,7 +32,7 @@
#include "sis_drv.h"
#include "drm_auth.h"
-#include "drm_agp_tmp.h"
+#include "drm_agpsupport.h"
#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
diff --git a/linux/drmP.h b/linux/drmP.h
index 3d352a6d..5626e4ff 100644
--- a/linux/drmP.h
+++ b/linux/drmP.h
@@ -66,6 +66,10 @@
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+#include <linux/types.h>
+#include <linux/agp_backend.h>
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)
#define HAS_WORKQUEUE 0
#else
@@ -82,10 +86,14 @@
#include "drm_os_linux.h"
+
/***********************************************************************/
/** \name DRM template customization defaults */
/*@{*/
+#ifndef __HAVE_AGP
+#define __HAVE_AGP 0
+#endif
#ifndef __HAVE_MTRR
#define __HAVE_MTRR 0
#endif
@@ -105,18 +113,14 @@
#define __HAVE_DMA_FREELIST 0
#endif
+#define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \
+ defined(CONFIG_AGP_MODULE)))
#define __REALLY_HAVE_MTRR (__HAVE_MTRR && defined(CONFIG_MTRR))
#define __REALLY_HAVE_SG (__HAVE_SG)
/*@}*/
-typedef struct drm_device drm_device_t;
-
-#include "drm_agp.h"
-#include "drm_sg.h"
-
-
/***********************************************************************/
/** \name Begin the DRM... */
/*@{*/
@@ -571,6 +575,48 @@ 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;
@@ -600,7 +646,7 @@ typedef struct drm_vbl_sig {
/**
* DRM device structure.
*/
-struct drm_device {
+typedef struct drm_device {
const char *name; /**< Simple driver name */
char *unique; /**< Unique identifier: e.g., busid */
int unique_len; /**< Length of unique field */
@@ -711,12 +757,11 @@ 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;
/******************************************************************/
@@ -785,10 +830,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(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);
+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);
#endif
/* Misc. IOCTL support (drm_ioctl.h) */
@@ -911,6 +956,32 @@ 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,
@@ -927,6 +998,15 @@ 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
deleted file mode 100644
index 1bd932e1..00000000
--- a/linux/drm_agp.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * \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_
-
-#ifndef __HAVE_AGP
-#define __HAVE_AGP 0
-#endif
-
-#define __REALLY_HAVE_AGP (__HAVE_AGP && \
- (defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)))
-
-#if __REALLY_HAVE_AGP
-
-
-#include <linux/types.h>
-#include <linux/agp_backend.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 long 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 /* __REALLY_HAVE_AGP */
-
-#endif /* !_DRM_AGP_H_ */
diff --git a/linux/drm_agpsupport.h b/linux/drm_agpsupport.h
new file mode 100644
index 00000000..81850593
--- /dev/null
+++ b/linux/drm_agpsupport.h
@@ -0,0 +1,451 @@
+/**
+ * \file drm_agpsupport.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.
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include <linux/module.h>
+
+#if __REALLY_HAVE_AGP
+
+
+#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
+#define DRM_AGP_PUT inter_module_put("drm_agp")
+
+/**
+ * Pointer to the drm_agp_t structure made available by the agpgart module.
+ */
+static const drm_agp_t *drm_agp = NULL;
+
+/**
+ * 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.
+ *
+ * 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.
+ */
+int DRM(agp_info)(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;
+ 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;
+}
+
+/**
+ * Acquire the AGP device (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device hasn't been acquired before and calls
+ * drm_agp->acquire().
+ */
+int DRM(agp_acquire)(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;
+ int retcode;
+
+ if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
+ return -EINVAL;
+ if ((retcode = drm_agp->acquire())) return retcode;
+ dev->agp->acquired = 1;
+ return 0;
+}
+
+/**
+ * Release the AGP device (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been acquired and calls drm_agp->release().
+ */
+int DRM(agp_release)(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;
+
+ if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
+ return -EINVAL;
+ drm_agp->release();
+ dev->agp->acquired = 0;
+ return 0;
+
+}
+
+/**
+ * Release the AGP device.
+ *
+ * Calls drm_agp->release().
+ */
+void DRM(agp_do_release)(void)
+{
+ if (drm_agp->release) drm_agp->release();
+}
+
+/**
+ * Enable the AGP bus.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \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().
+ */
+int DRM(agp_enable)(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_agp_mode_t mode;
+
+ if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
+ return -EINVAL;
+
+ if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
+ return -EFAULT;
+
+ dev->agp->mode = mode.mode;
+ drm_agp->enable(mode.mode);
+ dev->agp->base = dev->agp->agp_info.aper_base;
+ dev->agp->enabled = 1;
+ return 0;
+}
+
+/**
+ * Allocate AGP memory.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_buffer structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * 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)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_agp_buffer_t request;
+ drm_agp_mem_t *entry;
+ agp_memory *memory;
+ unsigned long pages;
+ u32 type;
+
+ if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+ if (copy_from_user(&request, (drm_agp_buffer_t *)arg, 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;
+
+ if (!(memory = DRM(alloc_agp)(pages, type))) {
+ DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+ return -ENOMEM;
+ }
+
+ entry->handle = (unsigned long)memory->key;
+ entry->memory = memory;
+ entry->bound = 0;
+ entry->pages = pages;
+ entry->prev = NULL;
+ entry->next = dev->agp->memory;
+ if (dev->agp->memory) dev->agp->memory->prev = entry;
+ dev->agp->memory = entry;
+
+ request.handle = entry->handle;
+ request.physical = memory->physical;
+
+ 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(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+ return -EFAULT;
+ }
+ return 0;
+}
+
+/**
+ * Search for the AGP memory entry associated with a handle.
+ *
+ * \param dev DRM device structure.
+ * \param handle AGP memory handle.
+ * \return pointer to the drm_agp_mem structure associated with \p handle.
+ *
+ * Walks through drm_agp_head::memory until finding a matching handle.
+ */
+static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
+ unsigned long handle)
+{
+ drm_agp_mem_t *entry;
+
+ for (entry = dev->agp->memory; entry; entry = entry->next) {
+ if (entry->handle == handle) return entry;
+ }
+ return NULL;
+}
+
+/**
+ * Unbind AGP memory from the GATT (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_binding structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * 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)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->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 *)arg, sizeof(request)))
+ return -EFAULT;
+ if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
+ return -EINVAL;
+ if (!entry->bound) return -EINVAL;
+ ret = DRM(unbind_agp)(entry->memory);
+ if (ret == 0)
+ entry->bound = 0;
+ return ret;
+}
+
+/**
+ * Bind AGP memory into the GATT (ioctl)
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_binding structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired and that no memory
+ * 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)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_agp_binding_t request;
+ drm_agp_mem_t *entry;
+ int retcode;
+ int page;
+
+ if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
+ return -EINVAL;
+ if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
+ return -EFAULT;
+ if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
+ 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;
+ entry->bound = dev->agp->base + (page << PAGE_SHIFT);
+ DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
+ dev->agp->base, entry->bound);
+ return 0;
+}
+
+/**
+ * Free AGP memory (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_buffer structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired and looks up the
+ * AGP memory entry. If the memory it's currently bound, unbind it via
+ * 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)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->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 *)arg, sizeof(request)))
+ return -EFAULT;
+ if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
+ return -EINVAL;
+ if (entry->bound) DRM(unbind_agp)(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(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+ return 0;
+}
+
+/**
+ * Initialize the AGP resources.
+ *
+ * \return pointer to a drm_agp_head structure.
+ *
+ * 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.
+ */
+drm_agp_head_t *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;
+}
+
+/**
+ * Free the AGP resources.
+ *
+ * Releases the pointer in ::drm_agp.
+ */
+void DRM(agp_uninit)(void)
+{
+ DRM_AGP_PUT;
+ drm_agp = NULL;
+}
+
+/** Calls drm_agp->allocate_memory() */
+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);
+}
+
+/** 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;
+}
+
+/** 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);
+}
+
+/** Calls drm_agp->unbind_memory() */
+int DRM(agp_unbind_memory)(agp_memory *handle)
+{
+ if (!handle || !drm_agp->unbind_memory) return -EINVAL;
+ return drm_agp->unbind_memory(handle);
+}
+
+#endif /* __REALLY_HAVE_AGP */
diff --git a/linux/drm_bufs.h b/linux/drm_bufs.h
index f42fabef..77573709 100644
--- a/linux/drm_bufs.h
+++ b/linux/drm_bufs.h
@@ -174,8 +174,6 @@ 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);
@@ -183,7 +181,6 @@ 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 5a4ab36e..90c2d18b 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_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 },
+ [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 },
#endif
#if __HAVE_SG
- [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 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { DRM(sg_alloc), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 },
#endif
#if __HAVE_VBL_IRQ
@@ -416,6 +416,29 @@ 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 ) {
@@ -463,7 +486,10 @@ static int DRM(takedown)( drm_device_t *dev )
* isn't defined.
*/
#if __HAVE_SG
- DRM(sg_cleanup)(dev);
+ if(dev->sg) {
+ DRM(sg_cleanup)(dev->sg);
+ dev->sg = NULL;
+ }
#endif
break;
}
@@ -592,10 +618,6 @@ 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) );
@@ -608,9 +630,8 @@ static int __init drm_init( void )
dev->name = DRIVER_NAME;
#if __REALLY_HAVE_AGP
- DRM(agp_init_dev)( dev );
+ dev->agp = DRM(agp_init)();
#if __MUST_HAVE_AGP
-
if ( dev->agp == NULL ) {
DRM_ERROR( "Cannot initialize the agpgart module.\n" );
DRM(stub_unregister)(DRM(minor)[i]);
@@ -618,12 +639,14 @@ 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 );
@@ -689,14 +712,13 @@ static void __exit drm_cleanup( void )
DRM(takedown)( dev );
#if __REALLY_HAVE_AGP
- DRM(agp_cleanup_dev)( dev );
+ if ( dev->agp ) {
+ DRM(agp_uninit)();
+ DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+ dev->agp = NULL;
+ }
#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 9999c213..2a969fcd 100644
--- a/linux/drm_memory.h
+++ b/linux/drm_memory.h
@@ -332,29 +332,27 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
#if __REALLY_HAVE_AGP
/** Wrapper around agp_allocate_memory() */
-agp_memory *DRM(agp_alloc)(int pages, u32 type)
+agp_memory *DRM(alloc_agp)(int pages, u32 type)
{
return DRM(agp_allocate_memory)(pages, type);
}
/** Wrapper around agp_free_memory() */
-int DRM(agp_free)(agp_memory *handle, int pages)
+int DRM(free_agp)(agp_memory *handle, int pages)
{
return DRM(agp_free_memory)(handle) ? 0 : -EINVAL;
}
/** Wrapper around agp_bind_memory() */
-int DRM(agp_bind)(agp_memory *handle, unsigned int start)
+int DRM(bind_agp)(agp_memory *handle, unsigned int start)
{
return DRM(agp_bind_memory)(handle, start);
}
/** Wrapper around agp_unbind_memory() */
-int DRM(agp_unbind)(agp_memory *handle)
+int DRM(unbind_agp)(agp_memory *handle)
{
return DRM(agp_unbind_memory)(handle);
}
-#endif /* __REALLY_HAVE_AGP */
-
-
+#endif /* agp */
#endif /* debug_memory */
diff --git a/linux/drm_memory_debug.h b/linux/drm_memory_debug.h
index 91b42126..5cfff83a 100644
--- a/linux/drm_memory_debug.h
+++ b/linux/drm_memory_debug.h
@@ -1,5 +1,5 @@
/**
- * \file drm_memory_debug.h
+ * \file drm_memory.h
* Memory management wrappers for DRM.
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -343,7 +343,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
#if __REALLY_HAVE_AGP
-agp_memory *DRM(agp_alloc)(int pages, u32 type)
+agp_memory *DRM(alloc_agp)(int pages, u32 type)
{
agp_memory *handle;
@@ -366,7 +366,7 @@ agp_memory *DRM(agp_alloc)(int pages, u32 type)
return NULL;
}
-int DRM(agp_free)(agp_memory *handle, int pages)
+int DRM(free_agp)(agp_memory *handle, int pages)
{
int alloc_count;
int free_count;
@@ -395,7 +395,7 @@ int DRM(agp_free)(agp_memory *handle, int pages)
return retval;
}
-int DRM(agp_bind)(agp_memory *handle, unsigned int start)
+int DRM(bind_agp)(agp_memory *handle, unsigned int start)
{
int retcode = -EINVAL;
@@ -419,7 +419,7 @@ int DRM(agp_bind)(agp_memory *handle, unsigned int start)
return retcode;
}
-int DRM(agp_unbind)(agp_memory *handle)
+int DRM(unbind_agp)(agp_memory *handle)
{
int alloc_count;
int free_count;
diff --git a/linux/drm_scatter.h b/linux/drm_scatter.h
new file mode 100644
index 00000000..45a30fc3
--- /dev/null
+++ b/linux/drm_scatter.h
@@ -0,0 +1,229 @@
+/**
+ * \file drm_scatter.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.
+ *
+ * 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.
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/vmalloc.h>
+#include "drmP.h"
+
+#define DEBUG_SCATTER 0
+
+void DRM(sg_cleanup)( drm_sg_mem_t *entry )
+{
+ struct page *page;
+ int i;
+
+ for ( i = 0 ; i < entry->pages ; i++ ) {
+ page = entry->pagelist[i];
+ if ( page )
+ ClearPageReserved( page );
+ }
+
+ vfree( entry->virtual );
+
+ DRM(free)( entry->busaddr,
+ entry->pages * sizeof(*entry->busaddr),
+ DRM_MEM_PAGES );
+ DRM(free)( entry->pagelist,
+ entry->pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES );
+ DRM(free)( entry,
+ sizeof(*entry),
+ DRM_MEM_SGLISTS );
+}
+
+int DRM(sg_alloc)( 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;
+ 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;
+
+ memset( entry, 0, sizeof(*entry) );
+
+ pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+ DRM_DEBUG( "sg size=%ld pages=%ld\n", request.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;
+ }
+
+ memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
+
+ entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
+ DRM_MEM_PAGES );
+ if ( !entry->busaddr ) {
+ DRM(free)( entry->pagelist,
+ entry->pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES );
+ DRM(free)( entry,
+ sizeof(*entry),
+ DRM_MEM_SGLISTS );
+ return -ENOMEM;
+ }
+ memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
+
+ entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
+ if ( !entry->virtual ) {
+ DRM(free)( entry->busaddr,
+ entry->pages * sizeof(*entry->busaddr),
+ DRM_MEM_PAGES );
+ DRM(free)( entry->pagelist,
+ entry->pages * sizeof(*entry->pagelist),
+ DRM_MEM_PAGES );
+ DRM(free)( entry,
+ sizeof(*entry),
+ DRM_MEM_SGLISTS );
+ return -ENOMEM;
+ }
+
+ /* This also forces the mapping of COW pages, so our page list
+ * will be valid. Please don't remove it...
+ */
+ memset( entry->virtual, 0, pages << PAGE_SHIFT );
+
+ entry->handle = (unsigned long)entry->virtual;
+
+ DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
+ DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
+
+ for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
+ entry->pagelist[j] = vmalloc_to_page((void *)i);
+ if (!entry->pagelist[j])
+ goto failed;
+ 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;
+
+ for ( i = 0 ; i < pages ; i++ ) {
+ unsigned long *tmp;
+
+ tmp = page_address( entry->pagelist[i] );
+ for ( j = 0 ;
+ j < PAGE_SIZE / sizeof(unsigned long) ;
+ j++, tmp++ ) {
+ *tmp = 0xcafebabe;
+ }
+ tmp = (unsigned long *)((u8 *)entry->virtual +
+ (PAGE_SIZE * i));
+ for( j = 0 ;
+ j < PAGE_SIZE / sizeof(unsigned long) ;
+ j++, tmp++ ) {
+ if ( *tmp != 0xcafebabe && error == 0 ) {
+ error = 1;
+ DRM_ERROR( "Scatter allocation error, "
+ "pagelist does not match "
+ "virtual mapping\n" );
+ }
+ }
+ tmp = page_address( entry->pagelist[i] );
+ for(j = 0 ;
+ j < PAGE_SIZE / sizeof(unsigned long) ;
+ j++, tmp++) {
+ *tmp = 0;
+ }
+ }
+ if (error == 0)
+ DRM_ERROR( "Scatter allocation matches pagelist\n" );
+ }
+#endif
+
+ return 0;
+
+ failed:
+ DRM(sg_cleanup)( entry );
+ return -ENOMEM;
+}
+
+int DRM(sg_free)( 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;
+
+ if ( copy_from_user( &request,
+ (drm_scatter_gather_t *)arg,
+ sizeof(request) ) )
+ return -EFAULT;
+
+ entry = dev->sg;
+ dev->sg = NULL;
+
+ if ( !entry || entry->handle != request.handle )
+ return -EINVAL;
+
+ DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
+
+ DRM(sg_cleanup)( entry );
+
+ return 0;
+}
diff --git a/linux/drm_sg.h b/linux/drm_sg.h
deleted file mode 100644
index afd80ef0..00000000
--- a/linux/drm_sg.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * \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/gamma_drv.c b/linux/gamma_drv.c
index 1313418e..f1b8b205 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_agp_tmp.h"
+#include "drm_agpsupport.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 2b816fbf..0bc79386 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_agp_tmp.h"
+#include "drm_agpsupport.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 496c41ee..0735c94d 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_agp_tmp.h"
+#include "drm_agpsupport.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 f438660c..f0d4935d 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_agp_tmp.h"
+#include "drm_agpsupport.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 474c1418..e2e42690 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_agp_tmp.h"
+#include "drm_agpsupport.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_sg_tmp.h"
+#include "drm_scatter.h"
diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c
index 1473e2ee..6152b8a5 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_agp_tmp.h"
+#include "drm_agpsupport.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_sg_tmp.h"
+#include "drm_scatter.h"
diff --git a/linux/sis_drv.c b/linux/sis_drv.c
index 64d0754f..3dd075d3 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_agp_tmp.h"
+#include "drm_agpsupport.h"
#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"