drm/i915: fix WC mapping in non-GEM i915 code.
[safe/jmp/linux-2.6] / drivers / gpu / drm / drm_stub.c
index c2f584f..46bb923 100644 (file)
@@ -57,6 +57,14 @@ static int drm_minor_get_id(struct drm_device *dev, int type)
        int ret;
        int base = 0, limit = 63;
 
+       if (type == DRM_MINOR_CONTROL) {
+                base += 64;
+                limit = base + 127;
+        } else if (type == DRM_MINOR_RENDER) {
+                base += 128;
+                limit = base + 255;
+        }
+
 again:
        if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) {
                DRM_ERROR("Out of memory expanding drawable idr\n");
@@ -79,6 +87,112 @@ again:
        return new_id;
 }
 
+struct drm_master *drm_master_create(struct drm_minor *minor)
+{
+       struct drm_master *master;
+
+       master = drm_calloc(1, sizeof(*master), DRM_MEM_DRIVER);
+       if (!master)
+               return NULL;
+
+       kref_init(&master->refcount);
+       spin_lock_init(&master->lock.spinlock);
+       init_waitqueue_head(&master->lock.lock_queue);
+       drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER);
+       INIT_LIST_HEAD(&master->magicfree);
+       master->minor = minor;
+
+       list_add_tail(&master->head, &minor->master_list);
+
+       return master;
+}
+
+struct drm_master *drm_master_get(struct drm_master *master)
+{
+       kref_get(&master->refcount);
+       return master;
+}
+
+static void drm_master_destroy(struct kref *kref)
+{
+       struct drm_master *master = container_of(kref, struct drm_master, refcount);
+       struct drm_magic_entry *pt, *next;
+       struct drm_device *dev = master->minor->dev;
+       struct drm_map_list *r_list, *list_temp;
+
+       list_del(&master->head);
+
+       if (dev->driver->master_destroy)
+               dev->driver->master_destroy(dev, master);
+
+       list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
+               if (r_list->master == master) {
+                       drm_rmmap_locked(dev, r_list->map);
+                       r_list = NULL;
+               }
+       }
+
+       if (master->unique) {
+               drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER);
+               master->unique = NULL;
+               master->unique_len = 0;
+       }
+
+       list_for_each_entry_safe(pt, next, &master->magicfree, head) {
+               list_del(&pt->head);
+               drm_ht_remove_item(&master->magiclist, &pt->hash_item);
+               drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+       }
+
+       drm_ht_remove(&master->magiclist);
+
+       if (master->lock.hw_lock) {
+               if (dev->sigdata.lock == master->lock.hw_lock)
+                       dev->sigdata.lock = NULL;
+               master->lock.hw_lock = NULL;
+               master->lock.file_priv = NULL;
+               wake_up_interruptible(&master->lock.lock_queue);
+       }
+
+       drm_free(master, sizeof(*master), DRM_MEM_DRIVER);
+}
+
+void drm_master_put(struct drm_master **master)
+{
+       kref_put(&(*master)->refcount, drm_master_destroy);
+       *master = NULL;
+}
+
+int drm_setmaster_ioctl(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv)
+{
+       if (file_priv->minor->master && file_priv->minor->master != file_priv->master)
+               return -EINVAL;
+
+       if (!file_priv->master)
+               return -EINVAL;
+
+       if (!file_priv->minor->master &&
+           file_priv->minor->master != file_priv->master) {
+               mutex_lock(&dev->struct_mutex);
+               file_priv->minor->master = drm_master_get(file_priv->master);
+               mutex_lock(&dev->struct_mutex);
+       }
+
+       return 0;
+}
+
+int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv)
+{
+       if (!file_priv->master)
+               return -EINVAL;
+       mutex_lock(&dev->struct_mutex);
+       drm_master_put(&file_priv->minor->master);
+       mutex_unlock(&dev->struct_mutex);
+       return 0;
+}
+
 static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
                           const struct pci_device_id *ent,
                           struct drm_driver *driver)
@@ -92,8 +206,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
 
        spin_lock_init(&dev->count_lock);
        spin_lock_init(&dev->drw_lock);
-       spin_lock_init(&dev->tasklet_lock);
-       spin_lock_init(&dev->lock.spinlock);
        init_timer(&dev->timer);
        mutex_init(&dev->struct_mutex);
        mutex_init(&dev->ctxlist_mutex);
@@ -107,7 +219,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
 #ifdef __alpha__
        dev->hose = pdev->sysdata;
 #endif
-       dev->irq = pdev->irq;
 
        if (drm_ht_create(&dev->map_hash, 12)) {
                return -ENOMEM;
@@ -142,9 +253,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
                }
        }
 
-       if (dev->driver->load)
-               if ((retcode = dev->driver->load(dev, ent->driver_data)))
-                       goto error_out_unreg;
 
        retcode = drm_ctxbitmap_init(dev);
        if (retcode) {
@@ -152,6 +260,15 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
                goto error_out_unreg;
        }
 
+       if (driver->driver_features & DRIVER_GEM) {
+               retcode = drm_gem_init(dev);
+               if (retcode) {
+                       DRM_ERROR("Cannot initialize graphics execution "
+                                 "manager (GEM)\n");
+                       goto error_out_unreg;
+               }
+       }
+
        return 0;
 
       error_out_unreg:
@@ -193,6 +310,7 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t
        new_minor->device = MKDEV(DRM_MAJOR, minor_id);
        new_minor->dev = dev;
        new_minor->index = minor_id;
+       INIT_LIST_HEAD(&new_minor->master_list);
 
        idr_replace(&drm_minors_idr, new_minor, minor_id);
 
@@ -260,8 +378,30 @@ 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_g2;
        }
+
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+               if (ret)
+                       goto err_g2;
+       }
+
        if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
-               goto err_g2;
+               goto err_g3;
+
+       if (dev->driver->load) {
+               ret = dev->driver->load(dev, ent->driver_data);
+               if (ret)
+                       goto err_g3;
+       }
+
+        /* setup the grouping for the legacy output */
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group);
+               if (ret)
+                       goto err_g3;
+       }
+
+       list_add_tail(&dev->driver_item, &driver->device_list);
 
        DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
                 driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -269,6 +409,8 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 
        return 0;
 
+err_g3:
+       drm_put_minor(&dev->primary);
 err_g2:
        pci_disable_device(pdev);
 err_g1:
@@ -290,11 +432,6 @@ int drm_put_dev(struct drm_device * dev)
 {
        DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name);
 
-       if (dev->unique) {
-               drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
-               dev->unique = NULL;
-               dev->unique_len = 0;
-       }
        if (dev->devname) {
                drm_free(dev->devname, strlen(dev->devname) + 1,
                         DRM_MEM_DRIVER);
@@ -317,6 +454,7 @@ int drm_put_dev(struct drm_device * dev)
 int drm_put_minor(struct drm_minor **minor_p)
 {
        struct drm_minor *minor = *minor_p;
+
        DRM_DEBUG("release secondary minor %d\n", minor->index);
 
        if (minor->type == DRM_MINOR_LEGACY)