summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drmP.h26
-rw-r--r--linux-core/drm_bufs.c34
-rw-r--r--linux-core/drm_drv.c507
-rw-r--r--linux-core/drm_fops.c315
-rw-r--r--linux-core/drm_ioctl.c19
-rw-r--r--linux-core/drm_lock.c140
-rw-r--r--linux-core/drm_stub.c111
-rw-r--r--shared-core/r128_cce.c2
-rw-r--r--shared-core/radeon_cp.c2
9 files changed, 569 insertions, 587 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index d694d661..0d121243 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -740,28 +740,24 @@ extern void drm_parse_options( char *s );
extern int drm_cpu_valid( void );
/* Driver support (drm_drv.h) */
+extern int drm_fb_loaded;
extern int __devinit drm_init(struct pci_driver *driver, struct pci_device_id* pciidlist,
struct drm_driver_fn *driver_fn);
extern void __exit drm_exit (struct pci_driver *driver);
extern void __exit drm_cleanup_pci(struct pci_dev *pdev);
extern int drm_version(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_open(struct inode *inode, struct file *filp);
-extern int drm_release(struct inode *inode, struct file *filp);
extern int drm_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_lock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_unlock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev,
- const struct pci_device_id *ent, struct drm_driver_fn *driver_fn);
-extern int drm_fb_loaded;
+extern int drm_takedown( drm_device_t *dev );
/* Device support (drm_fops.h) */
+extern int drm_open(struct inode *inode, struct file *filp);
+extern int drm_stub_open(struct inode *inode, struct file *filp);
extern int drm_open_helper(struct inode *inode, struct file *filp,
drm_device_t *dev);
extern int drm_fasync(int fd, struct file *filp, int on);
+extern int drm_release(struct inode *inode, struct file *filp);
/* Mapping support (drm_vm.h) */
extern void drm_vm_open(struct vm_area_struct *vma);
@@ -802,6 +798,8 @@ extern int drm_getstats(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_setversion(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+extern int drm_noop(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* Context IOCTL support (drm_context.h) */
extern int drm_resctx( struct inode *inode, struct file *filp,
@@ -847,11 +845,11 @@ extern int drm_getmagic(struct inode *inode, struct file *filp,
extern int drm_authmagic(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Placeholder for ioctls past */
-extern int drm_noop(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
/* Locking IOCTL support (drm_lock.h) */
+extern int drm_lock(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int drm_unlock(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
extern int drm_lock_take(__volatile__ unsigned int *lock,
unsigned int context);
extern int drm_lock_transfer(drm_device_t *dev,
@@ -863,7 +861,6 @@ extern int drm_lock_free(drm_device_t *dev,
extern int drm_notifier(void *priv);
/* Buffer management support (drm_bufs.h) */
-extern int drm_order( unsigned long size );
extern int drm_addmap( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int drm_rmmap( struct inode *inode, struct file *filp,
@@ -938,7 +935,6 @@ extern unsigned int cards_limit;
extern drm_minor_t *drm_minors;
extern struct drm_sysfs_class *drm_class;
extern struct proc_dir_entry *drm_proc_root;
-extern struct file_operations drm_stub_fops;
/* Proc support (drm_proc.h) */
extern int drm_proc_init(drm_device_t *dev,
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index 88ca09ce..602dd3f8 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -36,30 +36,6 @@
#include <linux/vmalloc.h>
#include "drmP.h"
-/**
- * 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);
-
/**
* 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
@@ -227,7 +203,7 @@ int drm_addmap( struct inode *inode, struct file *filp,
case _DRM_SHM:
map->handle = vmalloc_32(map->size);
DRM_DEBUG( "%lu %d %p\n",
- map->size, drm_order( map->size ), map->handle );
+ map->size, get_order( map->size ), map->handle );
if ( !map->handle ) {
drm_free( map, sizeof(*map), DRM_MEM_MAPS );
return -ENOMEM;
@@ -460,7 +436,7 @@ int drm_addbufs_agp( struct inode *inode, struct file *filp,
return -EFAULT;
count = request.count;
- order = drm_order( request.size );
+ order = get_order( request.size );
size = 1 << order;
alignment = (request.flags & _DRM_PAGE_ALIGN)
@@ -628,7 +604,7 @@ int drm_addbufs_pci( struct inode *inode, struct file *filp,
return -EFAULT;
count = request.count;
- order = drm_order( request.size );
+ order = get_order( request.size );
size = 1 << order;
DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
@@ -858,7 +834,7 @@ int drm_addbufs_sg( struct inode *inode, struct file *filp,
return -EFAULT;
count = request.count;
- order = drm_order( request.size );
+ order = get_order( request.size );
size = 1 << order;
alignment = (request.flags & _DRM_PAGE_ALIGN)
@@ -1158,7 +1134,7 @@ int drm_markbufs( struct inode *inode, struct file *filp,
DRM_DEBUG( "%d, %d, %d\n",
request.size, request.low_mark, request.high_mark );
- order = drm_order( request.size );
+ order = get_order( request.size );
if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
entry = &dma->bufs[order];
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index c9958815..630e29dc 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -142,82 +142,6 @@ drm_ioctl_desc_t drm_ioctls[] = {
#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls )
-static int drm_setup( drm_device_t *dev )
-{
- int i;
-
- if (dev->fn_tbl->presetup)
- dev->fn_tbl->presetup(dev);
-
- atomic_set( &dev->ioctl_count, 0 );
- atomic_set( &dev->vma_count, 0 );
- dev->buf_use = 0;
- atomic_set( &dev->buf_alloc, 0 );
-
- if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
- {
- i = drm_dma_setup( dev );
- if ( i < 0 )
- return i;
- }
-
- for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
- atomic_set( &dev->counts[i], 0 );
-
- for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
- dev->magiclist[i].head = NULL;
- dev->magiclist[i].tail = NULL;
- }
-
- dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
- DRM_MEM_CTXLIST);
- if(dev->ctxlist == NULL) return -ENOMEM;
- memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
- INIT_LIST_HEAD(&dev->ctxlist->head);
-
- dev->vmalist = NULL;
- dev->sigdata.lock = dev->lock.hw_lock = NULL;
- init_waitqueue_head( &dev->lock.lock_queue );
- dev->queue_count = 0;
- dev->queue_reserved = 0;
- dev->queue_slots = 0;
- dev->queuelist = NULL;
- dev->irq_enabled = 0;
- dev->context_flag = 0;
- dev->interrupt_flag = 0;
- dev->dma_flag = 0;
- dev->last_context = 0;
- dev->last_switch = 0;
- dev->last_checked = 0;
- init_waitqueue_head( &dev->context_wait );
- dev->if_version = 0;
-
- dev->ctx_start = 0;
- dev->lck_start = 0;
-
- dev->buf_rp = dev->buf;
- dev->buf_wp = dev->buf;
- dev->buf_end = dev->buf + DRM_BSZ;
- dev->buf_async = NULL;
- init_waitqueue_head( &dev->buf_readers );
- init_waitqueue_head( &dev->buf_writers );
-
- DRM_DEBUG( "\n" );
-
- /*
- * The kernel's context could be created here, but is now created
- * in drm_dma_enqueue. This is more resource-efficient for
- * hardware that does not do DMA, but may mean that
- * drm_select_queue fails between the time the interrupt is
- * initialized and the time the queues are initialized.
- */
- if (dev->fn_tbl->postsetup)
- dev->fn_tbl->postsetup(dev);
-
- return 0;
-}
-
-
/**
* Take down the DRM device.
*
@@ -227,7 +151,7 @@ static int drm_setup( drm_device_t *dev )
*
* \sa drm_device and setup().
*/
-static int drm_takedown( drm_device_t *dev )
+int drm_takedown( drm_device_t *dev )
{
drm_magic_entry_t *pt, *next;
drm_map_t *map;
@@ -362,87 +286,6 @@ static int drm_takedown( drm_device_t *dev )
return 0;
}
-int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver_fn *driver_fn)
-{
- int retcode;
-
- dev->count_lock = SPIN_LOCK_UNLOCKED;
- init_timer( &dev->timer );
- sema_init( &dev->struct_sem, 1 );
- sema_init( &dev->ctxlist_sem, 1 );
-
- dev->name = DRIVER_NAME;
- dev->pdev = pdev;
-
-#ifdef __alpha__
- dev->hose = pdev->sysdata;
- dev->pci_domain = dev->hose->bus->number;
-#else
- dev->pci_domain = 0;
-#endif
- dev->pci_bus = pdev->bus->number;
- dev->pci_slot = PCI_SLOT(pdev->devfn);
- dev->pci_func = PCI_FUNC(pdev->devfn);
- 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 counters */
- dev->counters = 6;
- dev->types[0] = _DRM_STAT_LOCK;
- dev->types[1] = _DRM_STAT_OPENS;
- dev->types[2] = _DRM_STAT_CLOSES;
- dev->types[3] = _DRM_STAT_IOCTLS;
- dev->types[4] = _DRM_STAT_LOCKS;
- dev->types[5] = _DRM_STAT_UNLOCKS;
-
- dev->fn_tbl = driver_fn;
-
- if (dev->fn_tbl->preinit)
- if ((retcode = dev->fn_tbl->preinit(dev, ent->driver_data)))
- goto error_out_unreg;
-
- if (drm_core_has_AGP(dev)) {
- dev->agp = drm_agp_init();
- if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
- DRM_ERROR( "Cannot initialize the agpgart module.\n" );
- retcode = -EINVAL;
- goto error_out_unreg;
- }
-
-
- if (drm_core_has_MTRR(dev)) {
- if (dev->agp)
- dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
- dev->agp->agp_info.aper_size*1024*1024,
- MTRR_TYPE_WRCOMB,
- 1 );
- }
- }
-
- retcode = drm_ctxbitmap_init( dev );
- if( retcode ) {
- DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
- goto error_out_unreg;
- }
-
- dev->device = MKDEV(DRM_MAJOR, dev->minor );
-DRM_DEBUG("driver_fn->postinit %p\n", driver_fn->postinit);
-
- /* postinit is a required function to display the signon banner */
- /* drivers add secondary heads here if needed */
- if ((retcode = dev->fn_tbl->postinit(dev, ent->driver_data)))
- goto error_out_unreg;
-
- return 0;
-
- error_out_unreg:
- drm_takedown(dev);
- return retcode;
-}
-
void __exit drm_cleanup_pci(struct pci_dev *pdev)
{
drm_device_t *dev = pci_get_drvdata(pdev);
@@ -630,6 +473,12 @@ void __exit drm_exit (struct pci_driver *driver)
}
EXPORT_SYMBOL(drm_exit);
+/** File operations structure */
+static struct file_operations drm_stub_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_stub_open
+};
+
static int __init drm_core_init(void)
{
int ret = -ENOMEM;
@@ -725,210 +574,6 @@ int drm_version( struct inode *inode, struct file *filp,
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 )
-{
- drm_device_t *dev = NULL;
- int minor = iminor(inode);
- int retcode = 0;
-
- if (!((minor >= 0) && (minor < cards_limit)))
- return -ENODEV;
-
- dev = drm_minors[minor].dev;
- if (!dev)
- return -ENODEV;
-
- retcode = drm_open_helper( inode, filp, dev );
- if ( !retcode ) {
- atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
- spin_lock( &dev->count_lock );
- if ( !dev->open_count++ ) {
- spin_unlock( &dev->count_lock );
- return drm_setup( dev );
- }
- spin_unlock( &dev->count_lock );
- }
-
- return retcode;
-}
-EXPORT_SYMBOL(drm_open);
-
-/**
- * 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 )
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
- int retcode = 0;
-
- lock_kernel();
- dev = priv->dev;
-
- DRM_DEBUG( "open_count = %d\n", dev->open_count );
-
- if (dev->fn_tbl->prerelease)
- dev->fn_tbl->prerelease(dev, filp);
-
- /* ========================================================
- * Begin inline drm_release
- */
-
- DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
- current->pid, (long)old_encode_dev(dev->device), dev->open_count );
-
- if ( priv->lock_count && dev->lock.hw_lock &&
- _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
- dev->lock.filp == filp ) {
- DRM_DEBUG( "File %p released, freeing lock for context %d\n",
- filp,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-
- if (dev->fn_tbl->release)
- dev->fn_tbl->release(dev, filp);
-
- drm_lock_free( dev, &dev->lock.hw_lock->lock,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-
- /* FIXME: may require heavy-handed reset of
- hardware at this point, possibly
- processed via a callback to the X
- server. */
- }
- else if ( dev->fn_tbl->release && priv->lock_count && dev->lock.hw_lock ) {
- /* The lock is required to reclaim buffers */
- DECLARE_WAITQUEUE( entry, current );
-
- add_wait_queue( &dev->lock.lock_queue, &entry );
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- if ( !dev->lock.hw_lock ) {
- /* Device has been unregistered */
- retcode = -EINTR;
- break;
- }
- if ( drm_lock_take( &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT ) ) {
- dev->lock.filp = filp;
- dev->lock.lock_time = jiffies;
- atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
- break; /* Got lock */
- }
- /* Contention */
- schedule();
- if ( signal_pending( current ) ) {
- retcode = -ERESTARTSYS;
- break;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue( &dev->lock.lock_queue, &entry );
- if( !retcode ) {
- if (dev->fn_tbl->release)
- dev->fn_tbl->release(dev, filp);
- drm_lock_free( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT );
- }
- }
-
- if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
- {
- dev->fn_tbl->reclaim_buffers(filp);
- }
-
- drm_fasync( -1, filp, 0 );
-
- down( &dev->ctxlist_sem );
- if ( !list_empty( &dev->ctxlist->head ) ) {
- drm_ctx_list_t *pos, *n;
-
- list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
- if ( pos->tag == priv &&
- pos->handle != DRM_KERNEL_CONTEXT ) {
- if (dev->fn_tbl->context_dtor)
- dev->fn_tbl->context_dtor(dev, pos->handle);
-
- drm_ctxbitmap_free( dev, pos->handle );
-
- list_del( &pos->head );
- drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
- --dev->ctx_count;
- }
- }
- }
- up( &dev->ctxlist_sem );
-
- down( &dev->struct_sem );
- if ( priv->remove_auth_on_close == 1 ) {
- drm_file_t *temp = dev->file_first;
- while ( temp ) {
- temp->authenticated = 0;
- temp = temp->next;
- }
- }
- if ( priv->prev ) {
- priv->prev->next = priv->next;
- } else {
- dev->file_first = priv->next;
- }
- if ( priv->next ) {
- priv->next->prev = priv->prev;
- } else {
- dev->file_last = priv->prev;
- }
- up( &dev->struct_sem );
-
- if (dev->fn_tbl->free_filp_priv)
- dev->fn_tbl->free_filp_priv( dev, priv );
- drm_free( priv, sizeof(*priv), DRM_MEM_FILES );
-
- /* ========================================================
- * End inline drm_release
- */
-
- atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
- spin_lock( &dev->count_lock );
- if ( !--dev->open_count ) {
- if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
- DRM_ERROR( "Device busy: %d %d\n",
- atomic_read( &dev->ioctl_count ),
- dev->blocked );
- spin_unlock( &dev->count_lock );
- unlock_kernel();
- return -EBUSY;
- }
- spin_unlock( &dev->count_lock );
- unlock_kernel();
- return drm_takedown( dev );
- }
- spin_unlock( &dev->count_lock );
-
- unlock_kernel();
-
- return retcode;
-}
-EXPORT_SYMBOL(drm_release);
-
/**
* Called whenever a process performs an ioctl on /dev/drm.
*
@@ -986,141 +631,3 @@ err_i1:
}
EXPORT_SYMBOL(drm_ioctl);
-/**
- * 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,
- unsigned int cmd, unsigned long arg )
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- DECLARE_WAITQUEUE( entry, current );
- drm_lock_t lock;
- int ret = 0;
-
- ++priv->lock_count;
-
- if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
- return -EFAULT;
-
- if ( lock.context == DRM_KERNEL_CONTEXT ) {
- DRM_ERROR( "Process %d using kernel context %d\n",
- current->pid, lock.context );
- return -EINVAL;
- }
-
- DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
- lock.context, current->pid,
- dev->lock.hw_lock->lock, lock.flags );
-
- if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
- if ( lock.context < 0 )
- return -EINVAL;
-
- add_wait_queue( &dev->lock.lock_queue, &entry );
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- if ( !dev->lock.hw_lock ) {
- /* Device has been unregistered */
- ret = -EINTR;
- break;
- }
- if ( drm_lock_take( &dev->lock.hw_lock->lock,
- lock.context ) ) {
- dev->lock.filp = filp;
- dev->lock.lock_time = jiffies;
- atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
- break; /* Got lock */
- }
-
- /* Contention */
- schedule();
- if ( signal_pending( current ) ) {
- ret = -ERESTARTSYS;
- break;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue( &dev->lock.lock_queue, &entry );
-
- sigemptyset( &dev->sigmask );
- sigaddset( &dev->sigmask, SIGSTOP );
- sigaddset( &dev->sigmask, SIGTSTP );
- sigaddset( &dev->sigmask, SIGTTIN );
- sigaddset( &dev->sigmask, SIGTTOU );
- dev->sigdata.context = lock.context;
- dev->sigdata.lock = dev->lock.hw_lock;
- block_all_signals( drm_notifier,
- &dev->sigdata, &dev->sigmask );
-
- if (dev->fn_tbl->dma_ready && (lock.flags & _DRM_LOCK_READY))
- dev->fn_tbl->dma_ready(dev);
-
- if ( dev->fn_tbl->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
- return dev->fn_tbl->dma_quiescent(dev);
-
-
- if ( dev->fn_tbl->kernel_context_switch && dev->last_context != lock.context ) {
- dev->fn_tbl->kernel_context_switch(dev, dev->last_context,
- lock.context);
- }
-
-
- DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
-
- 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,
- unsigned int cmd, unsigned long arg )
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_lock_t lock;
-
- if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
- return -EFAULT;
-
- if ( lock.context == DRM_KERNEL_CONTEXT ) {
- DRM_ERROR( "Process %d using kernel context %d\n",
- current->pid, lock.context );
- return -EINVAL;
- }
-
- atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
-
- if (dev->fn_tbl->kernel_context_switch_unlock)
- dev->fn_tbl->kernel_context_switch_unlock(dev);
- else
- {
- drm_lock_transfer( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT );
-
- if ( drm_lock_free( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT ) ) {
- DRM_ERROR( "\n" );
- }
- }
-
- unblock_all_signals();
- return 0;
-}
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
index 0ee303df..fea01130 100644
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -37,6 +37,156 @@
#include "drmP.h"
#include <linux/poll.h>
+static int drm_setup( drm_device_t *dev )
+{
+ int i;
+
+ if (dev->fn_tbl->presetup)
+ dev->fn_tbl->presetup(dev);
+
+ atomic_set( &dev->ioctl_count, 0 );
+ atomic_set( &dev->vma_count, 0 );
+ dev->buf_use = 0;
+ atomic_set( &dev->buf_alloc, 0 );
+
+ if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+ {
+ i = drm_dma_setup( dev );
+ if ( i < 0 )
+ return i;
+ }
+
+ for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
+ atomic_set( &dev->counts[i], 0 );
+
+ for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+ dev->magiclist[i].head = NULL;
+ dev->magiclist[i].tail = NULL;
+ }
+
+ dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
+ DRM_MEM_CTXLIST);
+ if(dev->ctxlist == NULL) return -ENOMEM;
+ memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
+ INIT_LIST_HEAD(&dev->ctxlist->head);
+
+ dev->vmalist = NULL;
+ dev->sigdata.lock = dev->lock.hw_lock = NULL;
+ init_waitqueue_head( &dev->lock.lock_queue );
+ dev->queue_count = 0;
+ dev->queue_reserved = 0;
+ dev->queue_slots = 0;
+ dev->queuelist = NULL;
+ dev->irq_enabled = 0;
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma_flag = 0;
+ dev->last_context = 0;
+ dev->last_switch = 0;
+ dev->last_checked = 0;
+ init_waitqueue_head( &dev->context_wait );
+ dev->if_version = 0;
+
+ dev->ctx_start = 0;
+ dev->lck_start = 0;
+
+ dev->buf_rp = dev->buf;
+ dev->buf_wp = dev->buf;
+ dev->buf_end = dev->buf + DRM_BSZ;
+ dev->buf_async = NULL;
+ init_waitqueue_head( &dev->buf_readers );
+ init_waitqueue_head( &dev->buf_writers );
+
+ DRM_DEBUG( "\n" );
+
+ /*
+ * The kernel's context could be created here, but is now created
+ * in drm_dma_enqueue. This is more resource-efficient for
+ * hardware that does not do DMA, but may mean that
+ * drm_select_queue fails between the time the interrupt is
+ * initialized and the time the queues are initialized.
+ */
+ if (dev->fn_tbl->postsetup)
+ dev->fn_tbl->postsetup(dev);
+
+ 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 )
+{
+ drm_device_t *dev = NULL;
+ int minor = iminor(inode);
+ int retcode = 0;
+
+ if (!((minor >= 0) && (minor < cards_limit)))
+ return -ENODEV;
+
+ dev = drm_minors[minor].dev;
+ if (!dev)
+ return -ENODEV;
+
+ retcode = drm_open_helper( inode, filp, dev );
+ if ( !retcode ) {
+ atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
+ spin_lock( &dev->count_lock );
+ if ( !dev->open_count++ ) {
+ spin_unlock( &dev->count_lock );
+ return drm_setup( dev );
+ }
+ spin_unlock( &dev->count_lock );
+ }
+
+ return retcode;
+}
+EXPORT_SYMBOL(drm_open);
+
+/**
+ * File \c open operation.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ *
+ * Puts the dev->fops corresponding to the device minor number into
+ * \p filp, call the \c open method, and restore the file operations.
+ */
+int drm_stub_open(struct inode *inode, struct file *filp)
+{
+ drm_device_t *dev = NULL;
+ int minor = iminor(inode);
+ int err = -ENODEV;
+ struct file_operations *old_fops;
+
+ DRM_DEBUG("\n");
+
+ if (!((minor >= 0) && (minor < cards_limit)))
+ return -ENODEV;
+
+ dev = drm_minors[minor].dev;
+ if (!dev)
+ return -ENODEV;
+
+ old_fops = filp->f_op;
+ filp->f_op = fops_get(&dev->fn_tbl->fops);
+ if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
+ fops_put(filp->f_op);
+ filp->f_op = fops_get(old_fops);
+ }
+ fops_put(old_fops);
+
+ return err;
+}
/**
* Called whenever a process opens /dev/drm.
@@ -128,3 +278,168 @@ int drm_fasync(int fd, struct file *filp, int on)
return 0;
}
EXPORT_SYMBOL(drm_fasync);
+
+/**
+ * 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 )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev;
+ int retcode = 0;
+
+ lock_kernel();
+ dev = priv->dev;
+
+ DRM_DEBUG( "open_count = %d\n", dev->open_count );
+
+ if (dev->fn_tbl->prerelease)
+ dev->fn_tbl->prerelease(dev, filp);
+
+ /* ========================================================
+ * Begin inline drm_release
+ */
+
+ DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
+ current->pid, (long)old_encode_dev(dev->device), dev->open_count );
+
+ if ( priv->lock_count && dev->lock.hw_lock &&
+ _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+ dev->lock.filp == filp ) {
+ DRM_DEBUG( "File %p released, freeing lock for context %d\n",
+ filp,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+
+ if (dev->fn_tbl->release)
+ dev->fn_tbl->release(dev, filp);
+
+ drm_lock_free( dev, &dev->lock.hw_lock->lock,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+
+ /* FIXME: may require heavy-handed reset of
+ hardware at this point, possibly
+ processed via a callback to the X
+ server. */
+ }
+ else if ( dev->fn_tbl->release && priv->lock_count && dev->lock.hw_lock ) {
+ /* The lock is required to reclaim buffers */
+ DECLARE_WAITQUEUE( entry, current );
+
+ add_wait_queue( &dev->lock.lock_queue, &entry );
+ for (;;) {
+ current->state = TASK_INTERRUPTIBLE;
+ if ( !dev->lock.hw_lock ) {
+ /* Device has been unregistered */
+ retcode = -EINTR;
+ break;
+ }
+ if ( drm_lock_take( &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT ) ) {
+ dev->lock.filp = filp;
+ dev->lock.lock_time = jiffies;
+ atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+ break; /* Got lock */
+ }
+ /* Contention */
+ schedule();
+ if ( signal_pending( current ) ) {
+ retcode = -ERESTARTSYS;
+ break;
+ }
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue( &dev->lock.lock_queue, &entry );
+ if( !retcode ) {
+ if (dev->fn_tbl->release)
+ dev->fn_tbl->release(dev, filp);
+ drm_lock_free( dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT );
+ }
+ }
+
+ if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+ {
+ dev->fn_tbl->reclaim_buffers(filp);
+ }
+
+ drm_fasync( -1, filp, 0 );
+
+ down( &dev->ctxlist_sem );
+ if ( !list_empty( &dev->ctxlist->head ) ) {
+ drm_ctx_list_t *pos, *n;
+
+ list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+ if ( pos->tag == priv &&
+ pos->handle != DRM_KERNEL_CONTEXT ) {
+ if (dev->fn_tbl->context_dtor)
+ dev->fn_tbl->context_dtor(dev, pos->handle);
+
+ drm_ctxbitmap_free( dev, pos->handle );
+
+ list_del( &pos->head );
+ drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+ --dev->ctx_count;
+ }
+ }
+ }
+ up( &dev->ctxlist_sem );
+
+ down( &dev->struct_sem );
+ if ( priv->remove_auth_on_close == 1 ) {
+ drm_file_t *temp = dev->file_first;
+ while ( temp ) {
+ temp->authenticated = 0;
+ temp = temp->next;
+ }
+ }
+ if ( priv->prev ) {
+ priv->prev->next = priv->next;
+ } else {
+ dev->file_first = priv->next;
+ }
+ if ( priv->next ) {
+ priv->next->prev = priv->prev;
+ } else {
+ dev->file_last = priv->prev;
+ }
+ up( &dev->struct_sem );
+
+ if (dev->fn_tbl->free_filp_priv)
+ dev->fn_tbl->free_filp_priv( dev, priv );
+ drm_free( priv, sizeof(*priv), DRM_MEM_FILES );
+
+ /* ========================================================
+ * End inline drm_release
+ */
+
+ atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
+ spin_lock( &dev->count_lock );
+ if ( !--dev->open_count ) {
+ if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
+ DRM_ERROR( "Device busy: %d %d\n",
+ atomic_read( &dev->ioctl_count ),
+ dev->blocked );
+ spin_unlock( &dev->count_lock );
+ unlock_kernel();
+ return -EBUSY;
+ }
+ spin_unlock( &dev->count_lock );
+ unlock_kernel();
+ return drm_takedown( dev );
+ }
+ spin_unlock( &dev->count_lock );
+
+ unlock_kernel();
+
+ return retcode;
+}
+EXPORT_SYMBOL(drm_release);
diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c
index 6bccbcad..7221e5ba 100644
--- a/linux-core/drm_ioctl.c
+++ b/linux-core/drm_ioctl.c
@@ -304,6 +304,17 @@ int drm_getstats( struct inode *inode, struct file *filp,
return 0;
}
+/**
+ * Setversion 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.
+ *
+ * Sets the requested interface version
+ */
int drm_setversion(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
@@ -345,3 +356,11 @@ int drm_setversion(DRM_IOCTL_ARGS)
}
return 0;
}
+
+/** No-op ioctl. */
+int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ DRM_DEBUG("\n");
+ return 0;
+}
diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c
index 90c9109f..84cc460c 100644
--- a/linux-core/drm_lock.c
+++ b/linux-core/drm_lock.c
@@ -35,11 +35,143 @@
#include "drmP.h"
-/** No-op ioctl. */
-int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+
+/**
+ * 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,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ DECLARE_WAITQUEUE( entry, current );
+ drm_lock_t lock;
+ int ret = 0;
+
+ ++priv->lock_count;
+
+ if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
+ return -EFAULT;
+
+ if ( lock.context == DRM_KERNEL_CONTEXT ) {
+ DRM_ERROR( "Process %d using kernel context %d\n",
+ current->pid, lock.context );
+ return -EINVAL;
+ }
+
+ DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, current->pid,
+ dev->lock.hw_lock->lock, lock.flags );
+
+ if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
+ if ( lock.context < 0 )
+ return -EINVAL;
+
+ add_wait_queue( &dev->lock.lock_queue, &entry );
+ for (;;) {
+ current->state = TASK_INTERRUPTIBLE;
+ if ( !dev->lock.hw_lock ) {
+ /* Device has been unregistered */
+ ret = -EINTR;
+ break;
+ }
+ if ( drm_lock_take( &dev->lock.hw_lock->lock,
+ lock.context ) ) {
+ dev->lock.filp = filp;
+ dev->lock.lock_time = jiffies;
+ atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+ break; /* Got lock */
+ }
+
+ /* Contention */
+ schedule();
+ if ( signal_pending( current ) ) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue( &dev->lock.lock_queue, &entry );
+
+ sigemptyset( &dev->sigmask );
+ sigaddset( &dev->sigmask, SIGSTOP );
+ sigaddset( &dev->sigmask, SIGTSTP );
+ sigaddset( &dev->sigmask, SIGTTIN );
+ sigaddset( &dev->sigmask, SIGTTOU );
+ dev->sigdata.context = lock.context;
+ dev->sigdata.lock = dev->lock.hw_lock;
+ block_all_signals( drm_notifier,
+ &dev->sigdata, &dev->sigmask );
+
+ if (dev->fn_tbl->dma_ready && (lock.flags & _DRM_LOCK_READY))
+ dev->fn_tbl->dma_ready(dev);
+
+ if ( dev->fn_tbl->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
+ return dev->fn_tbl->dma_quiescent(dev);
+
+
+ if ( dev->fn_tbl->kernel_context_switch && dev->last_context != lock.context ) {
+ dev->fn_tbl->kernel_context_switch(dev, dev->last_context,
+ lock.context);
+ }
+
+
+ DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
+
+ 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,
+ unsigned int cmd, unsigned long arg )
{
- DRM_DEBUG("\n");
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_lock_t lock;
+
+ if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
+ return -EFAULT;
+
+ if ( lock.context == DRM_KERNEL_CONTEXT ) {
+ DRM_ERROR( "Process %d using kernel context %d\n",
+ current->pid, lock.context );
+ return -EINVAL;
+ }
+
+ atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
+
+ if (dev->fn_tbl->kernel_context_switch_unlock)
+ dev->fn_tbl->kernel_context_switch_unlock(dev);
+ else
+ {
+ drm_lock_transfer( dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT );
+
+ if ( drm_lock_free( dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT ) ) {
+ DRM_ERROR( "\n" );
+ }
+ }
+
+ unblock_all_signals();
return 0;
}
diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c
index 6333d25d..a213134e 100644
--- a/linux-core/drm_stub.c
+++ b/linux-core/drm_stub.c
@@ -51,48 +51,85 @@ drm_minor_t *drm_minors;
struct drm_sysfs_class *drm_class;
struct proc_dir_entry *drm_proc_root;
-/**
- * File \c open operation.
- *
- * \param inode device inode.
- * \param filp file pointer.
- *
- * Puts the dev->fops corresponding to the device minor number into
- * \p filp, call the \c open method, and restore the file operations.
- */
-static int stub_open(struct inode *inode, struct file *filp)
+static int fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver_fn *driver_fn)
{
- drm_device_t *dev = NULL;
- int minor = iminor(inode);
- int err = -ENODEV;
- struct file_operations *old_fops;
-
- DRM_DEBUG("\n");
-
- if (!((minor >= 0) && (minor < cards_limit)))
- return -ENODEV;
-
- dev = drm_minors[minor].dev;
- if (!dev)
- return -ENODEV;
+ int retcode;
+
+ dev->count_lock = SPIN_LOCK_UNLOCKED;
+ init_timer( &dev->timer );
+ sema_init( &dev->struct_sem, 1 );
+ sema_init( &dev->ctxlist_sem, 1 );
+
+ dev->name = DRIVER_NAME;
+ dev->pdev = pdev;
+
+#ifdef __alpha__
+ dev->hose = pdev->sysdata;
+ dev->pci_domain = dev->hose->bus->number;
+#else
+ dev->pci_domain = 0;
+#endif
+ dev->pci_bus = pdev->bus->number;
+ dev->pci_slot = PCI_SLOT(pdev->devfn);
+ dev->pci_func = PCI_FUNC(pdev->devfn);
+ 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 counters */
+ dev->counters = 6;
+ dev->types[0] = _DRM_STAT_LOCK;
+ dev->types[1] = _DRM_STAT_OPENS;
+ dev->types[2] = _DRM_STAT_CLOSES;
+ dev->types[3] = _DRM_STAT_IOCTLS;
+ dev->types[4] = _DRM_STAT_LOCKS;
+ dev->types[5] = _DRM_STAT_UNLOCKS;
+
+ dev->fn_tbl = driver_fn;
+
+ if (dev->fn_tbl->preinit)
+ if ((retcode = dev->fn_tbl->preinit(dev, ent->driver_data)))
+ goto error_out_unreg;
+
+ if (drm_core_has_AGP(dev)) {
+ dev->agp = drm_agp_init();
+ if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
+ DRM_ERROR( "Cannot initialize the agpgart module.\n" );
+ retcode = -EINVAL;
+ goto error_out_unreg;
+ }
+
+
+ if (drm_core_has_MTRR(dev)) {
+ if (dev->agp)
+ dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size*1024*1024,
+ MTRR_TYPE_WRCOMB,
+ 1 );
+ }
+ }
- old_fops = filp->f_op;
- filp->f_op = fops_get(&dev->fn_tbl->fops);
- if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
- fops_put(filp->f_op);
- filp->f_op = fops_get(old_fops);
+ retcode = drm_ctxbitmap_init( dev );
+ if( retcode ) {
+ DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
+ goto error_out_unreg;
}
- fops_put(old_fops);
- return err;
-}
+ dev->device = MKDEV(DRM_MAJOR, dev->minor );
-/** File operations structure */
-struct file_operations drm_stub_fops = {
- .owner = THIS_MODULE,
- .open = stub_open
-};
+ /* postinit is a required function to display the signon banner */
+ /* drivers add secondary heads here if needed */
+ if ((retcode = dev->fn_tbl->postinit(dev, ent->driver_data)))
+ goto error_out_unreg;
+ return 0;
+
+ error_out_unreg:
+ drm_takedown(dev);
+ return retcode;
+}
/**
* Register.
@@ -125,7 +162,7 @@ int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_
*minors = (drm_minor_t){.dev = dev, .class = DRM_MINOR_PRIMARY};
dev->minor = minor;
- if ((ret = drm_fill_in_dev(dev, pdev, ent, driver_fn))) {
+ if ((ret = fill_in_dev(dev, pdev, ent, driver_fn))) {
printk (KERN_ERR "DRM: Fill_in_dev failed.\n");
goto err_g1;
}
diff --git a/shared-core/r128_cce.c b/shared-core/r128_cce.c
index 809e6c8c..172ea258 100644
--- a/shared-core/r128_cce.c
+++ b/shared-core/r128_cce.c
@@ -543,7 +543,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
+ init->ring_size / sizeof(u32));
dev_priv->ring.size = init->ring_size;
- dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
+ dev_priv->ring.size_l2qw = get_order( init->ring_size / 8 );
dev_priv->ring.tail_mask =
(dev_priv->ring.size / sizeof(u32)) - 1;
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 78c41b5d..98bc4c46 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -1215,7 +1215,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
+ init->ring_size / sizeof(u32));
dev_priv->ring.size = init->ring_size;
- dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
+ dev_priv->ring.size_l2qw = get_order( init->ring_size / 8 );
dev_priv->ring.tail_mask =
(dev_priv->ring.size / sizeof(u32)) - 1;