add Egberts 32/64 bit patch (its in kernel already...)
authorDave Airlie <airlied@linux.ie>
Tue, 16 Aug 2005 12:51:57 +0000 (12:51 +0000)
committerDave Airlie <airlied@linux.ie>
Tue, 16 Aug 2005 12:51:57 +0000 (12:51 +0000)
14 files changed:
linux-core/drmP.h
linux-core/drm_bufs.c
linux-core/drm_context.c
linux-core/drm_ioctl.c
linux-core/drm_proc.c
linux-core/drm_scatter.c
linux-core/drm_vm.c
linux-core/i810_dma.c
linux-core/i830_dma.c
linux-core/mga_ioc32.c
shared-core/mga_dma.c
shared-core/mga_drm.h
shared-core/r128_cce.c
shared-core/radeon_cp.c

index 2b4dbcf..4f67747 100644 (file)
 #define DRIVER_USE_MTRR    0x4
 #define DRIVER_PCI_DMA     0x8
 #define DRIVER_SG          0x10
-#define DRIVER_FB_DMA      0x20
-#define DRIVER_HAVE_DMA    0x40
-#define DRIVER_HAVE_IRQ    0x80
-#define DRIVER_IRQ_SHARED  0x100
-#define DRIVER_IRQ_VBL     0x200
-#define DRIVER_DMA_QUEUE   0x400
+#define DRIVER_HAVE_DMA    0x20
+#define DRIVER_HAVE_IRQ    0x40
+#define DRIVER_IRQ_SHARED  0x80
+#define DRIVER_IRQ_VBL     0x100
+#define DRIVER_DMA_QUEUE   0x200
+#define DRIVER_FB_DMA      0x400
+
 
 /*@}*/
 
@@ -499,6 +500,7 @@ typedef struct drm_dma_handle {
 typedef struct drm_map_list {
        struct list_head head;          /**< list head */
        drm_map_t *map;                 /**< mapping */
+       unsigned int user_token;
 } drm_map_list_t;
 
 typedef drm_map_t drm_local_map_t;
@@ -729,6 +731,7 @@ typedef struct drm_device {
 
        struct drm_driver *driver;
        drm_local_map_t *agp_buffer_map;
+       unsigned int agp_buffer_token;
        drm_head_t primary;             /**< primary screen head */
 } drm_device_t;
 
@@ -1019,16 +1022,12 @@ static __inline__ void drm_core_ioremapfree(struct drm_map *map,
 }
 
 static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev,
-                                                  unsigned long offset)
+                                                  unsigned int token)
 {
-       struct list_head *_list;
-       list_for_each(_list, &dev->maplist->head) {
-               drm_map_list_t *_entry =
-                   list_entry(_list, drm_map_list_t, head);
-               if (_entry->map && _entry->map->offset == offset) {
+       drm_map_list_t *_entry;
+       list_for_each_entry(_entry, &dev->maplist->head, head)
+               if (_entry->user_token == token)
                        return _entry->map;
-               }
-       }
        return NULL;
 }
 
index 416d7d8..bad02f2 100644 (file)
@@ -56,8 +56,7 @@ static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
        list_for_each(list, &dev->maplist->head) {
                drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
                if (entry->map && map->type == entry->map->type &&
-                   ((entry->map->offset == map->offset) ||
-                    (map->type == _DRM_SHM))) {
+                   entry->map->offset == map->offset) {
                        return entry->map;
                }
        }
@@ -65,13 +64,42 @@ static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
        return NULL;
 }
 
-#ifdef CONFIG_COMPAT
+
 /*
- * Used to allocate 32-bit handles for _DRM_SHM regions
- * The 0x10000000 value is chosen to be out of the way of
- * FB/register and GART physical addresses.
+ * Used to allocate 32-bit handles for mappings.
  */
-static unsigned int map32_handle = 0x10000000;
+#define START_RANGE 0x10000000
+#define END_RANGE 0x40000000
+
+#ifdef _LP64
+static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev) 
+{
+       static unsigned int map32_handle = START_RANGE;
+       unsigned int hash;
+
+       if (lhandle & 0xffffffff00000000) {
+               hash = map32_handle;
+               map32_handle += PAGE_SIZE;
+               if (map32_handle > END_RANGE)
+                       map32_handle = START_RANGE;
+       } else 
+               hash = lhandle;
+
+       while (1) {
+               drm_map_list_t *_entry;
+               list_for_each_entry(_entry, &dev->maplist->head,head) {
+                       if (_entry->user_token == hash)
+                               break;
+               }
+               if (&_entry->head == &dev->maplist->head)
+                       return hash;
+
+               hash += PAGE_SIZE;
+               map32_handle += PAGE_SIZE;
+       }
+}
+#else
+# define HandleID(x,dev) (unsigned int)(x)
 #endif
 
 /**
@@ -228,7 +256,7 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
                        drm_free(map, sizeof(*map), DRM_MEM_MAPS);
                        return -EINVAL;
                }
-               map->offset += dev->sg->handle;
+               map->offset += (unsigned long)dev->sg->virtual;
                break;
        case _DRM_CONSISTENT: {
                /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G.
@@ -260,13 +288,11 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
 
        down(&dev->struct_sem);
        list_add(&list->head, &dev->maplist->head);
-#ifdef CONFIG_COMPAT
-       /* Assign a 32-bit handle for _DRM_SHM mappings */
+       /* Assign a 32-bit handle */
        /* We do it here so that dev->struct_sem protects the increment */
-       if (map->type == _DRM_SHM)
-               map->offset = map32_handle += PAGE_SIZE;
-#endif
-
+       list->user_token = HandleID(map->type==_DRM_SHM
+                                   ? (unsigned long)map->handle
+                                   : map->offset, dev);
        up(&dev->struct_sem);
 
        *map_ptr = map;
@@ -283,6 +309,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
        drm_map_t *map_ptr;
        drm_map_t __user *argp = (void __user *)arg;
        int err;
+       unsigned long handle = 0;
 
        if (!(filp->f_mode & 3))
                return -EACCES; /* Require read/write */
@@ -301,13 +328,20 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
                return err;
        }
 
-       if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
-               return -EFAULT;
-       if (map_ptr->type != _DRM_SHM) {
-               if (copy_to_user(&argp->handle,
-                                &map_ptr->offset, sizeof(map_ptr->offset)))
+       {
+               drm_map_list_t *_entry;
+               list_for_each_entry(_entry, &dev->maplist->head, head) {
+                       if (_entry->map == map_ptr)
+                               handle = _entry->user_token;
+               }
+               if (!handle)
                        return -EFAULT;
        }
+
+       if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
+               return -EFAULT;
+       if (put_user(handle, &argp->handle))
+               return -EFAULT;
        return 0;
 }
 
@@ -422,7 +456,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
                drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
 
                if (r_list->map &&
-                   r_list->map->handle == request.handle &&
+                   r_list->user_token == (unsigned long) request.handle &&
                    r_list->map->flags & _DRM_REMOVABLE) {
                        map = r_list->map;
                        break;
@@ -991,7 +1025,8 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
 
                buf->offset = (dma->byte_count + offset);
                buf->bus_address = agp_offset + offset;
-               buf->address = (void *)(agp_offset + offset + dev->sg->handle);
+               buf->address = (void *)(agp_offset + offset 
+                                       + (unsigned long)dev->sg->virtual);
                buf->next = NULL;
                buf->waiting = 0;
                buf->pending = 0;
@@ -1517,6 +1552,7 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
                     || (drm_core_check_feature(dev, DRIVER_FB_DMA)
                     && (dma->flags & _DRM_DMA_USE_FB))) {
                        drm_map_t *map = dev->agp_buffer_map;
+                       unsigned long token = dev->agp_buffer_token;
 
                        if (!map) {
                                retcode = -EINVAL;
@@ -1530,7 +1566,7 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
                        virtual = do_mmap(filp, 0, map->size,
                                          PROT_READ | PROT_WRITE,
                                          MAP_SHARED,
-                                         (unsigned long)map->offset);
+                                         token);
 #if LINUX_VERSION_CODE <= 0x020402
                        up(&current->mm->mmap_sem);
 #else
index baa8437..5947c8e 100644 (file)
@@ -217,6 +217,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
        drm_ctx_priv_map_t __user *argp = (void __user *)arg;
        drm_ctx_priv_map_t request;
        drm_map_t *map;
+       drm_map_list_t *_entry;
 
        if (copy_from_user(&request, argp, sizeof(request)))
                return -EFAULT;
@@ -231,7 +232,16 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
        map = dev->context_sareas[request.ctx_id];
        up(&dev->struct_sem);
 
-       request.handle = map->handle;
+       request.handle = 0;
+       list_for_each_entry(_entry, &dev->maplist->head,head) {
+               if (_entry->map == map) {
+                       request.handle = (void *)(unsigned long)_entry->user_token;
+                       break;
+               }
+       }
+       if (request.handle == 0)
+               return -EINVAL;
+
        if (copy_to_user(argp, &request, sizeof(request)))
                return -EFAULT;
        return 0;
@@ -266,7 +276,8 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
        down(&dev->struct_sem);
        list_for_each(list, &dev->maplist->head) {
                r_list = list_entry(list, drm_map_list_t, head);
-               if (r_list->map && r_list->map->handle == request.handle)
+               if (r_list->map
+                   && r_list->user_token == (unsigned long) request.handle)
                        goto found;
        }
       bad:
index eac89ea..e0998d5 100644 (file)
@@ -211,7 +211,7 @@ int drm_getmap(struct inode *inode, struct file *filp,
        map.size = r_list->map->size;
        map.type = r_list->map->type;
        map.flags = r_list->map->flags;
-       map.handle = r_list->map->handle;
+       map.handle = (void *)(unsigned long) r_list->user_token;
        map.mtrr = r_list->map->mtrr;
        up(&dev->struct_sem);
 
index 94aea2b..3e2b3ba 100644 (file)
@@ -238,11 +238,13 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
                        type = "??";
                else
                        type = types[map->type];
-               DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
+               DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08x ",
                               i,
                               map->offset,
                               map->size,
-                              type, map->flags, (unsigned long)map->handle);
+                              type, map->flags,
+                              r_list->user_token);
+
                if (map->mtrr < 0) {
                        DRM_PROC_PRINT("none\n");
                } else {
index 342e757..1647303 100644 (file)
@@ -58,6 +58,12 @@ void drm_sg_cleanup(drm_sg_mem_t * entry)
        drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
 }
 
+#ifdef _LP64
+# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1)))
+#else
+# define ScatterHandle(x) (unsigned int)(x)
+#endif
+
 int drm_sg_alloc(struct inode *inode, struct file *filp,
                 unsigned int cmd, unsigned long arg)
 {
@@ -125,12 +131,13 @@ int drm_sg_alloc(struct inode *inode, struct file *filp,
         */
        memset(entry->virtual, 0, pages << PAGE_SHIFT);
 
-       entry->handle = (unsigned long)entry->virtual;
+       entry->handle = ScatterHandle((unsigned long)entry->virtual);
 
        DRM_DEBUG("sg alloc handle  = %08lx\n", entry->handle);
        DRM_DEBUG("sg alloc virtual = %p\n", entry->virtual);
 
-       for (i = entry->handle, j = 0; j < pages; i += PAGE_SIZE, j++) {
+       for (i = (unsigned long)entry->virtual, j = 0; j < pages; 
+               i += PAGE_SIZE, j++) {
                entry->pagelist[j] = vmalloc_to_page((void *)i);
                if (!entry->pagelist[j])
                        goto failed;
index 227dc66..b253991 100644 (file)
@@ -75,13 +75,13 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
                map = r_list->map;
                if (!map)
                        continue;
-               if (map->offset == VM_OFFSET(vma))
+               if (r_list->user_token == VM_OFFSET(vma))
                        break;
        }
 
        if (map && map->type == _DRM_AGP) {
                unsigned long offset = address - vma->vm_start;
-               unsigned long baddr = VM_OFFSET(vma) + offset;
+               unsigned long baddr = map->offset + offset;
                struct drm_agp_mem *agpmem;
                struct page *page;
 
@@ -319,7 +319,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
                return NOPAGE_OOM;      /* Nothing allocated */
 
        offset = address - vma->vm_start;
-       map_offset = map->offset - dev->sg->handle;
+       map_offset = map->offset - (unsigned long)dev->sg->virtual;
        page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
        page = entry->pagelist[page_offset];
        get_page(page);
@@ -586,14 +586,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
           for performance, even if the list was a
           bit longer. */
        list_for_each(list, &dev->maplist->head) {
-               unsigned long off;
 
                r_list = list_entry(list, drm_map_list_t, head);
                map = r_list->map;
                if (!map)
                        continue;
-               off = dev->driver->get_map_ofs(map);
-               if (off == VM_OFFSET(vma))
+               if (r_list->user_token == VM_OFFSET(vma))
                        break;
        }
 
@@ -636,7 +634,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
                /* fall through to _DRM_FRAME_BUFFER... */
        case _DRM_FRAME_BUFFER:
        case _DRM_REGISTERS:
-               if (VM_OFFSET(vma) >= __pa(high_memory)) {
+               if (map->offset >= __pa(high_memory)) {
 #if defined(__i386__) || defined(__x86_64__)
                        if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
                                pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
@@ -659,13 +657,13 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
 #endif
                offset = dev->driver->get_reg_ofs(dev);
 #ifdef __sparc__
-               if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start,
-                                       VM_OFFSET(vma) + offset,
+               if (io_remap_pfn_range(vma, vma->vm_start,
+                                       (map->offset + offset) >>PAGE_SHIFT,
                                        vma->vm_end - vma->vm_start,
-                                       vma->vm_page_prot, 0))
+                                       vma->vm_page_prot))
 #else
                if (remap_pfn_range(vma, vma->vm_start,
-                                    (VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
+                                    (map->offset + offset) >> PAGE_SHIFT,
                                     vma->vm_end - vma->vm_start,
                                     vma->vm_page_prot))
 #endif
@@ -673,7 +671,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
                DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
                          " offset = 0x%lx\n",
                          map->type,
-                         vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
+                         vma->vm_start, vma->vm_end, map->offset + offset);
                vma->vm_ops = &drm_vm_ops;
                break;
        case _DRM_SHM:
index 9e0634a..2f0484e 100644 (file)
@@ -373,6 +373,7 @@ static int i810_dma_initialize(drm_device_t * dev,
                DRM_ERROR("can not find mmio map!\n");
                return -EINVAL;
        }
+       dev->agp_buffer_token = init->buffers_offset;
        dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
        if (!dev->agp_buffer_map) {
                dev->dev_private = (void *)dev_priv;
index 1c44f70..022cecf 100644 (file)
@@ -366,6 +366,7 @@ static int i830_dma_initialize(drm_device_t * dev,
                DRM_ERROR("can not find mmio map!\n");
                return -EINVAL;
        }
+       dev->agp_buffer_token = init->buffers_offset;
        dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
        if (!dev->agp_buffer_map) {
                dev->dev_private = (void *)dev_priv;
index bc745cf..5775cd6 100644 (file)
@@ -1,3 +1,4 @@
+
 /**
  * \file mga_ioc32.c
  *
@@ -129,9 +130,76 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd,
                         DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
 }
 
+typedef struct drm_mga_drm_bootstrap32 {
+       u32 texture_handle;
+       u32 texture_size;
+       u32 primary_size;
+       u32 secondary_bin_count;
+       u32 secondary_bin_size;
+       u32 agp_mode;
+       u8 agp_size;
+} drm_mga_dma_bootstrap32_t;
+
+static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
+                                   unsigned long arg)
+{
+       drm_mga_dma_bootstrap32_t dma_bootstrap32;
+       drm_mga_dma_bootstrap_t __user *dma_bootstrap;
+       int err;
+
+       if (copy_from_user(&dma_bootstrap32, (void __user *)arg,
+                          sizeof(dma_bootstrap32)))
+               return -EFAULT;
+
+       dma_bootstrap = compat_alloc_user_space(sizeof(*dma_bootstrap));
+       if (!access_ok(VERIFY_WRITE, dma_bootstrap, sizeof(*dma_bootstrap))
+           || __put_user(dma_bootstrap32.texture_handle,
+                         &dma_bootstrap->texture_handle)
+           || __put_user(dma_bootstrap32.texture_size,
+                         &dma_bootstrap->texture_size)
+           || __put_user(dma_bootstrap32.primary_size,
+                         &dma_bootstrap->primary_size)
+           || __put_user(dma_bootstrap32.secondary_bin_count,
+                         &dma_bootstrap->secondary_bin_count)
+           || __put_user(dma_bootstrap32.secondary_bin_size,
+                         &dma_bootstrap->secondary_bin_size)
+           || __put_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
+           || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_MGA_DMA_BOOTSTRAP,
+                       (unsigned long)dma_bootstrap);
+       if (err)
+               return err;
+
+       if (__get_user(dma_bootstrap32.texture_handle,
+                      &dma_bootstrap->texture_handle)
+           || __get_user(dma_bootstrap32.texture_size,
+                         &dma_bootstrap->texture_size)
+           || __get_user(dma_bootstrap32.primary_size,
+                         &dma_bootstrap->primary_size)
+           || __get_user(dma_bootstrap32.secondary_bin_count,
+                         &dma_bootstrap->secondary_bin_count)
+           || __get_user(dma_bootstrap32.secondary_bin_size,
+                         &dma_bootstrap->secondary_bin_size)
+           || __get_user(dma_bootstrap32.agp_mode,
+                         &dma_bootstrap->agp_mode)
+           || __get_user(dma_bootstrap32.agp_size,
+                         &dma_bootstrap->agp_size))
+               return -EFAULT;
+
+       if (copy_to_user((void __user *)arg, &dma_bootstrap32,
+                        sizeof(dma_bootstrap32)))
+               return -EFAULT;
+
+       return 0;
+}
+
 drm_ioctl_compat_t *mga_compat_ioctls[] = {
        [DRM_MGA_INIT] = compat_mga_init,
        [DRM_MGA_GETPARAM] = compat_mga_getparam,
+       [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap,
 };
 
 /**
index 31df5d6..005c523 100644 (file)
@@ -819,6 +819,7 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
                        DRM_ERROR("failed to find primary dma region!\n");
                        return DRM_ERR(EINVAL);
                }
+               dev->agp_buffer_token = init->buffers_offset;
                dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
                if (!dev->agp_buffer_map) {
                        DRM_ERROR("failed to find dma buffer region!\n");
index 5b8f156..5bcdbfa 100644 (file)
@@ -312,7 +312,7 @@ typedef struct drm_mga_dma_bootstrap {
         * an IOMMU) is being used for "AGP" textures.
         */
        /*@{*/
-       drm_handle_t texture_handle;  /**< Handle used to map AGP textures. */
+       unsigned long texture_handle;  /**< Handle used to map AGP textures. */
        uint32_t     texture_size;    /**< Size of the AGP texture region. */
        /*@}*/
 
index 34348cf..3355367 100644 (file)
@@ -323,7 +323,8 @@ static void r128_cce_init_ring_buffer(drm_device_t * dev,
                ring_start = dev_priv->cce_ring->offset - dev->agp->base;
        else
 #endif
-               ring_start = dev_priv->cce_ring->offset - dev->sg->handle;
+               ring_start = dev_priv->cce_ring->offset - 
+                               (unsigned long)dev->sg->virtual;
 
        R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET);
 
@@ -484,6 +485,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
                r128_do_cleanup_cce(dev);
                return DRM_ERR(EINVAL);
        }
+       dev->agp_buffer_token = init->buffers_offset;
        dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
        if (!dev->agp_buffer_map) {
                DRM_ERROR("could not find dma buffer region!\n");
@@ -535,7 +537,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
                dev_priv->cce_buffers_offset = dev->agp->base;
        else
 #endif
-               dev_priv->cce_buffers_offset = dev->sg->handle;
+               dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual;
 
        dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle;
        dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle
index 8694d04..09a473d 100644 (file)
@@ -1423,6 +1423,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
                radeon_do_cleanup_cp(dev);
                return DRM_ERR(EINVAL);
        }
+       dev->agp_buffer_token = init->buffers_offset;
        dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
        if (!dev->agp_buffer_map) {
                DRM_ERROR("could not find dma buffer region!\n");