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.c168
1 files changed, 86 insertions, 82 deletions
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index d2ed3ba5aca9..9b0feba6b063 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * \file drm_ioctl.h 2 * \file drm_ioctl.c
3 * IOCTL processing for DRM 3 * IOCTL processing for DRM
4 * 4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com> 5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -40,7 +40,7 @@
40 40
41/** 41/**
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 filp file pointer.
46 * \param cmd command. 46 * \param cmd command.
@@ -50,12 +50,12 @@
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 inode *inode, struct file *filp,
53 unsigned int cmd, unsigned long arg) 53 unsigned int cmd, unsigned long arg)
54{ 54{
55 drm_file_t *priv = filp->private_data; 55 drm_file_t *priv = filp->private_data;
56 drm_device_t *dev = priv->head->dev; 56 drm_device_t *dev = priv->head->dev;
57 drm_unique_t __user *argp = (void __user *)arg; 57 drm_unique_t __user *argp = (void __user *)arg;
58 drm_unique_t u; 58 drm_unique_t u;
59 59
60 if (copy_from_user(&u, argp, sizeof(u))) 60 if (copy_from_user(&u, argp, sizeof(u)))
61 return -EFAULT; 61 return -EFAULT;
@@ -71,7 +71,7 @@ int drm_getunique(struct inode *inode, struct file *filp,
71 71
72/** 72/**
73 * Set the bus id. 73 * Set the bus id.
74 * 74 *
75 * \param inode device inode. 75 * \param inode device inode.
76 * \param filp file pointer. 76 * \param filp file pointer.
77 * \param cmd command. 77 * \param cmd command.
@@ -84,34 +84,39 @@ int drm_getunique(struct inode *inode, struct file *filp,
84 * version 1.1 or greater. 84 * version 1.1 or greater.
85 */ 85 */
86int drm_setunique(struct inode *inode, struct file *filp, 86int drm_setunique(struct inode *inode, struct file *filp,
87 unsigned int cmd, unsigned long arg) 87 unsigned int cmd, unsigned long arg)
88{ 88{
89 drm_file_t *priv = filp->private_data; 89 drm_file_t *priv = filp->private_data;
90 drm_device_t *dev = priv->head->dev; 90 drm_device_t *dev = priv->head->dev;
91 drm_unique_t u; 91 drm_unique_t u;
92 int domain, bus, slot, func, ret; 92 int domain, bus, slot, func, ret;
93 93
94 if (dev->unique_len || dev->unique) return -EBUSY; 94 if (dev->unique_len || dev->unique)
95 return -EBUSY;
95 96
96 if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u))) 97 if (copy_from_user(&u, (drm_unique_t __user *) arg, sizeof(u)))
97 return -EFAULT; 98 return -EFAULT;
98 99
99 if (!u.unique_len || u.unique_len > 1024) return -EINVAL; 100 if (!u.unique_len || u.unique_len > 1024)
101 return -EINVAL;
100 102
101 dev->unique_len = u.unique_len; 103 dev->unique_len = u.unique_len;
102 dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER); 104 dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
103 if(!dev->unique) return -ENOMEM; 105 if (!dev->unique)
106 return -ENOMEM;
104 if (copy_from_user(dev->unique, u.unique, dev->unique_len)) 107 if (copy_from_user(dev->unique, u.unique, dev->unique_len))
105 return -EFAULT; 108 return -EFAULT;
106 109
107 dev->unique[dev->unique_len] = '\0'; 110 dev->unique[dev->unique_len] = '\0';
108 111
109 dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2, 112 dev->devname =
110 DRM_MEM_DRIVER); 113 drm_alloc(strlen(dev->driver->pci_driver.name) +
114 strlen(dev->unique) + 2, DRM_MEM_DRIVER);
111 if (!dev->devname) 115 if (!dev->devname)
112 return -ENOMEM; 116 return -ENOMEM;
113 117
114 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique); 118 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
119 dev->unique);
115 120
116 /* Return error if the busid submitted doesn't match the device's actual 121 /* Return error if the busid submitted doesn't match the device's actual
117 * busid. 122 * busid.
@@ -121,18 +126,16 @@ int drm_setunique(struct inode *inode, struct file *filp,
121 return DRM_ERR(EINVAL); 126 return DRM_ERR(EINVAL);
122 domain = bus >> 8; 127 domain = bus >> 8;
123 bus &= 0xff; 128 bus &= 0xff;
124 129
125 if ((domain != dev->pci_domain) || 130 if ((domain != dev->pci_domain) ||
126 (bus != dev->pci_bus) || 131 (bus != dev->pci_bus) ||
127 (slot != dev->pci_slot) || 132 (slot != dev->pci_slot) || (func != dev->pci_func))
128 (func != dev->pci_func))
129 return -EINVAL; 133 return -EINVAL;
130 134
131 return 0; 135 return 0;
132} 136}
133 137
134static int 138static int drm_set_busid(drm_device_t * dev)
135drm_set_busid(drm_device_t *dev)
136{ 139{
137 if (dev->unique != NULL) 140 if (dev->unique != NULL)
138 return EBUSY; 141 return EBUSY;
@@ -143,19 +146,20 @@ drm_set_busid(drm_device_t *dev)
143 return ENOMEM; 146 return ENOMEM;
144 147
145 snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", 148 snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
146 dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); 149 dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
147 150
148 dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2, 151 dev->devname =
149 DRM_MEM_DRIVER); 152 drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
153 2, DRM_MEM_DRIVER);
150 if (dev->devname == NULL) 154 if (dev->devname == NULL)
151 return ENOMEM; 155 return ENOMEM;
152 156
153 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique); 157 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
158 dev->unique);
154 159
155 return 0; 160 return 0;
156} 161}
157 162
158
159/** 163/**
160 * Get a mapping information. 164 * Get a mapping information.
161 * 165 *
@@ -163,23 +167,23 @@ drm_set_busid(drm_device_t *dev)
163 * \param filp file pointer. 167 * \param filp file pointer.
164 * \param cmd command. 168 * \param cmd command.
165 * \param arg user argument, pointing to a drm_map structure. 169 * \param arg user argument, pointing to a drm_map structure.
166 * 170 *
167 * \return zero on success or a negative number on failure. 171 * \return zero on success or a negative number on failure.
168 * 172 *
169 * Searches for the mapping with the specified offset and copies its information 173 * Searches for the mapping with the specified offset and copies its information
170 * into userspace 174 * into userspace
171 */ 175 */
172int drm_getmap( struct inode *inode, struct file *filp, 176int drm_getmap(struct inode *inode, struct file *filp,
173 unsigned int cmd, unsigned long arg ) 177 unsigned int cmd, unsigned long arg)
174{ 178{
175 drm_file_t *priv = filp->private_data; 179 drm_file_t *priv = filp->private_data;
176 drm_device_t *dev = priv->head->dev; 180 drm_device_t *dev = priv->head->dev;
177 drm_map_t __user *argp = (void __user *)arg; 181 drm_map_t __user *argp = (void __user *)arg;
178 drm_map_t map; 182 drm_map_t map;
179 drm_map_list_t *r_list = NULL; 183 drm_map_list_t *r_list = NULL;
180 struct list_head *list; 184 struct list_head *list;
181 int idx; 185 int idx;
182 int i; 186 int i;
183 187
184 if (copy_from_user(&map, argp, sizeof(map))) 188 if (copy_from_user(&map, argp, sizeof(map)))
185 return -EFAULT; 189 return -EFAULT;
@@ -193,26 +197,27 @@ int drm_getmap( struct inode *inode, struct file *filp,
193 197
194 i = 0; 198 i = 0;
195 list_for_each(list, &dev->maplist->head) { 199 list_for_each(list, &dev->maplist->head) {
196 if(i == idx) { 200 if (i == idx) {
197 r_list = list_entry(list, drm_map_list_t, head); 201 r_list = list_entry(list, drm_map_list_t, head);
198 break; 202 break;
199 } 203 }
200 i++; 204 i++;
201 } 205 }
202 if(!r_list || !r_list->map) { 206 if (!r_list || !r_list->map) {
203 up(&dev->struct_sem); 207 up(&dev->struct_sem);
204 return -EINVAL; 208 return -EINVAL;
205 } 209 }
206 210
207 map.offset = r_list->map->offset; 211 map.offset = r_list->map->offset;
208 map.size = r_list->map->size; 212 map.size = r_list->map->size;
209 map.type = r_list->map->type; 213 map.type = r_list->map->type;
210 map.flags = r_list->map->flags; 214 map.flags = r_list->map->flags;
211 map.handle = (void *)(unsigned long) r_list->user_token; 215 map.handle = (void *)(unsigned long)r_list->user_token;
212 map.mtrr = r_list->map->mtrr; 216 map.mtrr = r_list->map->mtrr;
213 up(&dev->struct_sem); 217 up(&dev->struct_sem);
214 218
215 if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT; 219 if (copy_to_user(argp, &map, sizeof(map)))
220 return -EFAULT;
216 return 0; 221 return 0;
217} 222}
218 223
@@ -223,83 +228,81 @@ int drm_getmap( struct inode *inode, struct file *filp,
223 * \param filp file pointer. 228 * \param filp file pointer.
224 * \param cmd command. 229 * \param cmd command.
225 * \param arg user argument, pointing to a drm_client structure. 230 * \param arg user argument, pointing to a drm_client structure.
226 * 231 *
227 * \return zero on success or a negative number on failure. 232 * \return zero on success or a negative number on failure.
228 * 233 *
229 * Searches for the client with the specified index and copies its information 234 * Searches for the client with the specified index and copies its information
230 * into userspace 235 * into userspace
231 */ 236 */
232int drm_getclient( struct inode *inode, struct file *filp, 237int drm_getclient(struct inode *inode, struct file *filp,
233 unsigned int cmd, unsigned long arg ) 238 unsigned int cmd, unsigned long arg)
234{ 239{
235 drm_file_t *priv = filp->private_data; 240 drm_file_t *priv = filp->private_data;
236 drm_device_t *dev = priv->head->dev; 241 drm_device_t *dev = priv->head->dev;
237 drm_client_t __user *argp = (void __user *)arg; 242 drm_client_t __user *argp = (void __user *)arg;
238 drm_client_t client; 243 drm_client_t client;
239 drm_file_t *pt; 244 drm_file_t *pt;
240 int idx; 245 int idx;
241 int i; 246 int i;
242 247
243 if (copy_from_user(&client, argp, sizeof(client))) 248 if (copy_from_user(&client, argp, sizeof(client)))
244 return -EFAULT; 249 return -EFAULT;
245 idx = client.idx; 250 idx = client.idx;
246 down(&dev->struct_sem); 251 down(&dev->struct_sem);
247 for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) 252 for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ;
248 ;
249 253
250 if (!pt) { 254 if (!pt) {
251 up(&dev->struct_sem); 255 up(&dev->struct_sem);
252 return -EINVAL; 256 return -EINVAL;
253 } 257 }
254 client.auth = pt->authenticated; 258 client.auth = pt->authenticated;
255 client.pid = pt->pid; 259 client.pid = pt->pid;
256 client.uid = pt->uid; 260 client.uid = pt->uid;
257 client.magic = pt->magic; 261 client.magic = pt->magic;
258 client.iocs = pt->ioctl_count; 262 client.iocs = pt->ioctl_count;
259 up(&dev->struct_sem); 263 up(&dev->struct_sem);
260 264
261 if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client))) 265 if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client)))
262 return -EFAULT; 266 return -EFAULT;
263 return 0; 267 return 0;
264} 268}
265 269
266/** 270/**
267 * Get statistics information. 271 * Get statistics information.
268 * 272 *
269 * \param inode device inode. 273 * \param inode device inode.
270 * \param filp file pointer. 274 * \param filp file pointer.
271 * \param cmd command. 275 * \param cmd command.
272 * \param arg user argument, pointing to a drm_stats structure. 276 * \param arg user argument, pointing to a drm_stats structure.
273 * 277 *
274 * \return zero on success or a negative number on failure. 278 * \return zero on success or a negative number on failure.
275 */ 279 */
276int drm_getstats( struct inode *inode, struct file *filp, 280int drm_getstats(struct inode *inode, struct file *filp,
277 unsigned int cmd, unsigned long arg ) 281 unsigned int cmd, unsigned long arg)
278{ 282{
279 drm_file_t *priv = filp->private_data; 283 drm_file_t *priv = filp->private_data;
280 drm_device_t *dev = priv->head->dev; 284 drm_device_t *dev = priv->head->dev;
281 drm_stats_t stats; 285 drm_stats_t stats;
282 int i; 286 int i;
283 287
284 memset(&stats, 0, sizeof(stats)); 288 memset(&stats, 0, sizeof(stats));
285 289
286 down(&dev->struct_sem); 290 down(&dev->struct_sem);
287 291
288 for (i = 0; i < dev->counters; i++) { 292 for (i = 0; i < dev->counters; i++) {
289 if (dev->types[i] == _DRM_STAT_LOCK) 293 if (dev->types[i] == _DRM_STAT_LOCK)
290 stats.data[i].value 294 stats.data[i].value
291 = (dev->lock.hw_lock 295 = (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
292 ? dev->lock.hw_lock->lock : 0); 296 else
293 else
294 stats.data[i].value = atomic_read(&dev->counts[i]); 297 stats.data[i].value = atomic_read(&dev->counts[i]);
295 stats.data[i].type = dev->types[i]; 298 stats.data[i].type = dev->types[i];
296 } 299 }
297 300
298 stats.count = dev->counters; 301 stats.count = dev->counters;
299 302
300 up(&dev->struct_sem); 303 up(&dev->struct_sem);
301 304
302 if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats))) 305 if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats)))
303 return -EFAULT; 306 return -EFAULT;
304 return 0; 307 return 0;
305} 308}
@@ -352,7 +355,8 @@ int drm_setversion(DRM_IOCTL_ARGS)
352 355
353 if (sv.drm_dd_major != -1) { 356 if (sv.drm_dd_major != -1) {
354 if (sv.drm_dd_major != version.version_major || 357 if (sv.drm_dd_major != version.version_major ||
355 sv.drm_dd_minor < 0 || sv.drm_dd_minor > version.version_minor) 358 sv.drm_dd_minor < 0
359 || sv.drm_dd_minor > version.version_minor)
356 return EINVAL; 360 return EINVAL;
357 361
358 if (dev->driver->set_version) 362 if (dev->driver->set_version)
@@ -363,7 +367,7 @@ int drm_setversion(DRM_IOCTL_ARGS)
363 367
364/** No-op ioctl. */ 368/** No-op ioctl. */
365int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd, 369int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
366 unsigned long arg) 370 unsigned long arg)
367{ 371{
368 DRM_DEBUG("\n"); 372 DRM_DEBUG("\n");
369 return 0; 373 return 0;