Revert "ati_pcigart: fixup properly this version might even work"
authorDave Airlie <airlied@redhat.com>
Wed, 14 May 2008 12:43:28 +0000 (22:43 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 14 May 2008 12:43:28 +0000 (22:43 +1000)
This reverts commit bc0836e12a9790f1cc83f8bc29bc05043c4bc840.

tree has some kref hacks in it - oops

linux-core/ati_pcigart.c
linux-core/drm_object.c
linux-core/drm_objects.h

index f7752b5..34081d4 100644 (file)
@@ -36,9 +36,6 @@
 # define ATI_PCIGART_PAGE_SIZE         4096    /**< PCI GART page size */
 # define ATI_PCIGART_PAGE_MASK         (~(ATI_PCIGART_PAGE_SIZE-1))
 
-#define ATI_PCIE_WRITE 0x4
-#define ATI_PCIE_READ 0x8
-
 static int drm_ati_alloc_pcigart_table(struct drm_device *dev,
                                       struct drm_ati_pcigart_info *gart_info)
 {
@@ -108,7 +105,6 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
        dma_addr_t bus_address = 0;
        int i, j, ret = 0;
        int max_pages;
-       dma_addr_t entry_addr;
 
        if (!entry) {
                DRM_ERROR("no scatter/gather memory!\n");
@@ -155,26 +151,27 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
                        goto done;
                }
 
-               entry_addr = entry->busaddr[i];
                for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
-                       page_base = (u32) entry_addr & ATI_PCIGART_PAGE_MASK;
                        switch(gart_info->gart_reg_if) {
                        case DRM_ATI_GART_IGP:
-                               page_base |= (upper_32_bits(entry_addr) & 0xff) << 4;
-                               page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE;
+                               page_base = (u32) entry->busaddr[i] & ATI_PCIGART_PAGE_MASK;
+                               page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 4;
+                               *pci_gart = cpu_to_le32((page_base) | 0xc);
                                break;
                        case DRM_ATI_GART_PCIE:
+                               page_base = (u32)(entry->busaddr[i] & ATI_PCIGART_PAGE_MASK);
                                page_base >>= 8;
-                               page_base |= (upper_32_bits(entry_addr) & 0xff) << 24;
-                               page_base |= 0xc;
+                               page_base |= (upper_32_bits(entry->busaddr[i]) & 0xff) << 24;
+                               *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
                                break;
                        default:
                        case DRM_ATI_GART_PCI:
+                               page_base = (u32) entry->busaddr[i];
+                               *pci_gart = cpu_to_le32(page_base);
                                break;
                        }
-                       *pci_gart = cpu_to_le32(page_base);
                        pci_gart++;
-                       entry_addr += ATI_PCIGART_PAGE_SIZE;
+                       page_base += ATI_PCIGART_PAGE_SIZE;
                }
        }
 
index 10924cf..2994b71 100644 (file)
@@ -39,7 +39,7 @@ int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item,
        DRM_ASSERT_LOCKED(&dev->struct_mutex);
 
        /* The refcount will be bumped to 1 when we add the ref object below. */
-       kref_init(&item->refcount);
+       atomic_set(&item->refcount, 0);
        item->shareable = shareable;
        item->owner = priv;
 
@@ -83,20 +83,16 @@ struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t k
 }
 EXPORT_SYMBOL(drm_lookup_user_object);
 
-static void drm_user_object_free(struct kref *kref)
+static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item)
 {
-       struct drm_user_object *item = container_of(kref, struct drm_user_object, refcount);
+       struct drm_device *dev = priv->minor->dev;
        int ret;
-       struct drm_device *dev = item->owner->minor->dev;
-
-       ret = drm_ht_remove_item(&dev->object_hash, &item->hash);
-       BUG_ON(ret);
-       item->remove(item->owner, item);
-}
 
-static void drm_deref_user_object(struct drm_user_object *item)
-{
-       kref_put(&item->refcount, drm_user_object_free);
+       if (atomic_dec_and_test(&item->refcount)) {
+               ret = drm_ht_remove_item(&dev->object_hash, &item->hash);
+               BUG_ON(ret);
+               item->remove(priv, item);
+       }
 }
 
 static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object *ro,
@@ -106,7 +102,7 @@ static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object *
 
        switch (action) {
        case _DRM_REF_USE:
-               kref_get(&ro->refcount);
+               atomic_inc(&ro->refcount);
                break;
        default:
                if (!ro->ref_struct_locked) {
@@ -150,7 +146,7 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced
        if (NULL !=
            (item =
             drm_lookup_ref_object(priv, referenced_object, ref_action))) {
-               kref_get(&item->refcount);
+               atomic_inc(&item->refcount);
                return drm_object_ref_action(priv, referenced_object,
                                             ref_action);
        }
@@ -161,10 +157,8 @@ int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced
                return -ENOMEM;
        }
 
-       kref_init(&item->refcount);
-       kref_get(&item->refcount);
+       atomic_set(&item->refcount, 1);
        item->hash.key = (unsigned long)referenced_object;
-       item->owner = priv;
        ret = drm_ht_insert_item(ht, &item->hash);
        item->unref_action = ref_action;
 
@@ -211,34 +205,27 @@ static void drm_remove_other_references(struct drm_file *priv,
        }
 }
 
-void drm_object_ref_free(struct kref *kref)
-{
-       struct drm_ref_object *item = container_of(kref, struct drm_ref_object, refcount);
-       struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key;
-       struct drm_file *priv = item->owner;
-       struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action];
-       int ret;
-
-       ret = drm_ht_remove_item(ht, &item->hash);
-       BUG_ON(ret);
-       list_del_init(&item->list);
-       if (item->unref_action == _DRM_REF_USE)
-               drm_remove_other_references(priv, user_object);
-       drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS);
-}
-
 void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item)
 {
+       int ret;
        struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key;
+       struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action];
        enum drm_ref_type unref_action;
 
        DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
        unref_action = item->unref_action;
-       kref_put(&item->refcount, drm_object_ref_free);
+       if (atomic_dec_and_test(&item->refcount)) {
+               ret = drm_ht_remove_item(ht, &item->hash);
+               BUG_ON(ret);
+               list_del_init(&item->list);
+               if (unref_action == _DRM_REF_USE)
+                       drm_remove_other_references(priv, user_object);
+               drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS);
+       }
 
        switch (unref_action) {
        case _DRM_REF_USE:
-               drm_deref_user_object(user_object);
+               drm_deref_user_object(priv, user_object);
                break;
        default:
                BUG_ON(!user_object->unref);
index 427a917..770fbc5 100644 (file)
@@ -65,8 +65,7 @@ struct drm_user_object {
        struct drm_hash_item hash;
        struct list_head list;
        enum drm_object_type type;
-       struct kref refcount;
-
+       atomic_t refcount;
        int shareable;
        struct drm_file *owner;
        void (*ref_struct_locked) (struct drm_file *priv,
@@ -87,9 +86,8 @@ struct drm_user_object {
 struct drm_ref_object {
        struct drm_hash_item hash;
        struct list_head list;
-       struct kref refcount;
+       atomic_t refcount;
        enum drm_ref_type unref_action;
-       struct drm_file *owner;
 };
 
 /**