Commit fd80ab16 authored by Linus Torvalds's avatar Linus Torvalds

Merge comment updates from DRI CVS tree.

parent 2850310b
/* ati_pcigart.h -- ATI PCI GART support -*- linux-c -*- /**
* \file ati_pcigart.h
* ATI PCI GART support
*
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com * Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com
* *
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
...@@ -22,9 +29,6 @@ ...@@ -22,9 +29,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
*
* Authors:
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
...@@ -45,8 +49,8 @@ ...@@ -45,8 +49,8 @@
# error - PAGE_SIZE not 64K, 16K, 8K or 4K # error - PAGE_SIZE not 64K, 16K, 8K or 4K
#endif #endif
# define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */ # define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
# define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */ # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
static unsigned long DRM(ati_alloc_pcigart_table)( void ) static unsigned long DRM(ati_alloc_pcigart_table)( void )
{ {
......
This diff is collapsed.
This diff is collapsed.
/* drm_agpsupport.h -- DRM support for AGP/GART backend -*- linux-c -*- /**
* Created: Mon Dec 13 09:56:45 1999 by faith@precisioninsight.com * \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 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved. * All Rights Reserved.
...@@ -23,10 +29,6 @@ ...@@ -23,10 +29,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Author:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
...@@ -34,17 +36,33 @@ ...@@ -34,17 +36,33 @@
#if __REALLY_HAVE_AGP #if __REALLY_HAVE_AGP
#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp") #define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
#define DRM_AGP_PUT inter_module_put("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; 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, int DRM(agp_info)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev; drm_device_t *dev = priv->dev;
struct agp_kern_info *kern; struct agp_kern_info *kern;
drm_agp_info_t info; drm_agp_info_t info;
if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info) if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
...@@ -66,6 +84,18 @@ int DRM(agp_info)(struct inode *inode, struct file *filp, ...@@ -66,6 +84,18 @@ int DRM(agp_info)(struct inode *inode, struct file *filp,
return 0; 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, int DRM(agp_acquire)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -80,6 +110,17 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp, ...@@ -80,6 +110,17 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
return 0; 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, int DRM(agp_release)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -94,11 +135,28 @@ int DRM(agp_release)(struct inode *inode, struct file *filp, ...@@ -94,11 +135,28 @@ int DRM(agp_release)(struct inode *inode, struct file *filp,
} }
/**
* Release the AGP device.
*
* Calls drm_agp->release().
*/
void DRM(agp_do_release)(void) void DRM(agp_do_release)(void)
{ {
if (drm_agp->release) drm_agp->release(); 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, int DRM(agp_enable)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -119,6 +177,18 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp, ...@@ -119,6 +177,18 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp,
return 0; 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, int DRM(agp_alloc)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -168,6 +238,15 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp, ...@@ -168,6 +238,15 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
return 0; 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, static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
unsigned long handle) unsigned long handle)
{ {
...@@ -179,6 +258,18 @@ static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev, ...@@ -179,6 +258,18 @@ static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
return NULL; 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, int DRM(agp_unbind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -200,6 +291,19 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp, ...@@ -200,6 +291,19 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
return ret; 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, int DRM(agp_bind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -225,6 +329,20 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp, ...@@ -225,6 +329,20 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
return 0; 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, int DRM(agp_free)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -248,6 +366,15 @@ int DRM(agp_free)(struct inode *inode, struct file *filp, ...@@ -248,6 +366,15 @@ int DRM(agp_free)(struct inode *inode, struct file *filp,
return 0; 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 *DRM(agp_init)(void)
{ {
drm_agp_head_t *head = NULL; drm_agp_head_t *head = NULL;
...@@ -274,18 +401,25 @@ drm_agp_head_t *DRM(agp_init)(void) ...@@ -274,18 +401,25 @@ drm_agp_head_t *DRM(agp_init)(void)
return head; return head;
} }
/**
* Free the AGP resources.
*
* Releases the pointer in ::drm_agp.
*/
void DRM(agp_uninit)(void) void DRM(agp_uninit)(void)
{ {
DRM_AGP_PUT; DRM_AGP_PUT;
drm_agp = NULL; drm_agp = NULL;
} }
/** Calls drm_agp->allocate_memory() */
struct agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type) struct agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
{ {
if (!drm_agp->allocate_memory) return NULL; if (!drm_agp->allocate_memory) return NULL;
return drm_agp->allocate_memory(pages, type); return drm_agp->allocate_memory(pages, type);
} }
/** Calls drm_agp->free_memory() */
int DRM(agp_free_memory)(struct agp_memory *handle) int DRM(agp_free_memory)(struct agp_memory *handle)
{ {
if (!handle || !drm_agp->free_memory) return 0; if (!handle || !drm_agp->free_memory) return 0;
...@@ -293,12 +427,14 @@ int DRM(agp_free_memory)(struct agp_memory *handle) ...@@ -293,12 +427,14 @@ int DRM(agp_free_memory)(struct agp_memory *handle)
return 1; return 1;
} }
/** Calls drm_agp->bind_memory() */
int DRM(agp_bind_memory)(struct agp_memory *handle, off_t start) int DRM(agp_bind_memory)(struct agp_memory *handle, off_t start)
{ {
if (!handle || !drm_agp->bind_memory) return -EINVAL; if (!handle || !drm_agp->bind_memory) return -EINVAL;
return drm_agp->bind_memory(handle, start); return drm_agp->bind_memory(handle, start);
} }
/** Calls drm_agp->unbind_memory() */
int DRM(agp_unbind_memory)(struct agp_memory *handle) int DRM(agp_unbind_memory)(struct agp_memory *handle)
{ {
if (!handle || !drm_agp->unbind_memory) return -EINVAL; if (!handle || !drm_agp->unbind_memory) return -EINVAL;
......
/* drm_auth.h -- IOCTLs for authentication -*- linux-c -*- /**
* \file drm_auth.h
* IOCTLs for authentication
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,19 +31,34 @@ ...@@ -23,19 +31,34 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
/**
* Generate a hash key from a magic.
*
* \param magic magic.
* \return hash key.
*
* The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
* a power of 2.
*/
static int DRM(hash_magic)(drm_magic_t magic) static int DRM(hash_magic)(drm_magic_t magic)
{ {
return magic & (DRM_HASH_SIZE-1); return magic & (DRM_HASH_SIZE-1);
} }
/**
* Find the file with the given magic number.
*
* \param dev DRM device.
* \param magic magic number.
*
* Searches in drm_device::magiclist within all files with the same hash key
* the one with matching magic number, while holding the drm_device::struct_sem
* lock.
*/
static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic) static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic)
{ {
drm_file_t *retval = NULL; drm_file_t *retval = NULL;
...@@ -53,6 +76,17 @@ static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic) ...@@ -53,6 +76,17 @@ static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic)
return retval; return retval;
} }
/**
* Adds a magic number.
*
* \param dev DRM device.
* \param priv file private data.
* \param magic magic number.
*
* Creates a drm_magic_entry structure and appends to the linked list
* associated the magic number hash key in drm_device::magiclist, while holding
* the drm_device::struct_sem lock.
*/
int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
{ {
int hash; int hash;
...@@ -81,12 +115,22 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) ...@@ -81,12 +115,22 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
return 0; return 0;
} }
/**
* Remove a magic number.
*
* \param dev DRM device.
* \param magic magic number.
*
* Searches and unlinks the entry in drm_device::magiclist with the magic
* number hash key, while holding the drm_device::struct_sem lock.
*/
int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic)
{ {
drm_magic_entry_t *prev = NULL; drm_magic_entry_t *prev = NULL;
drm_magic_entry_t *pt; drm_magic_entry_t *pt;
int hash; int hash;
DRM_DEBUG("%d\n", magic); DRM_DEBUG("%d\n", magic);
hash = DRM(hash_magic)(magic); hash = DRM(hash_magic)(magic);
...@@ -113,6 +157,19 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) ...@@ -113,6 +157,19 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic)
return -EINVAL; return -EINVAL;
} }
/**
* Get a unique magic number (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a resulting drm_auth structure.
* \return zero on success, or a negative number on failure.
*
* If there is a magic number in drm_file::magic then use it, otherwise
* searches an unique non-zero magic number and add it associating it with \p
* filp.
*/
int DRM(getmagic)(struct inode *inode, struct file *filp, int DRM(getmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -142,6 +199,17 @@ int DRM(getmagic)(struct inode *inode, struct file *filp, ...@@ -142,6 +199,17 @@ int DRM(getmagic)(struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Authenticate with a magic.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_auth structure.
* \return zero if authentication successed, or a negative number otherwise.
*
* Checks if \p filp is associated with the magic number passed in \arg.
*/
int DRM(authmagic)(struct inode *inode, struct file *filp, int DRM(authmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
......
/* drm_bufs.h -- Generic buffer template -*- linux-c -*- /**
* \file drm_bufs.h
* Generic buffer template
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
* *
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,10 +31,6 @@ ...@@ -23,10 +31,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
...@@ -51,8 +55,15 @@ ...@@ -51,8 +55,15 @@
#endif #endif
#endif #endif
/*
* Compute order. Can be made faster. /**
* Compute size order. Returns the exponent of the smaller power of two which
* is greater or equal to given number.
*
* \param size size.
* \return order.
*
* \todo Can be made faster.
*/ */
int DRM(order)( unsigned long size ) int DRM(order)( unsigned long size )
{ {
...@@ -67,6 +78,19 @@ int DRM(order)( unsigned long size ) ...@@ -67,6 +78,19 @@ int DRM(order)( unsigned long size )
return order; return order;
} }
/**
* Ioctl to specify a range of memory that is available for mapping by a non-root process.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_map structure.
* \return zero on success or a negative value on error.
*
* Adjusts the memory offset to its absolute value according to the mapping
* type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
* applicable and if supported by the kernel.
*/
int DRM(addmap)( struct inode *inode, struct file *filp, int DRM(addmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -186,10 +210,22 @@ int DRM(addmap)( struct inode *inode, struct file *filp, ...@@ -186,10 +210,22 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
} }
/* Remove a map private from list and deallocate resources if the mapping /**
* Remove a map private from list and deallocate resources if the mapping
* isn't in use. * isn't in use.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_map_t structure.
* \return zero on success or a negative value on error.
*
* Searches the map on drm_device::maplist, removes it from the list, see if
* its being used, and free any associate resource (such as MTRR's) if it's not
* being on use.
*
* \sa addmap().
*/ */
int DRM(rmmap)(struct inode *inode, struct file *filp, int DRM(rmmap)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -262,7 +298,13 @@ int DRM(rmmap)(struct inode *inode, struct file *filp, ...@@ -262,7 +298,13 @@ int DRM(rmmap)(struct inode *inode, struct file *filp,
#if __HAVE_DMA #if __HAVE_DMA
/**
* Cleanup after an error on one of the addbufs() functions.
*
* \param entry buffer entry where the error occurred.
*
* Frees any pages and buffers associated with the given entry.
*/
static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry) static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry)
{ {
int i; int i;
...@@ -305,6 +347,19 @@ static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry) ...@@ -305,6 +347,19 @@ static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry)
} }
#if __REALLY_HAVE_AGP #if __REALLY_HAVE_AGP
/**
* Add AGP buffers for DMA transfers (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_buf_desc_t request.
* \return zero on success or a negative number on failure.
*
* After some sanity checks creates a drm_buf structure for each buffer and
* reallocates the buffer list of the same size order to accommodate the new
* buffers.
*/
int DRM(addbufs_agp)( struct inode *inode, struct file *filp, int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -884,6 +939,20 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp, ...@@ -884,6 +939,20 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp,
} }
#endif /* __HAVE_SG */ #endif /* __HAVE_SG */
/**
* Add buffers for DMA transfers (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_buf_desc_t request.
* \return zero on success or a negative number on failure.
*
* According with the memory type specified in drm_buf_desc::flags and the
* build options, it dispatches the call either to addbufs_agp(),
* addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
* PCI memory respectively.
*/
int DRM(addbufs)( struct inode *inode, struct file *filp, int DRM(addbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -910,6 +979,24 @@ int DRM(addbufs)( struct inode *inode, struct file *filp, ...@@ -910,6 +979,24 @@ int DRM(addbufs)( struct inode *inode, struct file *filp,
#endif #endif
} }
/**
* Get information about the buffer mappings.
*
* This was originally mean for debugging purposes, or by a sophisticated
* client library to determine how best to use the available buffers (e.g.,
* large buffers can be used for image transfer).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_buf_info structure.
* \return zero on success or a negative number on failure.
*
* Increments drm_device::buf_use while holding the drm_device::count_lock
* lock, preventing of allocating more buffers after this call. Information
* about each requested buffer is then copied into user space.
*/
int DRM(infobufs)( struct inode *inode, struct file *filp, int DRM(infobufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -981,6 +1068,20 @@ int DRM(infobufs)( struct inode *inode, struct file *filp, ...@@ -981,6 +1068,20 @@ int DRM(infobufs)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Specifies a low and high water mark for buffer allocation
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg a pointer to a drm_buf_desc structure.
* \return zero on success or a negative number on failure.
*
* Verifies that the size order is bounded between the admissible orders and
* updates the respective drm_device_dma::bufs entry low and high water mark.
*
* \note This ioctl is deprecated and mostly never used.
*/
int DRM(markbufs)( struct inode *inode, struct file *filp, int DRM(markbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -1015,6 +1116,18 @@ int DRM(markbufs)( struct inode *inode, struct file *filp, ...@@ -1015,6 +1116,18 @@ int DRM(markbufs)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Unreserve the buffers in list, previously reserved using drmDMA.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_buf_free structure.
* \return zero on success or a negative number on failure.
*
* Calls free_buffer() for each used buffer.
* This function is primarily used for debugging.
*/
int DRM(freebufs)( struct inode *inode, struct file *filp, int DRM(freebufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -1056,6 +1169,19 @@ int DRM(freebufs)( struct inode *inode, struct file *filp, ...@@ -1056,6 +1169,19 @@ int DRM(freebufs)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Maps all of the DMA buffers into client-virtual space (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_buf_map structure.
* \return zero on success or a negative number on failure.
*
* Maps the AGP or SG buffer region with do_mmap(), and copies information
* about each buffer into user space. The PCI buffers are already mapped on the
* addbufs_pci() call.
*/
int DRM(mapbufs)( struct inode *inode, struct file *filp, int DRM(mapbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
......
/* drm_context.h -- IOCTLs for generic contexts -*- linux-c -*- /**
* \file drm_context.h
* IOCTLs for generic contexts
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
* *
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,10 +31,9 @@ ...@@ -23,10 +31,9 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
* */
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> /*
* Gareth Hughes <gareth@valinux.com>
* ChangeLog: * ChangeLog:
* 2001-11-16 Torsten Duwe <duwe@caldera.de> * 2001-11-16 Torsten Duwe <duwe@caldera.de>
* added context constructor/destructor hooks, * added context constructor/destructor hooks,
...@@ -40,10 +47,20 @@ ...@@ -40,10 +47,20 @@
#endif #endif
/* ================================================================ /******************************************************************/
* Context bitmap support /** \name Context bitmap support */
*/ /*@{*/
/**
* Free a handle from the context bitmap.
*
* \param dev DRM device.
* \param ctx_handle context handle.
*
* Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
* in drm_device::context_sareas, while holding the drm_device::struct_sem
* lock.
*/
void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle ) void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
{ {
if ( ctx_handle < 0 ) goto failed; if ( ctx_handle < 0 ) goto failed;
...@@ -62,6 +79,16 @@ void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle ) ...@@ -62,6 +79,16 @@ void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
return; return;
} }
/**
* Context bitmap allocation.
*
* \param dev DRM device.
* \return (non-negative) context handle on success or a negative number on failure.
*
* Find the first zero bit in drm_device::ctx_bitmap and (re)allocates
* drm_device::context_sareas to accommodate the new entry while holding the
* drm_device::struct_sem lock.
*/
int DRM(ctxbitmap_next)( drm_device_t *dev ) int DRM(ctxbitmap_next)( drm_device_t *dev )
{ {
int bit; int bit;
...@@ -112,6 +139,14 @@ int DRM(ctxbitmap_next)( drm_device_t *dev ) ...@@ -112,6 +139,14 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
return -1; return -1;
} }
/**
* Context bitmap initialization.
*
* \param dev DRM device.
*
* Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
* the drm_device::struct_sem lock.
*/
int DRM(ctxbitmap_init)( drm_device_t *dev ) int DRM(ctxbitmap_init)( drm_device_t *dev )
{ {
int i; int i;
...@@ -137,6 +172,14 @@ int DRM(ctxbitmap_init)( drm_device_t *dev ) ...@@ -137,6 +172,14 @@ int DRM(ctxbitmap_init)( drm_device_t *dev )
return 0; return 0;
} }
/**
* Context bitmap cleanup.
*
* \param dev DRM device.
*
* Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
* the drm_device::struct_sem lock.
*/
void DRM(ctxbitmap_cleanup)( drm_device_t *dev ) void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
{ {
down(&dev->struct_sem); down(&dev->struct_sem);
...@@ -148,10 +191,24 @@ void DRM(ctxbitmap_cleanup)( drm_device_t *dev ) ...@@ -148,10 +191,24 @@ void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
up(&dev->struct_sem); up(&dev->struct_sem);
} }
/* ================================================================ /*@}*/
* Per Context SAREA Support
*/ /******************************************************************/
/** \name Per Context SAREA Support */
/*@{*/
/**
* Get per-context SAREA.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_priv_map structure.
* \return zero on success or a negative number on failure.
*
* Gets the map from drm_device::context_sareas with the handle specified and
* returns its handle.
*/
int DRM(getsareactx)(struct inode *inode, struct file *filp, int DRM(getsareactx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -180,6 +237,18 @@ int DRM(getsareactx)(struct inode *inode, struct file *filp, ...@@ -180,6 +237,18 @@ int DRM(getsareactx)(struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Set per-context SAREA.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_priv_map structure.
* \return zero on success or a negative number on failure.
*
* Searches the mapping specified in \p arg and update the entry in
* drm_device::context_sareas with it.
*/
int DRM(setsareactx)(struct inode *inode, struct file *filp, int DRM(setsareactx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -218,10 +287,22 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp, ...@@ -218,10 +287,22 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp,
return 0; return 0;
} }
/* ================================================================ /*@}*/
* The actual DRM context handling routines
*/ /******************************************************************/
/** \name The actual DRM context handling routines */
/*@{*/
/**
* Switch context.
*
* \param dev DRM device.
* \param old old context handle.
* \param new new context handle.
* \return zero on success or a negative number on failure.
*
* Attempt to set drm_device::context_flag.
*/
int DRM(context_switch)( drm_device_t *dev, int old, int new ) int DRM(context_switch)( drm_device_t *dev, int old, int new )
{ {
if ( test_and_set_bit( 0, &dev->context_flag ) ) { if ( test_and_set_bit( 0, &dev->context_flag ) ) {
...@@ -240,6 +321,17 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new ) ...@@ -240,6 +321,17 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new )
return 0; return 0;
} }
/**
* Complete context switch.
*
* \param dev DRM device.
* \param new new context handle.
* \return zero on success or a negative number on failure.
*
* Updates drm_device::last_context and drm_device::last_switch. Verifies the
* hardware lock is held, clears the drm_device::context_flag and wakes up
* drm_device::context_wait.
*/
int DRM(context_switch_complete)( drm_device_t *dev, int new ) int DRM(context_switch_complete)( drm_device_t *dev, int new )
{ {
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
...@@ -258,6 +350,15 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new ) ...@@ -258,6 +350,15 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new )
return 0; return 0;
} }
/**
* Reserve contexts.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_res structure.
* \return zero on success or a negative number on failure.
*/
int DRM(resctx)( struct inode *inode, struct file *filp, int DRM(resctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -284,6 +385,17 @@ int DRM(resctx)( struct inode *inode, struct file *filp, ...@@ -284,6 +385,17 @@ int DRM(resctx)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Add context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Get a new handle for the context and copy to userspace.
*/
int DRM(addctx)( struct inode *inode, struct file *filp, int DRM(addctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -322,6 +434,15 @@ int DRM(modctx)( struct inode *inode, struct file *filp, ...@@ -322,6 +434,15 @@ int DRM(modctx)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Get context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*/
int DRM(getctx)( struct inode *inode, struct file *filp, int DRM(getctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -338,6 +459,17 @@ int DRM(getctx)( struct inode *inode, struct file *filp, ...@@ -338,6 +459,17 @@ int DRM(getctx)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Switch context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Calls context_switch().
*/
int DRM(switchctx)( struct inode *inode, struct file *filp, int DRM(switchctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -352,6 +484,17 @@ int DRM(switchctx)( struct inode *inode, struct file *filp, ...@@ -352,6 +484,17 @@ int DRM(switchctx)( struct inode *inode, struct file *filp,
return DRM(context_switch)( dev, dev->last_context, ctx.handle ); return DRM(context_switch)( dev, dev->last_context, ctx.handle );
} }
/**
* New context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Calls context_switch_complete().
*/
int DRM(newctx)( struct inode *inode, struct file *filp, int DRM(newctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -368,6 +511,17 @@ int DRM(newctx)( struct inode *inode, struct file *filp, ...@@ -368,6 +511,17 @@ int DRM(newctx)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Remove context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* If not the special kernel context, calls ctxbitmap_free() to free the specified context.
*/
int DRM(rmctx)( struct inode *inode, struct file *filp, int DRM(rmctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -392,3 +546,4 @@ int DRM(rmctx)( struct inode *inode, struct file *filp, ...@@ -392,3 +546,4 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/*@}*/
/* drm_dma.c -- DMA IOCTL and function support -*- linux-c -*- /**
* \file drm_dma.h
* DMA IOCTL and function support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
* *
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,10 +31,6 @@ ...@@ -23,10 +31,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
...@@ -51,6 +55,14 @@ ...@@ -51,6 +55,14 @@
#if __HAVE_DMA #if __HAVE_DMA
/**
* Initialize the DMA data.
*
* \param dev DRM device.
* \return zero on success or a negative value on failure.
*
* Allocate and initialize a drm_device_dma structure.
*/
int DRM(dma_setup)( drm_device_t *dev ) int DRM(dma_setup)( drm_device_t *dev )
{ {
int i; int i;
...@@ -67,6 +79,14 @@ int DRM(dma_setup)( drm_device_t *dev ) ...@@ -67,6 +79,14 @@ int DRM(dma_setup)( drm_device_t *dev )
return 0; return 0;
} }
/**
* Cleanup the DMA resources.
*
* \param dev DRM device.
*
* Free all pages associated with DMA buffers, the buffers and pages lists, and
* finally the the drm_device::dma structure itself.
*/
void DRM(dma_takedown)(drm_device_t *dev) void DRM(dma_takedown)(drm_device_t *dev)
{ {
drm_device_dma_t *dma = dev->dma; drm_device_dma_t *dma = dev->dma;
...@@ -128,7 +148,14 @@ void DRM(dma_takedown)(drm_device_t *dev) ...@@ -128,7 +148,14 @@ void DRM(dma_takedown)(drm_device_t *dev)
} }
/**
* Free a buffer.
*
* \param dev DRM device.
* \param buf buffer to free.
*
* Resets the fields of \p buf.
*/
void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
{ {
if (!buf) return; if (!buf) return;
...@@ -154,6 +181,13 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) ...@@ -154,6 +181,13 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
} }
#if !__HAVE_DMA_RECLAIM #if !__HAVE_DMA_RECLAIM
/**
* Reclaim the buffers.
*
* \param filp file pointer.
*
* Frees each buffer associated with \p filp not already on the hardware.
*/
void DRM(reclaim_buffers)( struct file *filp ) void DRM(reclaim_buffers)( struct file *filp )
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
...@@ -185,6 +219,16 @@ void DRM(reclaim_buffers)( struct file *filp ) ...@@ -185,6 +219,16 @@ void DRM(reclaim_buffers)( struct file *filp )
#if __HAVE_DMA_IRQ #if __HAVE_DMA_IRQ
/**
* Install IRQ handler.
*
* \param dev DRM device.
* \param irq IRQ number.
*
* Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
* \c DRM(driver_irq_preinstall)() and \c DRM(driver_irq_postinstall)() functions
* before and after the installation.
*/
int DRM(irq_install)( drm_device_t *dev, int irq ) int DRM(irq_install)( drm_device_t *dev, int irq )
{ {
int ret; int ret;
...@@ -250,6 +294,13 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) ...@@ -250,6 +294,13 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
return 0; return 0;
} }
/**
* Uninstall the IRQ handler.
*
* \param dev DRM device.
*
* Calls the driver's \c DRM(driver_irq_uninstall)() function, and stops the irq.
*/
int DRM(irq_uninstall)( drm_device_t *dev ) int DRM(irq_uninstall)( drm_device_t *dev )
{ {
int irq; int irq;
...@@ -271,6 +322,17 @@ int DRM(irq_uninstall)( drm_device_t *dev ) ...@@ -271,6 +322,17 @@ int DRM(irq_uninstall)( drm_device_t *dev )
return 0; return 0;
} }
/**
* IRQ control ioctl.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_control structure.
* \return zero on success or a negative number on failure.
*
* Calls irq_install() or irq_uninstall() according to \p arg.
*/
int DRM(control)( struct inode *inode, struct file *filp, int DRM(control)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -293,6 +355,25 @@ int DRM(control)( struct inode *inode, struct file *filp, ...@@ -293,6 +355,25 @@ int DRM(control)( struct inode *inode, struct file *filp,
#if __HAVE_VBL_IRQ #if __HAVE_VBL_IRQ
/**
* Wait for VBLANK.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param data user argument, pointing to a drm_wait_vblank structure.
* \return zero on success or a negative number on failure.
*
* Verifies the IRQ is installed.
*
* If a signal is requested checks if this task has already scheduled the same signal
* for the same vblank sequence number - nothing to be done in
* that case. If the number of tasks waiting for the interrupt exceeds 100 the
* function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
* task.
*
* If a signal is not requested, then calls vblank_wait().
*/
int DRM(wait_vblank)( DRM_IOCTL_ARGS ) int DRM(wait_vblank)( DRM_IOCTL_ARGS )
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
...@@ -381,6 +462,15 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) ...@@ -381,6 +462,15 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
return ret; return ret;
} }
/**
* Send the VBLANK signals.
*
* \param dev DRM device.
*
* Sends a signal for each task in drm_device::vbl_sigs and empties the list.
*
* If a signal is not requested, then calls vblank_wait().
*/
void DRM(vbl_send_signals)( drm_device_t *dev ) void DRM(vbl_send_signals)( drm_device_t *dev )
{ {
struct list_head *list, *tmp; struct list_head *list, *tmp;
......
/* drm_drawable.h -- IOCTLs for drawables -*- linux-c -*- /**
* \file drm_drawable.h
* IOCTLs for drawables
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,14 +31,11 @@ ...@@ -23,14 +31,11 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
/** No-op. */
int DRM(adddraw)(struct inode *inode, struct file *filp, int DRM(adddraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -43,6 +48,7 @@ int DRM(adddraw)(struct inode *inode, struct file *filp, ...@@ -43,6 +48,7 @@ int DRM(adddraw)(struct inode *inode, struct file *filp,
return 0; return 0;
} }
/** No-op. */
int DRM(rmdraw)(struct inode *inode, struct file *filp, int DRM(rmdraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
......
/* drm_drv.h -- Generic driver template -*- linux-c -*- /**
* \file drm_drv.h
* Generic driver template
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*
* To use this template, you must at least define the following (samples
* given for the MGA driver):
*
* \code
* #define DRIVER_AUTHOR "VA Linux Systems, Inc."
*
* #define DRIVER_NAME "mga"
* #define DRIVER_DESC "Matrox G200/G400"
* #define DRIVER_DATE "20001127"
*
* #define DRIVER_MAJOR 2
* #define DRIVER_MINOR 0
* #define DRIVER_PATCHLEVEL 2
*
* #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls )
*
* #define DRM(x) mga_##x
* \endcode
*/
/*
* Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
* *
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,29 +50,6 @@ ...@@ -23,29 +50,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/
/*
* To use this template, you must at least define the following (samples
* given for the MGA driver):
*
* #define DRIVER_AUTHOR "VA Linux Systems, Inc."
*
* #define DRIVER_NAME "mga"
* #define DRIVER_DESC "Matrox G200/G400"
* #define DRIVER_DATE "20001127"
*
* #define DRIVER_MAJOR 2
* #define DRIVER_MINOR 0
* #define DRIVER_PATCHLEVEL 2
*
* #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls )
*
* #define DRM(x) mga_##x
*/ */
#ifndef __MUST_HAVE_AGP #ifndef __MUST_HAVE_AGP
...@@ -134,12 +138,13 @@ static struct file_operations DRM(fops) = { \ ...@@ -134,12 +138,13 @@ static struct file_operations DRM(fops) = { \
#endif #endif
#ifndef MODULE #ifndef MODULE
/* DRM(options) is called by the kernel to parse command-line options /** Use an additional macro to avoid preprocessor troubles */
* passed via the boot-loader (e.g., LILO). It calls the insmod option
* routine, drm_parse_drm.
*/
/* Use an additional macro to avoid preprocessor troubles */
#define DRM_OPTIONS_FUNC DRM(options) #define DRM_OPTIONS_FUNC DRM(options)
/**
* Called by the kernel to parse command-line options passed via the
* boot-loader (e.g., LILO). It calls the insmod option routine,
* parse_options().
*/
static int __init DRM(options)( char *str ) static int __init DRM(options)( char *str )
{ {
DRM(parse_options)( str ); DRM(parse_options)( str );
...@@ -150,7 +155,7 @@ __setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC ); ...@@ -150,7 +155,7 @@ __setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC );
#undef DRM_OPTIONS_FUNC #undef DRM_OPTIONS_FUNC
#endif #endif
/* /**
* The default number of instances (minor numbers) to initialize. * The default number of instances (minor numbers) to initialize.
*/ */
#ifndef DRIVER_NUM_CARDS #ifndef DRIVER_NUM_CARDS
...@@ -163,6 +168,7 @@ static int DRM(numdevs) = 0; ...@@ -163,6 +168,7 @@ static int DRM(numdevs) = 0;
DRIVER_FOPS; DRIVER_FOPS;
/** Ioctl table */
static drm_ioctl_desc_t DRM(ioctls)[] = { static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 },
...@@ -348,7 +354,8 @@ static int DRM(setup)( drm_device_t *dev ) ...@@ -348,7 +354,8 @@ static int DRM(setup)( drm_device_t *dev )
DRM_DEBUG( "\n" ); DRM_DEBUG( "\n" );
/* The kernel's context could be created here, but is now created /*
* The kernel's context could be created here, but is now created
* in drm_dma_enqueue. This is more resource-efficient for * in drm_dma_enqueue. This is more resource-efficient for
* hardware that does not do DMA, but may mean that * hardware that does not do DMA, but may mean that
* drm_select_queue fails between the time the interrupt is * drm_select_queue fails between the time the interrupt is
...@@ -359,6 +366,15 @@ static int DRM(setup)( drm_device_t *dev ) ...@@ -359,6 +366,15 @@ static int DRM(setup)( drm_device_t *dev )
} }
/**
* Take down the DRM device.
*
* \param dev DRM device structure.
*
* Frees every resource in \p dev.
*
* \sa drm_device and setup().
*/
static int DRM(takedown)( drm_device_t *dev ) static int DRM(takedown)( drm_device_t *dev )
{ {
drm_magic_entry_t *pt, *next; drm_magic_entry_t *pt, *next;
...@@ -516,8 +532,12 @@ static int DRM(takedown)( drm_device_t *dev ) ...@@ -516,8 +532,12 @@ static int DRM(takedown)( drm_device_t *dev )
return 0; return 0;
} }
/* /**
* Figure out how many instances to initialize. * Figure out how many instances to initialize.
*
* \return number of cards found.
*
* Searches for every PCI card in \c DRIVER_CARD_LIST with matching vendor and device ids.
*/ */
static int drm_count_cards(void) static int drm_count_cards(void)
{ {
...@@ -551,8 +571,18 @@ static int drm_count_cards(void) ...@@ -551,8 +571,18 @@ static int drm_count_cards(void)
return num; return num;
} }
/* drm_init is called via init_module at module load time, or via /**
* Module initialization. Called via init_module at module load time, or via
* linux/init/main.c (this is not currently supported). * linux/init/main.c (this is not currently supported).
*
* \return zero on success or a negative number on failure.
*
* Allocates and initialize an array of drm_device structures, and attempts to
* initialize all available devices, using consecutive minors, registering the
* stubs and initializing the AGP device.
*
* Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
* after the initialization for driver customization.
*/ */
static int __init drm_init( void ) static int __init drm_init( void )
{ {
...@@ -641,7 +671,12 @@ static int __init drm_init( void ) ...@@ -641,7 +671,12 @@ static int __init drm_init( void )
return 0; return 0;
} }
/* drm_cleanup is called via cleanup_module at module unload time. /**
* Called via cleanup_module() at module unload time.
*
* Cleans up all DRM device, calling takedown().
*
* \sa drm_init().
*/ */
static void __exit drm_cleanup( void ) static void __exit drm_cleanup( void )
{ {
...@@ -694,6 +729,17 @@ module_init( drm_init ); ...@@ -694,6 +729,17 @@ module_init( drm_init );
module_exit( drm_cleanup ); module_exit( drm_cleanup );
/**
* Get version information
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_version structure.
* \return zero on success or negative number on failure.
*
* Fills in the version information in \p arg.
*/
int DRM(version)( struct inode *inode, struct file *filp, int DRM(version)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -729,6 +775,17 @@ int DRM(version)( struct inode *inode, struct file *filp, ...@@ -729,6 +775,17 @@ int DRM(version)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Open file.
*
* \param inode device inode
* \param filp file pointer.
* \return zero on success or a negative number on failure.
*
* Searches the DRM device with the same minor number, calls open_helper(), and
* increments the device open count. If the open count was previous at zero,
* i.e., it's the first that the device is open, then calls setup().
*/
int DRM(open)( struct inode *inode, struct file *filp ) int DRM(open)( struct inode *inode, struct file *filp )
{ {
drm_device_t *dev = NULL; drm_device_t *dev = NULL;
...@@ -759,6 +816,18 @@ int DRM(open)( struct inode *inode, struct file *filp ) ...@@ -759,6 +816,18 @@ int DRM(open)( struct inode *inode, struct file *filp )
return retcode; return retcode;
} }
/**
* Release file.
*
* \param inode device inode
* \param filp file pointer.
* \return zero on success or a negative number on failure.
*
* If the hardware lock is held then free it, and take it again for the kernel
* context since it's necessary to reclaim buffers. Unlink the file private
* data from its list and free it. Decreases the open count and if it reaches
* zero calls takedown().
*/
int DRM(release)( struct inode *inode, struct file *filp ) int DRM(release)( struct inode *inode, struct file *filp )
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
...@@ -885,7 +954,17 @@ int DRM(release)( struct inode *inode, struct file *filp ) ...@@ -885,7 +954,17 @@ int DRM(release)( struct inode *inode, struct file *filp )
return retcode; return retcode;
} }
/* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm. /**
* Called whenever a process performs an ioctl on /dev/drm.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument.
* \return zero on success or negative number on failure.
*
* Looks up the ioctl function in the ::ioctls table, checking for root
* previleges if so required, and dispatches to the respective function.
*/ */
int DRM(ioctl)( struct inode *inode, struct file *filp, int DRM(ioctl)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
...@@ -926,6 +1005,17 @@ int DRM(ioctl)( struct inode *inode, struct file *filp, ...@@ -926,6 +1005,17 @@ int DRM(ioctl)( struct inode *inode, struct file *filp,
return retcode; return retcode;
} }
/**
* Lock ioctl.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_lock structure.
* \return zero on success or negative number on failure.
*
* Add the current task to the lock wait queue, and attempt to take to lock.
*/
int DRM(lock)( struct inode *inode, struct file *filp, int DRM(lock)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -1031,7 +1121,17 @@ int DRM(lock)( struct inode *inode, struct file *filp, ...@@ -1031,7 +1121,17 @@ int DRM(lock)( struct inode *inode, struct file *filp,
return ret; return ret;
} }
/**
* Unlock ioctl.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_lock structure.
* \return zero on success or negative number on failure.
*
* Transfer and free the lock.
*/
int DRM(unlock)( struct inode *inode, struct file *filp, int DRM(unlock)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
......
/* drm_fops.h -- File operations for DRM -*- linux-c -*- /**
* \file drm_fops.h
* File operations for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Daryll Strauss <daryll@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,18 +32,23 @@ ...@@ -23,18 +32,23 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Daryll Strauss <daryll@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
#include <linux/poll.h> #include <linux/poll.h>
/* drm_open is called whenever a process opens /dev/drm. */
/**
* Called whenever a process opens /dev/drm.
*
* \param inode device inode.
* \param filp file pointer.
* \param dev device.
* \return zero on success or a negative number on failure.
*
* Creates and initializes a drm_file structure for the file private data in \p
* filp and add it into the double linked list in \p dev.
*/
int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev) int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
{ {
int minor = minor(inode->i_rdev); int minor = minor(inode->i_rdev);
...@@ -90,6 +104,7 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev) ...@@ -90,6 +104,7 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
return 0; return 0;
} }
/** No-op. */
int DRM(flush)(struct file *filp) int DRM(flush)(struct file *filp)
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
...@@ -100,6 +115,7 @@ int DRM(flush)(struct file *filp) ...@@ -100,6 +115,7 @@ int DRM(flush)(struct file *filp)
return 0; return 0;
} }
/** No-op. */
int DRM(fasync)(int fd, struct file *filp, int on) int DRM(fasync)(int fd, struct file *filp, int on)
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
...@@ -113,6 +129,7 @@ int DRM(fasync)(int fd, struct file *filp, int on) ...@@ -113,6 +129,7 @@ int DRM(fasync)(int fd, struct file *filp, int on)
} }
#if !__HAVE_DRIVER_FOPS_POLL #if !__HAVE_DRIVER_FOPS_POLL
/** No-op. */
unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait) unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait)
{ {
return 0; return 0;
...@@ -121,6 +138,7 @@ unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait) ...@@ -121,6 +138,7 @@ unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait)
#if !__HAVE_DRIVER_FOPS_READ #if !__HAVE_DRIVER_FOPS_READ
/** No-op. */
ssize_t DRM(read)(struct file *filp, char *buf, size_t count, loff_t *off) ssize_t DRM(read)(struct file *filp, char *buf, size_t count, loff_t *off)
{ {
return 0; return 0;
......
/* drm_init.h -- Setup/Cleanup for DRM -*- linux-c -*- /**
* \file drm_init.h
* Setup/Cleanup for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,22 +31,23 @@ ...@@ -23,22 +31,23 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
/** Debug flags. Set by parse_option(). */
#if 0 #if 0
int DRM(flags) = DRM_FLAG_DEBUG; int DRM(flags) = DRM_FLAG_DEBUG;
#else #else
int DRM(flags) = 0; int DRM(flags) = 0;
#endif #endif
/* drm_parse_option parses a single option. See description for /**
* drm_parse_options for details. * Parse a single option.
*
* \param s option string.
*
* \sa See parse_options() for details.
*/ */
static void DRM(parse_option)(char *s) static void DRM(parse_option)(char *s)
{ {
...@@ -58,26 +67,33 @@ static void DRM(parse_option)(char *s) ...@@ -58,26 +67,33 @@ static void DRM(parse_option)(char *s)
return; return;
} }
/* drm_parse_options parse the insmod "drm_opts=" options, or the command-line /**
* options passed to the kernel via LILO. The grammar of the format is as * Parse the insmod "drm_opts=" options, or the command-line
* options passed to the kernel via LILO.
*
* \param s contains option_list without the 'drm_opts=' part.
*
* The grammar of the format is as
* follows: * follows:
* *
* \code
* drm ::= 'drm_opts=' option_list * drm ::= 'drm_opts=' option_list
* option_list ::= option [ ';' option_list ] * option_list ::= option [ ';' option_list ]
* option ::= 'device:' major * option ::= 'device:' major
* | 'debug' * | 'debug'
* | 'noctx' * | 'noctx'
* major ::= INTEGER * major ::= INTEGER
* \endcode
* *
* Note that 's' contains option_list without the 'drm_opts=' part. * - device=major,minor specifies the device number used for /dev/drm
* * - if major == 0 then the misc device is used
* device=major,minor specifies the device number used for /dev/drm * - if major == 0 and minor == 0 then dynamic misc allocation is used
* if major == 0 then the misc device is used * - debug=on specifies that debugging messages will be printk'd
* if major == 0 and minor == 0 then dynamic misc allocation is used * - debug=trace specifies that each function call will be logged via printk
* debug=on specifies that debugging messages will be printk'd * - debug=off turns off all debugging options
* debug=trace specifies that each function call will be logged via printk
* debug=off turns off all debugging options
* *
* \todo Actually only the \e presence of the 'debug' option is currently
* checked.
*/ */
void DRM(parse_options)(char *s) void DRM(parse_options)(char *s)
...@@ -95,8 +111,10 @@ void DRM(parse_options)(char *s) ...@@ -95,8 +111,10 @@ void DRM(parse_options)(char *s)
} }
} }
/* drm_cpu_valid returns non-zero if the DRI will run on this CPU, and 0 /**
* otherwise. * Check whether DRI will run on this CPU.
*
* \return non-zero if the DRI will run on this CPU, or zero otherwise.
*/ */
int DRM(cpu_valid)(void) int DRM(cpu_valid)(void)
{ {
......
/* drm_ioctl.h -- IOCTL processing for DRM -*- linux-c -*- /**
* \file drm_ioctl.h
* IOCTL processing for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,15 +31,22 @@ ...@@ -23,15 +31,22 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
/**
* Get interrupt from bus id.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_irq_busid structure.
* \return zero on success or a negative number on failure.
*
* Finds the PCI device with the specified bus id and gets its IRQ number.
*/
int DRM(irq_busid)(struct inode *inode, struct file *filp, int DRM(irq_busid)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -84,6 +99,17 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp, ...@@ -84,6 +99,17 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Get the bus id.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_unique structure.
* \return zero on success or a negative number on failure.
*
* Copies the bus id from drm_device::unique into user space.
*/
int DRM(getunique)(struct inode *inode, struct file *filp, int DRM(getunique)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -103,6 +129,18 @@ int DRM(getunique)(struct inode *inode, struct file *filp, ...@@ -103,6 +129,18 @@ int DRM(getunique)(struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Set the bus id.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_unique structure.
* \return zero on success or a negative number on failure.
*
* Copies the bus id from userspace into drm_device::unique, and searches for
* the respective PCI device, updating drm_device::pdev.
*/
int DRM(setunique)(struct inode *inode, struct file *filp, int DRM(setunique)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -180,6 +218,19 @@ int DRM(setunique)(struct inode *inode, struct file *filp, ...@@ -180,6 +218,19 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
} }
/**
* Get a mapping information.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_map structure.
*
* \return zero on success or a negative number on failure.
*
* Searches for the mapping with the specified offset and copies its information
* into userspace
*/
int DRM(getmap)( struct inode *inode, struct file *filp, int DRM(getmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -226,6 +277,19 @@ int DRM(getmap)( struct inode *inode, struct file *filp, ...@@ -226,6 +277,19 @@ int DRM(getmap)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Get client information.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_client structure.
*
* \return zero on success or a negative number on failure.
*
* Searches for the client with the specified index and copies its information
* into userspace
*/
int DRM(getclient)( struct inode *inode, struct file *filp, int DRM(getclient)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
...@@ -259,6 +323,16 @@ int DRM(getclient)( struct inode *inode, struct file *filp, ...@@ -259,6 +323,16 @@ int DRM(getclient)( struct inode *inode, struct file *filp,
return 0; return 0;
} }
/**
* Get statistics information.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_stats structure.
*
* \return zero on success or a negative number on failure.
*/
int DRM(getstats)( struct inode *inode, struct file *filp, int DRM(getstats)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ) unsigned int cmd, unsigned long arg )
{ {
......
/* lock.c -- IOCTLs for locking -*- linux-c -*- /**
* \file drm_lock.h
* IOCTLs for locking
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,14 +31,11 @@ ...@@ -23,14 +31,11 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
/** No-op ioctl. */
int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd, int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
...@@ -38,7 +43,15 @@ int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd, ...@@ -38,7 +43,15 @@ int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd,
return 0; return 0;
} }
/**
* Take the heavyweight lock.
*
* \param lock lock pointer.
* \param context locking context.
* \return one if the lock is held, or zero otherwise.
*
* Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
*/
int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context) int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
{ {
unsigned int old, new, prev; unsigned int old, new, prev;
...@@ -65,8 +78,18 @@ int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context) ...@@ -65,8 +78,18 @@ int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
return 0; return 0;
} }
/* This takes a lock forcibly and hands it to context. Should ONLY be used /**
inside *_unlock to give lock to kernel before calling *_dma_schedule. */ * This takes a lock forcibly and hands it to context. Should ONLY be used
* inside *_unlock to give lock to kernel before calling *_dma_schedule.
*
* \param dev DRM device.
* \param lock lock pointer.
* \param context locking context.
* \return always one.
*
* Resets the lock file pointer.
* Marks the lock as held by the given context, via the \p cmpxchg instruction.
*/
int DRM(lock_transfer)(drm_device_t *dev, int DRM(lock_transfer)(drm_device_t *dev,
__volatile__ unsigned int *lock, unsigned int context) __volatile__ unsigned int *lock, unsigned int context)
{ {
...@@ -81,6 +104,17 @@ int DRM(lock_transfer)(drm_device_t *dev, ...@@ -81,6 +104,17 @@ int DRM(lock_transfer)(drm_device_t *dev,
return 1; return 1;
} }
/**
* Free lock.
*
* \param dev DRM device.
* \param lock lock.
* \param context context.
*
* Resets the lock file pointer.
* Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
* waiting on the lock queue.
*/
int DRM(lock_free)(drm_device_t *dev, int DRM(lock_free)(drm_device_t *dev,
__volatile__ unsigned int *lock, unsigned int context) __volatile__ unsigned int *lock, unsigned int context)
{ {
...@@ -102,18 +136,17 @@ int DRM(lock_free)(drm_device_t *dev, ...@@ -102,18 +136,17 @@ int DRM(lock_free)(drm_device_t *dev,
return 0; return 0;
} }
/* If we get here, it means that the process has called DRM_IOCTL_LOCK /**
without calling DRM_IOCTL_UNLOCK. * If we get here, it means that the process has called DRM_IOCTL_LOCK
* without calling DRM_IOCTL_UNLOCK.
If the lock is not held, then let the signal proceed as usual. *
* If the lock is not held, then let the signal proceed as usual. If the lock
If the lock is held, then set the contended flag and keep the signal * is held, then set the contended flag and keep the signal blocked.
blocked. *
* \param priv pointer to a drm_sigdata structure.
* \return one if the signal should be delivered normally, or zero if the
Return 1 if the signal should be delivered normally. * signal should be blocked.
Return 0 if the signal should be blocked. */ */
int DRM(notifier)(void *priv) int DRM(notifier)(void *priv)
{ {
drm_sigdata_t *s = (drm_sigdata_t *)priv; drm_sigdata_t *s = (drm_sigdata_t *)priv;
......
/* drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*- /**
* \file drm_memory.h
* Memory management wrappers for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,17 +31,14 @@ ...@@ -23,17 +31,14 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include "drmP.h" #include "drmP.h"
/* Cut down version of drm_memory_debug.h, which used to be called /**
* Cut down version of drm_memory_debug.h, which used to be called
* drm_memory.h. If you want the debug functionality, change 0 to 1 * drm_memory.h. If you want the debug functionality, change 0 to 1
* below. * below.
*/ */
...@@ -188,22 +193,38 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d ...@@ -188,22 +193,38 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d
#if DEBUG_MEMORY #if DEBUG_MEMORY
#include "drm_memory_debug.h" #include "drm_memory_debug.h"
#else #else
/** No-op. */
void DRM(mem_init)(void) void DRM(mem_init)(void)
{ {
} }
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */ /**
* Called when "/proc/dri/%dev%/mem" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param len requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*
* No-op.
*/
int DRM(mem_info)(char *buf, char **start, off_t offset, int DRM(mem_info)(char *buf, char **start, off_t offset,
int len, int *eof, void *data) int len, int *eof, void *data)
{ {
return 0; return 0;
} }
/** Wrapper around kmalloc() */
void *DRM(alloc)(size_t size, int area) void *DRM(alloc)(size_t size, int area)
{ {
return kmalloc(size, GFP_KERNEL); return kmalloc(size, GFP_KERNEL);
} }
/** Wrapper around kmalloc() and kfree() */
void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area) void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
{ {
void *pt; void *pt;
...@@ -216,11 +237,21 @@ void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area) ...@@ -216,11 +237,21 @@ void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
return pt; return pt;
} }
/** Wrapper around kfree() */
void DRM(free)(void *pt, size_t size, int area) void DRM(free)(void *pt, size_t size, int area)
{ {
kfree(pt); kfree(pt);
} }
/**
* Allocate pages.
*
* \param order size order.
* \param area memory area. (Not used.)
* \return page address on success, or zero on failure.
*
* Allocate and reserve free pages.
*/
unsigned long DRM(alloc_pages)(int order, int area) unsigned long DRM(alloc_pages)(int order, int area)
{ {
unsigned long address; unsigned long address;
...@@ -245,6 +276,15 @@ unsigned long DRM(alloc_pages)(int order, int area) ...@@ -245,6 +276,15 @@ unsigned long DRM(alloc_pages)(int order, int area)
return address; return address;
} }
/**
* Free pages.
*
* \param address address of the pages to free.
* \param order size order.
* \param area memory area. (Not used.)
*
* Unreserve and free pages allocated by alloc_pages().
*/
void DRM(free_pages)(unsigned long address, int order, int area) void DRM(free_pages)(unsigned long address, int order, int area)
{ {
unsigned long bytes = PAGE_SIZE << order; unsigned long bytes = PAGE_SIZE << order;
...@@ -264,37 +304,44 @@ void DRM(free_pages)(unsigned long address, int order, int area) ...@@ -264,37 +304,44 @@ void DRM(free_pages)(unsigned long address, int order, int area)
free_pages(address, order); free_pages(address, order);
} }
/** Wrapper around drm_ioremap() */
void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev) void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
{ {
return drm_ioremap(offset, size, dev); return drm_ioremap(offset, size, dev);
} }
/** Wrapper around drm_ioremap_nocache() */
void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev) void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
{ {
return drm_ioremap_nocache(offset, size, dev); return drm_ioremap_nocache(offset, size, dev);
} }
/** Wrapper around drm_iounmap() */
void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev) void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
{ {
drm_ioremapfree(pt, size, dev); drm_ioremapfree(pt, size, dev);
} }
#if __REALLY_HAVE_AGP #if __REALLY_HAVE_AGP
/** Wrapper around agp_allocate_memory() */
struct agp_memory *DRM(alloc_agp)(int pages, u32 type) struct agp_memory *DRM(alloc_agp)(int pages, u32 type)
{ {
return DRM(agp_allocate_memory)(pages, type); return DRM(agp_allocate_memory)(pages, type);
} }
/** Wrapper around agp_free_memory() */
int DRM(free_agp)(struct agp_memory *handle, int pages) int DRM(free_agp)(struct agp_memory *handle, int pages)
{ {
return DRM(agp_free_memory)(handle) ? 0 : -EINVAL; return DRM(agp_free_memory)(handle) ? 0 : -EINVAL;
} }
/** Wrapper around agp_bind_memory() */
int DRM(bind_agp)(struct agp_memory *handle, unsigned int start) int DRM(bind_agp)(struct agp_memory *handle, unsigned int start)
{ {
return DRM(agp_bind_memory)(handle, start); return DRM(agp_bind_memory)(handle, start);
} }
/** Wrapper around agp_unbind_memory() */
int DRM(unbind_agp)(struct agp_memory *handle) int DRM(unbind_agp)(struct agp_memory *handle)
{ {
return DRM(agp_unbind_memory)(handle); return DRM(agp_unbind_memory)(handle);
......
/* drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*- /**
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com * \file drm_memory.h
* Memory management wrappers for DRM.
* *
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved. * All Rights Reserved.
...@@ -23,10 +29,6 @@ ...@@ -23,10 +29,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include <linux/config.h> #include <linux/config.h>
......
/**
* \file drm_os_linux.h
* OS abstraction macros.
*/
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h> #include <linux/delay.h>
/** File pointer type */
#define DRMFILE struct file * #define DRMFILE struct file *
/** Ioctl arguments */
#define DRM_IOCTL_ARGS struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data #define DRM_IOCTL_ARGS struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data
#define DRM_ERR(d) -(d) #define DRM_ERR(d) -(d)
/** Current process ID */
#define DRM_CURRENTPID current->pid #define DRM_CURRENTPID current->pid
#define DRM_UDELAY(d) udelay(d) #define DRM_UDELAY(d) udelay(d)
/** Read a byte from a MMIO region */
#define DRM_READ8(map, offset) readb(((unsigned long)(map)->handle) + (offset)) #define DRM_READ8(map, offset) readb(((unsigned long)(map)->handle) + (offset))
/** Read a dword from a MMIO region */
#define DRM_READ32(map, offset) readl(((unsigned long)(map)->handle) + (offset)) #define DRM_READ32(map, offset) readl(((unsigned long)(map)->handle) + (offset))
/** Write a byte into a MMIO region */
#define DRM_WRITE8(map, offset, val) writeb(val, ((unsigned long)(map)->handle) + (offset)) #define DRM_WRITE8(map, offset, val) writeb(val, ((unsigned long)(map)->handle) + (offset))
/** Write a dword into a MMIO region */
#define DRM_WRITE32(map, offset, val) writel(val, ((unsigned long)(map)->handle) + (offset)) #define DRM_WRITE32(map, offset, val) writel(val, ((unsigned long)(map)->handle) + (offset))
/** Read memory barrier */
#define DRM_READMEMORYBARRIER() rmb() #define DRM_READMEMORYBARRIER() rmb()
/** Write memory barrier */
#define DRM_WRITEMEMORYBARRIER() wmb() #define DRM_WRITEMEMORYBARRIER() wmb()
/** Read/write memory barrier */
#define DRM_MEMORYBARRIER() mb() #define DRM_MEMORYBARRIER() mb()
/** DRM device local declaration */
#define DRM_DEVICE drm_file_t *priv = filp->private_data; \ #define DRM_DEVICE drm_file_t *priv = filp->private_data; \
drm_device_t *dev = priv->dev drm_device_t *dev = priv->dev
/** IRQ handler arguments */
#define DRM_IRQ_ARGS int irq, void *arg, struct pt_regs *regs #define DRM_IRQ_ARGS int irq, void *arg, struct pt_regs *regs
/** Task queue handler arguments */
#define DRM_TASKQUEUE_ARGS void *arg #define DRM_TASKQUEUE_ARGS void *arg
/* For data going from/to the kernel through the ioctl argument */ /** For data going into the kernel through the ioctl argument */
#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ #define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \
if ( copy_from_user(&arg1, arg2, arg3) ) \ if ( copy_from_user(&arg1, arg2, arg3) ) \
return -EFAULT return -EFAULT
/** For data going from the kernel through the ioctl argument */
#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ #define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
if ( copy_to_user(arg1, &arg2, arg3) ) \ if ( copy_to_user(arg1, &arg2, arg3) ) \
return -EFAULT return -EFAULT
/* Other copying of data from/to kernel space */ /** Other copying of data to kernel space */
#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ #define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
copy_from_user(arg1, arg2, arg3) copy_from_user(arg1, arg2, arg3)
/** Other copying of data from kernel space */
#define DRM_COPY_TO_USER(arg1, arg2, arg3) \ #define DRM_COPY_TO_USER(arg1, arg2, arg3) \
copy_to_user(arg1, arg2, arg3) copy_to_user(arg1, arg2, arg3)
/* Macros for copyfrom user, but checking readability only once */ /* Macros for copyfrom user, but checking readability only once */
...@@ -41,10 +61,16 @@ ...@@ -41,10 +61,16 @@
__get_user(val, uaddr) __get_user(val, uaddr)
/* malloc/free without the overhead of DRM(alloc) */ /** 'malloc' without the overhead of DRM(alloc)() */
#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
/** 'free' without the overhead of DRM(free)() */
#define DRM_FREE(x,size) kfree(x) #define DRM_FREE(x,size) kfree(x)
/**
* Get the pointer to the SAREA.
*
* Searches the SAREA on the mapping lists and points drm_device::sarea to it.
*/
#define DRM_GETSAREA() \ #define DRM_GETSAREA() \
do { \ do { \
drm_map_list_t *entry; \ drm_map_list_t *entry; \
......
/* drm_proc.h -- /proc support for DRM -*- linux-c -*- /**
* \file drm_proc.h
* /proc support for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*
* \par Acknowledgements:
* Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
* the problem with the proc files not outputting all their information.
*/
/*
* Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,14 +35,6 @@ ...@@ -23,14 +35,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*
* Acknowledgements:
* Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
* the problem with the proc files not outputting all their information.
*/ */
#include "drmP.h" #include "drmP.h"
...@@ -50,9 +54,12 @@ static int DRM(vma_info)(char *buf, char **start, off_t offset, ...@@ -50,9 +54,12 @@ static int DRM(vma_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data); int request, int *eof, void *data);
#endif #endif
/**
* Proc file list.
*/
struct drm_proc_list { struct drm_proc_list {
const char *name; const char *name; /**< file name */
int (*f)(char *, char **, off_t, int, int *, void *); int (*f)(char *, char **, off_t, int, int *, void *); /**< proc callback*/
} DRM(proc_list)[] = { } DRM(proc_list)[] = {
{ "name", DRM(name_info) }, { "name", DRM(name_info) },
{ "mem", DRM(mem_info) }, { "mem", DRM(mem_info) },
...@@ -66,6 +73,19 @@ struct drm_proc_list { ...@@ -66,6 +73,19 @@ struct drm_proc_list {
}; };
#define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0])) #define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
/**
* Initialize the DRI proc filesystem for a device.
*
* \param dev DRM device.
* \param minor device minor number.
* \param root DRI proc dir entry.
* \param dev_root resulting DRI device proc dir entry.
* \return root entry pointer on success, or NULL on failure.
*
* Create the DRI proc root entry "/proc/dri", the device proc root entry
* "/proc/dri/%minor%/", and each entry in proc_list as
* "/proc/dri/%minor%/%name%".
*/
struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
struct proc_dir_entry *root, struct proc_dir_entry *root,
struct proc_dir_entry **dev_root) struct proc_dir_entry **dev_root)
...@@ -83,7 +103,7 @@ struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, ...@@ -83,7 +103,7 @@ struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
sprintf(name, "%d", minor); sprintf(name, "%d", minor);
*dev_root = create_proc_entry(name, S_IFDIR, root); *dev_root = create_proc_entry(name, S_IFDIR, root);
if (!*dev_root) { if (!*dev_root) {
DRM_ERROR("Cannot create /proc/%s\n", name); DRM_ERROR("Cannot create /proc/dri/%s\n", name);
return NULL; return NULL;
} }
...@@ -108,6 +128,16 @@ struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, ...@@ -108,6 +128,16 @@ struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
} }
/**
* Cleanup the proc filesystem resources.
*
* \param minor device minor number.
* \param root DRI proc dir entry.
* \param dev_root DRI device proc dir entry.
* \return always zero.
*
* Remove all proc entries created by proc_init().
*/
int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root, int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
struct proc_dir_entry *dev_root) struct proc_dir_entry *dev_root)
{ {
...@@ -125,6 +155,19 @@ int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root, ...@@ -125,6 +155,19 @@ int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
return 0; return 0;
} }
/**
* Called when "/proc/dri/.../name" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*
* Prints the device name together with the bus id if available.
*/
static int DRM(name_info)(char *buf, char **start, off_t offset, int request, static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data) int *eof, void *data)
{ {
...@@ -151,6 +194,19 @@ static int DRM(name_info)(char *buf, char **start, off_t offset, int request, ...@@ -151,6 +194,19 @@ static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
return len - offset; return len - offset;
} }
/**
* Called when "/proc/dri/.../vm" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*
* Prints information about all mappings in drm_device::maplist.
*/
static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request, static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data) int *eof, void *data)
{ {
...@@ -204,6 +260,9 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request, ...@@ -204,6 +260,9 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
return len - offset; return len - offset;
} }
/**
* Simply calls _vm_info() while holding the drm_device::struct_sem lock.
*/
static int DRM(vm_info)(char *buf, char **start, off_t offset, int request, static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data) int *eof, void *data)
{ {
...@@ -216,7 +275,17 @@ static int DRM(vm_info)(char *buf, char **start, off_t offset, int request, ...@@ -216,7 +275,17 @@ static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
return ret; return ret;
} }
/**
* Called when "/proc/dri/.../queues" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*/
static int DRM(_queues_info)(char *buf, char **start, off_t offset, static int DRM(_queues_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data) int request, int *eof, void *data)
{ {
...@@ -261,6 +330,9 @@ static int DRM(_queues_info)(char *buf, char **start, off_t offset, ...@@ -261,6 +330,9 @@ static int DRM(_queues_info)(char *buf, char **start, off_t offset,
return len - offset; return len - offset;
} }
/**
* Simply calls _queues_info() while holding the drm_device::struct_sem lock.
*/
static int DRM(queues_info)(char *buf, char **start, off_t offset, int request, static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data) int *eof, void *data)
{ {
...@@ -273,9 +345,17 @@ static int DRM(queues_info)(char *buf, char **start, off_t offset, int request, ...@@ -273,9 +345,17 @@ static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
return ret; return ret;
} }
/* drm_bufs_info is called whenever a process reads /**
/dev/dri/<dev>/bufs. */ * Called when "/proc/dri/.../bufs" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*/
static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request, static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data) int *eof, void *data)
{ {
...@@ -320,6 +400,9 @@ static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request, ...@@ -320,6 +400,9 @@ static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
return len - offset; return len - offset;
} }
/**
* Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
*/
static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request, static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data) int *eof, void *data)
{ {
...@@ -332,7 +415,17 @@ static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request, ...@@ -332,7 +415,17 @@ static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
return ret; return ret;
} }
/**
* Called when "/proc/dri/.../clients" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*/
static int DRM(_clients_info)(char *buf, char **start, off_t offset, static int DRM(_clients_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data) int request, int *eof, void *data)
{ {
...@@ -364,6 +457,9 @@ static int DRM(_clients_info)(char *buf, char **start, off_t offset, ...@@ -364,6 +457,9 @@ static int DRM(_clients_info)(char *buf, char **start, off_t offset,
return len - offset; return len - offset;
} }
/**
* Simply calls _clients_info() while holding the drm_device::struct_sem lock.
*/
static int DRM(clients_info)(char *buf, char **start, off_t offset, static int DRM(clients_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data) int request, int *eof, void *data)
{ {
......
/* sarea.h -- SAREA definitions -*- linux-c -*- /**
* \file drm_sarea.h
* \brief SAREA definitions
* *
* \author Michel Dänzer <michel@daenzer.net>
*/
/*
* Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved. * All Rights Reserved.
* *
...@@ -21,22 +27,22 @@ ...@@ -21,22 +27,22 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Michel Dänzer <michel@daenzer.net>
*/ */
#ifndef _DRM_SAREA_H_ #ifndef _DRM_SAREA_H_
#define _DRM_SAREA_H_ #define _DRM_SAREA_H_
/** Maximum number of drawables in the SAREA */
#define SAREA_MAX_DRAWABLES 256 #define SAREA_MAX_DRAWABLES 256
typedef struct _drm_sarea_drawable_t { /** SAREA drawable */
typedef struct drm_sarea_drawable {
unsigned int stamp; unsigned int stamp;
unsigned int flags; unsigned int flags;
} drm_sarea_drawable_t; } drm_sarea_drawable_t;
typedef struct _dri_sarea_frame_t { /** SAREA frame */
typedef struct drm_sarea_frame {
unsigned int x; unsigned int x;
unsigned int y; unsigned int y;
unsigned int width; unsigned int width;
...@@ -44,13 +50,14 @@ typedef struct _dri_sarea_frame_t { ...@@ -44,13 +50,14 @@ typedef struct _dri_sarea_frame_t {
unsigned int fullscreen; unsigned int fullscreen;
} drm_sarea_frame_t; } drm_sarea_frame_t;
typedef struct _drm_sarea_t { /** SAREA */
/* first thing is always the drm locking structure */ typedef struct drm_sarea {
/** first thing is always the DRM locking structure */
drm_hw_lock_t lock; drm_hw_lock_t lock;
/* NOT_DONE: Use readers/writer lock for drawable_lock */ /** \todo Use readers/writer lock for drm_sarea::drawable_lock */
drm_hw_lock_t drawable_lock; drm_hw_lock_t drawable_lock;
drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */
drm_sarea_frame_t frame; drm_sarea_frame_t frame; /**< frame */
drm_context_t dummy_context; drm_context_t dummy_context;
} drm_sarea_t; } drm_sarea_t;
......
/* drm_scatter.h -- IOCTLs to manage scatter/gather memory -*- linux-c -*- /**
* \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 * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
* *
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
...@@ -22,9 +29,6 @@ ...@@ -22,9 +29,6 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
*
* Authors:
* Gareth Hughes <gareth@valinux.com>
*/ */
#include <linux/config.h> #include <linux/config.h>
......
/* drm_stub.h -- -*- linux-c -*- /**
* \file drm_stub.h
* Stub support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
*/
/*
* Created: Fri Jan 19 10:48:35 2001 by faith@acm.org * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
* *
* Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California. * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
...@@ -22,30 +29,37 @@ ...@@ -22,30 +29,37 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
*
*/ */
#include "drmP.h" #include "drmP.h"
#define DRM_STUB_MAXCARDS 16 /* Enough for one machine */ #define DRM_STUB_MAXCARDS 16 /* Enough for one machine */
/** Stub list. One for each minor. */
static struct drm_stub_list { static struct drm_stub_list {
const char *name; const char *name;
struct file_operations *fops; struct file_operations *fops; /**< file operations */
struct proc_dir_entry *dev_root; struct proc_dir_entry *dev_root; /**< proc directory entry */
} *DRM(stub_list); } *DRM(stub_list);
static struct proc_dir_entry *DRM(stub_root); static struct proc_dir_entry *DRM(stub_root);
/** Stub information */
static struct drm_stub_info { static struct drm_stub_info {
int (*info_register)(const char *name, struct file_operations *fops, int (*info_register)(const char *name, struct file_operations *fops,
drm_device_t *dev); drm_device_t *dev);
int (*info_unregister)(int minor); int (*info_unregister)(int minor);
} DRM(stub_info); } DRM(stub_info);
/**
* File \c open operation.
*
* \param inode device inode.
* \param filp file pointer.
*
* Puts the drm_stub_list::fops corresponding to the device minor number into
* \p filp, call the \c open method, and restore the file operations.
*/
static int DRM(stub_open)(struct inode *inode, struct file *filp) static int DRM(stub_open)(struct inode *inode, struct file *filp)
{ {
int minor = minor(inode->i_rdev); int minor = minor(inode->i_rdev);
...@@ -64,11 +78,24 @@ static int DRM(stub_open)(struct inode *inode, struct file *filp) ...@@ -64,11 +78,24 @@ static int DRM(stub_open)(struct inode *inode, struct file *filp)
return err; return err;
} }
/** File operations structure */
static struct file_operations DRM(stub_fops) = { static struct file_operations DRM(stub_fops) = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = DRM(stub_open) .open = DRM(stub_open)
}; };
/**
* Get a device minor number.
*
* \param name driver name.
* \param fops file operations.
* \param dev DRM device.
* \return minor number on success, or a negative number on failure.
*
* Allocate and initialize ::stub_list if one doesn't exist already. Search an
* empty entry and initialize it to the given parameters, and create the proc
* init entry via proc_init().
*/
static int DRM(stub_getminor)(const char *name, struct file_operations *fops, static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
drm_device_t *dev) drm_device_t *dev)
{ {
...@@ -96,6 +123,16 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops, ...@@ -96,6 +123,16 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
return -1; return -1;
} }
/**
* Put a device minor number.
*
* \param minor minor number.
* \return always zero.
*
* Cleans up the proc resources. If a minor is zero then release the foreign
* "drm" data, otherwise unregisters the "drm" data, frees the stub list and
* unregisters the character device.
*/
static int DRM(stub_putminor)(int minor) static int DRM(stub_putminor)(int minor)
{ {
if (minor < 0 || minor >= DRM_STUB_MAXCARDS) return -1; if (minor < 0 || minor >= DRM_STUB_MAXCARDS) return -1;
...@@ -115,7 +152,20 @@ static int DRM(stub_putminor)(int minor) ...@@ -115,7 +152,20 @@ static int DRM(stub_putminor)(int minor)
return 0; return 0;
} }
/**
* Register.
*
* \param name driver name.
* \param fops file operations
* \param dev DRM device.
* \return zero on success or a negative number on failure.
*
* Attempt to register the char device and get the foreign "drm" data. If
* successful then another module already registered so gets the stub info,
* otherwise use this module stub info and make it available for other modules.
*
* Finally calls stub_info::info_register.
*/
int DRM(stub_register)(const char *name, struct file_operations *fops, int DRM(stub_register)(const char *name, struct file_operations *fops,
drm_device_t *dev) drm_device_t *dev)
{ {
...@@ -141,6 +191,13 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, ...@@ -141,6 +191,13 @@ int DRM(stub_register)(const char *name, struct file_operations *fops,
return -1; return -1;
} }
/**
* Unregister.
*
* \param minor
*
* Calls drm_stub_info::unregister.
*/
int DRM(stub_unregister)(int minor) int DRM(stub_unregister)(int minor)
{ {
DRM_DEBUG("%d\n", minor); DRM_DEBUG("%d\n", minor);
......
/* drm_vm.h -- Memory mapping for DRM -*- linux-c -*- /**
* \file drm_vm.h
* Memory mapping for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
* *
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
...@@ -23,38 +31,49 @@ ...@@ -23,38 +31,49 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * 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 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*/ */
#include "drmP.h" #include "drmP.h"
/** AGP virtual memory operations */
struct vm_operations_struct DRM(vm_ops) = { struct vm_operations_struct DRM(vm_ops) = {
.nopage = DRM(vm_nopage), .nopage = DRM(vm_nopage),
.open = DRM(vm_open), .open = DRM(vm_open),
.close = DRM(vm_close), .close = DRM(vm_close),
}; };
/** Shared virtual memory operations */
struct vm_operations_struct DRM(vm_shm_ops) = { struct vm_operations_struct DRM(vm_shm_ops) = {
.nopage = DRM(vm_shm_nopage), .nopage = DRM(vm_shm_nopage),
.open = DRM(vm_open), .open = DRM(vm_open),
.close = DRM(vm_shm_close), .close = DRM(vm_shm_close),
}; };
/** DMA virtual memory operations */
struct vm_operations_struct DRM(vm_dma_ops) = { struct vm_operations_struct DRM(vm_dma_ops) = {
.nopage = DRM(vm_dma_nopage), .nopage = DRM(vm_dma_nopage),
.open = DRM(vm_open), .open = DRM(vm_open),
.close = DRM(vm_close), .close = DRM(vm_close),
}; };
/** Scatter-gather virtual memory operations */
struct vm_operations_struct DRM(vm_sg_ops) = { struct vm_operations_struct DRM(vm_sg_ops) = {
.nopage = DRM(vm_sg_nopage), .nopage = DRM(vm_sg_nopage),
.open = DRM(vm_open), .open = DRM(vm_open),
.close = DRM(vm_close), .close = DRM(vm_close),
}; };
/**
* \c nopage method for AGP virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \param write_access sharing.
* \return pointer to the page structure.
*
* Find the right map and if it's AGP memory find the real physical page to
* map, get the page, increment the use count and return it.
*/
struct page *DRM(vm_nopage)(struct vm_area_struct *vma, struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
unsigned long address, unsigned long address,
int write_access) int write_access)
...@@ -122,6 +141,17 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma, ...@@ -122,6 +141,17 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
return NOPAGE_SIGBUS; /* Disallow mremap */ return NOPAGE_SIGBUS; /* Disallow mremap */
} }
/**
* \c nopage method for shared virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \param write_access sharing.
* \return pointer to the page structure.
*
* Get the the mapping, find the real physical page to map, get the page, and
* return it.
*/
struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
unsigned long address, unsigned long address,
int write_access) int write_access)
...@@ -145,10 +175,15 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, ...@@ -145,10 +175,15 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
return page; return page;
} }
/* Special close routine which deletes map information if we are the last
/**
* \c close method for shared virtual memory.
*
* \param vma virtual memory area.
*
* Deletes map information if we are the last
* person to close a mapping and it's not in the global maplist. * person to close a mapping and it's not in the global maplist.
*/ */
void DRM(vm_shm_close)(struct vm_area_struct *vma) void DRM(vm_shm_close)(struct vm_area_struct *vma)
{ {
drm_file_t *priv = vma->vm_file->private_data; drm_file_t *priv = vma->vm_file->private_data;
...@@ -221,6 +256,16 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma) ...@@ -221,6 +256,16 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma)
up(&dev->struct_sem); up(&dev->struct_sem);
} }
/**
* \c nopage method for DMA virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \param write_access sharing.
* \return pointer to the page structure.
*
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
*/
struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
unsigned long address, unsigned long address,
int write_access) int write_access)
...@@ -247,6 +292,16 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, ...@@ -247,6 +292,16 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
return page; return page;
} }
/**
* \c nopage method for scatter-gather virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \param write_access sharing.
* \return pointer to the page structure.
*
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
*/
struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma, struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
unsigned long address, unsigned long address,
int write_access) int write_access)
...@@ -274,6 +329,14 @@ struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma, ...@@ -274,6 +329,14 @@ struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
return page; return page;
} }
/**
* \c open method for shared virtual memory.
*
* \param vma virtual memory area.
*
* Create a new drm_vma_entry structure as the \p vma private data entry and
* add it to drm_device::vmalist.
*/
void DRM(vm_open)(struct vm_area_struct *vma) void DRM(vm_open)(struct vm_area_struct *vma)
{ {
drm_file_t *priv = vma->vm_file->private_data; drm_file_t *priv = vma->vm_file->private_data;
...@@ -295,6 +358,14 @@ void DRM(vm_open)(struct vm_area_struct *vma) ...@@ -295,6 +358,14 @@ void DRM(vm_open)(struct vm_area_struct *vma)
} }
} }
/**
* \c close method for all virtual memory types.
*
* \param vma virtual memory area.
*
* Search the \p vma private data entry in drm_device::vmalist, unlink it, and
* free it.
*/
void DRM(vm_close)(struct vm_area_struct *vma) void DRM(vm_close)(struct vm_area_struct *vma)
{ {
drm_file_t *priv = vma->vm_file->private_data; drm_file_t *priv = vma->vm_file->private_data;
...@@ -320,6 +391,16 @@ void DRM(vm_close)(struct vm_area_struct *vma) ...@@ -320,6 +391,16 @@ void DRM(vm_close)(struct vm_area_struct *vma)
up(&dev->struct_sem); up(&dev->struct_sem);
} }
/**
* mmap DMA memory.
*
* \param filp file pointer.
* \param vma virtual memory area.
* \return zero on success or a negative number on failure.
*
* Sets the virtual memory area operations structure to vm_dma_ops, the file
* pointer, and calls vm_open().
*/
int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma) int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma)
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
...@@ -366,6 +447,19 @@ int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma) ...@@ -366,6 +447,19 @@ int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma)
#endif #endif
#endif #endif
/**
* mmap DMA memory.
*
* \param filp file pointer.
* \param vma virtual memory area.
* \return zero on success or a negative number on failure.
*
* If the virtual memory area has no offset associated with it then it's a DMA
* area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
* checks that the restricted flag is not set, sets the virtual memory operations
* according to the mapping type and remaps the pages. Finally sets the file
* pointer and calls vm_open().
*/
int DRM(mmap)(struct file *filp, struct vm_area_struct *vma) int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
{ {
drm_file_t *priv = filp->private_data; drm_file_t *priv = filp->private_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment