drm: reorganise minor number handling using code from modesetting branch
authorDave Airlie <airlied@linux.ie>
Wed, 5 Mar 2008 19:21:50 +0000 (05:21 +1000)
committerDave Airlie <airlied@linux.ie>
Wed, 5 Mar 2008 19:21:50 +0000 (05:21 +1000)
Rip out the whole head thing and replace it with an idr and drm_minor
structure.

14 files changed:
linux-core/drmP.h
linux-core/drm_agpsupport.c
linux-core/drm_bo.c
linux-core/drm_bo_lock.c
linux-core/drm_drv.c
linux-core/drm_fence.c
linux-core/drm_fops.c
linux-core/drm_object.c
linux-core/drm_proc.c
linux-core/drm_stub.c
linux-core/drm_sysfs.c
linux-core/drm_vm.c
linux-core/i810_dma.c
shared-core/i915_dma.c

index f196e11..1fea807 100644 (file)
@@ -408,13 +408,12 @@ enum drm_ref_type {
 struct drm_file {
        int authenticated;
        int master;
-       int minor;
        pid_t pid;
        uid_t uid;
        drm_magic_t magic;
        unsigned long ioctl_count;
        struct list_head lhead;
-       struct drm_head *head;
+       struct drm_minor *minor;
        int remove_auth_on_close;
        unsigned long lock_count;
 
@@ -721,16 +720,19 @@ struct drm_driver {
        struct pci_driver pci_driver;
 };
 
+#define DRM_MINOR_UNASSIGNED 0
+#define DRM_MINOR_LEGACY 1
+
 /**
- * DRM head structure. This structure represent a video head on a card
- * that may contain multiple heads. Embed one per head of these in the
- * private drm_device structure.
+ * DRM minor structure. This structure represents a drm minor number.
  */
-struct drm_head {
-       int minor;                      /**< Minor device number */
+struct drm_minor {
+       int index;                      /**< Minor device number */
+       int type;                       /**< Control or render */
+       dev_t device;                   /**< Device number for mknod */
+       struct device kdev;             /**< Linux device */
        struct drm_device *dev;
        struct proc_dir_entry *dev_root;  /**< proc directory entry */
-       dev_t device;                   /**< Device number for mknod */
        struct class_device *dev_class;
 };
 
@@ -740,7 +742,6 @@ struct drm_head {
  * may contain multiple heads.
  */
 struct drm_device {
-       struct device dev;              /**< Linux device */
        char *unique;                   /**< Unique identifier: e.g., busid */
        int unique_len;                 /**< Length of unique field */
        char *devname;                  /**< For /proc/interrupts */
@@ -870,7 +871,7 @@ struct drm_device {
        struct drm_driver *driver;
        drm_local_map_t *agp_buffer_map;
        unsigned int agp_buffer_token;
-       struct drm_head primary;                /**< primary screen head */
+       struct drm_minor *primary;              /**< render type primary screen head */
 
        struct drm_fence_manager fm;
        struct drm_buffer_manager bm;
@@ -1187,23 +1188,20 @@ extern void drm_agp_chipset_flush(struct drm_device *dev);
 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
                     struct drm_driver *driver);
 extern int drm_put_dev(struct drm_device *dev);
-extern int drm_put_head(struct drm_head * head);
+extern int drm_put_minor(struct drm_minor **minor);
 extern unsigned int drm_debug; /* 1 to enable debug output */
-extern unsigned int drm_cards_limit;
-extern struct drm_head **drm_heads;
+
 extern struct class *drm_class;
 extern struct proc_dir_entry *drm_proc_root;
 
+extern struct idr drm_minors_idr;
+
 extern drm_local_map_t *drm_getsarea(struct drm_device *dev);
 
                                /* Proc support (drm_proc.h) */
-extern int drm_proc_init(struct drm_device *dev,
-                        int minor,
-                        struct proc_dir_entry *root,
-                        struct proc_dir_entry **dev_root);
-extern int drm_proc_cleanup(int minor,
-                           struct proc_dir_entry *root,
-                           struct proc_dir_entry *dev_root);
+int drm_proc_init(struct drm_minor *minor, int minor_id,
+                 struct proc_dir_entry *root);
+int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root);
 
                                /* Scatter Gather Support (drm_scatter.h) */
 extern void drm_sg_cleanup(struct drm_sg_mem * entry);
@@ -1226,8 +1224,8 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah);
 struct drm_sysfs_class;
 extern struct class *drm_sysfs_create(struct module *owner, char *name);
 extern void drm_sysfs_destroy(void);
-extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head);
-extern void drm_sysfs_device_remove(struct drm_device *dev);
+extern int drm_sysfs_device_add(struct drm_minor *minor);
+extern void drm_sysfs_device_remove(struct drm_minor *minor);
 
 /*
  * Basic memory manager support (drm_mm.c)
index f58d551..0aa94a7 100644 (file)
@@ -130,7 +130,7 @@ EXPORT_SYMBOL(drm_agp_acquire);
 int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
                          struct drm_file *file_priv)
 {
-       return drm_agp_acquire((struct drm_device *) file_priv->head->dev);
+       return drm_agp_acquire((struct drm_device *) file_priv->minor->dev);
 }
 
 /**
index 17180d8..95802fe 100644 (file)
@@ -1190,7 +1190,7 @@ static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle,
                                 struct drm_bo_info_rep *rep)
 {
        struct drm_buffer_object *bo;
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        int ret = 0;
        int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
 
@@ -1262,7 +1262,7 @@ out:
 
 static int drm_buffer_object_unmap(struct drm_file *file_priv, uint32_t handle)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        struct drm_buffer_object *bo;
        struct drm_ref_object *ro;
        int ret = 0;
@@ -1654,7 +1654,7 @@ int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle,
                           struct drm_bo_info_rep *rep,
                           struct drm_buffer_object **bo_rep)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        struct drm_buffer_object *bo;
        int ret;
 
@@ -1690,7 +1690,7 @@ EXPORT_SYMBOL(drm_bo_handle_validate);
 static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle,
                              struct drm_bo_info_rep *rep)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        struct drm_buffer_object *bo;
 
        mutex_lock(&dev->struct_mutex);
@@ -1713,7 +1713,7 @@ static int drm_bo_handle_wait(struct drm_file *file_priv, uint32_t handle,
                              uint32_t hint,
                              struct drm_bo_info_rep *rep)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        struct drm_buffer_object *bo;
        int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
        int ret;
@@ -1833,7 +1833,7 @@ EXPORT_SYMBOL(drm_buffer_object_create);
 static int drm_bo_add_user_object(struct drm_file *file_priv,
                                  struct drm_buffer_object *bo, int shareable)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
@@ -1881,7 +1881,7 @@ int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
        if (bo_type == drm_bo_type_user)
                req->flags &= ~DRM_BO_FLAG_SHAREABLE;
 
-       ret = drm_buffer_object_create(file_priv->head->dev,
+       ret = drm_buffer_object_create(file_priv->minor->dev,
                                       req->size, bo_type, req->flags,
                                       req->hint, req->page_alignment,
                                       req->buffer_start, &entry);
index f967fb7..2795384 100644 (file)
@@ -141,7 +141,7 @@ int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv)
         * while holding it.
         */
 
-       dev = file_priv->head->dev;
+       dev = file_priv->minor->dev;
        mutex_lock(&dev->struct_mutex);
        ret = drm_add_user_object(file_priv, &lock->base, 0);
        lock->base.remove = &drm_bo_write_lock_remove;
@@ -156,7 +156,7 @@ int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv)
 
 int drm_bo_write_unlock(struct drm_bo_lock *lock, struct drm_file *file_priv)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        struct drm_ref_object *ro;
 
        mutex_lock(&dev->struct_mutex);
index 3c2794d..1daa865 100644 (file)
@@ -416,35 +416,35 @@ static void drm_cleanup(struct drm_device * dev)
        drm_mm_takedown(&dev->offset_manager);
        drm_ht_remove(&dev->object_hash);
 
-       drm_put_head(&dev->primary);
+       drm_put_minor(&dev->primary);
        if (drm_put_dev(dev))
                DRM_ERROR("Cannot unload module\n");
 }
 
-void drm_exit(struct drm_driver *driver)
+int drm_minors_cleanup(int id, void *ptr, void *data)
 {
-       int i;
-       struct drm_device *dev = NULL;
-       struct drm_head *head;
+       struct drm_minor *minor = ptr;
+       struct drm_device *dev;
+       struct drm_driver *driver = data;
+
+       dev = minor->dev;
+       if (minor->dev->driver != driver)
+               return 0;
+
+       if (minor->type != DRM_MINOR_LEGACY)
+               return 0;
 
+       if (dev)
+               pci_dev_put(dev->pdev);
+       drm_cleanup(dev);
+       return 1;
+}
+
+void drm_exit(struct drm_driver *driver)
+{
        DRM_DEBUG("\n");
        if (drm_fb_loaded) {
-               for (i = 0; i < drm_cards_limit; i++) {
-                       head = drm_heads[i];
-                       if (!head)
-                               continue;
-                       if (!head->dev)
-                               continue;
-                       if (head->dev->driver != driver)
-                               continue;
-                       dev = head->dev;
-                       if (dev) {
-                               /* release the pci driver */
-                               if (dev->pdev)
-                                       pci_dev_put(dev->pdev);
-                               drm_cleanup(dev);
-                       }
-               }
+               idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver);
        } else
                pci_unregister_driver(&driver->pci_driver);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
@@ -467,6 +467,7 @@ static int __init drm_core_init(void)
        unsigned long avail_memctl_mem;
        unsigned long max_memctl_mem;
 
+       idr_init(&drm_minors_idr);
        si_meminfo(&si);
 
        /*
@@ -488,11 +489,6 @@ static int __init drm_core_init(void)
        drm_init_memctl(avail_memctl_mem/2, avail_memctl_mem*3/4, si.mem_unit);
 
        ret = -ENOMEM;
-       drm_cards_limit =
-           (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
-       drm_heads = drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB);
-       if (!drm_heads)
-               goto err_p1;
 
        if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
                goto err_p1;
@@ -521,7 +517,8 @@ err_p3:
        drm_sysfs_destroy();
 err_p2:
        unregister_chrdev(DRM_MAJOR, "drm");
-       drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
+
+       idr_destroy(&drm_minors_idr);
 err_p1:
        return ret;
 }
@@ -533,7 +530,7 @@ static void __exit drm_core_exit(void)
 
        unregister_chrdev(DRM_MAJOR, "drm");
 
-       drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
+       idr_destroy(&drm_minors_idr);
 }
 
 module_init(drm_core_init);
@@ -593,7 +590,7 @@ EXPORT_SYMBOL(drm_ioctl);
 long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct drm_file *file_priv = filp->private_data;
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        struct drm_ioctl_desc *ioctl;
        drm_ioctl_t *func;
        unsigned int nr = DRM_IOCTL_NR(cmd);
@@ -605,7 +602,7 @@ long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        ++file_priv->ioctl_count;
 
        DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
-                 current->pid, cmd, nr, (long)old_encode_dev(file_priv->head->device),
+                 current->pid, cmd, nr, (long)old_encode_dev(file_priv->minor->device),
                  file_priv->authenticated);
 
        if ((nr >= DRM_CORE_IOCTL_COUNT) &&
index 247bc0a..9d80327 100644 (file)
@@ -494,7 +494,7 @@ static int drm_fence_object_init(struct drm_device *dev, uint32_t fence_class,
 int drm_fence_add_user_object(struct drm_file *priv,
                              struct drm_fence_object *fence, int shareable)
 {
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
@@ -590,7 +590,7 @@ void drm_fence_manager_takedown(struct drm_device *dev)
 struct drm_fence_object *drm_lookup_fence_object(struct drm_file *priv,
                                                 uint32_t handle)
 {
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_user_object *uo;
        struct drm_fence_object *fence;
 
index 0e1c486..7fe274a 100644 (file)
@@ -128,16 +128,15 @@ static int drm_setup(struct drm_device * dev)
 int drm_open(struct inode *inode, struct file *filp)
 {
        struct drm_device *dev = NULL;
-       int minor = iminor(inode);
+       int minor_id = iminor(inode);
+       struct drm_minor *minor;
        int retcode = 0;
 
-       if (!((minor >= 0) && (minor < drm_cards_limit)))
+       minor = idr_find(&drm_minors_idr, minor_id);
+       if (!minor)
                return -ENODEV;
 
-       if (!drm_heads[minor])
-               return -ENODEV;
-
-       if (!(dev = drm_heads[minor]->dev))
+       if (!(dev = minor->dev))
                return -ENODEV;
 
        retcode = drm_open_helper(inode, filp, dev);
@@ -176,19 +175,18 @@ EXPORT_SYMBOL(drm_open);
 int drm_stub_open(struct inode *inode, struct file *filp)
 {
        struct drm_device *dev = NULL;
-       int minor = iminor(inode);
+       struct drm_minor *minor;
+       int minor_id = iminor(inode);
        int err = -ENODEV;
        const struct file_operations *old_fops;
 
        DRM_DEBUG("\n");
 
-       if (!((minor >= 0) && (minor < drm_cards_limit)))
+       minor = idr_find(&drm_minors_idr, minor_id);
+       if (!minor)
                return -ENODEV;
-
-       if (!drm_heads[minor])
-               return -ENODEV;
-
-       if (!(dev = drm_heads[minor]->dev))
+       
+       if (!(dev = minor->dev))
                return -ENODEV;
 
        old_fops = filp->f_op;
@@ -233,7 +231,7 @@ static int drm_cpu_valid(void)
 static int drm_open_helper(struct inode *inode, struct file *filp,
                           struct drm_device * dev)
 {
-       int minor = iminor(inode);
+       int minor_id = iminor(inode);
        struct drm_file *priv;
        int ret;
        int i, j;
@@ -243,7 +241,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
        if (!drm_cpu_valid())
                return -EINVAL;
 
-       DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+       DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor_id);
 
        priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
        if (!priv)
@@ -254,8 +252,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
        priv->filp = filp;
        priv->uid = current->euid;
        priv->pid = current->pid;
-       priv->minor = minor;
-       priv->head = drm_heads[minor];
+       priv->minor = idr_find(&drm_minors_idr, minor_id);
        priv->ioctl_count = 0;
        /* for compatibility root is always authenticated */
        priv->authenticated = capable(CAP_SYS_ADMIN);
@@ -320,11 +317,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
 int drm_fasync(int fd, struct file *filp, int on)
 {
        struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        int retcode;
 
        DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
-                 (long)old_encode_dev(priv->head->device));
+                 (long)old_encode_dev(priv->minor->device));
        retcode = fasync_helper(fd, filp, on, &dev->buf_async);
        if (retcode < 0)
                return retcode;
@@ -374,7 +371,7 @@ static void drm_object_release(struct file *filp)
 int drm_release(struct inode *inode, struct file *filp)
 {
        struct drm_file *file_priv = filp->private_data;
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        int retcode = 0;
 
        lock_kernel();
@@ -389,7 +386,7 @@ int drm_release(struct inode *inode, struct file *filp)
         */
 
        DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
-                 current->pid, (long)old_encode_dev(file_priv->head->device),
+                 current->pid, (long)old_encode_dev(file_priv->minor->device),
                  dev->open_count);
 
        if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
index 7d2e3a2..2994b71 100644 (file)
@@ -33,7 +33,7 @@
 int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item,
                        int shareable)
 {
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        int ret;
 
        DRM_ASSERT_LOCKED(&dev->struct_mutex);
@@ -58,7 +58,7 @@ EXPORT_SYMBOL(drm_add_user_object);
 
 struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t key)
 {
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_hash_item *hash;
        int ret;
        struct drm_user_object *item;
@@ -85,7 +85,7 @@ EXPORT_SYMBOL(drm_lookup_user_object);
 
 static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item)
 {
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        int ret;
 
        if (atomic_dec_and_test(&item->refcount)) {
@@ -121,7 +121,7 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced
        struct drm_ref_object *item;
        struct drm_open_hash *ht = &priv->refd_object_hash[ref_action];
 
-       DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex);
+       DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
        if (!referenced_object->shareable && priv != referenced_object->owner) {
                DRM_ERROR("Not allowed to reference this object\n");
                return -EINVAL;
@@ -178,7 +178,7 @@ struct drm_ref_object *drm_lookup_ref_object(struct drm_file *priv,
        struct drm_hash_item *hash;
        int ret;
 
-       DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex);
+       DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
        ret = drm_ht_find_item(&priv->refd_object_hash[ref_action],
                               (unsigned long)referenced_object, &hash);
        if (ret)
@@ -212,7 +212,7 @@ void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item)
        struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action];
        enum drm_ref_type unref_action;
 
-       DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex);
+       DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
        unref_action = item->unref_action;
        if (atomic_dec_and_test(&item->refcount)) {
                ret = drm_ht_remove_item(ht, &item->hash);
@@ -239,7 +239,7 @@ EXPORT_SYMBOL(drm_remove_ref_object);
 int drm_user_object_ref(struct drm_file *priv, uint32_t user_token,
                        enum drm_object_type type, struct drm_user_object **object)
 {
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_user_object *uo;
        struct drm_hash_item *hash;
        int ret;
@@ -269,7 +269,7 @@ out_err:
 int drm_user_object_unref(struct drm_file *priv, uint32_t user_token,
                          enum drm_object_type type)
 {
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_user_object *uo;
        struct drm_ref_object *ro;
        int ret;
index 3012c5b..67afee8 100644 (file)
@@ -90,34 +90,35 @@ static struct drm_proc_list {
  * "/proc/dri/%minor%/", and each entry in proc_list as
  * "/proc/dri/%minor%/%name%".
  */
-int drm_proc_init(struct drm_device * dev, int minor,
-                 struct proc_dir_entry *root, struct proc_dir_entry **dev_root)
+int drm_proc_init(struct drm_minor *minor, int minor_id,
+                 struct proc_dir_entry *root)
 {
        struct proc_dir_entry *ent;
        int i, j;
        char name[64];
 
-       sprintf(name, "%d", minor);
-       *dev_root = proc_mkdir(name, root);
-       if (!*dev_root) {
+       sprintf(name, "%d", minor_id);
+       minor->dev_root = proc_mkdir(name, root);
+       if (!minor->dev_root) {
                DRM_ERROR("Cannot create /proc/dri/%s\n", name);
                return -1;
        }
 
        for (i = 0; i < DRM_PROC_ENTRIES; i++) {
                ent = create_proc_entry(drm_proc_list[i].name,
-                                       S_IFREG | S_IRUGO, *dev_root);
+                                       S_IFREG | S_IRUGO, minor->dev_root);
                if (!ent) {
                        DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
                                  name, drm_proc_list[i].name);
                        for (j = 0; j < i; j++)
                                remove_proc_entry(drm_proc_list[i].name,
-                                                 *dev_root);
+                                                 minor->dev_root);
                        remove_proc_entry(name, root);
+                       minor->dev_root = NULL;
                        return -1;
                }
                ent->read_proc = drm_proc_list[i].f;
-               ent->data = dev;
+               ent->data = minor;
        }
        return 0;
 }
@@ -132,18 +133,17 @@ int drm_proc_init(struct drm_device * dev, int minor,
  *
  * Remove all proc entries created by proc_init().
  */
-int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
-                    struct proc_dir_entry *dev_root)
+int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
 {
        int i;
        char name[64];
 
-       if (!root || !dev_root)
+       if (!root || !minor->dev_root)
                return 0;
 
        for (i = 0; i < DRM_PROC_ENTRIES; i++)
-               remove_proc_entry(drm_proc_list[i].name, dev_root);
-       sprintf(name, "%d", minor);
+               remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
+       sprintf(name, "%d", minor->index);
        remove_proc_entry(name, root);
 
        return 0;
@@ -165,7 +165,8 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
 static int drm_name_info(char *buf, char **start, off_t offset, int request,
                         int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int len = 0;
 
        if (offset > DRM_PROC_LIMIT) {
@@ -207,7 +208,8 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request,
 static int drm__vm_info(char *buf, char **start, off_t offset, int request,
                        int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int len = 0;
        struct drm_map *map;
        struct drm_map_list *r_list;
@@ -264,7 +266,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
 static int drm_vm_info(char *buf, char **start, off_t offset, int request,
                       int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
@@ -287,7 +290,8 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
 static int drm__queues_info(char *buf, char **start, off_t offset,
                            int request, int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int len = 0;
        int i;
        struct drm_queue *q;
@@ -337,7 +341,8 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
 static int drm_queues_info(char *buf, char **start, off_t offset, int request,
                           int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
@@ -360,7 +365,8 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
 static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
                          int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int len = 0;
        struct drm_device_dma *dma = dev->dma;
        int i;
@@ -409,7 +415,8 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
 static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
                         int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
@@ -432,7 +439,8 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
 static int drm__objects_info(char *buf, char **start, off_t offset, int request,
                          int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int len = 0;
        struct drm_buffer_manager *bm = &dev->bm;
        struct drm_fence_manager *fm = &dev->fm;
@@ -496,7 +504,8 @@ static int drm__objects_info(char *buf, char **start, off_t offset, int request,
 static int drm_objects_info(char *buf, char **start, off_t offset, int request,
                         int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
@@ -519,7 +528,8 @@ static int drm_objects_info(char *buf, char **start, off_t offset, int request,
 static int drm__clients_info(char *buf, char **start, off_t offset,
                             int request, int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int len = 0;
        struct drm_file *priv;
 
@@ -535,7 +545,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
        list_for_each_entry(priv, &dev->filelist, lhead) {
                DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
                               priv->authenticated ? 'y' : 'n',
-                              priv->minor,
+                              priv->minor->index,
                               priv->pid,
                               priv->uid, priv->magic, priv->ioctl_count);
        }
@@ -552,7 +562,8 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
 static int drm_clients_info(char *buf, char **start, off_t offset,
                            int request, int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
@@ -566,7 +577,8 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
 static int drm__vma_info(char *buf, char **start, off_t offset, int request,
                         int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int len = 0;
        struct drm_vma_entry *pt;
        struct vm_area_struct *vma;
@@ -625,7 +637,8 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
 static int drm_vma_info(char *buf, char **start, off_t offset, int request,
                        int *eof, void *data)
 {
-       struct drm_device *dev = (struct drm_device *) data;
+       struct drm_minor *minor = (struct drm_minor *) data; 
+       struct drm_device *dev = minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
index 00a2452..6584f51 100644 (file)
 #include "drmP.h"
 #include "drm_core.h"
 
-unsigned int drm_cards_limit = 16;     /* Enough for one machine */
 unsigned int drm_debug = 0;            /* 1 to enable debug output */
 EXPORT_SYMBOL(drm_debug);
 
 MODULE_AUTHOR(CORE_AUTHOR);
 MODULE_DESCRIPTION(CORE_DESC);
 MODULE_LICENSE("GPL and additional rights");
-MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards");
 MODULE_PARM_DESC(debug, "Enable debug output");
 
-module_param_named(cards_limit, drm_cards_limit, int, 0444);
 module_param_named(debug, drm_debug, int, 0600);
 
-struct drm_head **drm_heads;
+struct idr drm_minors_idr;
+
 struct class *drm_class;
 struct proc_dir_entry *drm_proc_root;
 
+static int drm_minor_get_id(struct drm_device *dev, int type)
+{
+       int new_id;
+       int ret;
+       int base = 0, limit = 63;
+
+again:
+       if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) {
+               DRM_ERROR("Out of memory expanding drawable idr\n");
+               return -ENOMEM;
+       }
+       mutex_lock(&dev->struct_mutex);
+       ret = idr_get_new_above(&drm_minors_idr, NULL,
+                               base, &new_id);
+       mutex_unlock(&dev->struct_mutex);
+       if (ret == -EAGAIN) {
+               goto again;
+       } else if (ret) {
+               return ret;
+       }
+
+       if (new_id >= limit) {
+               idr_remove(&drm_minors_idr, new_id);
+               return -EINVAL;
+       }
+       return new_id;
+}
+
 static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
                           const struct pci_device_id *ent,
                           struct drm_driver *driver)
@@ -161,49 +187,60 @@ error_out_unreg:
  * create the proc init entry via proc_init(). This routines assigns
  * minor numbers to secondary heads of multi-headed cards
  */
-static int drm_get_head(struct drm_device * dev, struct drm_head * head)
+static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
 {
-       struct drm_head **heads = drm_heads;
+       struct drm_minor *new_minor;
        int ret;
-       int minor;
+       int minor_id;
 
        DRM_DEBUG("\n");
 
-       for (minor = 0; minor < drm_cards_limit; minor++, heads++) {
-               if (!*heads) {
-
-                       *head = (struct drm_head) {
-                               .dev = dev,
-                               .device = MKDEV(DRM_MAJOR, minor),
-                               .minor = minor,
-                       };
-                       if ((ret =
-                            drm_proc_init(dev, minor, drm_proc_root,
-                                          &head->dev_root))) {
-                               printk(KERN_ERR
-                                      "DRM: Failed to initialize /proc/dri.\n");
-                               goto err_g1;
-                       }
-
-                       ret = drm_sysfs_device_add(dev, head);
-                       if (ret) {
-                               printk(KERN_ERR
-                                      "DRM: Error sysfs_device_add.\n");
-                               goto err_g2;
-                       }
-                       *heads = head;
-
-                       DRM_DEBUG("new minor assigned %d\n", minor);
-                       return 0;
+       minor_id = drm_minor_get_id(dev, type);
+       if (minor_id < 0)
+               return minor_id;
+
+       new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL);
+       if (!new_minor) {
+               ret = -ENOMEM;
+               goto err_idr;
+       }
+
+       new_minor->type = type;
+       new_minor->device = MKDEV(DRM_MAJOR, minor_id);
+       new_minor->dev = dev;
+       new_minor->index = minor_id;
+
+       idr_replace(&drm_minors_idr, new_minor, minor_id);
+       
+       if (type == DRM_MINOR_LEGACY) {
+               ret = drm_proc_init(new_minor, minor_id, drm_proc_root);
+               if (ret) {
+                       DRM_ERROR("DRM: Failed to initialize /proc/dri.\n");
+                       goto err_mem;
                }
+       } else
+               new_minor->dev_root = NULL;
+
+       ret = drm_sysfs_device_add(new_minor);
+       if (ret) {
+               printk(KERN_ERR
+                      "DRM: Error sysfs_device_add.\n");
+               goto err_g2;
        }
-       DRM_ERROR("out of minors\n");
-       return -ENOMEM;
+       *minor = new_minor;
+       
+       DRM_DEBUG("new minor assigned %d\n", minor_id);
+       return 0;
+
+
 err_g2:
-       drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
-err_g1:
-       *head = (struct drm_head) {
-               .dev = NULL};
+       if (new_minor->type == DRM_MINOR_LEGACY)
+               drm_proc_cleanup(new_minor, drm_proc_root);
+err_mem:
+       kfree(new_minor);
+err_idr:
+       idr_remove(&drm_minors_idr, minor_id);
+       *minor = NULL;
        return ret;
 }
 
@@ -246,22 +283,29 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
                printk(KERN_ERR "DRM: fill_in_dev failed\n");
                goto err_g3;
        }
-       if ((ret = drm_get_head(dev, &dev->primary)))
+
+       /* only add the control node on a modesetting platform */
+       if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
                goto err_g3;
 
+       if (dev->driver->load)
+               if ((ret = dev->driver->load(dev, ent->driver_data)))
+                       goto err_g4;
+
        DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
                 driver->name, driver->major, driver->minor, driver->patchlevel,
-                driver->date, dev->primary.minor);
+                driver->date, dev->primary->index);
 
        return 0;
-
- err_g3:
+err_g4:
+       drm_put_minor(&dev->primary);
+err_g3:
        if (!drm_fb_loaded)
                pci_disable_device(pdev);
- err_g2:
+err_g2:
        if (!drm_fb_loaded)
                pci_release_regions(pdev);
- err_g1:
+err_g1:
        if (!drm_fb_loaded)
                pci_set_drvdata(pdev, NULL);
 
@@ -310,17 +354,18 @@ int drm_put_dev(struct drm_device * dev)
  * last minor released.
  *
  */
-int drm_put_head(struct drm_head * head)
+int drm_put_minor(struct drm_minor **minor_p)
 {
-       int minor = head->minor;
-
-       DRM_DEBUG("release secondary minor %d\n", minor);
+       struct drm_minor *minor = *minor_p;
+       DRM_DEBUG("release secondary minor %d\n", minor->index);
 
-       drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
-       drm_sysfs_device_remove(head->dev);
+       if (minor->type == DRM_MINOR_LEGACY)
+               drm_proc_cleanup(minor, drm_proc_root);
+       drm_sysfs_device_remove(minor);
 
-       *head = (struct drm_head) {.dev = NULL};
+       idr_remove(&drm_minors_idr, minor->index);
 
-       drm_heads[minor] = NULL;
+       kfree(minor);
+       *minor_p = NULL;
        return 0;
 }
index c02e204..3275942 100644 (file)
@@ -19,7 +19,7 @@
 #include "drm_core.h"
 #include "drmP.h"
 
-#define to_drm_device(d) container_of(d, struct drm_device, dev)
+#define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
 
 /**
  * drm_sysfs_suspend - DRM class suspend hook
@@ -31,7 +31,8 @@
  */
 static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
 {
-       struct drm_device *drm_dev = to_drm_device(dev);
+       struct drm_minor *drm_minor = to_drm_minor(dev);
+       struct drm_device *drm_dev = drm_minor->dev;
 
        printk(KERN_ERR "%s\n", __FUNCTION__);
 
@@ -50,7 +51,8 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
  */
 static int drm_sysfs_resume(struct device *dev)
 {
-       struct drm_device *drm_dev = to_drm_device(dev);
+       struct drm_minor *drm_minor = to_drm_minor(dev);
+       struct drm_device *drm_dev = drm_minor->dev;
 
        if (drm_dev->driver->resume)
                return drm_dev->driver->resume(drm_dev);
@@ -122,10 +124,11 @@ void drm_sysfs_destroy(void)
 static ssize_t show_dri(struct device *device, struct device_attribute *attr,
                        char *buf)
 {
-       struct drm_device *dev = to_drm_device(device);
-       if (dev->driver->dri_library_name)
-               return dev->driver->dri_library_name(dev, buf);
-       return snprintf(buf, PAGE_SIZE, "%s\n", dev->driver->pci_driver.name);
+       struct drm_minor *drm_minor = to_drm_minor(device);
+       struct drm_device *drm_dev = drm_minor->dev;
+       if (drm_dev->driver->dri_library_name)
+               return drm_dev->driver->dri_library_name(drm_dev, buf);
+       return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name);
 }
 
 static struct device_attribute device_attrs[] = {
@@ -154,25 +157,28 @@ static void drm_sysfs_device_release(struct device *dev)
  * as the parent for the Linux device, and make sure it has a file containing
  * the driver we're using (for userspace compatibility).
  */
-int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head)
+int drm_sysfs_device_add(struct drm_minor *minor)
 {
        int err;
        int i, j;
+       char *minor_str;
 
-       dev->dev.parent = &dev->pdev->dev;
-       dev->dev.class = drm_class;
-       dev->dev.release = drm_sysfs_device_release;
-       dev->dev.devt = head->device;
-       snprintf(dev->dev.bus_id, BUS_ID_SIZE, "card%d", head->minor);
+       minor->kdev.parent = &minor->dev->pdev->dev;
+       minor->kdev.class = drm_class;
+       minor->kdev.release = drm_sysfs_device_release;
+       minor->kdev.devt = minor->device;
+       minor_str = "card%d";
+       
+       snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index);
 
-       err = device_register(&dev->dev);
+       err = device_register(&minor->kdev);
        if (err) {
                DRM_ERROR("device add failed: %d\n", err);
                goto err_out;
        }
 
        for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
-               err = device_create_file(&dev->dev, &device_attrs[i]);
+               err = device_create_file(&minor->kdev, &device_attrs[i]);
                if (err)
                        goto err_out_files;
        }
@@ -182,8 +188,8 @@ int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head)
 err_out_files:
        if (i > 0)
                for (j = 0; j < i; j++)
-                       device_remove_file(&dev->dev, &device_attrs[i]);
-       device_unregister(&dev->dev);
+                       device_remove_file(&minor->kdev, &device_attrs[i]);
+       device_unregister(&minor->kdev);
 err_out:
 
        return err;
@@ -196,11 +202,11 @@ err_out:
  * This call unregisters and cleans up a class device that was created with a
  * call to drm_sysfs_device_add()
  */
-void drm_sysfs_device_remove(struct drm_device *dev)
+void drm_sysfs_device_remove(struct drm_minor *minor)
 {
        int i;
 
        for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
-               device_remove_file(&dev->dev, &device_attrs[i]);
-       device_unregister(&dev->dev);
+               device_remove_file(&minor->kdev, &device_attrs[i]);
+       device_unregister(&minor->kdev);
 }
index c481a53..15e1c0f 100644 (file)
@@ -86,7 +86,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
                                                unsigned long address)
 {
        struct drm_file *priv = vma->vm_file->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_map *map = NULL;
        struct drm_map_list *r_list;
        struct drm_hash_item *hash;
@@ -204,7 +204,7 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
 static void drm_vm_shm_close(struct vm_area_struct *vma)
 {
        struct drm_file *priv = vma->vm_file->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_vma_entry *pt, *temp;
        struct drm_map *map;
        struct drm_map_list *r_list;
@@ -286,7 +286,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
                                                    unsigned long address)
 {
        struct drm_file *priv = vma->vm_file->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_device_dma *dma = dev->dma;
        unsigned long offset;
        unsigned long page_nr;
@@ -323,7 +323,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
 {
        struct drm_map *map = (struct drm_map *) vma->vm_private_data;
        struct drm_file *priv = vma->vm_file->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_sg_mem *entry = dev->sg;
        unsigned long offset;
        unsigned long map_offset;
@@ -419,7 +419,7 @@ static struct vm_operations_struct drm_vm_sg_ops = {
 static void drm_vm_open_locked(struct vm_area_struct *vma)
 {
        struct drm_file *priv = vma->vm_file->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_vma_entry *vma_entry;
 
        DRM_DEBUG("0x%08lx,0x%08lx\n",
@@ -437,7 +437,7 @@ static void drm_vm_open_locked(struct vm_area_struct *vma)
 static void drm_vm_open(struct vm_area_struct *vma)
 {
        struct drm_file *priv = vma->vm_file->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
 
        mutex_lock(&dev->struct_mutex);
        drm_vm_open_locked(vma);
@@ -455,7 +455,7 @@ static void drm_vm_open(struct vm_area_struct *vma)
 static void drm_vm_close(struct vm_area_struct *vma)
 {
        struct drm_file *priv = vma->vm_file->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_vma_entry *pt, *temp;
 
        DRM_DEBUG("0x%08lx,0x%08lx\n",
@@ -491,7 +491,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
        struct drm_device_dma *dma;
        unsigned long length = vma->vm_end - vma->vm_start;
 
-       dev = priv->head->dev;
+       dev = priv->minor->dev;
        dma = dev->dma;
        DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
                  vma->vm_start, vma->vm_end, vma->vm_pgoff);
@@ -556,7 +556,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
 static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
 {
        struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        struct drm_map *map = NULL;
        unsigned long offset = 0;
        struct drm_hash_item *hash;
@@ -677,7 +677,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
 int drm_mmap(struct file *filp, struct vm_area_struct *vma)
 {
        struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
+       struct drm_device *dev = priv->minor->dev;
        int ret;
 
        mutex_lock(&dev->struct_mutex);
index 3c9ca3b..f2bf5d9 100644 (file)
@@ -113,7 +113,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
        drm_i810_buf_priv_t *buf_priv;
 
        lock_kernel();
-       dev = priv->head->dev;
+       dev = priv->minor->dev;
        dev_priv = dev->dev_private;
        buf = dev_priv->mmap_buffer;
        buf_priv = buf->dev_private;
@@ -141,7 +141,7 @@ static const struct file_operations i810_buffer_fops = {
 
 static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        drm_i810_buf_priv_t *buf_priv = buf->dev_private;
        drm_i810_private_t *dev_priv = dev->dev_private;
        const struct file_operations *old_fops;
index 9e474bc..7d247f9 100644 (file)
@@ -988,7 +988,7 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
                           struct drm_i915_validate_buffer *buffers,
                           uint32_t buf_count)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        struct i915_relocatee_info relocatee;
        int ret = 0;
        int b;
@@ -1195,7 +1195,7 @@ void i915_fence_or_sync(struct drm_file *file_priv,
                        struct drm_fence_arg *fence_arg,
                        struct drm_fence_object **fence_p)
 {
-       struct drm_device *dev = file_priv->head->dev;
+       struct drm_device *dev = file_priv->minor->dev;
        int ret;
        struct drm_fence_object *fence;