aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/drm_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/drm_ioctl.c')
-rw-r--r--drivers/char/drm/drm_ioctl.c177
1 files changed, 74 insertions, 103 deletions
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 1b5d0da6566d..d9be14624526 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -49,22 +49,17 @@
49 * 49 *
50 * Copies the bus id from drm_device::unique into user space. 50 * Copies the bus id from drm_device::unique into user space.
51 */ 51 */
52int drm_getunique(struct inode *inode, struct drm_file *file_priv, 52int drm_getunique(struct drm_device *dev, void *data,
53 unsigned int cmd, unsigned long arg) 53 struct drm_file *file_priv)
54{ 54{
55 struct drm_device *dev = file_priv->head->dev; 55 struct drm_unique *u = data;
56 struct drm_unique __user *argp = (void __user *)arg;
57 struct drm_unique u;
58 56
59 if (copy_from_user(&u, argp, sizeof(u))) 57 if (u->unique_len >= dev->unique_len) {
60 return -EFAULT; 58 if (copy_to_user(u->unique, dev->unique, dev->unique_len))
61 if (u.unique_len >= dev->unique_len) {
62 if (copy_to_user(u.unique, dev->unique, dev->unique_len))
63 return -EFAULT; 59 return -EFAULT;
64 } 60 }
65 u.unique_len = dev->unique_len; 61 u->unique_len = dev->unique_len;
66 if (copy_to_user(argp, &u, sizeof(u))) 62
67 return -EFAULT;
68 return 0; 63 return 0;
69} 64}
70 65
@@ -82,27 +77,23 @@ int drm_getunique(struct inode *inode, struct drm_file *file_priv,
82 * in interface version 1.1 and will return EBUSY when setversion has requested 77 * in interface version 1.1 and will return EBUSY when setversion has requested
83 * version 1.1 or greater. 78 * version 1.1 or greater.
84 */ 79 */
85int drm_setunique(struct inode *inode, struct drm_file *file_priv, 80int drm_setunique(struct drm_device *dev, void *data,
86 unsigned int cmd, unsigned long arg) 81 struct drm_file *file_priv)
87{ 82{
88 struct drm_device *dev = file_priv->head->dev; 83 struct drm_unique *u = data;
89 struct drm_unique u;
90 int domain, bus, slot, func, ret; 84 int domain, bus, slot, func, ret;
91 85
92 if (dev->unique_len || dev->unique) 86 if (dev->unique_len || dev->unique)
93 return -EBUSY; 87 return -EBUSY;
94 88
95 if (copy_from_user(&u, (struct drm_unique __user *) arg, sizeof(u))) 89 if (!u->unique_len || u->unique_len > 1024)
96 return -EFAULT;
97
98 if (!u.unique_len || u.unique_len > 1024)
99 return -EINVAL; 90 return -EINVAL;
100 91
101 dev->unique_len = u.unique_len; 92 dev->unique_len = u->unique_len;
102 dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER); 93 dev->unique = drm_alloc(u->unique_len + 1, DRM_MEM_DRIVER);
103 if (!dev->unique) 94 if (!dev->unique)
104 return -ENOMEM; 95 return -ENOMEM;
105 if (copy_from_user(dev->unique, u.unique, dev->unique_len)) 96 if (copy_from_user(dev->unique, u->unique, dev->unique_len))
106 return -EFAULT; 97 return -EFAULT;
107 98
108 dev->unique[dev->unique_len] = '\0'; 99 dev->unique[dev->unique_len] = '\0';
@@ -179,20 +170,16 @@ static int drm_set_busid(struct drm_device * dev)
179 * Searches for the mapping with the specified offset and copies its information 170 * Searches for the mapping with the specified offset and copies its information
180 * into userspace 171 * into userspace
181 */ 172 */
182int drm_getmap(struct inode *inode, struct drm_file *file_priv, 173int drm_getmap(struct drm_device *dev, void *data,
183 unsigned int cmd, unsigned long arg) 174 struct drm_file *file_priv)
184{ 175{
185 struct drm_device *dev = file_priv->head->dev; 176 struct drm_map *map = data;
186 struct drm_map __user *argp = (void __user *)arg;
187 struct drm_map map;
188 struct drm_map_list *r_list = NULL; 177 struct drm_map_list *r_list = NULL;
189 struct list_head *list; 178 struct list_head *list;
190 int idx; 179 int idx;
191 int i; 180 int i;
192 181
193 if (copy_from_user(&map, argp, sizeof(map))) 182 idx = map->offset;
194 return -EFAULT;
195 idx = map.offset;
196 183
197 mutex_lock(&dev->struct_mutex); 184 mutex_lock(&dev->struct_mutex);
198 if (idx < 0) { 185 if (idx < 0) {
@@ -213,16 +200,14 @@ int drm_getmap(struct inode *inode, struct drm_file *file_priv,
213 return -EINVAL; 200 return -EINVAL;
214 } 201 }
215 202
216 map.offset = r_list->map->offset; 203 map->offset = r_list->map->offset;
217 map.size = r_list->map->size; 204 map->size = r_list->map->size;
218 map.type = r_list->map->type; 205 map->type = r_list->map->type;
219 map.flags = r_list->map->flags; 206 map->flags = r_list->map->flags;
220 map.handle = (void *)(unsigned long)r_list->user_token; 207 map->handle = (void *)(unsigned long) r_list->user_token;
221 map.mtrr = r_list->map->mtrr; 208 map->mtrr = r_list->map->mtrr;
222 mutex_unlock(&dev->struct_mutex); 209 mutex_unlock(&dev->struct_mutex);
223 210
224 if (copy_to_user(argp, &map, sizeof(map)))
225 return -EFAULT;
226 return 0; 211 return 0;
227} 212}
228 213
@@ -239,19 +224,15 @@ int drm_getmap(struct inode *inode, struct drm_file *file_priv,
239 * Searches for the client with the specified index and copies its information 224 * Searches for the client with the specified index and copies its information
240 * into userspace 225 * into userspace
241 */ 226 */
242int drm_getclient(struct inode *inode, struct drm_file *file_priv, 227int drm_getclient(struct drm_device *dev, void *data,
243 unsigned int cmd, unsigned long arg) 228 struct drm_file *file_priv)
244{ 229{
245 struct drm_device *dev = file_priv->head->dev; 230 struct drm_client *client = data;
246 struct drm_client __user *argp = (struct drm_client __user *)arg;
247 struct drm_client client;
248 struct drm_file *pt; 231 struct drm_file *pt;
249 int idx; 232 int idx;
250 int i; 233 int i;
251 234
252 if (copy_from_user(&client, argp, sizeof(client))) 235 idx = client->idx;
253 return -EFAULT;
254 idx = client.idx;
255 mutex_lock(&dev->struct_mutex); 236 mutex_lock(&dev->struct_mutex);
256 237
257 if (list_empty(&dev->filelist)) { 238 if (list_empty(&dev->filelist)) {
@@ -265,15 +246,13 @@ int drm_getclient(struct inode *inode, struct drm_file *file_priv,
265 break; 246 break;
266 } 247 }
267 248
268 client.auth = pt->authenticated; 249 client->auth = pt->authenticated;
269 client.pid = pt->pid; 250 client->pid = pt->pid;
270 client.uid = pt->uid; 251 client->uid = pt->uid;
271 client.magic = pt->magic; 252 client->magic = pt->magic;
272 client.iocs = pt->ioctl_count; 253 client->iocs = pt->ioctl_count;
273 mutex_unlock(&dev->struct_mutex); 254 mutex_unlock(&dev->struct_mutex);
274 255
275 if (copy_to_user(argp, &client, sizeof(client)))
276 return -EFAULT;
277 return 0; 256 return 0;
278} 257}
279 258
@@ -287,32 +266,29 @@ int drm_getclient(struct inode *inode, struct drm_file *file_priv,
287 * 266 *
288 * \return zero on success or a negative number on failure. 267 * \return zero on success or a negative number on failure.
289 */ 268 */
290int drm_getstats(struct inode *inode, struct drm_file *file_priv, 269int drm_getstats(struct drm_device *dev, void *data,
291 unsigned int cmd, unsigned long arg) 270 struct drm_file *file_priv)
292{ 271{
293 struct drm_device *dev = file_priv->head->dev; 272 struct drm_stats *stats = data;
294 struct drm_stats stats;
295 int i; 273 int i;
296 274
297 memset(&stats, 0, sizeof(stats)); 275 memset(stats, 0, sizeof(stats));
298 276
299 mutex_lock(&dev->struct_mutex); 277 mutex_lock(&dev->struct_mutex);
300 278
301 for (i = 0; i < dev->counters; i++) { 279 for (i = 0; i < dev->counters; i++) {
302 if (dev->types[i] == _DRM_STAT_LOCK) 280 if (dev->types[i] == _DRM_STAT_LOCK)
303 stats.data[i].value 281 stats->data[i].value =
304 = (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0); 282 (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
305 else 283 else
306 stats.data[i].value = atomic_read(&dev->counts[i]); 284 stats->data[i].value = atomic_read(&dev->counts[i]);
307 stats.data[i].type = dev->types[i]; 285 stats->data[i].type = dev->types[i];
308 } 286 }
309 287
310 stats.count = dev->counters; 288 stats->count = dev->counters;
311 289
312 mutex_unlock(&dev->struct_mutex); 290 mutex_unlock(&dev->struct_mutex);
313 291
314 if (copy_to_user((struct drm_stats __user *) arg, &stats, sizeof(stats)))
315 return -EFAULT;
316 return 0; 292 return 0;
317} 293}
318 294
@@ -327,57 +303,52 @@ int drm_getstats(struct inode *inode, struct drm_file *file_priv,
327 * 303 *
328 * Sets the requested interface version 304 * Sets the requested interface version
329 */ 305 */
330int drm_setversion(DRM_IOCTL_ARGS) 306int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
331{ 307{
332 DRM_DEVICE; 308 struct drm_set_version *sv = data;
333 struct drm_set_version sv; 309 int if_version, retcode = 0;
334 struct drm_set_version retv; 310
335 int if_version; 311 if (sv->drm_di_major != -1) {
336 struct drm_set_version __user *argp = (void __user *)data; 312 if (sv->drm_di_major != DRM_IF_MAJOR ||
337 int ret; 313 sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
338 314 retcode = -EINVAL;
339 if (copy_from_user(&sv, argp, sizeof(sv))) 315 goto done;
340 return -EFAULT; 316 }
341 317 if_version = DRM_IF_VERSION(sv->drm_di_major,
342 retv.drm_di_major = DRM_IF_MAJOR; 318 sv->drm_di_minor);
343 retv.drm_di_minor = DRM_IF_MINOR;
344 retv.drm_dd_major = dev->driver->major;
345 retv.drm_dd_minor = dev->driver->minor;
346
347 if (copy_to_user(argp, &retv, sizeof(retv)))
348 return -EFAULT;
349
350 if (sv.drm_di_major != -1) {
351 if (sv.drm_di_major != DRM_IF_MAJOR ||
352 sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
353 return -EINVAL;
354 if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor);
355 dev->if_version = max(if_version, dev->if_version); 319 dev->if_version = max(if_version, dev->if_version);
356 if (sv.drm_di_minor >= 1) { 320 if (sv->drm_di_minor >= 1) {
357 /* 321 /*
358 * Version 1.1 includes tying of DRM to specific device 322 * Version 1.1 includes tying of DRM to specific device
359 */ 323 */
360 ret = drm_set_busid(dev); 324 drm_set_busid(dev);
361 if (ret)
362 return ret;
363 } 325 }
364 } 326 }
365 327
366 if (sv.drm_dd_major != -1) { 328 if (sv->drm_dd_major != -1) {
367 if (sv.drm_dd_major != dev->driver->major || 329 if (sv->drm_dd_major != dev->driver->major ||
368 sv.drm_dd_minor < 0 330 sv->drm_dd_minor < 0 || sv->drm_dd_minor >
369 || sv.drm_dd_minor > dev->driver->minor) 331 dev->driver->minor) {
370 return -EINVAL; 332 retcode = -EINVAL;
333 goto done;
334 }
371 335
372 if (dev->driver->set_version) 336 if (dev->driver->set_version)
373 dev->driver->set_version(dev, &sv); 337 dev->driver->set_version(dev, sv);
374 } 338 }
375 return 0; 339
340done:
341 sv->drm_di_major = DRM_IF_MAJOR;
342 sv->drm_di_minor = DRM_IF_MINOR;
343 sv->drm_dd_major = dev->driver->major;
344 sv->drm_dd_minor = dev->driver->minor;
345
346 return retcode;
376} 347}
377 348
378/** No-op ioctl. */ 349/** No-op ioctl. */
379int drm_noop(struct inode *inode, struct drm_file *file_priv, unsigned int cmd, 350int drm_noop(struct drm_device *dev, void *data,
380 unsigned long arg) 351 struct drm_file *file_priv)
381{ 352{
382 DRM_DEBUG("\n"); 353 DRM_DEBUG("\n");
383 return 0; 354 return 0;