diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-11-11 06:33:39 -0500 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-11-11 06:33:39 -0500 |
commit | efa58395bee82dc5a87805e7eb7c710e88eb4bd7 (patch) | |
tree | 39b845cda408682638f48d955a066592863ba2d0 /drivers/char/drm/drm_agpsupport.c | |
parent | 732052ed3e7539d87136dd833be523747af3fb3e (diff) |
drm: add in-kernel entry points for rest of AGP ioctls
Allow DRM modules to call AGP internally in the kernel.
From: Ian Romanick <idr@us.ibm.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm/drm_agpsupport.c')
-rw-r--r-- | drivers/char/drm/drm_agpsupport.c | 123 |
1 files changed, 81 insertions, 42 deletions
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c index 2b6453a9ffce..b80e61a4c40b 100644 --- a/drivers/char/drm/drm_agpsupport.c +++ b/drivers/char/drm/drm_agpsupport.c | |||
@@ -208,30 +208,22 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, | |||
208 | * Verifies the AGP device is present and has been acquired, allocates the | 208 | * Verifies the AGP device is present and has been acquired, allocates the |
209 | * memory via alloc_agp() and creates a drm_agp_mem entry for it. | 209 | * memory via alloc_agp() and creates a drm_agp_mem entry for it. |
210 | */ | 210 | */ |
211 | int drm_agp_alloc(struct inode *inode, struct file *filp, | 211 | int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request) |
212 | unsigned int cmd, unsigned long arg) | ||
213 | { | 212 | { |
214 | drm_file_t *priv = filp->private_data; | ||
215 | drm_device_t *dev = priv->head->dev; | ||
216 | drm_agp_buffer_t request; | ||
217 | drm_agp_mem_t *entry; | 213 | drm_agp_mem_t *entry; |
218 | DRM_AGP_MEM *memory; | 214 | DRM_AGP_MEM *memory; |
219 | unsigned long pages; | 215 | unsigned long pages; |
220 | u32 type; | 216 | u32 type; |
221 | drm_agp_buffer_t __user *argp = (void __user *)arg; | ||
222 | 217 | ||
223 | if (!dev->agp || !dev->agp->acquired) | 218 | if (!dev->agp || !dev->agp->acquired) |
224 | return -EINVAL; | 219 | return -EINVAL; |
225 | if (copy_from_user(&request, argp, sizeof(request))) | ||
226 | return -EFAULT; | ||
227 | if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) | 220 | if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) |
228 | return -ENOMEM; | 221 | return -ENOMEM; |
229 | 222 | ||
230 | memset(entry, 0, sizeof(*entry)); | 223 | memset(entry, 0, sizeof(*entry)); |
231 | 224 | ||
232 | pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; | 225 | pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; |
233 | type = (u32) request.type; | 226 | type = (u32) request->type; |
234 | |||
235 | if (!(memory = drm_alloc_agp(dev, pages, type))) { | 227 | if (!(memory = drm_alloc_agp(dev, pages, type))) { |
236 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 228 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); |
237 | return -ENOMEM; | 229 | return -ENOMEM; |
@@ -247,16 +239,39 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, | |||
247 | dev->agp->memory->prev = entry; | 239 | dev->agp->memory->prev = entry; |
248 | dev->agp->memory = entry; | 240 | dev->agp->memory = entry; |
249 | 241 | ||
250 | request.handle = entry->handle; | 242 | request->handle = entry->handle; |
251 | request.physical = memory->physical; | 243 | request->physical = memory->physical; |
244 | |||
245 | return 0; | ||
246 | } | ||
247 | EXPORT_SYMBOL(drm_agp_alloc); | ||
248 | |||
249 | int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp, | ||
250 | unsigned int cmd, unsigned long arg) | ||
251 | { | ||
252 | drm_file_t *priv = filp->private_data; | ||
253 | drm_device_t *dev = priv->head->dev; | ||
254 | drm_agp_buffer_t request; | ||
255 | drm_agp_buffer_t __user *argp = (void __user *)arg; | ||
256 | int err; | ||
257 | |||
258 | if (copy_from_user(&request, argp, sizeof(request))) | ||
259 | return -EFAULT; | ||
260 | |||
261 | err = drm_agp_alloc(dev, &request); | ||
262 | if (err) | ||
263 | return err; | ||
252 | 264 | ||
253 | if (copy_to_user(argp, &request, sizeof(request))) { | 265 | if (copy_to_user(argp, &request, sizeof(request))) { |
266 | drm_agp_mem_t *entry = dev->agp->memory; | ||
267 | |||
254 | dev->agp->memory = entry->next; | 268 | dev->agp->memory = entry->next; |
255 | dev->agp->memory->prev = NULL; | 269 | dev->agp->memory->prev = NULL; |
256 | drm_free_agp(memory, pages); | 270 | drm_free_agp(entry->memory, entry->pages); |
257 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 271 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); |
258 | return -EFAULT; | 272 | return -EFAULT; |
259 | } | 273 | } |
274 | |||
260 | return 0; | 275 | return 0; |
261 | } | 276 | } |
262 | 277 | ||
@@ -293,21 +308,14 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev, | |||
293 | * Verifies the AGP device is present and acquired, looks-up the AGP memory | 308 | * Verifies the AGP device is present and acquired, looks-up the AGP memory |
294 | * entry and passes it to the unbind_agp() function. | 309 | * entry and passes it to the unbind_agp() function. |
295 | */ | 310 | */ |
296 | int drm_agp_unbind(struct inode *inode, struct file *filp, | 311 | int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request) |
297 | unsigned int cmd, unsigned long arg) | ||
298 | { | 312 | { |
299 | drm_file_t *priv = filp->private_data; | ||
300 | drm_device_t *dev = priv->head->dev; | ||
301 | drm_agp_binding_t request; | ||
302 | drm_agp_mem_t *entry; | 313 | drm_agp_mem_t *entry; |
303 | int ret; | 314 | int ret; |
304 | 315 | ||
305 | if (!dev->agp || !dev->agp->acquired) | 316 | if (!dev->agp || !dev->agp->acquired) |
306 | return -EINVAL; | 317 | return -EINVAL; |
307 | if (copy_from_user | 318 | if (!(entry = drm_agp_lookup_entry(dev, request->handle))) |
308 | (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) | ||
309 | return -EFAULT; | ||
310 | if (!(entry = drm_agp_lookup_entry(dev, request.handle))) | ||
311 | return -EINVAL; | 319 | return -EINVAL; |
312 | if (!entry->bound) | 320 | if (!entry->bound) |
313 | return -EINVAL; | 321 | return -EINVAL; |
@@ -316,6 +324,21 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, | |||
316 | entry->bound = 0; | 324 | entry->bound = 0; |
317 | return ret; | 325 | return ret; |
318 | } | 326 | } |
327 | EXPORT_SYMBOL(drm_agp_unbind); | ||
328 | |||
329 | int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp, | ||
330 | unsigned int cmd, unsigned long arg) | ||
331 | { | ||
332 | drm_file_t *priv = filp->private_data; | ||
333 | drm_device_t *dev = priv->head->dev; | ||
334 | drm_agp_binding_t request; | ||
335 | |||
336 | if (copy_from_user | ||
337 | (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) | ||
338 | return -EFAULT; | ||
339 | |||
340 | return drm_agp_unbind(dev, &request); | ||
341 | } | ||
319 | 342 | ||
320 | /** | 343 | /** |
321 | * Bind AGP memory into the GATT (ioctl) | 344 | * Bind AGP memory into the GATT (ioctl) |
@@ -330,26 +353,19 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, | |||
330 | * is currently bound into the GATT. Looks-up the AGP memory entry and passes | 353 | * is currently bound into the GATT. Looks-up the AGP memory entry and passes |
331 | * it to bind_agp() function. | 354 | * it to bind_agp() function. |
332 | */ | 355 | */ |
333 | int drm_agp_bind(struct inode *inode, struct file *filp, | 356 | int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request) |
334 | unsigned int cmd, unsigned long arg) | ||
335 | { | 357 | { |
336 | drm_file_t *priv = filp->private_data; | ||
337 | drm_device_t *dev = priv->head->dev; | ||
338 | drm_agp_binding_t request; | ||
339 | drm_agp_mem_t *entry; | 358 | drm_agp_mem_t *entry; |
340 | int retcode; | 359 | int retcode; |
341 | int page; | 360 | int page; |
342 | 361 | ||
343 | if (!dev->agp || !dev->agp->acquired) | 362 | if (!dev->agp || !dev->agp->acquired) |
344 | return -EINVAL; | 363 | return -EINVAL; |
345 | if (copy_from_user | 364 | if (!(entry = drm_agp_lookup_entry(dev, request->handle))) |
346 | (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) | ||
347 | return -EFAULT; | ||
348 | if (!(entry = drm_agp_lookup_entry(dev, request.handle))) | ||
349 | return -EINVAL; | 365 | return -EINVAL; |
350 | if (entry->bound) | 366 | if (entry->bound) |
351 | return -EINVAL; | 367 | return -EINVAL; |
352 | page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; | 368 | page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; |
353 | if ((retcode = drm_bind_agp(entry->memory, page))) | 369 | if ((retcode = drm_bind_agp(entry->memory, page))) |
354 | return retcode; | 370 | return retcode; |
355 | entry->bound = dev->agp->base + (page << PAGE_SHIFT); | 371 | entry->bound = dev->agp->base + (page << PAGE_SHIFT); |
@@ -357,6 +373,21 @@ int drm_agp_bind(struct inode *inode, struct file *filp, | |||
357 | dev->agp->base, entry->bound); | 373 | dev->agp->base, entry->bound); |
358 | return 0; | 374 | return 0; |
359 | } | 375 | } |
376 | EXPORT_SYMBOL(drm_agp_bind); | ||
377 | |||
378 | int drm_agp_bind_ioctl(struct inode *inode, struct file *filp, | ||
379 | unsigned int cmd, unsigned long arg) | ||
380 | { | ||
381 | drm_file_t *priv = filp->private_data; | ||
382 | drm_device_t *dev = priv->head->dev; | ||
383 | drm_agp_binding_t request; | ||
384 | |||
385 | if (copy_from_user | ||
386 | (&request, (drm_agp_binding_t __user *) arg, sizeof(request))) | ||
387 | return -EFAULT; | ||
388 | |||
389 | return drm_agp_bind(dev, &request); | ||
390 | } | ||
360 | 391 | ||
361 | /** | 392 | /** |
362 | * Free AGP memory (ioctl). | 393 | * Free AGP memory (ioctl). |
@@ -372,20 +403,13 @@ int drm_agp_bind(struct inode *inode, struct file *filp, | |||
372 | * unbind_agp(). Frees it via free_agp() as well as the entry itself | 403 | * unbind_agp(). Frees it via free_agp() as well as the entry itself |
373 | * and unlinks from the doubly linked list it's inserted in. | 404 | * and unlinks from the doubly linked list it's inserted in. |
374 | */ | 405 | */ |
375 | int drm_agp_free(struct inode *inode, struct file *filp, | 406 | int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request) |
376 | unsigned int cmd, unsigned long arg) | ||
377 | { | 407 | { |
378 | drm_file_t *priv = filp->private_data; | ||
379 | drm_device_t *dev = priv->head->dev; | ||
380 | drm_agp_buffer_t request; | ||
381 | drm_agp_mem_t *entry; | 408 | drm_agp_mem_t *entry; |
382 | 409 | ||
383 | if (!dev->agp || !dev->agp->acquired) | 410 | if (!dev->agp || !dev->agp->acquired) |
384 | return -EINVAL; | 411 | return -EINVAL; |
385 | if (copy_from_user | 412 | if (!(entry = drm_agp_lookup_entry(dev, request->handle))) |
386 | (&request, (drm_agp_buffer_t __user *) arg, sizeof(request))) | ||
387 | return -EFAULT; | ||
388 | if (!(entry = drm_agp_lookup_entry(dev, request.handle))) | ||
389 | return -EINVAL; | 413 | return -EINVAL; |
390 | if (entry->bound) | 414 | if (entry->bound) |
391 | drm_unbind_agp(entry->memory); | 415 | drm_unbind_agp(entry->memory); |
@@ -402,6 +426,21 @@ int drm_agp_free(struct inode *inode, struct file *filp, | |||
402 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 426 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); |
403 | return 0; | 427 | return 0; |
404 | } | 428 | } |
429 | EXPORT_SYMBOL(drm_agp_free); | ||
430 | |||
431 | int drm_agp_free_ioctl(struct inode *inode, struct file *filp, | ||
432 | unsigned int cmd, unsigned long arg) | ||
433 | { | ||
434 | drm_file_t *priv = filp->private_data; | ||
435 | drm_device_t *dev = priv->head->dev; | ||
436 | drm_agp_buffer_t request; | ||
437 | |||
438 | if (copy_from_user | ||
439 | (&request, (drm_agp_buffer_t __user *) arg, sizeof(request))) | ||
440 | return -EFAULT; | ||
441 | |||
442 | return drm_agp_free(dev, &request); | ||
443 | } | ||
405 | 444 | ||
406 | /** | 445 | /** |
407 | * Initialize the AGP resources. | 446 | * Initialize the AGP resources. |