diff -rNu ../unpatched/drm/libdrm/Makefile drm/libdrm/Makefile --- ../unpatched/drm/libdrm/Makefile 2005-01-30 04:30:45.000000000 +0100 +++ drm/libdrm/Makefile 2005-03-31 21:37:59.000000000 +0200 @@ -36,7 +36,7 @@ all: libdrm.so libdrm.so: $(OBJECTS) - $(CC) -shared -Wl,-hlibdrm.so.1 -o $@ $^ + $(CC) $(LDFLAGS) -shared -Wl,-hlibdrm.so.1 -o $@ $^ .c.o: $(CC) $(DEFINES) $(CFLAGS) -c -I../shared-core $< Files ../unpatched/drm/libdrm/libdrm.so and drm/libdrm/libdrm.so differ diff -rNu ../unpatched/drm/libdrm/xf86drm.c drm/libdrm/xf86drm.c --- ../unpatched/drm/libdrm/xf86drm.c 2004-08-12 01:23:35.000000000 +0200 +++ drm/libdrm/xf86drm.c 2005-04-05 21:29:50.000000000 +0200 @@ -898,7 +898,7 @@ { drm_map_t map; - map.handle = (void *)handle; + map.handle = handle; if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno; return 0; @@ -1501,7 +1501,7 @@ * arguments in a drm_agp_buffer structure. */ int drmAgpAlloc(int fd, unsigned long size, unsigned long type, - unsigned long *address, unsigned long *handle) + unsigned long *address, drm_handle_t *handle) { drm_agp_buffer_t b; @@ -1528,7 +1528,7 @@ * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the * argument in a drm_agp_buffer structure. */ -int drmAgpFree(int fd, unsigned long handle) +int drmAgpFree(int fd, drm_handle_t handle) { drm_agp_buffer_t b; @@ -1552,7 +1552,7 @@ * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the * argument in a drm_agp_binding structure. */ -int drmAgpBind(int fd, unsigned long handle, unsigned long offset) +int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset) { drm_agp_binding_t b; @@ -1575,7 +1575,7 @@ * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing * the argument in a drm_agp_binding structure. */ -int drmAgpUnbind(int fd, unsigned long handle) +int drmAgpUnbind(int fd, drm_handle_t handle) { drm_agp_binding_t b; @@ -1765,7 +1765,7 @@ return i.id_device; } -int drmScatterGatherAlloc(int fd, unsigned long size, unsigned long *handle) +int drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle) { drm_scatter_gather_t sg; @@ -1777,7 +1777,7 @@ return 0; } -int drmScatterGatherFree(int fd, unsigned long handle) +int drmScatterGatherFree(int fd, drm_handle_t handle) { drm_scatter_gather_t sg; @@ -1944,7 +1944,7 @@ drm_ctx_priv_map_t map; map.ctx_id = ctx_id; - map.handle = (void *)handle; + map.handle = handle; if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) return -errno; return 0; @@ -1974,7 +1974,7 @@ *size = map.size; *type = map.type; *flags = map.flags; - *handle = (unsigned long)map.handle; + *handle = (drm_handle_t)map.handle; *mtrr = map.mtrr; return 0; } diff -rNu ../unpatched/drm/libdrm/xf86drm.h drm/libdrm/xf86drm.h --- ../unpatched/drm/libdrm/xf86drm.h 2005-02-01 23:09:46.000000000 +0100 +++ drm/libdrm/xf86drm.h 2005-03-29 12:57:09.000000000 +0200 @@ -577,11 +577,11 @@ extern int drmAgpEnable(int fd, unsigned long mode); extern int drmAgpAlloc(int fd, unsigned long size, unsigned long type, unsigned long *address, - unsigned long *handle); -extern int drmAgpFree(int fd, unsigned long handle); -extern int drmAgpBind(int fd, unsigned long handle, + drm_handle_t *handle); +extern int drmAgpFree(int fd, drm_handle_t handle); +extern int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset); -extern int drmAgpUnbind(int fd, unsigned long handle); +extern int drmAgpUnbind(int fd, drm_handle_t handle); /* AGP/GART info: authenticated client and/or X */ extern int drmAgpVersionMajor(int fd); @@ -596,8 +596,8 @@ /* PCI scatter/gather support: X server (root) only */ extern int drmScatterGatherAlloc(int fd, unsigned long size, - unsigned long *handle); -extern int drmScatterGatherFree(int fd, unsigned long handle); + drm_handle_t *handle); +extern int drmScatterGatherFree(int fd, drm_handle_t handle); extern int drmWaitVBlank(int fd, drmVBlankPtr vbl); Files ../unpatched/drm/libdrm/xf86drm.o and drm/libdrm/xf86drm.o differ Files ../unpatched/drm/libdrm/xf86drmHash.o and drm/libdrm/xf86drmHash.o differ Files ../unpatched/drm/libdrm/xf86drmRandom.o and drm/libdrm/xf86drmRandom.o differ Files ../unpatched/drm/libdrm/xf86drmSL.o and drm/libdrm/xf86drmSL.o differ diff -rNu ../unpatched/drm/linux-core/Makefile drm/linux-core/Makefile --- ../unpatched/drm/linux-core/Makefile 2005-01-19 11:03:33.000000000 +0100 +++ drm/linux-core/Makefile 2005-03-24 20:29:42.000000000 +0100 @@ -50,7 +50,7 @@ MACHINE := $(shell uname -m) # Modules for all architectures -MODULE_LIST := drm.0 tdfx.o r128.o radeon.o mga.o sis.o savage.o via.o mach64.o +MODULE_LIST := drm.o drm_ioctl32.o tdfx.o r128.o radeon.o mga.o sis.o savage.o via.o mach64.o # Modules only for ix86 architectures ifneq (,$(findstring 86,$(MACHINE))) @@ -65,6 +65,11 @@ DRM_MODULES ?= $(MODULE_LIST) +ifeq ($(CONFIG_COMPAT),y) +DRMIOCTL32HEADER = drm_ioctl32.h +MODULE_LIST += drm_ioctl32.o +endif + # These definitions are for handling dependencies in the out of kernel build. DRMSHARED = drm.h drm_sarea.h @@ -73,12 +78,13 @@ TDFXHEADERS = tdfx_drv.h $(DRMHEADERS) TDFXSHARED = tdfx_drv.h -R128HEADERS = r128_drv.h r128_drm.h $(DRMHEADERS) +R128HEADERS = r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMIOCTL32HEADER) R128SHARED = r128_drv.h r128_drm.h r128_cce.c r128_state.c r128_irq.c -RADEONHEADERS = radeon_drv.h radeon_drm.h $(DRMHEADERS) +RADEONHEADERS = radeon_drv.h radeon_drm.h $(DRMHEADERS) $(DRMIOCTL32HEADER) RADEONSHARED = radeon_drv.h radeon_drm.h radeon_cp.c radeon_irq.c \ radeon_mem.c radeon_state.c -MGAHEADERS = mga_drv.h mga_drm.h mga_ucode.h $(DRMHEADERS) +MGAHEADERS = mga_drv.h mga_drm.h mga_ucode.h $(DRMHEADERS) \ + $(DRMIOCTL32HEADER) MGASHARED = mga_dma.c mga_drm.h mga_drv.h mga_irq.c mga_state.c \ mga_ucode.h mga_warp.c I810HEADERS = i810_drv.h i810_drm.h $(DRMHEADERS) @@ -379,6 +385,7 @@ # Depencencies $(drm-objs): $(DRMHEADERS) $(COREHEADERS) +$(ioctl32-objs): $(DRMIOCTL32HEADER) $(DRMSHARED) $(tdfx-objs): $(TDFXHEADERS) $(r128-objs): $(R128HEADERS) $(mga-objs): $(MGAHEADERS) @@ -391,6 +398,5 @@ $(savage-objs): $(SAVAGEHEADERS) $(via-objs): $(VIAHEADERS) $(mach64-objs): $(MACH64HEADERS) - endif diff -rNu ../unpatched/drm/linux-core/Makefile.kernel drm/linux-core/Makefile.kernel --- ../unpatched/drm/linux-core/Makefile.kernel 2005-01-16 08:49:55.000000000 +0100 +++ drm/linux-core/Makefile.kernel 2005-03-24 20:28:04.000000000 +0100 @@ -24,6 +27,16 @@ savage-objs := savage_drv.o savage_bci.o savage_state.o via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o mach64-objs := mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o +ioctl32-objs := drm_ioctl32.c + +CONFIG_DRM_IOCTL32 = n + +ifeq ($(CONFIG_COMPAT),y) +r128-objs += r128_ioctl32.o +radeon-objs += radeon_ioctl32.o +mga-objs += mga_ioctl32.o +CONFIG_DRM_IOCTL32 = $(CONFIG_DRM) +endif obj-m += drm.o obj-$(CONFIG_DRM_TDFX) += tdfx.o @@ -38,3 +51,4 @@ obj-$(CONFIG_DRM_SAVAGE)+= savage.o obj-$(CONFIG_DRM_VIA) += via.o obj-$(CONFIG_DRM_MACH64)+= mach64.o +obj-$(CONFIG_DRM_IOCTL32) += drm_ioctl32.o diff -rNu ../unpatched/drm/linux-core/drmP.h drm/linux-core/drmP.h --- ../unpatched/drm/linux-core/drmP.h 2005-02-07 11:44:28.000000000 +0100 +++ drm/linux-core/drmP.h 2005-04-05 14:27:52.000000000 +0200 @@ -992,6 +992,21 @@ 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->pub_handle == offset) { + return _entry->map; + } + } + return NULL; +} + +static __inline__ struct drm_map *drm_core_findmap_by_base( + struct drm_device *dev, + unsigned long offset) +{ + 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) { return _entry->map; } diff -rNu ../unpatched/drm/linux-core/drm_bufs.c drm/linux-core/drm_bufs.c --- ../unpatched/drm/linux-core/drm_bufs.c 2005-02-05 09:00:14.000000000 +0100 +++ drm/linux-core/drm_bufs.c 2005-04-05 21:31:37.000000000 +0200 @@ -36,6 +36,36 @@ #include #include "drmP.h" +#ifdef _LP64 +static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev) +{ + unsigned int hash; + struct list_head *list; + drm_map_list_t *r_list = NULL; + + hash = (unsigned int)(((lhandle >> 32) + + ((lhandle >> 16) /* & 0xffff0000 */) + + lhandle) & PAGE_MASK); + while (1) { + if (hash == 0) hash = (1 << 16); + list = &dev->maplist->head; + list_for_each(list, &dev->maplist->head) { + r_list = list_entry(list, drm_map_list_t, head); + + if (r_list->map && r_list->map->pub_handle + && r_list->map->pub_handle == hash) + break; + } + + if(list == (&dev->maplist->head)) + return hash; + hash += (1 << 14); + } +} +#else +# define HandleID(x,dev) (unsigned int)(x) +#endif + unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) { return pci_resource_start(dev->pdev, resource); @@ -78,7 +108,7 @@ *map = (drm_map_t) { .offset = offset,.size = size,.type = type,.flags = - flags,.mtrr = -1,.handle = 0,}; + flags,.mtrr = -1,.pub_handle = 0,.handle = 0,}; list->map = map; DRM_DEBUG("initmap offset = 0x%08lx, size = 0x%08lx, type = %d\n", @@ -98,6 +128,9 @@ if (map->type == _DRM_REGISTERS) map->handle = drm_ioremap(map->offset, map->size, dev); + if (map->offset) + map->pub_handle = HandleID((unsigned long) map->offset,dev); + down(&dev->struct_sem); list_add(&list->head, &dev->maplist->head); up(&dev->struct_sem); @@ -128,7 +161,8 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_map_t *map; - drm_map_t __user *argp = (void __user *)arg; + drm_pub_map_t __user *argp = (void __user *)arg; + drm_pub_map_t tmp_map; drm_map_list_t *list; if (!(filp->f_mode & 3)) @@ -138,10 +172,14 @@ if (!map) return -ENOMEM; - if (copy_from_user(map, argp, sizeof(*map))) { + if (copy_from_user(&tmp_map, argp, sizeof(tmp_map))) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EFAULT; } + map->offset = tmp_map.offset; + map->size = tmp_map.size; + map->type = tmp_map.type; + map->flags = tmp_map.flags; /* Only allow shared memory to be removable since we only keep enough * book keeping information about shared memory to allow for removal @@ -222,7 +260,7 @@ break; } case _DRM_SHM: - map->handle = vmalloc_32(map->size); + map->handle = vmalloc(map->size); DRM_DEBUG("%lu %d %p\n", map->size, drm_order(map->size), map->handle); if (!map->handle) { @@ -254,7 +292,7 @@ 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. @@ -288,13 +326,15 @@ list_add(&list->head, &dev->maplist->head); up(&dev->struct_sem); found_it: - if (copy_to_user(argp, map, sizeof(*map))) + + map->pub_handle = + tmp_map.handle = (map->type == _DRM_SHM + ? HandleID((unsigned long)map->handle,dev) + : HandleID(map->offset,dev)); + + if ( copy_to_user( argp, &tmp_map, sizeof(tmp_map) ) ) return -EFAULT; - if (map->type != _DRM_SHM) { - if (copy_to_user(&argp->handle, - &map->offset, sizeof(map->offset))) - return -EFAULT; - } + return 0; } @@ -323,10 +363,10 @@ drm_map_list_t *r_list = NULL; drm_vma_entry_t *pt, *prev; drm_map_t *map; - drm_map_t request; + drm_pub_map_t request; int found_maps = 0; - if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) { + if (copy_from_user(&request, (drm_pub_map_t __user *) arg, sizeof(request))) { return -EFAULT; } @@ -336,7 +376,7 @@ r_list = list_entry(list, drm_map_list_t, head); if (r_list->map && - r_list->map->handle == request.handle && + r_list->map->pub_handle == request.handle && r_list->map->flags & _DRM_REMOVABLE) break; } @@ -933,7 +973,8 @@ 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; @@ -1470,7 +1511,7 @@ virtual = do_mmap(filp, 0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, - (unsigned long)map->offset); + (unsigned long)map->pub_handle); #if LINUX_VERSION_CODE <= 0x020402 up(¤t->mm->mmap_sem); #else diff -rNu ../unpatched/drm/linux-core/drm_context.c drm/linux-core/drm_context.c --- ../unpatched/drm/linux-core/drm_context.c 2004-10-18 16:16:41.000000000 +0200 +++ drm/linux-core/drm_context.c 2005-03-24 18:40:01.000000000 +0100 @@ -231,7 +231,7 @@ map = dev->context_sareas[request.ctx_id]; up(&dev->struct_sem); - request.handle = map->handle; + request.handle = map->pub_handle; if (copy_to_user(argp, &request, sizeof(request))) return -EFAULT; return 0; @@ -266,7 +266,7 @@ 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->map->pub_handle == request.handle) goto found; } bad: diff -rNu ../unpatched/drm/linux-core/drm_ioctl.c drm/linux-core/drm_ioctl.c --- ../unpatched/drm/linux-core/drm_ioctl.c 2005-03-09 00:47:11.000000000 +0100 +++ drm/linux-core/drm_ioctl.c 2005-04-04 23:05:40.000000000 +0200 @@ -177,8 +177,8 @@ { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; - drm_map_t __user *argp = (void __user *)arg; - drm_map_t map; + drm_pub_map_t __user *argp = (void __user *)arg; + drm_pub_map_t map; drm_map_list_t *r_list = NULL; struct list_head *list; int idx; @@ -211,7 +211,7 @@ 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 = r_list->map->pub_handle; map.mtrr = r_list->map->mtrr; up(&dev->struct_sem); diff -rNu ../unpatched/drm/linux-core/drm_ioctl32.c drm/linux-core/drm_ioctl32.c --- ../unpatched/drm/linux-core/drm_ioctl32.c 1970-01-01 01:00:00.000000000 +0100 +++ drm/linux-core/drm_ioctl32.c 2005-03-24 18:42:50.000000000 +0100 @@ -0,0 +1,1134 @@ +/* + * Copyright 2003, 2004, Egbert Eich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * EGBERT EICH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Egbert Eich shall not + * be used in advertising or otherwise to promote the sale, use or other deal- + *ings in this Software without prior written authorization from Egbert Eich. + * + */ +#include +#include +#include +#include +#include +#if 0 +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +#ifdef __x86_64__ + +#include +#include "drm.h" +#define IOCTL32_PRIVATE +#include "drm_ioctl32.h" + + +MODULE_AUTHOR( "Egbert Eich, eich@suse.de" ); +MODULE_DESCRIPTION( "DRM ioctl32 translations" ); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL and additional rights"); +#endif + +#define DRM_IOCTL_VERSION_32 DRM_IOWR(0x00, drm32_version_t) +#define DRM_IOCTL_GET_UNIQUE_32 DRM_IOWR(0x01, drm32_unique_t) +#define DRM_IOCTL_GET_MAP_32 DRM_IOWR(0x04, drm32_map_t) +#define DRM_IOCTL_GET_CLIENT_32 DRM_IOWR(0x05, drm32_client_t) +#define DRM_IOCTL_GET_STATS_32 DRM_IOR( 0x06, drm32_stats_t) +#define DRM_IOCTL_SET_UNIQUE_32 DRM_IOW( 0x10, drm32_unique_t) +#define DRM_IOCTL_ADD_MAP_32 DRM_IOWR(0x15, drm32_map_t) +#define DRM_IOCTL_ADD_BUFS_32 DRM_IOWR(0x16, drm32_buf_desc_t) +#define DRM_IOCTL_MARK_BUFS_32 DRM_IOW( 0x17, drm32_buf_desc_t) +#define DRM_IOCTL_INFO_BUFS_32 DRM_IOWR(0x18, drm32_buf_info_t) +#define DRM_IOCTL_MAP_BUFS_32 DRM_IOWR(0x19, drm32_buf_map_t) +#define DRM_IOCTL_FREE_BUFS_32 DRM_IOW( 0x1a, drm32_buf_free_t) +#define DRM_IOCTL_RM_MAP_32 DRM_IOW( 0x1b, drm32_map_t) +#if 0 +#define DRM_IOCTL_SET_SAREA_CTX_32 DRM_IOW( 0x1c, drm32_ctx_priv_map_t) +#define DRM_IOCTL_GET_SAREA_CTX_32 DRM_IOWR(0x1d, drm32_ctx_priv_map_t) +#endif +#define DRM_IOCTL_RES_CTX_32 DRM_IOWR(0x26, drm32_ctx_res_t) +#define DRM_IOCTL_DMA_32 DRM_IOWR(0x29, drm32_dma_t) +#define DRM_IOCTL_AGP_ENABLE_32 DRM_IOW( 0x32, drm32_agp_mode_t) +#define DRM_IOCTL_AGP_INFO_32 DRM_IOR( 0x33, drm32_agp_info_t) +#define DRM_IOCTL_AGP_ALLOC_32 DRM_IOWR(0x34, drm32_agp_buffer_t) +#define DRM_IOCTL_AGP_FREE_32 DRM_IOW( 0x35, drm32_agp_buffer_t) +#define DRM_IOCTL_AGP_BIND_32 DRM_IOW( 0x36, drm32_agp_binding_t) +#define DRM_IOCTL_AGP_UNBIND_32 DRM_IOW( 0x37, drm32_agp_binding_t) +#define DRM_IOCTL_SG_ALLOC_32 DRM_IOW( 0x38, drm32_scatter_gather_t) +#define DRM_IOCTL_SG_FREE_32 DRM_IOW( 0x39, drm32_scatter_gather_t) +#define DRM_IOCTL_WAIT_VBLANK_32 DRM_IOWR(0x3a, drm32_wait_vblank_t) + +typedef struct drm32_version { /* OK */ + int version_major; /* Major version */ + int version_minor; /* Minor version */ + int version_patchlevel;/* Patch level */ + unsigned int name_len; /* Length of name buffer */ + u32 name; /* Name of driver */ + unsigned int date_len; /* Length of date buffer */ + u32 date; /* User-space buffer to hold date*/ + unsigned int desc_len; /* Length of desc buffer */ + u32 desc; /* User-space buffer to hold desc*/ +} drm32_version_t; + +typedef struct drm32_unique { /* OK */ + unsigned int unique_len;/* Length of unique */ + u32 unique; /* Unique name for driver instantiation */ +} drm32_unique_t; + +typedef struct drm32_client { + int idx; /* Which client desired? */ + int auth; /* Is client authenticated? */ +/*?*/ unsigned int pid; /* Process id */ +/*?*/ unsigned int uid; /* User id */ +/*?*/ unsigned int magic; /* Magic */ +/*?*/ unsigned int iocs; /* Ioctl count */ +} drm32_client_t; + +#if 0 +typedef struct drm32_ctx_priv_map { + unsigned int ctx_id; /* Context requesting private mapping */ +/*?*/ u32 handle; /* Handle of map */ +} drm32_ctx_priv_map_t; +#endif + +typedef struct drm32_buf_desc { /* OK */ + int count; /* Number of buffers of this size */ + int size; /* Size in bytes */ + int low_mark; /* Low water mark */ + int high_mark; /* High water mark */ + int flags; +/*?*/ unsigned int agp_start; /* Start address of where the agp buffers + * are in the agp aperture */ +} drm32_buf_desc_t; + +typedef struct drm32_buf_info { /* OK */ + int count; /* Entries in list */ + u32 list; +} drm32_buf_info_t; + +typedef struct drm32_buf_pub { /* OK (see drm32_buf_map) */ + int idx; /* Index into master buflist */ + int total; /* Buffer size */ + int used; /* Amount of buffer in use (for DMA) */ + u32 address; /* Address of buffer */ +} drm32_buf_pub_t; + +typedef struct drm32_buf_map { /*OK (if do_mmap works correctly) */ + int count; /* Length of buflist */ + u32 virtual; /* Mmaped area in user-virtual */ + u32 list; /* Buffer information */ +} drm32_buf_map_t; + +typedef struct drm32_buf_free { /* OK (see above) */ + int count; + u32 list; +} drm32_buf_free_t; + +typedef struct drm32_stats { +/*?*/ unsigned int count; + struct { + unsigned int value; + drm_stat_type_t type; + } data[15]; +} drm32_stats_t; + +typedef struct drm32_map { +/*?*/ unsigned int offset; /* Requested physical address (0 for SARA)*/ +/*?*/ unsigned int size; /* Requested physical size (bytes) */ + drm_map_type_t type; /* Type of memory to map */ + drm_map_flags_t flags; /* Flags */ + unsigned long pub_handle; /* User-space: "Handle" to pass to mmap */ + int mtrr; /* MTRR slot used */ + /* Private data */ +} drm32_map_t; + +typedef struct drm32_ctx_res { /* OK */ + int count; + u32 contexts; +} drm32_ctx_res_t; + +typedef struct drm32_dma { /* should be OK */ + /* Indices here refer to the offset into + buflist in drm_buf_get_t. */ + int context; /* Context handle */ + int send_count; /* Number of buffers to send */ + u32 send_indices; /* List of handles to buffers */ + u32 send_sizes; /* Lengths of data to send */ + drm_dma_flags_t flags; /* Flags */ + int request_count; /* Number of buffers requested */ + int request_size; /* Desired size for buffers */ + u32 request_indices; /* Buffer information */ + u32 request_sizes; + int granted_count; /* Number of buffers granted */ +} drm32_dma_t; + +typedef struct drm32_agp_buffer { +/*?*/ int size; +/*?*/ int handle; +/*?*/ int type; +/*?*/ int physical; +} drm32_agp_buffer_t; + +typedef struct drm32_agp_info { + int agp_version_major; + int agp_version_minor; +/*?*/ unsigned int mode; +/*?*/ unsigned int aperture_base; /* physical address */ +/*?*/ unsigned int aperture_size; /* bytes */ +/*?*/ unsigned int memory_allowed; /* bytes */ +/*?*/ unsigned int memory_used; + + /* PCI information */ + unsigned short id_vendor; + unsigned short id_device; +} drm32_agp_info_t; + +typedef struct drm32_agp_mode { +/*?*/ unsigned int mode; +} drm32_agp_mode_t; + +typedef struct drm32_agp_binding { +/*?*/ unsigned int handle; /* From drm_agp_buffer */ +/*?*/ unsigned int offset; /* In bytes -- will round to page boundary */ +} drm32_agp_binding_t; + +typedef struct drm32_scatter_gather { +/*?*/ unsigned int size; /* In bytes -- will round to page boundary */ +/*?*/ unsigned int handle; /* Used for mapping / unmapping */ +} drm32_scatter_gather_t; + +struct drm32_wait_vblank_request { + drm_vblank_seq_type_t type; + unsigned int sequence; + unsigned int signal; +}; + +struct drm32_wait_vblank_reply { + drm_vblank_seq_type_t type; + unsigned int sequence; + int tval_sec; + int tval_usec; +}; + +typedef union drm32_wait_vblank { + struct drm32_wait_vblank_request request; + struct drm32_wait_vblank_reply reply; +} drm32_wait_vblank_t; + +static void drm_unregister_ioctl32(void); + +static int ioctl_conversions_successful = 0; + +static int +drm_version_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_version_t *arg32 = (drm32_version_t *) arg; + drm_version_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_version_32_64"); + GET_USER(version_major); + GET_USER(version_minor); + GET_USER(version_patchlevel); + GET_USER(name_len); + GET_USER_P(name); + GET_USER(date_len); + GET_USER_P(date); + GET_USER(desc_len); + GET_USER_P(desc); + + if (err) return -EFAULT; + + SYS_IOCTL; + if (err) return err; + + PUT_USER(version_major); + PUT_USER(version_minor); + PUT_USER(version_patchlevel); + PUT_USER(name_len); +// PUT_USER(name); + PUT_USER(date_len); +// PUT_USER(date); + PUT_USER(desc_len); +// PUT_USER(desc); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + +static int +drm_unique_wr_32_64(unsigned int fd, unsigned cmd, + unsigned long arg, struct file *file) +{ + drm32_unique_t *arg32 = (drm32_unique_t *) arg; + drm_unique_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_unique_wr_32_64"); + GET_USER(unique_len); + GET_USER_P(unique); + + if (err) return -EFAULT; + + SYS_IOCTL; + if (err) return err; + + PUT_USER(unique_len); +// PUT_USER(unique); + DEBUG("done"); + return err ? -EFAULT : 0; +} + +static int +drm_unique_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_unique_t *arg32 = (drm32_unique_t *) arg; + drm_unique_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_unique_w_32_64"); + GET_USER(unique_len); + GET_USER_P(unique); + + if (err) return -EFAULT; + + SYS_IOCTL; + DEBUG("done"); + return err; +} + +static int +drm_addmap_rw_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_map_t *arg32 = (drm32_map_t *) arg; + drm_map_t arg64; + mm_segment_t old_fs; + int err = 0; +// u64 dummy; + + DEBUG("drm_addmap_rw_32_64"); + GET_USER(offset); + GET_USER(size); + GET_USER(type); + GET_USER(flags); +// GET_USER(pub_handle); + GET_USER(mtrr); + + if (err) return -EFAULT; + + SYS_IOCTL; + + if (err) return err; + + PUT_USER(pub_handle); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + +static int +drm_getmap_rw_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_map_t *arg32 = (drm32_map_t *) arg; + drm_map_t arg64; + mm_segment_t old_fs; + int err = 0; +// u64 dummy; + + DEBUG("drm_getmap_rw_32_64"); + GET_USER(offset); + + if (err) return -EFAULT; + + SYS_IOCTL; + + if (err) return err; + + ASSERT32(offset); + PUT_USER(offset); + ASSERT32(size); + PUT_USER(size); + PUT_USER(type); + PUT_USER(flags); + PUT_USER(pub_handle); + PUT_USER(mtrr); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + +static int +drm_map_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_map_t *arg32 = (drm32_map_t *) arg; + drm_map_t arg64; + mm_segment_t old_fs; + int err = 0; +// u64 dummy; + + DEBUG("drm_map_w_32_64"); + GET_USER(offset); + GET_USER(size); + GET_USER(type); + GET_USER(flags); +// GET_USER_P(handle); + GET_USER(mtrr); + + if (err) return -EFAULT; + + SYS_IOCTL; + DEBUG("done"); + return err; +} + +static int +drm_client_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_client_t *arg32 = (drm32_client_t *) arg; + drm_client_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_client_32_64"); + GET_USER(idx); +// GET_USER(auth); +// GET_USER(pid); +// GET_USER(uid); +// GET_USER(magic); +// GET_USER(iocs); + + if (err) return -EFAULT; + + SYS_IOCTL; + if (err) return err; + +// PUT_USER(idx); + PUT_USER(auth); + ASSERT32(pid); + PUT_USER(pid); + ASSERT32(uid); + PUT_USER(uid); + ASSERT32(magic); + PUT_USER(magic); + ASSERT32(iocs); + PUT_USER(iocs); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + +static int +drm_stats_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_stats_t *arg32 = (drm32_stats_t *) arg; + drm_stats_t arg64; + mm_segment_t old_fs; + int err = 0; + int i; + + DEBUG("drm_stats_32_64"); + SYS_IOCTL; + if (err) return err; + + PUT_USER(count); + for (i = 0; i < arg64.count; i ++) { + PUT_USER(data[i].value); + PUT_USER(data[i].type); + } + + DEBUG("done"); + return err ? -EFAULT : 0; +} + +#if 0 +static int +drm_ctx_priv_map_wr_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_ctx_priv_map_t *arg32 = (drm32_ctx_priv_map_t *) arg; + drm_ctx_priv_map_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_ctx_priv_map_wr_32_64"); + GET_USER(ctx_id); +// GET_USER_P(handle); + + if (err) return -EFAULT; + + SYS_IOCTL; + if (err) return err; + +// PUT_USER(ctx_id); + PUT_USER_P(handle); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + +static int +drm_ctx_priv_map_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_ctx_priv_map_t *arg32 = (drm32_ctx_priv_map_t *) arg; + drm_ctx_priv_map_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_ctx_priv_map_w_32_64"); + GET_USER(ctx_id); + GET_USER_P(handle); + + if (err) return -EFAULT; + + SYS_IOCTL; + + DEBUG("done"); + return err; +} +#endif + +static int +drm_ctx_res_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_ctx_res_t *arg32 = (drm32_ctx_res_t *) arg; + drm_ctx_res_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_ctx_res_32_64"); + GET_USER(count); + GET_USER_P(contexts); + + if (err) return -EFAULT; + + SYS_IOCTL; + if (err) return err; + + PUT_USER(count); +// PUT_USER(contexts); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + + +static int +drm_dma_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_dma_t *arg32 = (drm32_dma_t *) arg; + drm_dma_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_dma_32_64"); + GET_USER(context); + GET_USER(send_count); + GET_USER_P(send_indices); + GET_USER_P(send_sizes); + GET_USER(flags); + GET_USER(request_count); + GET_USER(request_size); + GET_USER_P(request_indices); + GET_USER_P(request_sizes); + GET_USER(granted_count); + + if (err) return -EFAULT; + + SYS_IOCTL; + if (err) return err; + + PUT_USER(context); + PUT_USER(send_count); +// PUT_USER(send_indices); +// PUT_USER(send_sizes); + PUT_USER(flags); + PUT_USER(request_count); + PUT_USER(request_size); +// PUT_USER(request_indices); +// PUT_USER(request_sizes); + PUT_USER(granted_count); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + +static int +drm_buf_desc_wr_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_buf_desc_t *arg32 = (drm32_buf_desc_t *) arg; + drm_buf_desc_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_buf_desc_wr_32_64"); + GET_USER(count); + GET_USER(size); + GET_USER(low_mark); + GET_USER(high_mark); + GET_USER(flags); + GET_USER(agp_start); + + if (err) return -EFAULT; + + SYS_IOCTL; + if (err) return err; + + PUT_USER(count); + PUT_USER(size); +// PUT_USER(low_mark); +// PUT_USER(high_mark); +// PUT_USER(flags); +// PUT_USER(agp_start); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + +static int +drm_buf_desc_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_buf_desc_t *arg32 = (drm32_buf_desc_t *) arg; + drm_buf_desc_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_buf_desc_w_32_64"); + GET_USER(count); + GET_USER(size); + GET_USER(low_mark); + GET_USER(high_mark); + GET_USER(flags); + GET_USER(agp_start); + + if (err) return -EFAULT; + + SYS_IOCTL; + + DEBUG("done"); + return err; +} + +static int +drm_buf_info_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_buf_info_t *arg32 = (drm32_buf_info_t *) arg; + drm_buf_info_t arg64; + mm_segment_t old_fs; + int err = 0; + drm32_buf_desc_t *list32 = (drm32_buf_desc_t*)(u64)arg32->list; + drm_buf_desc_t *list64; + int i; + + DEBUG("drm_buf_info_32_64"); + list64 = K_ALLOC(arg32->count * sizeof (drm_buf_desc_t)); + if (!list64) return -EFAULT; + + GET_USER(count); + arg64.list = list64; + + for (i = 0 ; i < arg32->count; i ++) { + err |= get_user(list64[i].count,&list32[i].count); + err |= get_user(list64[i].size,&list32[i].size); + err |= get_user(list64[i].high_mark,&list32[i].low_mark); + err |= get_user(list64[i].flags,&list32[i].flags); + err |= get_user(list64[i].agp_start,&list32[i].agp_start); + } + + if (err) { + K_FREE(list64); + return -EFAULT; + } + + SYS_IOCTL; + if (err) { + K_FREE(list64); + return err; + } + + + for (i = 0 ; i < arg32->count; i ++) { + err |= put_user(list64[i].count,&list32[i].count); + err |= put_user(list64[i].size,&list32[i].size); + err |= put_user(list64[i].low_mark,&list32[i].low_mark); + err |= put_user(list64[i].high_mark,&list32[i].high_mark); + err |= put_user(list64[i].flags,&list32[i].flags); +// err |= put_user(list64[i].agp_start,&list32[i].agp_start); + } + PUT_USER(count); + + K_FREE(list64); + + DEBUG("done"); + return err ? -EFAULT : 0; +} + + +static int +drm_buf_map_32_64(unsigned int fd, unsigned cmd, + unsigned long arg, struct file *file) +{ + drm32_buf_map_t *arg32 = (drm32_buf_map_t *) arg; + drm_buf_map_t arg64; + mm_segment_t old_fs; + int err = 0; + drm32_buf_pub_t *list32 = (drm32_buf_pub_t*)(unsigned long)arg32->list; + drm_buf_pub_t *list64; + int count, i; + u64 dummy; + + DEBUG("drm_buf_map_32_64"); + list64 = K_ALLOC(arg32->count * sizeof (drm_buf_pub_t)); + if (!list64) return -EFAULT; + + GET_USER(count); + GET_USER_P(virtual); + arg64.list = list64; +#if 0 + for (i = 0 ; i < arg32->count; i ++) { + err |= get_user(list64[i].idx,&list32[i].idx); + err |= get_user(list64[i].total,&list32[i].total); + err |= get_user(list64[i].used,&list32[i].used); + err |= get_user(dummy,&list32[i].address); + list64[i].address = (void *)dummy; + } +#endif + if (err) { + K_FREE(list64); + return -EFAULT; + } + + SYS_IOCTL; + if (err) { + K_FREE(list64); + return err; + } + + count = arg32->count < arg64.count ? arg32->count : arg64.count; + PUT_USER(count); + PUT_USER_P(virtual); + + for (i = 0 ; i < count; i ++) { + err |= put_user(list64[i].idx,&list32[i].idx); + err |= put_user(list64[i].total,&list32[i].total); + err |= put_user(list64[i].used,&list32[i].used); + dummy = (u64)list64[i].address; + err |= put_user((u32)dummy,&list32[i].address); + } + K_FREE(list64); + + return err ? -EFAULT : 0; +} + +static int +drm_buf_free_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_buf_free_t *arg32 = (drm32_buf_free_t *) arg; + drm_buf_free_t arg64; + mm_segment_t old_fs; + int err = 0; + int i; + int *list32 = (int *)(unsigned long)arg32->list; + + DEBUG("drm_buf_free_w_32_64"); + GET_USER(count); + for (i = 0; i < arg32->count; i++) + err |= get_user(arg64.list[i],&list32[i]); + + + if (err) return -EFAULT; + + SYS_IOCTL; + + DEBUG("done"); + return err; +} + +static int +drm_agp_info_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_agp_info_t *arg32 = (drm32_agp_info_t *) arg; + drm_agp_info_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_agp_info_32_64"); + + SYS_IOCTL; + if (err) return err; + + PUT_USER(agp_version_major); + PUT_USER(agp_version_minor); + PUT_USER(mode); + ASSERT32(aperture_base); + PUT_USER(aperture_base); + ASSERT32(aperture_size); + PUT_USER(aperture_size); + ASSERT32(memory_allowed); + PUT_USER(memory_allowed); + ASSERT32(memory_used); + PUT_USER(memory_used); + PUT_USER(id_vendor); + PUT_USER(id_device); + + return err ? -EFAULT : 0; +} + +static int +drm_agp_buffer_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_agp_buffer_t *arg32 = (drm32_agp_buffer_t *) arg; + drm_agp_buffer_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_agp_buffer_w_32_64"); + GET_USER(handle); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_agp_buffer_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_agp_buffer_t *arg32 = (drm32_agp_buffer_t *) arg; + drm_agp_buffer_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_agp_buffer_32_64"); + GET_USER(size); + GET_USER(handle); + GET_USER(type); + GET_USER(physical); + + if (err) return -EFAULT; + + SYS_IOCTL; + if (err) return err; + + ASSERT32(size); + PUT_USER(size); + ASSERT32(handle); + PUT_USER(handle); + ASSERT32(type); + PUT_USER(type); +// PUT_USER(physical); + + return err ? -EFAULT : 0; +} + +static int +drm_agp_mode_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_agp_mode_t *arg32 = (drm32_agp_mode_t *) arg; + drm_agp_mode_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_agp_mode_w_32_64"); + GET_USER(mode); + + if (err) return -EFAULT; + + SYS_IOCTL; + + return err; +} + +static int +drm_agp_binding_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_agp_binding_t *arg32 = (drm32_agp_binding_t *) arg; + drm_agp_binding_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_agp_binding_w_32_64"); + GET_USER(handle); + GET_USER(offset); + + if (err) return -EFAULT; + + SYS_IOCTL; + + return err; +} + +static int +drm32_scatter_gather_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_scatter_gather_t *arg32 = (drm32_scatter_gather_t *) arg; + drm_scatter_gather_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_agp_scatter_gather_w_32_64"); + + GET_USER(size); + GET_USER(handle); + + if (err) return -EFAULT; + + SYS_IOCTL; + + return err; +} + +static int +drm32_wait_vblank_rw_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_wait_vblank_t *arg32 = (drm32_wait_vblank_t *) arg; + drm_wait_vblank_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("drm_agp_scatter_gather_rw_32_64"); + + err |= get_user(arg64.request.type,&arg32->request.type); + err |= get_user(arg64.request.sequence,&arg32->request.sequence); + err |= get_user(arg64.request.signal,&arg32->request.signal); + + if (err) return -EFAULT; + + SYS_IOCTL; + + err |= put_user(arg64.reply.type,&arg32->reply.type); + err |= put_user(arg64.reply.sequence,&arg32->reply.sequence); + ASSERT32(reply.tval_sec); + err |= put_user(arg64.reply.tval_sec,&arg32->reply.tval_sec); + ASSERT32(reply.tval_usec); + err |= put_user(arg64.reply.tval_usec,&arg32->reply.tval_usec); + + return err ? -EFAULT : 0; +} + +int +drm32_default_handler(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + return SYS_IOCTL_FUNC(fd,cmd,arg); +} + + +static int +drm_register_ioctl32(void) +{ + int err; + REG_IOCTL32(DRM_IOCTL_VERSION_32,drm_version_32_64); + REG_IOCTL32(DRM_IOCTL_GET_UNIQUE_32,drm_unique_wr_32_64); + REG_IOCTL32(DRM_IOCTL_GET_MAP_32,drm_getmap_rw_32_64); + REG_IOCTL32(DRM_IOCTL_GET_CLIENT_32,drm_client_32_64); + REG_IOCTL32(DRM_IOCTL_GET_STATS_32,drm_stats_32_64); + REG_IOCTL32(DRM_IOCTL_SET_UNIQUE_32,drm_unique_w_32_64); + REG_IOCTL32(DRM_IOCTL_ADD_MAP_32,drm_addmap_rw_32_64); + REG_IOCTL32(DRM_IOCTL_ADD_BUFS_32,drm_buf_desc_wr_32_64); + REG_IOCTL32(DRM_IOCTL_MARK_BUFS_32,drm_buf_desc_w_32_64); + REG_IOCTL32(DRM_IOCTL_INFO_BUFS_32,drm_buf_info_32_64); + REG_IOCTL32(DRM_IOCTL_MAP_BUFS_32,drm_buf_map_32_64); + REG_IOCTL32(DRM_IOCTL_FREE_BUFS_32,drm_buf_free_w_32_64); + REG_IOCTL32(DRM_IOCTL_RM_MAP_32,drm_map_w_32_64); +#if 0 + REG_IOCTL32(DRM_IOCTL_SET_SAREA_CTX_32,drm_ctx_priv_map_w_32_64); + REG_IOCTL32(DRM_IOCTL_GET_SAREA_CTX_32,drm_ctx_priv_map_wr_32_64); +#endif + REG_IOCTL32(DRM_IOCTL_RES_CTX_32,drm_ctx_res_32_64) + REG_IOCTL32(DRM_IOCTL_DMA_32,drm_dma_32_64); + REG_IOCTL32(DRM_IOCTL_AGP_ENABLE_32,drm_agp_mode_w_32_64); + REG_IOCTL32(DRM_IOCTL_AGP_INFO_32,drm_agp_info_32_64); + REG_IOCTL32(DRM_IOCTL_AGP_ALLOC_32,drm_agp_buffer_32_64); + REG_IOCTL32(DRM_IOCTL_AGP_FREE_32,drm_agp_buffer_w_32_64); + REG_IOCTL32(DRM_IOCTL_AGP_BIND_32,drm_agp_binding_w_32_64); + REG_IOCTL32(DRM_IOCTL_AGP_UNBIND_32,drm_agp_binding_w_32_64); + REG_IOCTL32(DRM_IOCTL_SG_ALLOC_32,drm32_scatter_gather_w_32_64); + REG_IOCTL32(DRM_IOCTL_SG_FREE_32,drm32_scatter_gather_w_32_64); + REG_IOCTL32(DRM_IOCTL_WAIT_VBLANK_32,drm32_wait_vblank_rw_32_64); + REG_IOCTL32(DRM_IOCTL_GET_MAGIC,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_IRQ_BUSID,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_SET_VERSION,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_AUTH_MAGIC,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_BLOCK,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_UNBLOCK,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_CONTROL,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_SET_SAREA_CTX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_GET_SAREA_CTX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_ADD_CTX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RM_CTX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_MOD_CTX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_GET_CTX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_SWITCH_CTX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_NEW_CTX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_ADD_DRAW,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RM_DRAW,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_LOCK,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_UNLOCK,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_FINISH,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_AGP_ACQUIRE,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_AGP_RELEASE,drm32_default_handler); + + ioctl_conversions_successful = 1; + + return 0; + failed: + return -1; +} + + +static void +drm_unregister_ioctl32(void) +{ + UNREG_IOCTL32(DRM_IOCTL_VERSION_32); + UNREG_IOCTL32(DRM_IOCTL_GET_UNIQUE_32); + UNREG_IOCTL32(DRM_IOCTL_GET_CLIENT_32); +#if 0 + UNREG_IOCTL32(DRM_IOCTL_SET_SAREA_CTX_32); + UNREG_IOCTL32(DRM_IOCTL_GET_SAREA_CTX_32); +#endif + UNREG_IOCTL32(DRM_IOCTL_RES_CTX_32); + UNREG_IOCTL32(DRM_IOCTL_DMA_32); + + UNREG_IOCTL32(DRM_IOCTL_INFO_BUFS_32); + UNREG_IOCTL32(DRM_IOCTL_MAP_BUFS_32); + UNREG_IOCTL32(DRM_IOCTL_FREE_BUFS_32); + + UNREG_IOCTL32(DRM_IOCTL_GET_MAP_32); + UNREG_IOCTL32(DRM_IOCTL_GET_STATS_32); + UNREG_IOCTL32(DRM_IOCTL_SET_UNIQUE_32); + UNREG_IOCTL32(DRM_IOCTL_ADD_MAP_32); + UNREG_IOCTL32(DRM_IOCTL_RM_MAP_32); + UNREG_IOCTL32(DRM_IOCTL_ADD_BUFS_32); + UNREG_IOCTL32(DRM_IOCTL_MARK_BUFS_32); + UNREG_IOCTL32(DRM_IOCTL_AGP_ALLOC_32); + UNREG_IOCTL32(DRM_IOCTL_AGP_FREE_32); + UNREG_IOCTL32(DRM_IOCTL_AGP_INFO_32); + UNREG_IOCTL32(DRM_IOCTL_AGP_ENABLE_32); + UNREG_IOCTL32(DRM_IOCTL_AGP_BIND_32); + UNREG_IOCTL32(DRM_IOCTL_AGP_UNBIND_32); + UNREG_IOCTL32(DRM_IOCTL_SG_ALLOC_32); + UNREG_IOCTL32(DRM_IOCTL_SG_FREE_32); + UNREG_IOCTL32(DRM_IOCTL_WAIT_VBLANK_32); + + UNREG_IOCTL32(DRM_IOCTL_GET_MAGIC); + UNREG_IOCTL32(DRM_IOCTL_IRQ_BUSID); + UNREG_IOCTL32(DRM_IOCTL_SET_VERSION); + UNREG_IOCTL32(DRM_IOCTL_AUTH_MAGIC); + UNREG_IOCTL32(DRM_IOCTL_BLOCK); + UNREG_IOCTL32(DRM_IOCTL_UNBLOCK); + UNREG_IOCTL32(DRM_IOCTL_CONTROL); + UNREG_IOCTL32(DRM_IOCTL_SET_SAREA_CTX); + UNREG_IOCTL32(DRM_IOCTL_GET_SAREA_CTX); + UNREG_IOCTL32(DRM_IOCTL_ADD_CTX); + UNREG_IOCTL32(DRM_IOCTL_RM_CTX); + UNREG_IOCTL32(DRM_IOCTL_MOD_CTX); + UNREG_IOCTL32(DRM_IOCTL_GET_CTX); + UNREG_IOCTL32(DRM_IOCTL_SWITCH_CTX); + UNREG_IOCTL32(DRM_IOCTL_NEW_CTX); + UNREG_IOCTL32(DRM_IOCTL_ADD_DRAW); + UNREG_IOCTL32(DRM_IOCTL_RM_DRAW); + UNREG_IOCTL32(DRM_IOCTL_LOCK); + UNREG_IOCTL32(DRM_IOCTL_UNLOCK); + UNREG_IOCTL32(DRM_IOCTL_FINISH); + UNREG_IOCTL32(DRM_IOCTL_AGP_ACQUIRE); + UNREG_IOCTL32(DRM_IOCTL_AGP_RELEASE); +} + +int +drm32_register(void) +{ + if (ioctl_conversions_successful == 0) + return 0; +#if 0 && defined(MODULE) + MOD_INC_USE_COUNT; +#endif + return 1; +} + +void +drm32_unregister(void) +{ +#if 0 && defined(MODULE) + if (ioctl_conversions_successful == 0) + return; + MOD_DEC_USE_COUNT; +#endif + return; +} + +static int +__init drm32_init( void ) +{ + return drm_register_ioctl32(); +} + +static void +__exit drm32_cleanup (void) +{ + drm_unregister_ioctl32(); +} + + +module_init(drm32_init); +module_exit(drm32_cleanup); + +EXPORT_SYMBOL(drm32_register); +EXPORT_SYMBOL(drm32_unregister); +EXPORT_SYMBOL(drm32_default_handler); + +#endif diff -rNu ../unpatched/drm/linux-core/drm_ioctl32.h drm/linux-core/drm_ioctl32.h --- ../unpatched/drm/linux-core/drm_ioctl32.h 1970-01-01 01:00:00.000000000 +0100 +++ drm/linux-core/drm_ioctl32.h 2005-04-08 14:16:28.000000000 +0200 @@ -0,0 +1,86 @@ +/* + * Copyright 2003, 2004, Egbert Eich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * EGBERT EICH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Egbert Eich shall not + * be used in advertising or otherwise to promote the sale, use or other deal- + *ings in this Software without prior written authorization from Egbert Eich. + * + */ +#ifndef _DRM_IOCTL32_H +# define _DRM_IOCTL32_H + +# ifdef IOCTL32_PRIVATE + +#define DEBUG(x) /**/ /* printk(KERN_DEBUG"%s\n",x) */ + +#define SYS_IOCTL_FUNC sys_ioctl + +# define GET_USER_ARGS(x32,x64,elem) err |= get_user(x64.elem,&x32->elem) +# define PUT_USER_ARGS(x32,x64,elem) err |= put_user(x64.elem,&x32->elem) +# define GET_USER(elem) GET_USER_ARGS(arg32,arg64,elem) +# define PUT_USER(elem) PUT_USER_ARGS(arg32,arg64,elem) +# define GET_USER_P_ARGS(x32,x64,elem) do { \ + err |= get_user(dummy,&x32->elem); \ + x64.elem = (void *) dummy; \ +} while (0); +# define PUT_USER_P_ARGS(x32,x64,elem) do { \ + dummy = (u64) x64.elem; \ + err |= put_user((u32)dummy,&x32->elem); \ +} while (0); + +# define GET_USER_P(elem) GET_USER_P_ARGS(arg32,arg64,elem) +# define PUT_USER_P(elem) PUT_USER_P_ARGS(arg32,arg64,elem) + +# define SYS_IOCTL do { \ + old_fs = get_fs(); \ + set_fs(KERNEL_DS); \ + DEBUG("SYS_IOCTL_FUNC called"); \ + err = SYS_IOCTL_FUNC(fd,cmd,(unsigned long)&arg64); \ + DEBUG("SYS_IOCTL_FUNC done"); \ + set_fs(old_fs); \ + } while (0); + +#define DEBUG_IOCTL32(nr) \ + printk(KERN_WARNING "Registering IOCTL32: %lx\n",nr); + +# define REG_IOCTL32(nr,c_func) \ + err = register_ioctl32_conversion(nr,c_func); \ + if (err) goto failed; + +# define UNREG_IOCTL32(nr) \ + unregister_ioctl32_conversion(nr); + +# define K_ALLOC(x) kmalloc(x,GFP_KERNEL) +# define K_FREE(x) kfree(x) + +# define ASSERT32(x) do { \ + if (arg64.x & 0xFFFFFFFF00000000) \ + printk(KERN_WARNING "ioctl32: var " #x " is > 32bit in ioctl(0x%x)\n",cmd); \ + } while (0) + +extern int drm32_default_handler(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file); + +# endif + +extern int drm32_register(void); +extern void drm32_unregister(void); + +#endif diff -rNu ../unpatched/drm/linux-core/drm_os_linux.h drm/linux-core/drm_os_linux.h --- ../unpatched/drm/linux-core/drm_os_linux.h 2005-02-08 05:17:14.000000000 +0100 +++ drm/linux-core/drm_os_linux.h 2005-03-24 18:43:46.000000000 +0100 @@ -5,6 +5,9 @@ #include /* For task queue support */ #include +#ifdef CONFIG_COMPAT +# define CONFIG_IOCTL32 +#endif /** File pointer type */ #define DRMFILE struct file * diff -rNu ../unpatched/drm/linux-core/drm_scatter.c drm/linux-core/drm_scatter.c --- ../unpatched/drm/linux-core/drm_scatter.c 2004-10-18 16:16:41.000000000 +0200 +++ drm/linux-core/drm_scatter.c 2005-03-24 18:47:25.000000000 +0100 @@ -58,6 +58,12 @@ 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) { @@ -109,7 +115,7 @@ } memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr)); - entry->virtual = vmalloc_32(pages << PAGE_SHIFT); + entry->virtual = vmalloc(pages << PAGE_SHIFT); if (!entry->virtual) { drm_free(entry->busaddr, entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); @@ -125,12 +131,12 @@ */ 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; diff -rNu ../unpatched/drm/linux-core/drm_vm.c drm/linux-core/drm_vm.c --- ../unpatched/drm/linux-core/drm_vm.c 2005-01-12 17:07:49.000000000 +0100 +++ drm/linux-core/drm_vm.c 2005-04-04 21:57:47.000000000 +0200 @@ -69,13 +69,13 @@ map = r_list->map; if (!map) continue; - if (map->offset == VM_OFFSET(vma)) + if (map->pub_handle == 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; @@ -309,7 +309,7 @@ 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); @@ -489,7 +489,7 @@ lock_kernel(); dev = priv->head->dev; dma = dev->dma; - DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", + DRM_DEBUG( "start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); /* Length must match exact page count */ @@ -547,7 +547,7 @@ drm_device_t *dev = priv->head->dev; drm_map_t *map = NULL; drm_map_list_t *r_list; - unsigned long offset = 0; + unsigned long vm_offset = 0, offset = 0; struct list_head *list; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", @@ -576,15 +576,12 @@ 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)) - break; + if (map->pub_handle == VM_OFFSET(vma)) + break; } if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) @@ -609,6 +606,8 @@ #endif } + /* fetch real vm_offset from map structure */ + vm_offset = dev->driver->get_map_ofs(map); switch (map->type) { case _DRM_AGP: if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) { @@ -626,7 +625,7 @@ /* fall through to _DRM_FRAME_BUFFER... */ case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: - if (VM_OFFSET(vma) >= __pa(high_memory)) { + if (vm_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; @@ -646,12 +645,12 @@ 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, + vm_offset + offset, vma->vm_end - vma->vm_start, vma->vm_page_prot, 0)) #else if (remap_pfn_range(vma, vma->vm_start, - (VM_OFFSET(vma) + offset) >> PAGE_SHIFT, + (vm_offset + offset) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) #endif @@ -659,7 +658,7 @@ 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, vm_offset + offset); vma->vm_ops = &drm_vm_ops; break; case _DRM_SHM: diff -rNu ../unpatched/drm/linux-core/mga_drv.c drm/linux-core/mga_drv.c --- ../unpatched/drm/linux-core/mga_drv.c 2004-11-09 17:58:02.000000000 +0100 +++ drm/linux-core/mga_drv.c 2005-03-24 18:58:20.000000000 +0100 @@ -120,11 +120,17 @@ static int __init mga_init(void) { driver.num_ioctls = mga_max_ioctl; +#ifdef CONFIG_IOCTL32 + mga_register_ioctl32(); +#endif return drm_init(&driver, pciidlist); } static void __exit mga_exit(void) { +#ifdef CONFIG_IOCTL32 + mga_unregister_ioctl32(); +#endif drm_exit(&driver); } diff -rNu ../unpatched/drm/linux-core/mga_ioctl32.c drm/linux-core/mga_ioctl32.c --- ../unpatched/drm/linux-core/mga_ioctl32.c 1970-01-01 01:00:00.000000000 +0100 +++ drm/linux-core/mga_ioctl32.c 2005-03-24 19:00:20.000000000 +0100 @@ -0,0 +1,189 @@ +/* + * Copyright 2003, 2004, Egbert Eich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * EGBERT EICH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Egbert Eich shall not + * be used in advertising or otherwise to promote the sale, use or other deal- + *ings in this Software without prior written authorization from Egbert Eich. + * + */ +#include +#include +#include +#include +#if 0 +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +#ifdef __x86_64__ + +#include +#include "drm.h" +#include "mga_drm.h" +#define IOCTL32_PRIVATE +#include "drm_ioctl32.h" + + +typedef struct drm32_mga_init { + int func; + u32 sarea_priv_offset; + int chipset; + int sgram; + unsigned int maccess; + unsigned int fb_cpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_cpp; + unsigned int depth_offset, depth_pitch; + unsigned int texture_offset[MGA_NR_TEX_HEAPS]; + unsigned int texture_size[MGA_NR_TEX_HEAPS]; + u32 fb_offset; + u32 mmio_offset; + u32 status_offset; + u32 warp_offset; + u32 primary_offset; + u32 buffers_offset; +} drm32_mga_init_t; + +typedef struct drm32_mga_getpram { + int param; + u32 value; +} drm32_mga_getparam_t; + +#define DRM_IOCTL_MGA_INIT32 DRM_IOW( 0x40, drm32_mga_init_t) +#define DRM_IOCTL_MGA_GETPARAM32 DRM_IOWR(0x49, drm32_mga_getparam_t) + +void mga_unregister_ioctl32(void); + +static int +mga_init_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_mga_init_t *arg32 = (drm32_mga_init_t *) arg; + drm_mga_init_t arg64; + mm_segment_t old_fs; + int err = 0; + int i; + + DEBUG("mga_init_w_32_64"); + GET_USER(func); + GET_USER(sarea_priv_offset); + GET_USER(chipset); + GET_USER(sgram); + GET_USER(maccess); + GET_USER(fb_cpp); + GET_USER(front_offset); + GET_USER(front_pitch); + GET_USER(back_offset); + GET_USER(back_pitch); + GET_USER(depth_cpp); + GET_USER(depth_offset); + GET_USER(depth_pitch); + + for (i = 0; i < MGA_NR_TEX_HEAPS; i++) { + GET_USER(texture_offset[i]); + GET_USER(texture_size[i]); + } + + GET_USER(fb_offset); + GET_USER(mmio_offset); + GET_USER(status_offset); + GET_USER(warp_offset); + GET_USER(primary_offset); + GET_USER(buffers_offset); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +mga_getparam_wr_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_mga_getparam_t *arg32 = (drm32_mga_getparam_t *) arg; + drm_mga_getparam_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("mga_getparam_wr_32_64"); + GET_USER(param); + GET_USER_P(value); + + if (err) return -EFAULT; + + SYS_IOCTL; + DEBUG("done"); + + return err; +} + +int +mga_register_ioctl32(void) +{ + int err; + + if (!drm32_register()) return -1; + REG_IOCTL32(DRM_IOCTL_MGA_INIT32,mga_init_w_32_64); + REG_IOCTL32(DRM_IOCTL_MGA_GETPARAM32,mga_getparam_wr_32_64); + + REG_IOCTL32(DRM_IOCTL_MGA_FLUSH,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_MGA_RESET,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_MGA_SWAP,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_MGA_CLEAR,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_MGA_VERTEX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_MGA_INDICES,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_MGA_ILOAD,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_MGA_BLIT,drm32_default_handler); + + return 0; + failed: + mga_unregister_ioctl32(); + return -1; +} + +void +mga_unregister_ioctl32(void) +{ + UNREG_IOCTL32(DRM_IOCTL_MGA_INIT32); + UNREG_IOCTL32(DRM_IOCTL_MGA_GETPARAM32); + UNREG_IOCTL32(DRM_IOCTL_MGA_FLUSH); + UNREG_IOCTL32(DRM_IOCTL_MGA_RESET); + UNREG_IOCTL32(DRM_IOCTL_MGA_RESET); + UNREG_IOCTL32(DRM_IOCTL_MGA_SWAP); + UNREG_IOCTL32(DRM_IOCTL_MGA_CLEAR); + UNREG_IOCTL32(DRM_IOCTL_MGA_VERTEX); + UNREG_IOCTL32(DRM_IOCTL_MGA_INDICES); + UNREG_IOCTL32(DRM_IOCTL_MGA_INDICES); + UNREG_IOCTL32(DRM_IOCTL_MGA_ILOAD); + UNREG_IOCTL32(DRM_IOCTL_MGA_BLIT); + + drm32_unregister(); +} + +#endif diff -rNu ../unpatched/drm/linux-core/r128_drv.c drm/linux-core/r128_drv.c --- ../unpatched/drm/linux-core/r128_drv.c 2004-11-06 17:41:24.000000000 +0100 +++ drm/linux-core/r128_drv.c 2005-03-24 19:04:48.000000000 +0100 @@ -116,12 +116,17 @@ static int __init r128_init(void) { driver.num_ioctls = r128_max_ioctl; - +#ifdef CONFIG_IOCTL32 + r128_register_ioctl32(); +#endif return drm_init(&driver, pciidlist); } static void __exit r128_exit(void) { +#ifdef CONFIG_IOCTL32 + r128_unregister_ioctl32(); +#endif drm_exit(&driver); } diff -rNu ../unpatched/drm/linux-core/r128_ioctl32.c drm/linux-core/r128_ioctl32.c --- ../unpatched/drm/linux-core/r128_ioctl32.c 1970-01-01 01:00:00.000000000 +0100 +++ drm/linux-core/r128_ioctl32.c 2005-04-08 14:54:32.000000000 +0200 @@ -0,0 +1,265 @@ +/* + * Copyright 2003, 2004, Egbert Eich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * EGBERT EICH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Egbert Eich shall not + * be used in advertising or otherwise to promote the sale, use or other deal- + *ings in this Software without prior written authorization from Egbert Eich. + * + */ +#include +#include +#include +#include +#if 0 +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +#ifdef __x86_64__ + +#include +#include "drm.h" +#include "r128_drm.h" +#define IOCTL32_PRIVATE +#include "drm_ioctl32.h" + +#define DRM_IOCTL_R128_INIT32 DRM_IOW( 0x40, drm32_r128_init_t) +#define DRM_IOCTL_R128_DEPTH32 DRM_IOW( 0x4c, drm32_r128_depth_t) +#define DRM_IOCTL_R128_STIPPLE32 DRM_IOW( 0x4d, drm32_r128_stipple_t) +#define DRM_IOCTL_R128_GETPARAM32 DRM_IOWR( 0x52, drm32_r128_getparam_t) + +typedef struct drm32_r128_init { + int func; + unsigned int sarea_priv_offset; + int is_pci; + int cce_mode; + int cce_secure; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + unsigned int span_offset; + + unsigned int fb_offset; + unsigned int mmio_offset; + unsigned int ring_offset; + unsigned int ring_rptr_offset; + unsigned int buffers_offset; + unsigned int agp_textures_offset; +} drm32_r128_init_t; + +typedef struct drm32_r128_depth { + int func; + int n; + u32 x; + u32 y; + u32 buffer; + u32 mask; +} drm32_r128_depth_t; + +typedef struct drm32_r128_stipple { + u32 mask; +} drm32_r128_stipple_t; + +typedef struct drm32_r128_getparam { + int param; + u32 value; +} drm32_r128_getparam_t; + +static int +drm_128_init_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_r128_init_t *arg32 = (drm32_r128_init_t *) arg; + drm_r128_init_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("r128_init_32_64"); + + GET_USER(func); + GET_USER(sarea_priv_offset); + GET_USER(is_pci); + GET_USER(cce_mode); + GET_USER(cce_secure); + GET_USER(ring_size); + GET_USER(usec_timeout); + GET_USER(fb_bpp); + GET_USER(front_offset); + GET_USER(front_pitch); + GET_USER(back_offset); + GET_USER(back_pitch); + GET_USER(depth_bpp); + GET_USER(depth_offset); + GET_USER(depth_pitch); + GET_USER(span_offset); + GET_USER(fb_offset); + GET_USER(mmio_offset); + GET_USER(ring_offset); + GET_USER(ring_rptr_offset); + GET_USER(buffers_offset); + GET_USER(agp_textures_offset); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_128_depth_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_r128_depth_t *arg32 = (drm32_r128_depth_t *) arg; + drm_r128_depth_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("r128_depth_32_64"); + + GET_USER(func); + GET_USER(n); + GET_USER_P(x); + GET_USER_P(y); + GET_USER_P(buffer); + GET_USER_P(mask); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_128_stipple_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_r128_stipple_t *arg32 = (drm32_r128_stipple_t *) arg; + drm_r128_stipple_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("r128_stipple_32_64"); + + GET_USER_P(mask); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_128_getparam_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_r128_getparam_t *arg32 = (drm32_r128_getparam_t *) arg; + drm_r128_getparam_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("r128_getparam_wr_32_64"); + GET_USER(param); + GET_USER_P(value); + + if (err) return -EFAULT; + + SYS_IOCTL; + DEBUG("done"); + + return err; +} + + +void +r128_unregister_ioctl32(void); + +int +r128_register_ioctl32(void) +{ + int err; + + if (!drm32_register()) return -1; + REG_IOCTL32(DRM_IOCTL_R128_INIT32, drm_128_init_32_64); + REG_IOCTL32(DRM_IOCTL_R128_DEPTH32, drm_128_depth_32_64); + REG_IOCTL32(DRM_IOCTL_R128_STIPPLE32, drm_128_stipple_32_64); + REG_IOCTL32(DRM_IOCTL_R128_GETPARAM32, drm_128_getparam_32_64); + + REG_IOCTL32(DRM_IOCTL_R128_CCE_START, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_CCE_STOP, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_CCE_RESET, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_CCE_IDLE, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_RESET, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_SWAP, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_CLEAR, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_VERTEX, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_INDICES, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_BLIT, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_INDIRECT, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_FULLSCREEN, drm32_default_handler); +// REG_IOCTL32(DRM_IOCTL_R128_CLEAR2, drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_R128_FLIP, drm32_default_handler); + + return 0; + failed: + r128_unregister_ioctl32(); + return -1; +} + +void +r128_unregister_ioctl32(void) +{ + UNREG_IOCTL32(DRM_IOCTL_R128_INIT32); + UNREG_IOCTL32(DRM_IOCTL_R128_DEPTH32); + UNREG_IOCTL32(DRM_IOCTL_R128_STIPPLE32); + UNREG_IOCTL32(DRM_IOCTL_R128_GETPARAM32); + + UNREG_IOCTL32(DRM_IOCTL_R128_CCE_START); + UNREG_IOCTL32(DRM_IOCTL_R128_CCE_STOP); + UNREG_IOCTL32(DRM_IOCTL_R128_CCE_RESET); + UNREG_IOCTL32(DRM_IOCTL_R128_CCE_IDLE); + UNREG_IOCTL32(DRM_IOCTL_R128_RESET); + UNREG_IOCTL32(DRM_IOCTL_R128_SWAP); + UNREG_IOCTL32(DRM_IOCTL_R128_CLEAR); + UNREG_IOCTL32(DRM_IOCTL_R128_VERTEX); + UNREG_IOCTL32(DRM_IOCTL_R128_INDICES); + UNREG_IOCTL32(DRM_IOCTL_R128_BLIT); + UNREG_IOCTL32(DRM_IOCTL_R128_INDIRECT); + UNREG_IOCTL32(DRM_IOCTL_R128_FULLSCREEN); +// UNREG_IOCTL32(DRM_IOCTL_R128_CLEAR2); + UNREG_IOCTL32(DRM_IOCTL_R128_FLIP); + + drm32_unregister(); +} + +#endif diff -rNu ../unpatched/drm/linux-core/radeon_drv.c drm/linux-core/radeon_drv.c --- ../unpatched/drm/linux-core/radeon_drv.c 2005-01-30 00:05:35.000000000 +0100 +++ drm/linux-core/radeon_drv.c 2005-03-24 20:12:59.000000000 +0100 @@ -118,12 +118,18 @@ static int __init radeon_init(void) { +#ifdef CONFIG_IOCTL32 + radeon_register_ioctl32(); +#endif driver.num_ioctls = radeon_max_ioctl; return drm_init(&driver, pciidlist); } static void __exit radeon_exit(void) { +#ifdef CONFIG_IOCTL32 + radeon_unregister_ioctl32(); +#endif drm_exit(&driver); } diff -rNu ../unpatched/drm/linux-core/radeon_ioctl32.c drm/linux-core/radeon_ioctl32.c --- ../unpatched/drm/linux-core/radeon_ioctl32.c 1970-01-01 01:00:00.000000000 +0100 +++ drm/linux-core/radeon_ioctl32.c 2005-03-24 19:12:49.000000000 +0100 @@ -0,0 +1,486 @@ +/* + * Copyright 2003, 2004, Egbert Eich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * EGBERT EICH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Egbert Eich shall not + * be used in advertising or otherwise to promote the sale, use or other deal- + *ings in this Software without prior written authorization from Egbert Eich. + * + */ +#include +#include +#include +#include +#if 0 +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +#ifdef __x86_64__ + +#include +#include "drm.h" +#include "radeon_drm.h" +#define IOCTL32_PRIVATE +#include "drm_ioctl32.h" + + + +typedef struct drm32_radeon_clear { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; + u32 depth_boxes; /* drm_radeon_clear_rect_t * */ +} drm32_radeon_clear_t; + +typedef struct drm32_radeon_stipple { + u32 mask; /* unsigned int * */ +} drm32_radeon_stipple_t; + +typedef struct drm32_radeon_tex_image { + unsigned int x, y; /* Blit coordinates */ + unsigned int width, height; + u32 data; /* const void * */ +} drm32_radeon_tex_image_t; + +typedef struct drm32_radeon_texture { + int offset; + int pitch; + int format; + int width; /* Texture image coordinates */ + int height; + u32 image; /* drm_radeon_tex_image_t * */ +} drm32_radeon_texture_t; + +typedef struct drm32_radeon_vertex2 { + int idx; + int discard; + int nr_states; + u32 state; /* drm_radeon_state_t */ + int nr_prims; + u32 prim; /* drm_radeon_prim_t */ +} drm32_radeon_vertex2_t; + +typedef struct drm32_radeon_init { + int func; + unsigned int sarea_priv_offset; + int is_pci; + int cp_mode; + int gart_size; + int ring_size; + int usec_timeout; + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + + u32 fb_offset; + u32 mmio_offset; + u32 ring_offset; + u32 ring_rptr_offset; + u32 buffers_offset; + u32 gart_textures_offset; +} drm32_radeon_init_t; + +typedef struct drm32_radeon_getparam { + int param; + u32 value; +} drm32_radeon_getparam_t; + +typedef struct drm32_radeon_mem_alloc { + int region; + int alignment; + int size; + u32 region_offset; /* offset from start of fb or agp */ +} drm32_radeon_mem_alloc_t; + +typedef struct drm32_radeon_irq_emit { + u32 irq_seq; +} drm32_radeon_irq_emit_t; + +typedef struct drm32_radeon_cmd_buffer { + int bufsz; + u32 buf; + int nbox; + u32 boxes; +} drm32_radeon_cmd_buffer_t; + +typedef struct drm32_radeon_setparam { + unsigned int param; + int64_t value; +} __attribute__((packed)) drm32_radeon_setparam_t; + + +#define DRM_IOCTL_RADEON_CLEAR32 DRM_IOW( 0x48, drm32_radeon_clear_t) +#define DRM_IOCTL_RADEON_STIPPLE32 DRM_IOW( 0x4c, drm32_radeon_stipple_t) +#define DRM_IOCTL_RADEON_TEXTURE32 DRM_IOWR(0x4e, drm32_radeon_texture_t) +#define DRM_IOCTL_RADEON_VERTEX232 DRM_IOW( 0x4f, drm32_radeon_vertex2_t) +#define DRM_IOCTL_RADEON_CP_INIT32 DRM_IOW( 0x40, drm32_radeon_init_t) +#define DRM_IOCTL_RADEON_ALLOC32 DRM_IOWR(0x53, drm32_radeon_mem_alloc_t) +#define DRM_IOCTL_RADEON_IRQ_EMIT32 DRM_IOWR(0x56, drm32_radeon_irq_emit_t) +#define DRM_IOCTL_RADEON_GETPARAM32 DRM_IOWR(0x51, drm32_radeon_getparam_t) +#define DRM_IOCTL_RADEON_CMDBUF32 DRM_IOW(0x50, drm32_radeon_cmd_buffer_t) +#define DRM_IOCTL_RADEON_SETPARAM32 DRM_IOW(0x59, drm32_radeon_setparam_t) + + +void radeon_unregister_ioctl32(void); + +static int +drm_clear_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_clear_t *arg32 = (drm32_radeon_clear_t *) arg; + drm_radeon_clear_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_clear_w_32_64"); + GET_USER(flags); + GET_USER(clear_color); + GET_USER(clear_depth); + GET_USER(color_mask); + GET_USER(depth_mask); + GET_USER_P(depth_boxes); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_stipple_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_stipple_t *arg32 = (drm32_radeon_stipple_t *) arg; + drm_radeon_stipple_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("drm_stipple_w_32_64"); + GET_USER_P(mask); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_texture_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_texture_t *arg32 = (drm32_radeon_texture_t *) arg; + drm_radeon_texture_t arg64; + drm32_radeon_tex_image_t *image32; + drm_radeon_tex_image_t image64; + mm_segment_t old_fs; + int err = 0, err_tmp = 0; + u64 dummy; + + DEBUG("drm_texture_32_64"); + GET_USER(offset); + GET_USER(pitch); + GET_USER(format); + GET_USER(width); + GET_USER(height); + image32 = (drm32_radeon_tex_image_t *)(unsigned long)(arg32->image); + arg64.image = &image64; + err |= get_user(image64.x,&image32->x); + err |= get_user(image64.y,&image32->y); + err |= get_user(image64.width,&image32->width); + err |= get_user(image64.height,&image32->height); + err |= get_user(dummy,&image32->data); + image64.data = (void *)dummy; + + if (err) return -EFAULT; + + SYS_IOCTL; + err_tmp = err; + err = 0; + + PUT_USER(offset); + PUT_USER(pitch); + PUT_USER(format); + PUT_USER(width); + PUT_USER(height); + err |= put_user(image64.x,&image32->x); + err |= put_user(image64.y,&image32->y); + err |= put_user(image64.width,&image32->width); + err |= put_user(image64.height,&image32->height); + dummy = (u64)image64.data; + + err |= put_user((u32)dummy,&image32->data); + return err ? -EFAULT : err_tmp; +} + +static int +drm_vertex2_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_vertex2_t *arg32 = (drm32_radeon_vertex2_t *) arg; + drm_radeon_vertex2_t arg64; + mm_segment_t old_fs; + u64 dummy; + int err = 0; + + DEBUG("drm_vertex2_32_64"); + + GET_USER(idx); + GET_USER(discard); + GET_USER(nr_states); + GET_USER_P(state); + GET_USER(nr_prims); + GET_USER_P(prim); + + if (err) + return -EFAULT; + + SYS_IOCTL; + + return err; +} + +static int +drm_radeon_init_w_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_init_t *arg32 = (drm32_radeon_init_t *) arg; + drm_radeon_init_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("radeon_init_w_32_64"); + + GET_USER(func); + GET_USER(sarea_priv_offset); + GET_USER(is_pci); + GET_USER(cp_mode); + GET_USER(gart_size); + GET_USER(ring_size); + GET_USER(usec_timeout); + GET_USER(fb_bpp); + GET_USER(front_offset); + GET_USER(front_pitch); + GET_USER(back_offset); + GET_USER(back_pitch); + GET_USER(depth_bpp); + GET_USER(depth_offset); + GET_USER(depth_pitch); + GET_USER(fb_offset); + GET_USER(mmio_offset); + GET_USER(ring_offset); + GET_USER(ring_rptr_offset); + GET_USER(buffers_offset); + GET_USER(gart_textures_offset); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_radeon_cmd_buffer_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_cmd_buffer_t *arg32 = (drm32_radeon_cmd_buffer_t *) arg; + drm_radeon_cmd_buffer_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("radeon_cmd_buffer_32_64"); + + GET_USER(bufsz); + GET_USER_P(buf); + GET_USER(nbox); + GET_USER_P(boxes); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_radeon_mem_alloc_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_mem_alloc_t *arg32 = (drm32_radeon_mem_alloc_t *) arg; + drm_radeon_mem_alloc_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("radeon_alloc_32_64"); + + GET_USER(region); + GET_USER(alignment); + GET_USER(size); + GET_USER_P(region_offset); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_radeon_irq_emit_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_irq_emit_t *arg32 = (drm32_radeon_irq_emit_t *) arg; + drm_radeon_irq_emit_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("radeon_irq_emit_32_64"); + + GET_USER_P(irq_seq); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_radeon_getparam_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_getparam_t *arg32 = (drm32_radeon_getparam_t *) arg; + drm_radeon_getparam_t arg64; + mm_segment_t old_fs; + int err = 0; + u64 dummy; + + DEBUG("radeon_getpram_32_64"); + + GET_USER(param); + GET_USER_P(value); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +static int +drm_radeon_setparam_32_64(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + drm32_radeon_setparam_t *arg32 = (drm32_radeon_setparam_t *) arg; + drm_radeon_setparam_t arg64; + mm_segment_t old_fs; + int err = 0; + + DEBUG("radeon_setparam_32_64"); + + GET_USER(param); + GET_USER(value); + + if (err) return -EFAULT; + + SYS_IOCTL; + return err; +} + +int +radeon_register_ioctl32(void) +{ + int err; + + if (!drm32_register()) return -1; + REG_IOCTL32(DRM_IOCTL_RADEON_CLEAR32,drm_clear_w_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_STIPPLE32,drm_stipple_w_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_TEXTURE32,drm_texture_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_VERTEX232,drm_vertex2_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_CP_INIT32,drm_radeon_init_w_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_ALLOC32,drm_radeon_mem_alloc_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_IRQ_EMIT32,drm_radeon_irq_emit_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_GETPARAM32,drm_radeon_getparam_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_CMDBUF32,drm_radeon_cmd_buffer_32_64); + REG_IOCTL32(DRM_IOCTL_RADEON_SETPARAM32,drm_radeon_setparam_32_64); + + REG_IOCTL32(DRM_IOCTL_RADEON_CP_START,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_CP_STOP,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_CP_RESET,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_CP_IDLE,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_RESET,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_FULLSCREEN,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_SWAP,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_VERTEX,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_INDICES,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_INDIRECT,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_FLIP,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_FREE,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_IRQ_WAIT,drm32_default_handler); + REG_IOCTL32(DRM_IOCTL_RADEON_CP_RESUME,drm32_default_handler); + return 0; + failed: + radeon_unregister_ioctl32(); + return -1; +} + +void +radeon_unregister_ioctl32(void) +{ + UNREG_IOCTL32(DRM_IOCTL_RADEON_CLEAR32); + UNREG_IOCTL32(DRM_IOCTL_RADEON_STIPPLE32); + UNREG_IOCTL32(DRM_IOCTL_RADEON_TEXTURE32); + UNREG_IOCTL32(DRM_IOCTL_RADEON_VERTEX232); + UNREG_IOCTL32(DRM_IOCTL_RADEON_CP_INIT32); + UNREG_IOCTL32(DRM_IOCTL_RADEON_ALLOC32); + UNREG_IOCTL32(DRM_IOCTL_RADEON_IRQ_EMIT32); + UNREG_IOCTL32(DRM_IOCTL_RADEON_GETPARAM32); + UNREG_IOCTL32(DRM_IOCTL_RADEON_CMDBUF32); + UNREG_IOCTL32(DRM_IOCTL_RADEON_SETPARAM32); + + UNREG_IOCTL32(DRM_IOCTL_RADEON_CP_START); + UNREG_IOCTL32(DRM_IOCTL_RADEON_CP_STOP); + UNREG_IOCTL32(DRM_IOCTL_RADEON_CP_RESET); + UNREG_IOCTL32(DRM_IOCTL_RADEON_CP_IDLE); + UNREG_IOCTL32(DRM_IOCTL_RADEON_RESET); + UNREG_IOCTL32(DRM_IOCTL_RADEON_FULLSCREEN); + UNREG_IOCTL32(DRM_IOCTL_RADEON_SWAP); + UNREG_IOCTL32(DRM_IOCTL_RADEON_VERTEX); + UNREG_IOCTL32(DRM_IOCTL_RADEON_INDICES); + UNREG_IOCTL32(DRM_IOCTL_RADEON_INDIRECT); + UNREG_IOCTL32(DRM_IOCTL_RADEON_FLIP); + UNREG_IOCTL32(DRM_IOCTL_RADEON_FREE); + UNREG_IOCTL32(DRM_IOCTL_RADEON_IRQ_WAIT); + UNREG_IOCTL32(DRM_IOCTL_RADEON_CP_RESUME); + + drm32_unregister(); +} + +#endif diff -rNu ../unpatched/drm/shared/drm.h drm/shared/drm.h --- ../unpatched/drm/shared/drm.h 2005-01-16 06:40:12.000000000 +0100 +++ drm/shared/drm.h 2005-03-30 22:44:34.000000000 +0200 @@ -126,7 +126,7 @@ #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) -typedef unsigned long drm_handle_t; /**< To mapped regions */ +typedef unsigned int drm_handle_t; /**< To mapped regions */ typedef unsigned int drm_context_t; /**< GLXContext handle */ typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; /**< Magic for authentication */ diff -rNu ../unpatched/drm/shared/radeon_cp.c drm/shared/radeon_cp.c --- ../unpatched/drm/shared/radeon_cp.c 2005-01-26 18:48:59.000000000 +0100 +++ drm/shared/radeon_cp.c 2005-04-05 21:36:25.000000000 +0200 @@ -2065,7 +2065,7 @@ /* Check if we need a reset */ if (!(dev_priv->mmio = drm_core_findmap(dev , pci_resource_start( dev->pdev, 2 )))) return DRM_ERR(ENOMEM); - + #if defined(__linux__) ret = radeon_create_i2c_busses(dev); #endif diff -rNu ../unpatched/drm/shared-core/drm.h drm/shared-core/drm.h --- ../unpatched/drm/shared-core/drm.h 2005-01-16 06:40:12.000000000 +0100 +++ drm/shared-core/drm.h 2005-03-24 20:05:52.000000000 +0100 @@ -125,7 +125,7 @@ #define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) -typedef unsigned long drm_handle_t; /**< To mapped regions */ +typedef unsigned int drm_handle_t; /**< To mapped regions */ typedef unsigned int drm_context_t; /**< GLXContext handle */ typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; /**< Magic for authentication */ @@ -265,7 +265,7 @@ typedef struct drm_ctx_priv_map { unsigned int ctx_id; /**< Context requesting private mapping */ - void *handle; /**< Handle of map */ + unsigned long handle; /**< Handle of map */ } drm_ctx_priv_map_t; /** @@ -274,16 +274,41 @@ * * \sa drmAddMap(). */ +/* + * semantics have changed slightly: to make the handle passed to user space + * 32 bit we keep the kernel pointer in a separate structure element. + * For backward compatibility we use the 'old' structure to communicate + * with user space. + */ +#ifdef __KERNEL__ typedef struct drm_map { unsigned long offset; /**< Requested physical address (0 for SAREA)*/ unsigned long size; /**< Requested physical size (bytes) */ drm_map_type_t type; /**< Type of memory to map */ drm_map_flags_t flags; /**< Flags */ - void *handle; /**< User-space: "Handle" to pass to mmap() */ + unsigned long pub_handle; /**< User-space: "Handle" to pass to mmap() */ /**< Kernel-space: kernel-virtual address */ int mtrr; /**< MTRR slot used */ /* Private data */ + void *handle; } drm_map_t; +#endif + +typedef struct drm_pub_map { + unsigned long offset; /**< Requested physical address (0 for SAREA)*/ + unsigned long size; /**< Requested physical size (bytes) */ + drm_map_type_t type; /**< Type of memory to map */ + drm_map_flags_t flags; /**< Flags */ + unsigned long handle; /**< User-space: "Handle" to pass to mmap() */ + /**< Kernel-space: kernel-virtual address */ + int mtrr; /**< MTRR slot used */ + /* Private data */ +} +#ifdef __KERNEL__ + drm_pub_map_t; +#else + drm_map_t; +#endif /** * DRM_IOCTL_GET_CLIENT ioctl argument type. diff -rNu ../unpatched/drm/shared-core/mga_drv.h drm/shared-core/mga_drv.h --- ../unpatched/drm/shared-core/mga_drv.h 2005-02-01 12:08:31.000000000 +0100 +++ drm/shared-core/mga_drv.h 2005-03-24 20:02:02.000000000 +0100 @@ -112,6 +112,10 @@ drm_local_map_t *agp_textures; } drm_mga_private_t; + /* mga_ioctl32.c */ +extern int mga_register_ioctl32( void ); +extern void mga_unregister_ioctl32( void ); + /* mga_dma.c */ extern int mga_dma_init(DRM_IOCTL_ARGS); extern int mga_dma_flush(DRM_IOCTL_ARGS); diff -rNu ../unpatched/drm/shared-core/r128_cce.c drm/shared-core/r128_cce.c --- ../unpatched/drm/shared-core/r128_cce.c 2005-02-01 12:08:31.000000000 +0100 +++ drm/shared-core/r128_cce.c 2005-03-24 20:12:31.000000000 +0100 @@ -323,7 +323,8 @@ 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); @@ -535,7 +536,7 @@ 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 diff -rNu ../unpatched/drm/shared-core/r128_drv.h drm/shared-core/r128_drv.h --- ../unpatched/drm/shared-core/r128_drv.h 2005-02-01 12:08:31.000000000 +0100 +++ drm/shared-core/r128_drv.h 2005-03-24 20:02:02.000000000 +0100 @@ -129,6 +129,10 @@ drm_r128_freelist_t *list_entry; } drm_r128_buf_priv_t; + /* r128_ioctl32.c */ +extern int r128_register_ioctl32( void ); +extern void r128_unregister_ioctl32( void ); + /* r128_cce.c */ extern int r128_cce_init(DRM_IOCTL_ARGS); extern int r128_cce_start(DRM_IOCTL_ARGS); diff -rNu ../unpatched/drm/shared-core/radeon_cp.c drm/shared-core/radeon_cp.c --- ../unpatched/drm/shared-core/radeon_cp.c 2005-02-07 11:44:27.000000000 +0100 +++ drm/shared-core/radeon_cp.c 2005-03-29 15:42:50.000000000 +0200 @@ -1129,7 +1129,7 @@ } else #endif ring_start = (dev_priv->cp_ring->offset - - dev->sg->handle + dev_priv->gart_vm_start); + - (unsigned long)dev->sg->virtual + dev_priv->gart_vm_start); RADEON_WRITE(RADEON_CP_RB_BASE, ring_start); @@ -1155,13 +1155,14 @@ drm_sg_mem_t *entry = dev->sg; unsigned long tmp_ofs, page_ofs; - tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; + tmp_ofs = dev_priv->ring_rptr->offset + - (unsigned long)dev->sg->virtual; page_ofs = tmp_ofs >> PAGE_SHIFT; RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", (unsigned long)entry->busaddr[page_ofs], - entry->handle + tmp_ofs); + (unsigned long)entry->virtual + tmp_ofs); } /* Initialize the scratch register pointer. This will cause @@ -1471,7 +1472,7 @@ else #endif dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - dev->sg->handle + - (unsigned long) dev->sg->virtual + dev_priv->gart_vm_start); DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); @@ -2054,7 +2055,7 @@ /* Check if we need a reset */ if (! (dev_priv->mmio = - drm_core_findmap(dev, pci_resource_start(dev->pdev, 2)))) + drm_core_findmap_by_base(dev, pci_resource_start(dev->pdev, 2)))) return DRM_ERR(ENOMEM); ret = radeon_create_i2c_busses(dev); diff -rNu ../unpatched/drm/shared-core/radeon_drv.h drm/shared-core/radeon_drv.h --- ../unpatched/drm/shared-core/radeon_drv.h 2005-03-15 23:12:30.000000000 +0100 +++ drm/shared-core/radeon_drv.h 2005-03-24 20:02:02.000000000 +0100 @@ -277,6 +277,10 @@ u32 age; } drm_radeon_buf_priv_t; + /* radeon_ioctl32.c */ +extern int radeon_register_ioctl32( void ); +extern void radeon_unregister_ioctl32( void ); + /* radeon_cp.c */ extern int radeon_cp_init(DRM_IOCTL_ARGS); extern int radeon_cp_start(DRM_IOCTL_ARGS); diff -rNu ../unpatched/drm/shared-core/savage_bci.c drm/shared-core/savage_bci.c --- ../unpatched/drm/shared-core/savage_bci.c 2005-03-13 03:16:10.000000000 +0100 +++ drm/shared-core/savage_bci.c 2005-03-31 18:09:43.000000000 +0200 @@ -625,20 +625,20 @@ if ((ret = drm_initmap(dev, mmio_base, SAVAGE_MMIO_SIZE, 0, _DRM_REGISTERS, 0))) return ret; - if (!(dev_priv->mmio = drm_core_findmap (dev, mmio_base))) + if (!(dev_priv->mmio = drm_core_findmap_by_base (dev, mmio_base))) return DRM_ERR(ENOMEM); if ((ret = drm_initmap(dev, fb_base, fb_size, fb_rsrc, _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING))) return ret; - if (!(dev_priv->fb = drm_core_findmap (dev, fb_base))) + if (!(dev_priv->fb = drm_core_findmap_by_base (dev, fb_base))) return DRM_ERR(ENOMEM); if ((ret = drm_initmap(dev, aperture_base, SAVAGE_APERTURE_SIZE, aper_rsrc, _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING))) return ret; - if (!(dev_priv->aperture = drm_core_findmap (dev, aperture_base))) + if (!(dev_priv->aperture = drm_core_findmap_by_base (dev, aperture_base))) return DRM_ERR(ENOMEM); return ret;