Split declarations/definitions in drm_scatter.h into drm_sg.h/drm_sg_tmp.h

respectively. Splited the work out of the ioctls and renamed (with the
    _ioctl prefix). Added some more documentation. Did the same for
    drm_sgpsupport.h.
main
Jose Fonseca 2003-06-03 23:27:01 +00:00
parent a709d4c97c
commit 6611a5fb7f
29 changed files with 648 additions and 1162 deletions

View File

@ -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,

View File

@ -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 );

View File

@ -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));

View File

@ -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 */

View File

@ -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;

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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,

95
linux/drm_agp.h Normal file
View File

@ -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

View File

@ -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,34 +31,179 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#if __REALLY_HAVE_AGP
#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.
* 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.
*/
/**
* AGP information ioctl.
* Acquire the AGP device.
*/
int DRM(agp_acquire)(void)
{
return drm_agp->acquire();
}
/**
* 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.
*
* 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->bind_memory)
return -EINVAL;
return drm_agp->bind_memory(handle, start);
}
/**
* 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);
}
/**@}*/
/**********************************************************************/
/** \name Ioctl's */
/**
* Acquire the AGP device.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a (output) drm_agp_info structure.
* \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_acquire().
*/
int DRM(agp_acquire_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;
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.
*
* \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_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;
if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
return -EINVAL;
drm_agp->release();
dev->agp->acquired = 0;
return 0;
}
/**
* 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.
*
* 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,
int DRM(agp_info_ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
@ -85,67 +230,6 @@ int DRM(agp_info)(struct inode *inode, struct file *filp,
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.
*
@ -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;
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);
}
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->free_memory() */
int DRM(agp_free_memory)(agp_memory *handle)
/**
* Free the device AGP resources.
*/
void DRM(agp_cleanup_dev)(drm_device_t *dev)
{
if (!handle || !drm_agp->free_memory) return 0;
drm_agp->free_memory(handle);
return 1;
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;
}
}
/** 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 */

View File

@ -1,451 +0,0 @@
/**
* \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 */

View File

@ -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 );

View File

@ -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));

View File

@ -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 */

View File

@ -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;

View File

@ -1,229 +0,0 @@
/**
* \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;
}

65
linux/drm_sg.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"