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 | |
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')
-rw-r--r-- | drivers/char/drm/drmP.h | 12 | ||||
-rw-r--r-- | drivers/char/drm/drm_agpsupport.c | 123 | ||||
-rw-r--r-- | drivers/char/drm/drm_core.h | 4 | ||||
-rw-r--r-- | drivers/char/drm/drm_drv.c | 8 |
4 files changed, 95 insertions, 52 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index e9ede8d69e20..66814291949a 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -925,13 +925,17 @@ extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, | |||
925 | extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info); | 925 | extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info); |
926 | extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp, | 926 | extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp, |
927 | unsigned int cmd, unsigned long arg); | 927 | unsigned int cmd, unsigned long arg); |
928 | extern int drm_agp_alloc(struct inode *inode, struct file *filp, | 928 | extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request); |
929 | extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp, | ||
929 | unsigned int cmd, unsigned long arg); | 930 | unsigned int cmd, unsigned long arg); |
930 | extern int drm_agp_free(struct inode *inode, struct file *filp, | 931 | extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request); |
932 | extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp, | ||
931 | unsigned int cmd, unsigned long arg); | 933 | unsigned int cmd, unsigned long arg); |
932 | extern int drm_agp_unbind(struct inode *inode, struct file *filp, | 934 | extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request); |
935 | extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp, | ||
933 | unsigned int cmd, unsigned long arg); | 936 | unsigned int cmd, unsigned long arg); |
934 | extern int drm_agp_bind(struct inode *inode, struct file *filp, | 937 | extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request); |
938 | extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp, | ||
935 | unsigned int cmd, unsigned long arg); | 939 | unsigned int cmd, unsigned long arg); |
936 | extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, | 940 | extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, |
937 | size_t pages, u32 type); | 941 | size_t pages, u32 type); |
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. |
diff --git a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h index cc97bb906dda..f4f9db6c7ed4 100644 --- a/drivers/char/drm/drm_core.h +++ b/drivers/char/drm/drm_core.h | |||
@@ -24,11 +24,11 @@ | |||
24 | 24 | ||
25 | #define CORE_NAME "drm" | 25 | #define CORE_NAME "drm" |
26 | #define CORE_DESC "DRM shared core routines" | 26 | #define CORE_DESC "DRM shared core routines" |
27 | #define CORE_DATE "20040925" | 27 | #define CORE_DATE "20051102" |
28 | 28 | ||
29 | #define DRM_IF_MAJOR 1 | 29 | #define DRM_IF_MAJOR 1 |
30 | #define DRM_IF_MINOR 2 | 30 | #define DRM_IF_MINOR 2 |
31 | 31 | ||
32 | #define CORE_MAJOR 1 | 32 | #define CORE_MAJOR 1 |
33 | #define CORE_MINOR 0 | 33 | #define CORE_MINOR 0 |
34 | #define CORE_PATCHLEVEL 0 | 34 | #define CORE_PATCHLEVEL 1 |
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index d8ff84bdc3e7..222ae09ae65f 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -106,10 +106,10 @@ static drm_ioctl_desc_t drm_ioctls[] = { | |||
106 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1}, | 106 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1}, |
107 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1}, | 107 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1}, |
108 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0}, | 108 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0}, |
109 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1}, | 109 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, 1, 1}, |
110 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1}, | 110 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, 1, 1}, |
111 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1}, | 111 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, 1, 1}, |
112 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1}, | 112 | [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, 1, 1}, |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1}, | 115 | [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1}, |