Keep hashed user tokens, with the following changes:
authorThomas Hellstrom <thomas@tungstengraphics.com>
Tue, 11 Jul 2006 14:37:37 +0000 (14:37 +0000)
committerThomas Hellstrom <thomas@tungstengraphics.com>
Tue, 11 Jul 2006 14:37:37 +0000 (14:37 +0000)
32-bit physical device addresses are mapped directly to user-tokens. No
    duplicate maps are allowed, and the addresses are assumed to be outside
    of the range 0x10000000 through 0x30000000. The user-token is identical
    to the 32-bit physical start-address of the map.
64-bit physical device addressed are mapped to user-tokens in the range
0x10000000 to 0x30000000 with page-size increments. The user_token should
    not be interpreted as an address.
Other map types, like upcoming TTM maps are mapped to user-tokens in the
    range
0x10000000 to 0x30000000 with page-size increments. The user_token should
    not be interpreted as an address.
This keeps compatibility with buggy drivers, while still implementing a
    hashed map lookup. The SiS and via device driver major bumps are
    reverted.

linux-core/drm_bufs.c
linux-core/drm_hashtab.c
linux-core/drm_hashtab.h
linux-core/drm_sman.c
linux-core/drm_vm.c
shared-core/sis_drv.h
shared-core/via_drm.h

index 4470525..7dd46b6 100644 (file)
@@ -65,6 +65,29 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
        return NULL;
 }
 
+int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, 
+                  unsigned long user_token, int hashed_handle)
+{
+       int use_hashed_handle;
+
+#if (BITS_PER_LONG == 64)
+       use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
+#elif (BITS_PER_LONG == 32)
+       use_hashed_handle = hashed_handle;
+#else
+#error Unsupported long size. Neither 64 nor 32 bits.
+#endif
+
+       if (use_hashed_handle) {
+               return drm_ht_just_insert_please(&dev->map_hash, hash, 
+                                                user_token, 32 - PAGE_SHIFT - 3,
+                                                PAGE_SHIFT, DRM_MAP_HASH_OFFSET);
+       } else {
+               hash->key = user_token;
+               return drm_ht_insert_item(&dev->map_hash, hash);
+       }
+}
+
 /**
  * Ioctl to specify a range of memory that is available for mapping by a non-root process.
  *
@@ -85,6 +108,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
        drm_map_t *map;
        drm_map_list_t *list;
        drm_dma_handle_t *dmah;
+       unsigned long user_token;
+       int ret;
 
        map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
        if (!map)
@@ -260,20 +285,21 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
 
        down(&dev->struct_sem);
        list_add(&list->head, &dev->maplist->head);
+
        /* Assign a 32-bit handle */
-       /* We do it here so that dev->struct_sem protects the increment */
 
-        if (drm_ht_just_insert_please(&dev->map_hash, &list->hash, 
-                                     ((map->type == _DRM_SHM) ? (unsigned long)map->handle : 
-                                       map->offset) >> PAGE_SHIFT,
-                                     32 - PAGE_SHIFT - 1)) {
+       user_token = (map->type == _DRM_SHM) ? (unsigned long) map->handle : 
+               map->offset;
+        ret = drm_map_handle(dev, &list->hash, user_token, FALSE); 
+
+       if (ret) {
                 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
                 drm_free(list, sizeof(*list), DRM_MEM_MAPS);
                 up(&dev->struct_sem);
-                return -ENOMEM;
+                return ret;
        }
 
-       list->user_token = (list->hash.key << PAGE_SHIFT) + DRM_MAP_HASH_OFFSET;
+       list->user_token = list->hash.key;
        up(&dev->struct_sem);
 
        *maplist = list;
@@ -358,8 +384,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
 
                if (r_list->map == map) {
                        list_del(list);
-                        drm_ht_remove_key(&dev->map_hash, 
-                                          (r_list->user_token - DRM_MAP_HASH_OFFSET) >> PAGE_SHIFT);
+                        drm_ht_remove_key(&dev->map_hash, r_list->user_token);
                        drm_free(list, sizeof(*list), DRM_MEM_MAPS);
                        break;
                }
index 3be781d..d8c4549 100644 (file)
@@ -128,19 +128,21 @@ drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item)
 
 int
 drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item,
-                          unsigned long seed, int bits)
+                          unsigned long seed, int bits, int shift, 
+                         unsigned long add)
 {
         int ret;
         unsigned long mask = (1 << bits) - 1;
-        unsigned long first;
+        unsigned long first, unshifted_key;
 
-        item->key = hash_long(seed, bits);
-        first = item->key;
+        unshifted_key = hash_long(seed, bits);
+        first = unshifted_key;
         do{
+               item->key = (unshifted_key << shift) + add;
                 ret = drm_ht_insert_item(ht, item);
                 if (ret)
-                        item->key = (item->key + 1) & mask; 
-        } while(ret && (item->key != first));
+                        unshifted_key = (unshifted_key + 1) & mask; 
+        } while(ret && (unshifted_key != first));
 
         if (ret) {
                 DRM_ERROR("Available key bit space exhausted\n");
index d792499..157353d 100644 (file)
@@ -53,7 +53,8 @@ typedef struct drm_open_hash{
 extern int drm_ht_create(drm_open_hash_t *ht, unsigned int order);
 extern int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item);
 extern int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item,
-                              unsigned long seed, int bits);
+                                    unsigned long seed, int bits, int shift, 
+                                    unsigned long add);
 extern int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, drm_hash_item_t **item);
 
 extern void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key);
index a03c9f5..d894e82 100644 (file)
@@ -223,7 +223,7 @@ drm_memblock_item_t *drm_sman_alloc(drm_sman_t * sman, unsigned int manager,
 
        if (drm_ht_just_insert_please
            (&sman->user_hash_tab, &memblock->user_hash,
-            (unsigned long)memblock, 32))
+            (unsigned long)memblock, 32, 0, 0))
                goto out1;
 
        owner_item = drm_sman_get_owner_item(sman, owner);
index 93037bd..19866dc 100644 (file)
@@ -70,8 +70,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
        if (!dev->agp || !dev->agp->cant_use_aperture)
                goto vm_nopage_error;
 
-        if (drm_ht_find_item(&dev->map_hash, (VM_OFFSET(vma) - DRM_MAP_HASH_OFFSET) >> PAGE_SHIFT,  
-                             &hash)) 
+        if (drm_ht_find_item(&dev->map_hash, VM_OFFSET(vma), &hash)) 
                 goto vm_nopage_error;
 
         r_list = drm_hash_entry(hash, drm_map_list_t, hash);
@@ -575,8 +574,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
            )
                return drm_mmap_dma(filp, vma);
 
-        if (drm_ht_find_item(&dev->map_hash, (VM_OFFSET(vma) - DRM_MAP_HASH_OFFSET) >> PAGE_SHIFT,
-                             &hash)) {
+        if (drm_ht_find_item(&dev->map_hash, VM_OFFSET(vma), &hash)) {
                 DRM_ERROR("Could not find map\n");
                return -EINVAL;
         }
index a06a96a..b739a48 100644 (file)
 #define DRIVER_AUTHOR          "SIS, Tungsten Graphics"
 #define DRIVER_NAME            "sis"
 #define DRIVER_DESC            "SIS 300/630/540"
-#define DRIVER_DATE            "20060704"
-#define DRIVER_MAJOR           2
-#define DRIVER_MINOR           0
-#define DRIVER_PATCHLEVEL      0
+#define DRIVER_DATE            "20060619"
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           2
+#define DRIVER_PATCHLEVEL      1
 
 enum sis_family {
         SIS_OTHER = 0,
index 96082f2..049c63e 100644 (file)
@@ -44,9 +44,9 @@
 
 #define VIA_DRM_DRIVER_DATE            "20060616"
 
-#define VIA_DRM_DRIVER_MAJOR           3
-#define VIA_DRM_DRIVER_MINOR           0
-#define VIA_DRM_DRIVER_PATCHLEVEL      0
+#define VIA_DRM_DRIVER_MAJOR           2
+#define VIA_DRM_DRIVER_MINOR           10
+#define VIA_DRM_DRIVER_PATCHLEVEL      2
 #define VIA_DRM_DRIVER_VERSION          (((VIA_DRM_DRIVER_MAJOR) << 16) | (VIA_DRM_DRIVER_MINOR))
 
 #define VIA_NR_SAREA_CLIPRECTS                 8