diff options
Diffstat (limited to 'drivers/char/drm/drm_ioctl.c')
-rw-r--r-- | drivers/char/drm/drm_ioctl.c | 168 |
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 | */ |
52 | int drm_getunique(struct inode *inode, struct file *filp, | 52 | int 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 | */ |
86 | int drm_setunique(struct inode *inode, struct file *filp, | 86 | int 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 | ||
134 | static int | 138 | static int drm_set_busid(drm_device_t * dev) |
135 | drm_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 | */ |
172 | int drm_getmap( struct inode *inode, struct file *filp, | 176 | int 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 | */ |
232 | int drm_getclient( struct inode *inode, struct file *filp, | 237 | int 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 | */ |
276 | int drm_getstats( struct inode *inode, struct file *filp, | 280 | int 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. */ |
365 | int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd, | 369 | int 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; |