From 1c0a437fa20e8c3fb971cd8947754a9b274bea76 Mon Sep 17 00:00:00 2001
From: Jon Smirl <jonsmirl@yahoo.com>
Date: Thu, 30 Sep 2004 19:26:35 +0000
Subject: Move things around to reduce public symbols and even out files.
 Switch to     get_order from drm_order.

---
 linux-core/drmP.h       |  26 ++-
 linux-core/drm_bufs.c   |  34 +---
 linux-core/drm_drv.c    | 507 +-----------------------------------------------
 linux-core/drm_fops.c   | 315 ++++++++++++++++++++++++++++++
 linux-core/drm_ioctl.c  |  19 ++
 linux-core/drm_lock.c   | 140 ++++++++++++-
 linux-core/drm_stub.c   | 111 +++++++----
 shared-core/r128_cce.c  |   2 +-
 shared-core/radeon_cp.c |   2 +-
 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;
-- 
cgit v1.2.3