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
parent
a709d4c97c
commit
6611a5fb7f
|
@ -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,
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
97
linux/drmP.h
97
linux/drmP.h
|
@ -86,7 +86,6 @@
|
|||
|
||||
#include "drm_os_linux.h"
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/** \name DRM template customization defaults */
|
||||
/*@{*/
|
||||
|
@ -121,6 +120,12 @@
|
|||
/*@}*/
|
||||
|
||||
|
||||
typedef struct drm_device drm_device_t;
|
||||
|
||||
#include "drm_agp.h"
|
||||
#include "drm_sg.h"
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/** \name Begin the DRM... */
|
||||
/*@{*/
|
||||
|
@ -575,48 +580,6 @@ typedef struct drm_device_dma {
|
|||
/*@}*/
|
||||
} drm_device_dma_t;
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
/**
|
||||
* AGP memory entry. Stored as a doubly linked list.
|
||||
*/
|
||||
typedef struct drm_agp_mem {
|
||||
unsigned long handle; /**< handle */
|
||||
agp_memory *memory;
|
||||
unsigned long bound; /**< address */
|
||||
int pages;
|
||||
struct drm_agp_mem *prev; /**< previous entry */
|
||||
struct drm_agp_mem *next; /**< next entry */
|
||||
} drm_agp_mem_t;
|
||||
|
||||
/**
|
||||
* AGP data.
|
||||
*
|
||||
* \sa DRM(agp_init)() and drm_device::agp.
|
||||
*/
|
||||
typedef struct drm_agp_head {
|
||||
agp_kern_info agp_info; /**< AGP device information */
|
||||
drm_agp_mem_t *memory; /**< memory entries */
|
||||
unsigned long mode; /**< AGP mode */
|
||||
int enabled; /**< whether the AGP bus as been enabled */
|
||||
int acquired; /**< whether the AGP device has been acquired */
|
||||
unsigned long base;
|
||||
int agp_mtrr;
|
||||
int cant_use_aperture;
|
||||
unsigned long page_mask;
|
||||
} drm_agp_head_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Scatter-gather memory.
|
||||
*/
|
||||
typedef struct drm_sg_mem {
|
||||
unsigned long handle;
|
||||
void *virtual;
|
||||
int pages;
|
||||
struct page **pagelist;
|
||||
dma_addr_t *busaddr;
|
||||
} drm_sg_mem_t;
|
||||
|
||||
typedef struct drm_sigdata {
|
||||
int context;
|
||||
drm_hw_lock_t *lock;
|
||||
|
@ -646,7 +609,7 @@ typedef struct drm_vbl_sig {
|
|||
/**
|
||||
* DRM device structure.
|
||||
*/
|
||||
typedef struct drm_device {
|
||||
struct drm_device {
|
||||
const char *name; /**< Simple driver name */
|
||||
char *unique; /**< Unique identifier: e.g., busid */
|
||||
int unique_len; /**< Length of unique field */
|
||||
|
@ -757,11 +720,12 @@ typedef struct drm_device {
|
|||
#endif
|
||||
#endif
|
||||
drm_sg_mem_t *sg; /**< Scatter gather memory */
|
||||
|
||||
unsigned long *ctx_bitmap; /**< context bitmap */
|
||||
void *dev_private; /**< device private data */
|
||||
drm_sigdata_t sigdata; /**< For block_all_signals */
|
||||
sigset_t sigmask;
|
||||
} drm_device_t;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
|
@ -830,10 +794,10 @@ extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size,
|
|||
extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
extern agp_memory *DRM(alloc_agp)(int pages, u32 type);
|
||||
extern int DRM(free_agp)(agp_memory *handle, int pages);
|
||||
extern int DRM(bind_agp)(agp_memory *handle, unsigned int start);
|
||||
extern int DRM(unbind_agp)(agp_memory *handle);
|
||||
extern agp_memory *DRM(agp_alloc)(int pages, u32 type);
|
||||
extern int DRM(agp_free)(agp_memory *handle, int pages);
|
||||
extern int DRM(agp_bind)(agp_memory *handle, unsigned int start);
|
||||
extern int DRM(agp_unbind)(agp_memory *handle);
|
||||
#endif
|
||||
|
||||
/* Misc. IOCTL support (drm_ioctl.h) */
|
||||
|
@ -956,32 +920,6 @@ extern void DRM(dma_immediate_bh)( void *dev );
|
|||
|
||||
#endif /* __HAVE_DMA */
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
/* AGP/GART support (drm_agpsupport.h) */
|
||||
extern drm_agp_head_t *DRM(agp_init)(void);
|
||||
extern void DRM(agp_uninit)(void);
|
||||
extern int DRM(agp_acquire)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern void DRM(agp_do_release)(void);
|
||||
extern int DRM(agp_release)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(agp_enable)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(agp_info)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(agp_alloc)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(agp_free)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(agp_unbind)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(agp_bind)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
|
||||
extern int DRM(agp_free_memory)(agp_memory *handle);
|
||||
extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start);
|
||||
extern int DRM(agp_unbind_memory)(agp_memory *handle);
|
||||
#endif
|
||||
|
||||
/* Stub support (drm_stub.h) */
|
||||
int DRM(stub_register)(const char *name,
|
||||
|
@ -998,15 +936,6 @@ extern int DRM(proc_cleanup)(int minor,
|
|||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry *dev_root);
|
||||
|
||||
#if __HAVE_SG
|
||||
/* Scatter Gather Support (drm_scatter.h) */
|
||||
extern void DRM(sg_cleanup)(drm_sg_mem_t *entry);
|
||||
extern int DRM(sg_alloc)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(sg_free)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
#endif
|
||||
|
||||
/* ATI PCIGART support (ati_pcigart.h) */
|
||||
extern int DRM(ati_pcigart_init)(drm_device_t *dev,
|
||||
unsigned long *addr,
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 );
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue