aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/radeon_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/radeon_state.c')
-rw-r--r--drivers/char/drm/radeon_state.c105
1 files changed, 47 insertions, 58 deletions
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 7bc27516d425..c5b8f774a599 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -45,22 +45,53 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
45 u32 off = *offset; 45 u32 off = *offset;
46 struct drm_radeon_driver_file_fields *radeon_priv; 46 struct drm_radeon_driver_file_fields *radeon_priv;
47 47
48 if (off >= dev_priv->fb_location && 48 /* Hrm ... the story of the offset ... So this function converts
49 off < (dev_priv->gart_vm_start + dev_priv->gart_size)) 49 * the various ideas of what userland clients might have for an
50 return 0; 50 * offset in the card address space into an offset into the card
51 51 * address space :) So with a sane client, it should just keep
52 radeon_priv = filp_priv->driver_priv; 52 * the value intact and just do some boundary checking. However,
53 off += radeon_priv->radeon_fb_delta; 53 * not all clients are sane. Some older clients pass us 0 based
54 * offsets relative to the start of the framebuffer and some may
55 * assume the AGP aperture it appended to the framebuffer, so we
56 * try to detect those cases and fix them up.
57 *
58 * Note: It might be a good idea here to make sure the offset lands
59 * in some "allowed" area to protect things like the PCIE GART...
60 */
54 61
55 DRM_DEBUG("offset fixed up to 0x%x\n", off); 62 /* First, the best case, the offset already lands in either the
63 * framebuffer or the GART mapped space
64 */
65 if ((off >= dev_priv->fb_location &&
66 off < (dev_priv->fb_location + dev_priv->fb_size)) ||
67 (off >= dev_priv->gart_vm_start &&
68 off < (dev_priv->gart_vm_start + dev_priv->gart_size)))
69 return 0;
56 70
57 if (off < dev_priv->fb_location || 71 /* Ok, that didn't happen... now check if we have a zero based
58 off >= (dev_priv->gart_vm_start + dev_priv->gart_size)) 72 * offset that fits in the framebuffer + gart space, apply the
59 return DRM_ERR(EINVAL); 73 * magic offset we get from SETPARAM or calculated from fb_location
74 */
75 if (off < (dev_priv->fb_size + dev_priv->gart_size)) {
76 radeon_priv = filp_priv->driver_priv;
77 off += radeon_priv->radeon_fb_delta;
78 }
60 79
61 *offset = off; 80 /* Finally, assume we aimed at a GART offset if beyond the fb */
81 if (off > (dev_priv->fb_location + dev_priv->fb_size))
82 off = off - (dev_priv->fb_location + dev_priv->fb_size) +
83 dev_priv->gart_vm_start;
62 84
63 return 0; 85 /* Now recheck and fail if out of bounds */
86 if ((off >= dev_priv->fb_location &&
87 off < (dev_priv->fb_location + dev_priv->fb_size)) ||
88 (off >= dev_priv->gart_vm_start &&
89 off < (dev_priv->gart_vm_start + dev_priv->gart_size))) {
90 DRM_DEBUG("offset fixed up to 0x%x\n", off);
91 *offset = off;
92 return 0;
93 }
94 return DRM_ERR(EINVAL);
64} 95}
65 96
66static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * 97static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
@@ -1939,11 +1970,6 @@ static int radeon_surface_alloc(DRM_IOCTL_ARGS)
1939 drm_radeon_private_t *dev_priv = dev->dev_private; 1970 drm_radeon_private_t *dev_priv = dev->dev_private;
1940 drm_radeon_surface_alloc_t alloc; 1971 drm_radeon_surface_alloc_t alloc;
1941 1972
1942 if (!dev_priv) {
1943 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
1944 return DRM_ERR(EINVAL);
1945 }
1946
1947 DRM_COPY_FROM_USER_IOCTL(alloc, 1973 DRM_COPY_FROM_USER_IOCTL(alloc,
1948 (drm_radeon_surface_alloc_t __user *) data, 1974 (drm_radeon_surface_alloc_t __user *) data,
1949 sizeof(alloc)); 1975 sizeof(alloc));
@@ -1960,12 +1986,7 @@ static int radeon_surface_free(DRM_IOCTL_ARGS)
1960 drm_radeon_private_t *dev_priv = dev->dev_private; 1986 drm_radeon_private_t *dev_priv = dev->dev_private;
1961 drm_radeon_surface_free_t memfree; 1987 drm_radeon_surface_free_t memfree;
1962 1988
1963 if (!dev_priv) { 1989 DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_surface_free_t __user *) data,
1964 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
1965 return DRM_ERR(EINVAL);
1966 }
1967
1968 DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data,
1969 sizeof(memfree)); 1990 sizeof(memfree));
1970 1991
1971 if (free_surface(filp, dev_priv, memfree.address)) 1992 if (free_surface(filp, dev_priv, memfree.address))
@@ -2100,11 +2121,6 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS)
2100 2121
2101 LOCK_TEST_WITH_RETURN(dev, filp); 2122 LOCK_TEST_WITH_RETURN(dev, filp);
2102 2123
2103 if (!dev_priv) {
2104 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2105 return DRM_ERR(EINVAL);
2106 }
2107
2108 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2124 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2109 2125
2110 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, 2126 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data,
@@ -2189,11 +2205,6 @@ static int radeon_cp_indices(DRM_IOCTL_ARGS)
2189 2205
2190 LOCK_TEST_WITH_RETURN(dev, filp); 2206 LOCK_TEST_WITH_RETURN(dev, filp);
2191 2207
2192 if (!dev_priv) {
2193 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2194 return DRM_ERR(EINVAL);
2195 }
2196
2197 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2208 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2198 2209
2199 DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, 2210 DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data,
@@ -2340,11 +2351,6 @@ static int radeon_cp_indirect(DRM_IOCTL_ARGS)
2340 2351
2341 LOCK_TEST_WITH_RETURN(dev, filp); 2352 LOCK_TEST_WITH_RETURN(dev, filp);
2342 2353
2343 if (!dev_priv) {
2344 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2345 return DRM_ERR(EINVAL);
2346 }
2347
2348 DRM_COPY_FROM_USER_IOCTL(indirect, 2354 DRM_COPY_FROM_USER_IOCTL(indirect,
2349 (drm_radeon_indirect_t __user *) data, 2355 (drm_radeon_indirect_t __user *) data,
2350 sizeof(indirect)); 2356 sizeof(indirect));
@@ -2417,11 +2423,6 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS)
2417 2423
2418 LOCK_TEST_WITH_RETURN(dev, filp); 2424 LOCK_TEST_WITH_RETURN(dev, filp);
2419 2425
2420 if (!dev_priv) {
2421 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2422 return DRM_ERR(EINVAL);
2423 }
2424
2425 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2426 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2426 2427
2427 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, 2428 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data,
@@ -2738,11 +2739,6 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
2738 2739
2739 LOCK_TEST_WITH_RETURN(dev, filp); 2740 LOCK_TEST_WITH_RETURN(dev, filp);
2740 2741
2741 if (!dev_priv) {
2742 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2743 return DRM_ERR(EINVAL);
2744 }
2745
2746 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2742 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2747 2743
2748 DRM_COPY_FROM_USER_IOCTL(cmdbuf, 2744 DRM_COPY_FROM_USER_IOCTL(cmdbuf,
@@ -2897,11 +2893,6 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
2897 drm_radeon_getparam_t param; 2893 drm_radeon_getparam_t param;
2898 int value; 2894 int value;
2899 2895
2900 if (!dev_priv) {
2901 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2902 return DRM_ERR(EINVAL);
2903 }
2904
2905 DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, 2896 DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data,
2906 sizeof(param)); 2897 sizeof(param));
2907 2898
@@ -2981,11 +2972,6 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
2981 drm_radeon_setparam_t sp; 2972 drm_radeon_setparam_t sp;
2982 struct drm_radeon_driver_file_fields *radeon_priv; 2973 struct drm_radeon_driver_file_fields *radeon_priv;
2983 2974
2984 if (!dev_priv) {
2985 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2986 return DRM_ERR(EINVAL);
2987 }
2988
2989 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2975 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2990 2976
2991 DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, 2977 DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data,
@@ -3012,6 +2998,9 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
3012 case RADEON_SETPARAM_PCIGART_LOCATION: 2998 case RADEON_SETPARAM_PCIGART_LOCATION:
3013 dev_priv->pcigart_offset = sp.value; 2999 dev_priv->pcigart_offset = sp.value;
3014 break; 3000 break;
3001 case RADEON_SETPARAM_NEW_MEMMAP:
3002 dev_priv->new_memmap = sp.value;
3003 break;
3015 default: 3004 default:
3016 DRM_DEBUG("Invalid parameter %d\n", sp.param); 3005 DRM_DEBUG("Invalid parameter %d\n", sp.param);
3017 return DRM_ERR(EINVAL); 3006 return DRM_ERR(EINVAL);