Merge master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-drm-fsl-dcu.git] / drivers / char / drm / drm_hashtab.c
index 480611395481b7521a9b107a7e89e48332add537..31acb621dcce1e4fd813b0422b8afefb339d53fe 100644 (file)
@@ -43,7 +43,16 @@ int drm_ht_create(drm_open_hash_t *ht, unsigned int order)
        ht->size = 1 << order;
        ht->order = order;
        ht->fill = 0;
-       ht->table = vmalloc(ht->size*sizeof(*ht->table));
+       ht->table = NULL;
+       ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE);
+       if (!ht->use_vmalloc) {
+               ht->table = drm_calloc(ht->size, sizeof(*ht->table),
+                                      DRM_MEM_HASHTAB);
+       }
+       if (!ht->table) {
+               ht->use_vmalloc = 1;
+               ht->table = vmalloc(ht->size*sizeof(*ht->table));
+       }
        if (!ht->table) {
                DRM_ERROR("Out of memory for hash table\n");
                return -ENOMEM;
@@ -106,7 +115,7 @@ int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item)
        hlist_for_each(list, h_list) {
                entry = hlist_entry(list, drm_hash_item_t, head);
                if (entry->key == key)
-                       return -1;
+                       return -EINVAL;
                if (entry->key > key)
                        break;
                parent = list;
@@ -154,7 +163,7 @@ int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key,
 
        list = drm_ht_find_key(ht, key);
        if (!list)
-               return -1;
+               return -EINVAL;
 
        *item = hlist_entry(list, drm_hash_item_t, head);
        return 0;
@@ -170,7 +179,7 @@ int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key)
                ht->fill--;
                return 0;
        }
-       return -1;
+       return -EINVAL;
 }
 
 int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item)
@@ -183,7 +192,11 @@ int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item)
 void drm_ht_remove(drm_open_hash_t *ht)
 {
        if (ht->table) {
-               vfree(ht->table);
+               if (ht->use_vmalloc)
+                       vfree(ht->table);
+               else
+                       drm_free(ht->table, ht->size * sizeof(*ht->table),
+                                DRM_MEM_HASHTAB);
                ht->table = NULL;
        }
 }