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.c196
1 files changed, 81 insertions, 115 deletions
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index b195e102e737..d9be14624526 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -42,30 +42,24 @@
42 * Get the bus id. 42 * Get the bus id.
43 * 43 *
44 * \param inode device inode. 44 * \param inode device inode.
45 * \param filp file pointer. 45 * \param file_priv DRM file private.
46 * \param cmd command. 46 * \param cmd command.
47 * \param arg user argument, pointing to a drm_unique structure. 47 * \param arg user argument, pointing to a drm_unique structure.
48 * \return zero on success or a negative number on failure. 48 * \return zero on success or a negative number on failure.
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 file *filp, 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_file *priv = filp->private_data; 55 struct drm_unique *u = data;
56 struct drm_device *dev = priv->head->dev;
57 struct drm_unique __user *argp = (void __user *)arg;
58 struct drm_unique u;
59 56
60 if (copy_from_user(&u, argp, sizeof(u))) 57 if (u->unique_len >= dev->unique_len) {
61 return -EFAULT; 58 if (copy_to_user(u->unique, dev->unique, dev->unique_len))
62 if (u.unique_len >= dev->unique_len) {
63 if (copy_to_user(u.unique, dev->unique, dev->unique_len))
64 return -EFAULT; 59 return -EFAULT;
65 } 60 }
66 u.unique_len = dev->unique_len; 61 u->unique_len = dev->unique_len;
67 if (copy_to_user(argp, &u, sizeof(u))) 62
68 return -EFAULT;
69 return 0; 63 return 0;
70} 64}
71 65
@@ -73,7 +67,7 @@ int drm_getunique(struct inode *inode, struct file *filp,
73 * Set the bus id. 67 * Set the bus id.
74 * 68 *
75 * \param inode device inode. 69 * \param inode device inode.
76 * \param filp file pointer. 70 * \param file_priv DRM file private.
77 * \param cmd command. 71 * \param cmd command.
78 * \param arg user argument, pointing to a drm_unique structure. 72 * \param arg user argument, pointing to a drm_unique structure.
79 * \return zero on success or a negative number on failure. 73 * \return zero on success or a negative number on failure.
@@ -83,28 +77,23 @@ int drm_getunique(struct inode *inode, struct file *filp,
83 * 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
84 * version 1.1 or greater. 78 * version 1.1 or greater.
85 */ 79 */
86int drm_setunique(struct inode *inode, struct file *filp, 80int drm_setunique(struct drm_device *dev, void *data,
87 unsigned int cmd, unsigned long arg) 81 struct drm_file *file_priv)
88{ 82{
89 struct drm_file *priv = filp->private_data; 83 struct drm_unique *u = data;
90 struct drm_device *dev = priv->head->dev;
91 struct drm_unique u;
92 int domain, bus, slot, func, ret; 84 int domain, bus, slot, func, ret;
93 85
94 if (dev->unique_len || dev->unique) 86 if (dev->unique_len || dev->unique)
95 return -EBUSY; 87 return -EBUSY;
96 88
97 if (copy_from_user(&u, (struct drm_unique __user *) arg, sizeof(u))) 89 if (!u->unique_len || u->unique_len > 1024)
98 return -EFAULT;
99
100 if (!u.unique_len || u.unique_len > 1024)
101 return -EINVAL; 90 return -EINVAL;
102 91
103 dev->unique_len = u.unique_len; 92 dev->unique_len = u->unique_len;
104 dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER); 93 dev->unique = drm_alloc(u->unique_len + 1, DRM_MEM_DRIVER);
105 if (!dev->unique) 94 if (!dev->unique)
106 return -ENOMEM; 95 return -ENOMEM;
107 if (copy_from_user(dev->unique, u.unique, dev->unique_len)) 96 if (copy_from_user(dev->unique, u->unique, dev->unique_len))
108 return -EFAULT; 97 return -EFAULT;
109 98
110 dev->unique[dev->unique_len] = '\0'; 99 dev->unique[dev->unique_len] = '\0';
@@ -123,7 +112,7 @@ int drm_setunique(struct inode *inode, struct file *filp,
123 */ 112 */
124 ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func); 113 ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
125 if (ret != 3) 114 if (ret != 3)
126 return DRM_ERR(EINVAL); 115 return -EINVAL;
127 domain = bus >> 8; 116 domain = bus >> 8;
128 bus &= 0xff; 117 bus &= 0xff;
129 118
@@ -172,7 +161,7 @@ static int drm_set_busid(struct drm_device * dev)
172 * Get a mapping information. 161 * Get a mapping information.
173 * 162 *
174 * \param inode device inode. 163 * \param inode device inode.
175 * \param filp file pointer. 164 * \param file_priv DRM file private.
176 * \param cmd command. 165 * \param cmd command.
177 * \param arg user argument, pointing to a drm_map structure. 166 * \param arg user argument, pointing to a drm_map structure.
178 * 167 *
@@ -181,21 +170,16 @@ static int drm_set_busid(struct drm_device * dev)
181 * 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
182 * into userspace 171 * into userspace
183 */ 172 */
184int drm_getmap(struct inode *inode, struct file *filp, 173int drm_getmap(struct drm_device *dev, void *data,
185 unsigned int cmd, unsigned long arg) 174 struct drm_file *file_priv)
186{ 175{
187 struct drm_file *priv = filp->private_data; 176 struct drm_map *map = data;
188 struct drm_device *dev = priv->head->dev;
189 struct drm_map __user *argp = (void __user *)arg;
190 struct drm_map map;
191 struct drm_map_list *r_list = NULL; 177 struct drm_map_list *r_list = NULL;
192 struct list_head *list; 178 struct list_head *list;
193 int idx; 179 int idx;
194 int i; 180 int i;
195 181
196 if (copy_from_user(&map, argp, sizeof(map))) 182 idx = map->offset;
197 return -EFAULT;
198 idx = map.offset;
199 183
200 mutex_lock(&dev->struct_mutex); 184 mutex_lock(&dev->struct_mutex);
201 if (idx < 0) { 185 if (idx < 0) {
@@ -216,16 +200,14 @@ int drm_getmap(struct inode *inode, struct file *filp,
216 return -EINVAL; 200 return -EINVAL;
217 } 201 }
218 202
219 map.offset = r_list->map->offset; 203 map->offset = r_list->map->offset;
220 map.size = r_list->map->size; 204 map->size = r_list->map->size;
221 map.type = r_list->map->type; 205 map->type = r_list->map->type;
222 map.flags = r_list->map->flags; 206 map->flags = r_list->map->flags;
223 map.handle = (void *)(unsigned long)r_list->user_token; 207 map->handle = (void *)(unsigned long) r_list->user_token;
224 map.mtrr = r_list->map->mtrr; 208 map->mtrr = r_list->map->mtrr;
225 mutex_unlock(&dev->struct_mutex); 209 mutex_unlock(&dev->struct_mutex);
226 210
227 if (copy_to_user(argp, &map, sizeof(map)))
228 return -EFAULT;
229 return 0; 211 return 0;
230} 212}
231 213
@@ -233,7 +215,7 @@ int drm_getmap(struct inode *inode, struct file *filp,
233 * Get client information. 215 * Get client information.
234 * 216 *
235 * \param inode device inode. 217 * \param inode device inode.
236 * \param filp file pointer. 218 * \param file_priv DRM file private.
237 * \param cmd command. 219 * \param cmd command.
238 * \param arg user argument, pointing to a drm_client structure. 220 * \param arg user argument, pointing to a drm_client structure.
239 * 221 *
@@ -242,20 +224,15 @@ int drm_getmap(struct inode *inode, struct file *filp,
242 * 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
243 * into userspace 225 * into userspace
244 */ 226 */
245int drm_getclient(struct inode *inode, struct file *filp, 227int drm_getclient(struct drm_device *dev, void *data,
246 unsigned int cmd, unsigned long arg) 228 struct drm_file *file_priv)
247{ 229{
248 struct drm_file *priv = filp->private_data; 230 struct drm_client *client = data;
249 struct drm_device *dev = priv->head->dev;
250 struct drm_client __user *argp = (struct drm_client __user *)arg;
251 struct drm_client client;
252 struct drm_file *pt; 231 struct drm_file *pt;
253 int idx; 232 int idx;
254 int i; 233 int i;
255 234
256 if (copy_from_user(&client, argp, sizeof(client))) 235 idx = client->idx;
257 return -EFAULT;
258 idx = client.idx;
259 mutex_lock(&dev->struct_mutex); 236 mutex_lock(&dev->struct_mutex);
260 237
261 if (list_empty(&dev->filelist)) { 238 if (list_empty(&dev->filelist)) {
@@ -269,15 +246,13 @@ int drm_getclient(struct inode *inode, struct file *filp,
269 break; 246 break;
270 } 247 }
271 248
272 client.auth = pt->authenticated; 249 client->auth = pt->authenticated;
273 client.pid = pt->pid; 250 client->pid = pt->pid;
274 client.uid = pt->uid; 251 client->uid = pt->uid;
275 client.magic = pt->magic; 252 client->magic = pt->magic;
276 client.iocs = pt->ioctl_count; 253 client->iocs = pt->ioctl_count;
277 mutex_unlock(&dev->struct_mutex); 254 mutex_unlock(&dev->struct_mutex);
278 255
279 if (copy_to_user(argp, &client, sizeof(client)))
280 return -EFAULT;
281 return 0; 256 return 0;
282} 257}
283 258
@@ -285,39 +260,35 @@ int drm_getclient(struct inode *inode, struct file *filp,
285 * Get statistics information. 260 * Get statistics information.
286 * 261 *
287 * \param inode device inode. 262 * \param inode device inode.
288 * \param filp file pointer. 263 * \param file_priv DRM file private.
289 * \param cmd command. 264 * \param cmd command.
290 * \param arg user argument, pointing to a drm_stats structure. 265 * \param arg user argument, pointing to a drm_stats structure.
291 * 266 *
292 * \return zero on success or a negative number on failure. 267 * \return zero on success or a negative number on failure.
293 */ 268 */
294int drm_getstats(struct inode *inode, struct file *filp, 269int drm_getstats(struct drm_device *dev, void *data,
295 unsigned int cmd, unsigned long arg) 270 struct drm_file *file_priv)
296{ 271{
297 struct drm_file *priv = filp->private_data; 272 struct drm_stats *stats = data;
298 struct drm_device *dev = priv->head->dev;
299 struct drm_stats stats;
300 int i; 273 int i;
301 274
302 memset(&stats, 0, sizeof(stats)); 275 memset(stats, 0, sizeof(stats));
303 276
304 mutex_lock(&dev->struct_mutex); 277 mutex_lock(&dev->struct_mutex);
305 278
306 for (i = 0; i < dev->counters; i++) { 279 for (i = 0; i < dev->counters; i++) {
307 if (dev->types[i] == _DRM_STAT_LOCK) 280 if (dev->types[i] == _DRM_STAT_LOCK)
308 stats.data[i].value 281 stats->data[i].value =
309 = (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0); 282 (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
310 else 283 else
311 stats.data[i].value = atomic_read(&dev->counts[i]); 284 stats->data[i].value = atomic_read(&dev->counts[i]);
312 stats.data[i].type = dev->types[i]; 285 stats->data[i].type = dev->types[i];
313 } 286 }
314 287
315 stats.count = dev->counters; 288 stats->count = dev->counters;
316 289
317 mutex_unlock(&dev->struct_mutex); 290 mutex_unlock(&dev->struct_mutex);
318 291
319 if (copy_to_user((struct drm_stats __user *) arg, &stats, sizeof(stats)))
320 return -EFAULT;
321 return 0; 292 return 0;
322} 293}
323 294
@@ -325,64 +296,59 @@ int drm_getstats(struct inode *inode, struct file *filp,
325 * Setversion ioctl. 296 * Setversion ioctl.
326 * 297 *
327 * \param inode device inode. 298 * \param inode device inode.
328 * \param filp file pointer. 299 * \param file_priv DRM file private.
329 * \param cmd command. 300 * \param cmd command.
330 * \param arg user argument, pointing to a drm_lock structure. 301 * \param arg user argument, pointing to a drm_lock structure.
331 * \return zero on success or negative number on failure. 302 * \return zero on success or negative number on failure.
332 * 303 *
333 * Sets the requested interface version 304 * Sets the requested interface version
334 */ 305 */
335int drm_setversion(DRM_IOCTL_ARGS) 306int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
336{ 307{
337 DRM_DEVICE; 308 struct drm_set_version *sv = data;
338 struct drm_set_version sv; 309 int if_version, retcode = 0;
339 struct drm_set_version retv; 310
340 int if_version; 311 if (sv->drm_di_major != -1) {
341 struct drm_set_version __user *argp = (void __user *)data; 312 if (sv->drm_di_major != DRM_IF_MAJOR ||
342 int ret; 313 sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
343 314 retcode = -EINVAL;
344 if (copy_from_user(&sv, argp, sizeof(sv))) 315 goto done;
345 return -EFAULT; 316 }
346 317 if_version = DRM_IF_VERSION(sv->drm_di_major,
347 retv.drm_di_major = DRM_IF_MAJOR; 318 sv->drm_di_minor);
348 retv.drm_di_minor = DRM_IF_MINOR;
349 retv.drm_dd_major = dev->driver->major;
350 retv.drm_dd_minor = dev->driver->minor;
351
352 if (copy_to_user(argp, &retv, sizeof(retv)))
353 return -EFAULT;
354
355 if (sv.drm_di_major != -1) {
356 if (sv.drm_di_major != DRM_IF_MAJOR ||
357 sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
358 return -EINVAL;
359 if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor);
360 dev->if_version = max(if_version, dev->if_version); 319 dev->if_version = max(if_version, dev->if_version);
361 if (sv.drm_di_minor >= 1) { 320 if (sv->drm_di_minor >= 1) {
362 /* 321 /*
363 * Version 1.1 includes tying of DRM to specific device 322 * Version 1.1 includes tying of DRM to specific device
364 */ 323 */
365 ret = drm_set_busid(dev); 324 drm_set_busid(dev);
366 if (ret)
367 return ret;
368 } 325 }
369 } 326 }
370 327
371 if (sv.drm_dd_major != -1) { 328 if (sv->drm_dd_major != -1) {
372 if (sv.drm_dd_major != dev->driver->major || 329 if (sv->drm_dd_major != dev->driver->major ||
373 sv.drm_dd_minor < 0 330 sv->drm_dd_minor < 0 || sv->drm_dd_minor >
374 || sv.drm_dd_minor > dev->driver->minor) 331 dev->driver->minor) {
375 return -EINVAL; 332 retcode = -EINVAL;
333 goto done;
334 }
376 335
377 if (dev->driver->set_version) 336 if (dev->driver->set_version)
378 dev->driver->set_version(dev, &sv); 337 dev->driver->set_version(dev, sv);
379 } 338 }
380 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;
381} 347}
382 348
383/** No-op ioctl. */ 349/** No-op ioctl. */
384int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd, 350int drm_noop(struct drm_device *dev, void *data,
385 unsigned long arg) 351 struct drm_file *file_priv)
386{ 352{
387 DRM_DEBUG("\n"); 353 DRM_DEBUG("\n");
388 return 0; 354 return 0;