drm: cleanup buffer/map code
This is a patch from DRM CVS that cleans up some code that was in CVS that I never moved to the kernel, this patch produces the result of the cleanups and puts it into the kernel drm. From: Eric Anholt <anholt@freebsd.org>, Jon Smirl, Dave Airlie Signed-off-by: Dave Airlie <airlied@linux.ie>
This commit is contained in:
@@ -908,10 +908,11 @@ extern int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request);
|
|||||||
extern int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request);
|
extern int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request);
|
||||||
extern int drm_addmap(drm_device_t *dev, unsigned int offset,
|
extern int drm_addmap(drm_device_t *dev, unsigned int offset,
|
||||||
unsigned int size, drm_map_type_t type,
|
unsigned int size, drm_map_type_t type,
|
||||||
drm_map_flags_t flags, drm_map_t **map_ptr);
|
drm_map_flags_t flags, drm_local_map_t **map_ptr);
|
||||||
extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
|
extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
extern int drm_rmmap(drm_device_t *dev, void *handle);
|
extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
|
||||||
|
extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map);
|
||||||
extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
|
extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
|
|
||||||
@@ -926,6 +927,10 @@ extern int drm_freebufs( struct inode *inode, struct file *filp,
|
|||||||
unsigned int cmd, unsigned long arg );
|
unsigned int cmd, unsigned long arg );
|
||||||
extern int drm_mapbufs( struct inode *inode, struct file *filp,
|
extern int drm_mapbufs( struct inode *inode, struct file *filp,
|
||||||
unsigned int cmd, unsigned long arg );
|
unsigned int cmd, unsigned long arg );
|
||||||
|
extern unsigned long drm_get_resource_start(drm_device_t *dev,
|
||||||
|
unsigned int resource);
|
||||||
|
extern unsigned long drm_get_resource_len(drm_device_t *dev,
|
||||||
|
unsigned int resource);
|
||||||
|
|
||||||
/* DMA support (drm_dma.h) */
|
/* DMA support (drm_dma.h) */
|
||||||
extern int drm_dma_setup(drm_device_t *dev);
|
extern int drm_dma_setup(drm_device_t *dev);
|
||||||
|
@@ -36,29 +36,33 @@
|
|||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
|
|
||||||
/**
|
unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
|
||||||
* 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 order;
|
return pci_resource_start(dev->pdev, resource);
|
||||||
unsigned long tmp;
|
}
|
||||||
|
EXPORT_SYMBOL(drm_get_resource_start);
|
||||||
for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
|
|
||||||
;
|
unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
|
||||||
|
{
|
||||||
if (size & (size - 1))
|
return pci_resource_len(dev->pdev, resource);
|
||||||
++order;
|
}
|
||||||
|
EXPORT_SYMBOL(drm_get_resource_len);
|
||||||
return order;
|
|
||||||
|
static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
|
||||||
|
drm_local_map_t *map)
|
||||||
|
{
|
||||||
|
struct list_head *list;
|
||||||
|
|
||||||
|
list_for_each(list, &dev->maplist->head) {
|
||||||
|
drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
|
||||||
|
if (entry->map && map->type == entry->map->type &&
|
||||||
|
entry->map->offset == map->offset) {
|
||||||
|
return entry->map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_order);
|
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
/*
|
/*
|
||||||
@@ -89,6 +93,7 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
|
|||||||
drm_map_t *map;
|
drm_map_t *map;
|
||||||
drm_map_list_t *list;
|
drm_map_list_t *list;
|
||||||
drm_dma_handle_t *dmah;
|
drm_dma_handle_t *dmah;
|
||||||
|
drm_local_map_t *found_map;
|
||||||
|
|
||||||
map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
|
map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
|
||||||
if ( !map )
|
if ( !map )
|
||||||
@@ -129,6 +134,24 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
|
|||||||
#ifdef __alpha__
|
#ifdef __alpha__
|
||||||
map->offset += dev->hose->mem_space->start;
|
map->offset += dev->hose->mem_space->start;
|
||||||
#endif
|
#endif
|
||||||
|
/* Some drivers preinitialize some maps, without the X Server
|
||||||
|
* needing to be aware of it. Therefore, we just return success
|
||||||
|
* when the server tries to create a duplicate map.
|
||||||
|
*/
|
||||||
|
found_map = drm_find_matching_map(dev, map);
|
||||||
|
if (found_map != NULL) {
|
||||||
|
if (found_map->size != map->size) {
|
||||||
|
DRM_DEBUG("Matching maps of type %d with "
|
||||||
|
"mismatched sizes, (%ld vs %ld)\n",
|
||||||
|
map->type, map->size, found_map->size);
|
||||||
|
found_map->size = map->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||||
|
*map_ptr = found_map;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (drm_core_has_MTRR(dev)) {
|
if (drm_core_has_MTRR(dev)) {
|
||||||
if ( map->type == _DRM_FRAME_BUFFER ||
|
if ( map->type == _DRM_FRAME_BUFFER ||
|
||||||
(map->flags & _DRM_WRITE_COMBINING) ) {
|
(map->flags & _DRM_WRITE_COMBINING) ) {
|
||||||
@@ -270,93 +293,136 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
|
|||||||
*
|
*
|
||||||
* \sa drm_addmap
|
* \sa drm_addmap
|
||||||
*/
|
*/
|
||||||
int drm_rmmap(drm_device_t *dev, void *handle)
|
int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
|
||||||
{
|
{
|
||||||
struct list_head *list;
|
struct list_head *list;
|
||||||
drm_map_list_t *r_list = NULL;
|
drm_map_list_t *r_list = NULL;
|
||||||
drm_vma_entry_t *pt, *prev;
|
drm_dma_handle_t dmah;
|
||||||
drm_map_t *map;
|
|
||||||
int found_maps = 0;
|
|
||||||
|
|
||||||
down(&dev->struct_sem);
|
/* Find the list entry for the map and remove it */
|
||||||
list = &dev->maplist->head;
|
|
||||||
list_for_each(list, &dev->maplist->head) {
|
list_for_each(list, &dev->maplist->head) {
|
||||||
r_list = list_entry(list, drm_map_list_t, head);
|
r_list = list_entry(list, drm_map_list_t, head);
|
||||||
|
|
||||||
if(r_list->map &&
|
if (r_list->map == map) {
|
||||||
r_list->map->handle == handle &&
|
list_del(list);
|
||||||
r_list->map->flags & _DRM_REMOVABLE) break;
|
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
||||||
}
|
|
||||||
|
|
||||||
/* List has wrapped around to the head pointer, or its empty we didn't
|
|
||||||
* find anything.
|
|
||||||
*/
|
|
||||||
if(list == (&dev->maplist->head)) {
|
|
||||||
up(&dev->struct_sem);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
map = r_list->map;
|
|
||||||
list_del(list);
|
|
||||||
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
|
||||||
|
|
||||||
for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
|
|
||||||
if (pt->vma->vm_private_data == map) found_maps++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!found_maps) {
|
|
||||||
drm_dma_handle_t dmah;
|
|
||||||
|
|
||||||
switch (map->type) {
|
|
||||||
case _DRM_REGISTERS:
|
|
||||||
case _DRM_FRAME_BUFFER:
|
|
||||||
if (drm_core_has_MTRR(dev)) {
|
|
||||||
if (map->mtrr >= 0) {
|
|
||||||
int retcode;
|
|
||||||
retcode = mtrr_del(map->mtrr,
|
|
||||||
map->offset,
|
|
||||||
map->size);
|
|
||||||
DRM_DEBUG("mtrr_del = %d\n", retcode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
drm_ioremapfree(map->handle, map->size, dev);
|
|
||||||
break;
|
|
||||||
case _DRM_SHM:
|
|
||||||
vfree(map->handle);
|
|
||||||
break;
|
|
||||||
case _DRM_AGP:
|
|
||||||
case _DRM_SCATTER_GATHER:
|
|
||||||
break;
|
|
||||||
case _DRM_CONSISTENT:
|
|
||||||
dmah.vaddr = map->handle;
|
|
||||||
dmah.busaddr = map->offset;
|
|
||||||
dmah.size = map->size;
|
|
||||||
__drm_pci_free(dev, &dmah);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
|
||||||
}
|
}
|
||||||
up(&dev->struct_sem);
|
|
||||||
|
/* List has wrapped around to the head pointer, or it's empty and we
|
||||||
|
* didn't find anything.
|
||||||
|
*/
|
||||||
|
if (list == (&dev->maplist->head)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (map->type) {
|
||||||
|
case _DRM_REGISTERS:
|
||||||
|
drm_ioremapfree(map->handle, map->size, dev);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case _DRM_FRAME_BUFFER:
|
||||||
|
if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
|
||||||
|
int retcode;
|
||||||
|
retcode = mtrr_del(map->mtrr, map->offset,
|
||||||
|
map->size);
|
||||||
|
DRM_DEBUG ("mtrr_del=%d\n", retcode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _DRM_SHM:
|
||||||
|
vfree(map->handle);
|
||||||
|
break;
|
||||||
|
case _DRM_AGP:
|
||||||
|
case _DRM_SCATTER_GATHER:
|
||||||
|
break;
|
||||||
|
case _DRM_CONSISTENT:
|
||||||
|
dmah.vaddr = map->handle;
|
||||||
|
dmah.busaddr = map->offset;
|
||||||
|
dmah.size = map->size;
|
||||||
|
__drm_pci_free(dev, &dmah);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(drm_rmmap_locked);
|
||||||
|
|
||||||
|
int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
down(&dev->struct_sem);
|
||||||
|
ret = drm_rmmap_locked(dev, map);
|
||||||
|
up(&dev->struct_sem);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(drm_rmmap);
|
EXPORT_SYMBOL(drm_rmmap);
|
||||||
|
|
||||||
|
/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on
|
||||||
|
* the last close of the device, and this is necessary for cleanup when things
|
||||||
|
* exit uncleanly. Therefore, having userland manually remove mappings seems
|
||||||
|
* like a pointless exercise since they're going away anyway.
|
||||||
|
*
|
||||||
|
* One use case might be after addmap is allowed for normal users for SHM and
|
||||||
|
* gets used by drivers that the server doesn't need to care about. This seems
|
||||||
|
* unlikely.
|
||||||
|
*/
|
||||||
int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
|
int drm_rmmap_ioctl(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->head->dev;
|
drm_device_t *dev = priv->head->dev;
|
||||||
drm_map_t request;
|
drm_map_t request;
|
||||||
|
drm_local_map_t *map = NULL;
|
||||||
|
struct list_head *list;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) {
|
if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return drm_rmmap(dev, request.handle);
|
down(&dev->struct_sem);
|
||||||
|
list_for_each(list, &dev->maplist->head) {
|
||||||
|
drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
|
||||||
|
|
||||||
|
if (r_list->map &&
|
||||||
|
r_list->map->handle == request.handle &&
|
||||||
|
r_list->map->flags & _DRM_REMOVABLE) {
|
||||||
|
map = r_list->map;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List has wrapped around to the head pointer, or its empty we didn't
|
||||||
|
* find anything.
|
||||||
|
*/
|
||||||
|
if (list == (&dev->maplist->head)) {
|
||||||
|
up(&dev->struct_sem);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!map)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Register and framebuffer maps are permanent */
|
||||||
|
if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
|
||||||
|
up(&dev->struct_sem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drm_rmmap_locked(dev, map);
|
||||||
|
|
||||||
|
up(&dev->struct_sem);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleanup after an error on one of the addbufs() functions.
|
* Cleanup after an error on one of the addbufs() functions.
|
||||||
*
|
*
|
||||||
|
* \param dev DRM device.
|
||||||
* \param entry buffer entry where the error occurred.
|
* \param entry buffer entry where the error occurred.
|
||||||
*
|
*
|
||||||
* Frees any pages and buffers associated with the given entry.
|
* Frees any pages and buffers associated with the given entry.
|
||||||
@@ -1470,3 +1536,26 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
|
|||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 order;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (size & (size - 1))
|
||||||
|
++order;
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_order);
|
||||||
|
@@ -132,9 +132,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
|
|||||||
int drm_takedown( drm_device_t *dev )
|
int drm_takedown( drm_device_t *dev )
|
||||||
{
|
{
|
||||||
drm_magic_entry_t *pt, *next;
|
drm_magic_entry_t *pt, *next;
|
||||||
drm_map_t *map;
|
|
||||||
drm_map_list_t *r_list;
|
drm_map_list_t *r_list;
|
||||||
struct list_head *list, *list_next;
|
|
||||||
drm_vma_entry_t *vma, *vma_next;
|
drm_vma_entry_t *vma, *vma_next;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -142,6 +140,7 @@ int drm_takedown( drm_device_t *dev )
|
|||||||
|
|
||||||
if (dev->driver->pretakedown)
|
if (dev->driver->pretakedown)
|
||||||
dev->driver->pretakedown(dev);
|
dev->driver->pretakedown(dev);
|
||||||
|
DRM_DEBUG("driver pretakedown completed\n");
|
||||||
|
|
||||||
if (dev->unique) {
|
if (dev->unique) {
|
||||||
drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
|
drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
|
||||||
@@ -184,6 +183,10 @@ int drm_takedown( drm_device_t *dev )
|
|||||||
dev->agp->acquired = 0;
|
dev->agp->acquired = 0;
|
||||||
dev->agp->enabled = 0;
|
dev->agp->enabled = 0;
|
||||||
}
|
}
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
|
||||||
|
drm_sg_cleanup(dev->sg);
|
||||||
|
dev->sg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear vma list (only built for debugging) */
|
/* Clear vma list (only built for debugging) */
|
||||||
if ( dev->vmalist ) {
|
if ( dev->vmalist ) {
|
||||||
@@ -195,56 +198,11 @@ int drm_takedown( drm_device_t *dev )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( dev->maplist ) {
|
if( dev->maplist ) {
|
||||||
list_for_each_safe( list, list_next, &dev->maplist->head ) {
|
while (!list_empty(&dev->maplist->head)) {
|
||||||
r_list = (drm_map_list_t *)list;
|
struct list_head *list = dev->maplist->head.next;
|
||||||
|
r_list = list_entry(list, drm_map_list_t, head);
|
||||||
if ( ( map = r_list->map ) ) {
|
drm_rmmap_locked(dev, r_list->map);
|
||||||
drm_dma_handle_t dmah;
|
}
|
||||||
|
|
||||||
switch ( map->type ) {
|
|
||||||
case _DRM_REGISTERS:
|
|
||||||
case _DRM_FRAME_BUFFER:
|
|
||||||
if (drm_core_has_MTRR(dev)) {
|
|
||||||
if ( map->mtrr >= 0 ) {
|
|
||||||
int retcode;
|
|
||||||
retcode = mtrr_del( map->mtrr,
|
|
||||||
map->offset,
|
|
||||||
map->size );
|
|
||||||
DRM_DEBUG( "mtrr_del=%d\n", retcode );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
drm_ioremapfree( map->handle, map->size, dev );
|
|
||||||
break;
|
|
||||||
case _DRM_SHM:
|
|
||||||
vfree(map->handle);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _DRM_AGP:
|
|
||||||
/* Do nothing here, because this is all
|
|
||||||
* handled in the AGP/GART driver.
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case _DRM_SCATTER_GATHER:
|
|
||||||
/* Handle it */
|
|
||||||
if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
|
|
||||||
drm_sg_cleanup(dev->sg);
|
|
||||||
dev->sg = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case _DRM_CONSISTENT:
|
|
||||||
dmah.vaddr = map->handle;
|
|
||||||
dmah.busaddr = map->offset;
|
|
||||||
dmah.size = map->size;
|
|
||||||
__drm_pci_free(dev, &dmah);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
|
||||||
}
|
|
||||||
list_del( list );
|
|
||||||
drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS);
|
|
||||||
}
|
|
||||||
drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
|
|
||||||
dev->maplist = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
|
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
|
||||||
@@ -273,6 +231,7 @@ int drm_takedown( drm_device_t *dev )
|
|||||||
}
|
}
|
||||||
up( &dev->struct_sem );
|
up( &dev->struct_sem );
|
||||||
|
|
||||||
|
DRM_DEBUG("takedown completed\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,6 +293,11 @@ static void drm_cleanup( drm_device_t *dev )
|
|||||||
|
|
||||||
drm_takedown( dev );
|
drm_takedown( dev );
|
||||||
|
|
||||||
|
if (dev->maplist) {
|
||||||
|
drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
|
||||||
|
dev->maplist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
drm_ctxbitmap_cleanup( dev );
|
drm_ctxbitmap_cleanup( dev );
|
||||||
|
|
||||||
if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
|
if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
|
||||||
|
@@ -71,12 +71,6 @@ static int drm_setup( drm_device_t *dev )
|
|||||||
dev->magiclist[i].tail = NULL;
|
dev->magiclist[i].tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->maplist = drm_alloc(sizeof(*dev->maplist),
|
|
||||||
DRM_MEM_MAPS);
|
|
||||||
if(dev->maplist == NULL) return -ENOMEM;
|
|
||||||
memset(dev->maplist, 0, sizeof(*dev->maplist));
|
|
||||||
INIT_LIST_HEAD(&dev->maplist->head);
|
|
||||||
|
|
||||||
dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
|
dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
|
||||||
DRM_MEM_CTXLIST);
|
DRM_MEM_CTXLIST);
|
||||||
if(dev->ctxlist == NULL) return -ENOMEM;
|
if(dev->ctxlist == NULL) return -ENOMEM;
|
||||||
|
@@ -75,6 +75,11 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
|
|||||||
dev->pci_func = PCI_FUNC(pdev->devfn);
|
dev->pci_func = PCI_FUNC(pdev->devfn);
|
||||||
dev->irq = pdev->irq;
|
dev->irq = pdev->irq;
|
||||||
|
|
||||||
|
dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
|
||||||
|
if (dev->maplist == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
INIT_LIST_HEAD(&dev->maplist->head);
|
||||||
|
|
||||||
/* the DRM has 6 basic counters */
|
/* the DRM has 6 basic counters */
|
||||||
dev->counters = 6;
|
dev->counters = 6;
|
||||||
dev->types[0] = _DRM_STAT_LOCK;
|
dev->types[0] = _DRM_STAT_LOCK;
|
||||||
|
@@ -2048,6 +2048,27 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int radeon_presetup(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
drm_local_map_t *map;
|
||||||
|
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
|
ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
|
||||||
|
drm_get_resource_len(dev, 2), _DRM_REGISTERS,
|
||||||
|
_DRM_READ_ONLY, &dev_priv->mmio);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = drm_addmap(dev, drm_get_resource_start(dev, 0),
|
||||||
|
drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
|
||||||
|
_DRM_WRITE_COMBINING, &map);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int radeon_driver_postcleanup(struct drm_device *dev)
|
int radeon_driver_postcleanup(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||||
|
@@ -76,6 +76,7 @@ static struct drm_driver driver = {
|
|||||||
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
|
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
|
||||||
.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
|
.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
|
||||||
.preinit = radeon_driver_preinit,
|
.preinit = radeon_driver_preinit,
|
||||||
|
.presetup = radeon_presetup,
|
||||||
.postcleanup = radeon_driver_postcleanup,
|
.postcleanup = radeon_driver_postcleanup,
|
||||||
.prerelease = radeon_driver_prerelease,
|
.prerelease = radeon_driver_prerelease,
|
||||||
.pretakedown = radeon_driver_pretakedown,
|
.pretakedown = radeon_driver_pretakedown,
|
||||||
|
@@ -290,6 +290,7 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
|
|||||||
extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
|
extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
|
||||||
|
|
||||||
extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
|
extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
|
||||||
|
extern int radeon_presetup(struct drm_device *dev);
|
||||||
extern int radeon_driver_postcleanup(struct drm_device *dev);
|
extern int radeon_driver_postcleanup(struct drm_device *dev);
|
||||||
|
|
||||||
extern int radeon_mem_alloc( DRM_IOCTL_ARGS );
|
extern int radeon_mem_alloc( DRM_IOCTL_ARGS );
|
||||||
|
Reference in New Issue
Block a user