|
Lines 45-66
Link Here
|
| 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 |
|
54 |
* offsets relative to the start of the framebuffer and some may |
| 55 |
DRM_DEBUG("offset fixed up to 0x%x\n", off); |
55 |
* assume the AGP aperture it appended to the framebuffer, so we |
| 56 |
|
56 |
* try to detect those cases and fix them up. |
| 57 |
if (off < dev_priv->fb_location || |
57 |
* |
| 58 |
off >= (dev_priv->gart_vm_start + dev_priv->gart_size)) |
58 |
* Note: It might be a good idea here to make sure the offset lands |
| 59 |
return DRM_ERR(EINVAL); |
59 |
* in some "allowed" area to protect things like the PCIE GART... |
| 60 |
|
60 |
*/ |
| 61 |
*offset = off; |
61 |
|
| 62 |
|
62 |
/* First, the best case, the offset already lands in either the |
| 63 |
return 0; |
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; |
| 70 |
|
| 71 |
/* Ok, that didn't happen... now check if we have a zero based |
| 72 |
* offset that fits in the framebuffer + gart space, apply the |
| 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 |
} |
| 79 |
|
| 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; |
| 84 |
|
| 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 |
|
| 66 |
static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * |
97 |
static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * |
|
Lines 3012-3017
Link Here
|
| 3012 |
case RADEON_SETPARAM_PCIGART_LOCATION: |
3043 |
case RADEON_SETPARAM_PCIGART_LOCATION: |
| 3013 |
dev_priv->pcigart_offset = sp.value; |
3044 |
dev_priv->pcigart_offset = sp.value; |
| 3014 |
break; |
3045 |
break; |
|
|
3046 |
case RADEON_SETPARAM_NEW_MEMMAP: |
| 3047 |
dev_priv->new_memmap = sp.value; |
| 3048 |
break; |
| 3015 |
default: |
3049 |
default: |
| 3016 |
DRM_DEBUG("Invalid parameter %d\n", sp.param); |
3050 |
DRM_DEBUG("Invalid parameter %d\n", sp.param); |
| 3017 |
return DRM_ERR(EINVAL); |
3051 |
return DRM_ERR(EINVAL); |