Keep hashed user tokens, with the following changes:
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.main
parent
a392349691
commit
126673d62a
|
@ -65,6 +65,29 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
|
||||||
return NULL;
|
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.
|
* 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_t *map;
|
||||||
drm_map_list_t *list;
|
drm_map_list_t *list;
|
||||||
drm_dma_handle_t *dmah;
|
drm_dma_handle_t *dmah;
|
||||||
|
unsigned long user_token;
|
||||||
|
int ret;
|
||||||
|
|
||||||
map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
|
map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
|
||||||
if (!map)
|
if (!map)
|
||||||
|
@ -260,20 +285,21 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
||||||
|
|
||||||
down(&dev->struct_sem);
|
down(&dev->struct_sem);
|
||||||
list_add(&list->head, &dev->maplist->head);
|
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,
|
/* Assign a 32-bit handle */
|
||||||
((map->type == _DRM_SHM) ? (unsigned long)map->handle :
|
|
||||||
map->offset) >> PAGE_SHIFT,
|
user_token = (map->type == _DRM_SHM) ? (unsigned long) map->handle :
|
||||||
32 - PAGE_SHIFT - 1)) {
|
map->offset;
|
||||||
|
ret = drm_map_handle(dev, &list->hash, user_token, FALSE);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||||
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
||||||
up(&dev->struct_sem);
|
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);
|
up(&dev->struct_sem);
|
||||||
|
|
||||||
*maplist = list;
|
*maplist = list;
|
||||||
|
@ -358,8 +384,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
|
||||||
|
|
||||||
if (r_list->map == map) {
|
if (r_list->map == map) {
|
||||||
list_del(list);
|
list_del(list);
|
||||||
drm_ht_remove_key(&dev->map_hash,
|
drm_ht_remove_key(&dev->map_hash, r_list->user_token);
|
||||||
(r_list->user_token - DRM_MAP_HASH_OFFSET) >> PAGE_SHIFT);
|
|
||||||
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,19 +128,21 @@ drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item)
|
||||||
|
|
||||||
int
|
int
|
||||||
drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item,
|
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;
|
int ret;
|
||||||
unsigned long mask = (1 << bits) - 1;
|
unsigned long mask = (1 << bits) - 1;
|
||||||
unsigned long first;
|
unsigned long first, unshifted_key;
|
||||||
|
|
||||||
item->key = hash_long(seed, bits);
|
unshifted_key = hash_long(seed, bits);
|
||||||
first = item->key;
|
first = unshifted_key;
|
||||||
do{
|
do{
|
||||||
|
item->key = (unshifted_key << shift) + add;
|
||||||
ret = drm_ht_insert_item(ht, item);
|
ret = drm_ht_insert_item(ht, item);
|
||||||
if (ret)
|
if (ret)
|
||||||
item->key = (item->key + 1) & mask;
|
unshifted_key = (unshifted_key + 1) & mask;
|
||||||
} while(ret && (item->key != first));
|
} while(ret && (unshifted_key != first));
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("Available key bit space exhausted\n");
|
DRM_ERROR("Available key bit space exhausted\n");
|
||||||
|
|
|
@ -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_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_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,
|
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 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);
|
extern void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key);
|
||||||
|
|
|
@ -223,7 +223,7 @@ drm_memblock_item_t *drm_sman_alloc(drm_sman_t * sman, unsigned int manager,
|
||||||
|
|
||||||
if (drm_ht_just_insert_please
|
if (drm_ht_just_insert_please
|
||||||
(&sman->user_hash_tab, &memblock->user_hash,
|
(&sman->user_hash_tab, &memblock->user_hash,
|
||||||
(unsigned long)memblock, 32))
|
(unsigned long)memblock, 32, 0, 0))
|
||||||
goto out1;
|
goto out1;
|
||||||
|
|
||||||
owner_item = drm_sman_get_owner_item(sman, owner);
|
owner_item = drm_sman_get_owner_item(sman, owner);
|
||||||
|
|
|
@ -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)
|
if (!dev->agp || !dev->agp->cant_use_aperture)
|
||||||
goto vm_nopage_error;
|
goto vm_nopage_error;
|
||||||
|
|
||||||
if (drm_ht_find_item(&dev->map_hash, (VM_OFFSET(vma) - DRM_MAP_HASH_OFFSET) >> PAGE_SHIFT,
|
if (drm_ht_find_item(&dev->map_hash, VM_OFFSET(vma), &hash))
|
||||||
&hash))
|
|
||||||
goto vm_nopage_error;
|
goto vm_nopage_error;
|
||||||
|
|
||||||
r_list = drm_hash_entry(hash, drm_map_list_t, hash);
|
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);
|
return drm_mmap_dma(filp, vma);
|
||||||
|
|
||||||
if (drm_ht_find_item(&dev->map_hash, (VM_OFFSET(vma) - DRM_MAP_HASH_OFFSET) >> PAGE_SHIFT,
|
if (drm_ht_find_item(&dev->map_hash, VM_OFFSET(vma), &hash)) {
|
||||||
&hash)) {
|
|
||||||
DRM_ERROR("Could not find map\n");
|
DRM_ERROR("Could not find map\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,10 @@
|
||||||
#define DRIVER_AUTHOR "SIS, Tungsten Graphics"
|
#define DRIVER_AUTHOR "SIS, Tungsten Graphics"
|
||||||
#define DRIVER_NAME "sis"
|
#define DRIVER_NAME "sis"
|
||||||
#define DRIVER_DESC "SIS 300/630/540"
|
#define DRIVER_DESC "SIS 300/630/540"
|
||||||
#define DRIVER_DATE "20060704"
|
#define DRIVER_DATE "20060619"
|
||||||
#define DRIVER_MAJOR 2
|
#define DRIVER_MAJOR 1
|
||||||
#define DRIVER_MINOR 0
|
#define DRIVER_MINOR 2
|
||||||
#define DRIVER_PATCHLEVEL 0
|
#define DRIVER_PATCHLEVEL 1
|
||||||
|
|
||||||
enum sis_family {
|
enum sis_family {
|
||||||
SIS_OTHER = 0,
|
SIS_OTHER = 0,
|
||||||
|
|
|
@ -44,9 +44,9 @@
|
||||||
|
|
||||||
#define VIA_DRM_DRIVER_DATE "20060616"
|
#define VIA_DRM_DRIVER_DATE "20060616"
|
||||||
|
|
||||||
#define VIA_DRM_DRIVER_MAJOR 3
|
#define VIA_DRM_DRIVER_MAJOR 2
|
||||||
#define VIA_DRM_DRIVER_MINOR 0
|
#define VIA_DRM_DRIVER_MINOR 10
|
||||||
#define VIA_DRM_DRIVER_PATCHLEVEL 0
|
#define VIA_DRM_DRIVER_PATCHLEVEL 2
|
||||||
#define VIA_DRM_DRIVER_VERSION (((VIA_DRM_DRIVER_MAJOR) << 16) | (VIA_DRM_DRIVER_MINOR))
|
#define VIA_DRM_DRIVER_VERSION (((VIA_DRM_DRIVER_MAJOR) << 16) | (VIA_DRM_DRIVER_MINOR))
|
||||||
|
|
||||||
#define VIA_NR_SAREA_CLIPRECTS 8
|
#define VIA_NR_SAREA_CLIPRECTS 8
|
||||||
|
|
Loading…
Reference in New Issue