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