1 /*
2 * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
3 */
4
5 /**
6 * \file drm_agpsupport.c
7 * DRM support for AGP/GART backend
8 *
9 * \author Rickard E. (Rik) Faith <faith@valinux.com>
10 * \author Gareth Hughes <gareth@valinux.com>
11 */
12
13 /*
14 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
15 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
16 * Copyright (c) 2009, 2013, Intel Corporation.
17 * All Rights Reserved.
18 *
19 * Permission is hereby granted, free of charge, to any person obtaining a
20 * copy of this software and associated documentation files (the "Software"),
21 * to deal in the Software without restriction, including without limitation
22 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
23 * and/or sell copies of the Software, and to permit persons to whom the
24 * Software is furnished to do so, subject to the following conditions:
25 *
26 * The above copyright notice and this permission notice (including the next
27 * paragraph) shall be included in all copies or substantial portions of the
28 * Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
33 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
34 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
35 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
36 * OTHER DEALINGS IN THE SOFTWARE.
37 */
38
39 #include "drm.h"
40 #include "drmP.h"
41
42 #ifndef AGP_PAGE_SIZE
43 #define AGP_PAGE_SIZE 4096
44 #define AGP_PAGE_SHIFT 12
45 #endif
46
47 /*
48 * The agpa_key field of struct agp_allocate_t actually is
49 * an index to an array. It can be zero. But we will use
50 * this agpa_key as a handle returned to userland. Generally,
51 * 0 is not a valid value for a handle, so we add an offset
52 * to the key to get a handle.
53 */
54 #define DRM_AGP_KEY_OFFSET 8
55
drm_agp_cleanup(struct drm_device * dev)56 void drm_agp_cleanup(struct drm_device *dev)
57 {
58 struct drm_agp_head *agp = dev->agp;
59
60 (void) ldi_close(agp->agpgart_lh, FEXCL, kcred);
61 ldi_ident_release(agp->agpgart_li);
62 }
63
64 /**
65 * Get AGP information.
66 *
67 * \param inode device inode.
68 * \param file_priv DRM file private.
69 * \param cmd command.
70 * \param arg pointer to a (output) drm_agp_info structure.
71 * \return zero on success or a negative number on failure.
72 *
73 * Verifies the AGP device has been initialized and acquired and fills in the
74 * drm_agp_info structure with the information in drm_agp_head::agp_info.
75 */
drm_agp_info(struct drm_device * dev,struct drm_agp_info * info)76 int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info)
77 {
78 agp_info_t *agpinfo;
79
80 if (!dev->agp || !dev->agp->acquired)
81 return -EINVAL;
82
83 agpinfo = &dev->agp->agp_info;
84 info->agp_version_major = agpinfo->agpi_version.agpv_major;
85 info->agp_version_minor = agpinfo->agpi_version.agpv_minor;
86 info->mode = agpinfo->agpi_mode;
87 info->aperture_base = agpinfo->agpi_aperbase;
88 info->aperture_size = agpinfo->agpi_apersize * 1024 * 1024;
89 info->memory_allowed = agpinfo->agpi_pgtotal << PAGE_SHIFT;
90 info->memory_used = agpinfo->agpi_pgused << PAGE_SHIFT;
91 info->id_vendor = agpinfo->agpi_devid & 0xffff;
92 info->id_device = agpinfo->agpi_devid >> 16;
93
94 return 0;
95 }
96
97 /* LINTED */
drm_agp_info_ioctl(DRM_IOCTL_ARGS)98 int drm_agp_info_ioctl(DRM_IOCTL_ARGS)
99 {
100 struct drm_agp_info *info = data;
101 int err;
102
103 err = drm_agp_info(dev, info);
104 if (err)
105 return err;
106
107 return 0;
108 }
109
110 /**
111 * Acquire the AGP device.
112 *
113 * \param dev DRM device that is to acquire AGP.
114 * \return zero on success or a negative number on failure.
115 *
116 * Verifies the AGP device hasn't been acquired before and calls
117 * \c agp_backend_acquire.
118 */
drm_agp_acquire(struct drm_device * dev)119 int drm_agp_acquire(struct drm_device * dev)
120 {
121 if (!dev->agp)
122 return -ENODEV;
123 if (dev->agp->acquired)
124 return -EBUSY;
125 {
126 int ret, rval;
127 if (ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_ACQUIRE,
128 (uintptr_t)0, FKIOCTL, kcred, &rval)) {
129 DRM_ERROR("AGPIOC_ACQUIRE failed");
130 return -ret;
131 }
132 }
133 dev->agp->acquired = 1;
134 return 0;
135 }
136
137 /**
138 * Acquire the AGP device (ioctl).
139 *
140 * \param inode device inode.
141 * \param file_priv DRM file private.
142 * \param cmd command.
143 * \param arg user argument.
144 * \return zero on success or a negative number on failure.
145 *
146 * Verifies the AGP device hasn't been acquired before and calls
147 * \c agp_backend_acquire.
148 */
149 /* LINTED */
drm_agp_acquire_ioctl(DRM_IOCTL_ARGS)150 int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS)
151 {
152 return drm_agp_acquire((struct drm_device *) file->minor->dev);
153 }
154
155 /**
156 * Release the AGP device.
157 *
158 * \param dev DRM device that is to release AGP.
159 * \return zero on success or a negative number on failure.
160 *
161 * Verifies the AGP device has been acquired and calls \c agp_backend_release.
162 */
drm_agp_release(struct drm_device * dev)163 int drm_agp_release(struct drm_device * dev)
164 {
165 if (!dev->agp || !dev->agp->acquired)
166 return -EINVAL;
167 {
168 int ret, rval;
169 if (ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_RELEASE,
170 (intptr_t)0, FKIOCTL, kcred, &rval)) {
171 DRM_ERROR("AGPIOC_RELEASE failed");
172 return -ret;
173 }
174 }
175 dev->agp->acquired = 0;
176 return 0;
177 }
178
179 /* LINTED */
drm_agp_release_ioctl(DRM_IOCTL_ARGS)180 int drm_agp_release_ioctl(DRM_IOCTL_ARGS)
181 {
182 return drm_agp_release(dev);
183 }
184
185 /**
186 * Enable the AGP bus.
187 *
188 * \param dev DRM device that has previously acquired AGP.
189 * \param mode Requested AGP mode.
190 * \return zero on success or a negative number on failure.
191 *
192 * Verifies the AGP device has been acquired but not enabled, and calls
193 * \c agp_enable.
194 */
drm_agp_enable(struct drm_device * dev,struct drm_agp_mode mode)195 int drm_agp_enable(struct drm_device * dev, struct drm_agp_mode mode)
196 {
197 if (!dev->agp || !dev->agp->acquired)
198 return -EINVAL;
199
200 dev->agp->mode = mode.mode;
201 {
202 agp_setup_t setup;
203 int ret, rval;
204 setup.agps_mode = (uint32_t)mode.mode;
205 if (ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_SETUP,
206 (intptr_t)&setup, FKIOCTL, kcred, &rval)) {
207 DRM_ERROR("AGPIOC_SETUP failed");
208 return -ret;
209 }
210 }
211 dev->agp->enabled = 1;
212 return 0;
213 }
214
215 /* LINTED */
drm_agp_enable_ioctl(DRM_IOCTL_ARGS)216 int drm_agp_enable_ioctl(DRM_IOCTL_ARGS)
217 {
218 struct drm_agp_mode *mode = data;
219
220 return drm_agp_enable(dev, *mode);
221 }
222
223 /**
224 * Allocate AGP memory.
225 *
226 * \param inode device inode.
227 * \param file_priv file private pointer.
228 * \param cmd command.
229 * \param arg pointer to a drm_agp_buffer structure.
230 * \return zero on success or a negative number on failure.
231 *
232 * Verifies the AGP device is present and has been acquired, allocates the
233 * memory via alloc_agp() and creates a drm_agp_mem entry for it.
234 */
drm_agp_alloc(struct drm_device * dev,struct drm_agp_buffer * request)235 int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request)
236 {
237 struct drm_agp_mem *entry;
238 agp_allocate_t alloc;
239 unsigned long pages;
240 int ret, rval;
241
242 if (!dev->agp || !dev->agp->acquired)
243 return -EINVAL;
244 if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
245 return -ENOMEM;
246
247 (void) memset(entry, 0, sizeof(*entry));
248
249 pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
250
251 alloc.agpa_pgcount = (uint32_t) pages;
252 alloc.agpa_type = AGP_NORMAL;
253 ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_ALLOCATE,
254 (intptr_t)&alloc, FKIOCTL, kcred, &rval);
255 if (ret) {
256 DRM_ERROR("AGPIOC_ALLOCATE failed");
257 kfree(entry, sizeof (*entry));
258 return -ret;
259 }
260
261 entry->handle = alloc.agpa_key + DRM_AGP_KEY_OFFSET;
262 entry->bound = 0;
263 entry->pages = (int) pages;
264 list_add(&entry->head, &dev->agp->memory, (caddr_t)entry);
265
266 request->handle = entry->handle;
267 request->physical = alloc.agpa_physical;
268
269 return 0;
270 }
271
272 /* LINTED */
drm_agp_alloc_ioctl(DRM_IOCTL_ARGS)273 int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS)
274 {
275 struct drm_agp_buffer *request = data;
276
277 return drm_agp_alloc(dev, request);
278 }
279
280 /**
281 * Search for the AGP memory entry associated with a handle.
282 *
283 * \param dev DRM device structure.
284 * \param handle AGP memory handle.
285 * \return pointer to the drm_agp_mem structure associated with \p handle.
286 *
287 * Walks through drm_agp_head::memory until finding a matching handle.
288 */
drm_agp_lookup_entry(struct drm_device * dev,unsigned long handle)289 static struct drm_agp_mem *drm_agp_lookup_entry(struct drm_device * dev,
290 unsigned long handle)
291 {
292 struct drm_agp_mem *entry;
293
294 list_for_each_entry(entry, struct drm_agp_mem, &dev->agp->memory, head) {
295 if (entry->handle == handle)
296 return entry;
297 }
298 return NULL;
299 }
300
301 /**
302 * Unbind AGP memory from the GATT (ioctl).
303 *
304 * \param inode device inode.
305 * \param file_priv DRM file private.
306 * \param cmd command.
307 * \param arg pointer to a drm_agp_binding structure.
308 * \return zero on success or a negative number on failure.
309 *
310 * Verifies the AGP device is present and acquired, looks-up the AGP memory
311 * entry and passes it to the unbind_agp() function.
312 */
drm_agp_unbind(struct drm_device * dev,struct drm_agp_binding * request)313 int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request)
314 {
315 struct drm_agp_mem *entry;
316 int ret;
317
318 if (!dev->agp || !dev->agp->acquired)
319 return -EINVAL;
320 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
321 return -EINVAL;
322 if (!entry->bound)
323 return -EINVAL;
324 {
325 agp_unbind_t unbind;
326 int rval;
327 unbind.agpu_pri = 0;
328 unbind.agpu_key = (uintptr_t)entry->handle - DRM_AGP_KEY_OFFSET;
329 if (ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_UNBIND,
330 (intptr_t)&unbind, FKIOCTL, kcred, &rval)) {
331 DRM_ERROR("AGPIOC_UNBIND failed");
332 return -ret;
333 }
334 }
335 entry->bound = 0;
336 return ret;
337 }
338
339 /* LINTED */
drm_agp_unbind_ioctl(DRM_IOCTL_ARGS)340 int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS)
341 {
342 struct drm_agp_binding *request = data;
343
344 return drm_agp_unbind(dev, request);
345 }
346
347 /**
348 * Bind AGP memory into the GATT (ioctl)
349 *
350 * \param inode device inode.
351 * \param file_priv DRM file private.
352 * \param cmd command.
353 * \param arg pointer to a drm_agp_binding structure.
354 * \return zero on success or a negative number on failure.
355 *
356 * Verifies the AGP device is present and has been acquired and that no memory
357 * is currently bound into the GATT. Looks-up the AGP memory entry and passes
358 * it to bind_agp() function.
359 */
drm_agp_bind(struct drm_device * dev,struct drm_agp_binding * request)360 int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request)
361 {
362 struct drm_agp_mem *entry;
363 int retcode;
364 int page;
365
366 if (!dev->agp || !dev->agp->acquired)
367 return -EINVAL;
368 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
369 return -EINVAL;
370 if (entry->bound)
371 return -EINVAL;
372 page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE;
373 {
374 uint_t key = (uintptr_t)entry->handle - DRM_AGP_KEY_OFFSET;
375 if (retcode = drm_agp_bind_memory(key, page, dev)) {
376 DRM_ERROR("failed key=0x%x, page=0x%x, "
377 "agp_base=0x%lx", key, page, dev->agp->base);
378 return retcode;
379 }
380 }
381 entry->bound = dev->agp->base + (page << PAGE_SHIFT);
382 DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
383 dev->agp->base, entry->bound);
384 return 0;
385 }
386
387 /* LINTED */
drm_agp_bind_ioctl(DRM_IOCTL_ARGS)388 int drm_agp_bind_ioctl(DRM_IOCTL_ARGS)
389 {
390 struct drm_agp_binding *request = data;
391
392 return drm_agp_bind(dev, request);
393 }
394
395 /**
396 * Free AGP memory (ioctl).
397 *
398 * \param inode device inode.
399 * \param file_priv DRM file private.
400 * \param cmd command.
401 * \param arg pointer to a drm_agp_buffer structure.
402 * \return zero on success or a negative number on failure.
403 *
404 * Verifies the AGP device is present and has been acquired and looks up the
405 * AGP memory entry. If the memory it's currently bound, unbind it via
406 * unbind_agp(). Frees it via free_agp() as well as the entry itself
407 * and unlinks from the doubly linked list it's inserted in.
408 */
drm_agp_free(struct drm_device * dev,struct drm_agp_buffer * request)409 int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request)
410 {
411 struct drm_agp_mem *entry;
412
413 if (!dev->agp || !dev->agp->acquired)
414 return -EINVAL;
415 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
416 return -EINVAL;
417 if (entry->bound)
418 (void) drm_agp_unbind_memory(request->handle, dev);
419
420 list_del(&entry->head);
421 {
422 int agpu_key = (uintptr_t)entry->handle - DRM_AGP_KEY_OFFSET;
423 int ret, rval;
424 ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_DEALLOCATE,
425 (intptr_t)agpu_key, FKIOCTL, kcred, &rval);
426 if (ret) {
427 DRM_ERROR("AGPIOC_DEALLOCATE failed,"
428 "akey=%d, ret=%d", agpu_key, ret);
429 return -ret;
430 }
431 }
432 kfree(entry, sizeof (*entry));
433 return 0;
434 }
435
436 /* LINTED */
drm_agp_free_ioctl(DRM_IOCTL_ARGS)437 int drm_agp_free_ioctl(DRM_IOCTL_ARGS)
438 {
439 struct drm_agp_buffer *request = data;
440
441 return drm_agp_free(dev, request);
442 }
443
444 /**
445 * Initialize the AGP resources.
446 *
447 * \return pointer to a drm_agp_head structure.
448 *
449 * Gets the drm_agp_t structure which is made available by the agpgart module
450 * via the inter_module_* functions. Creates and initializes a drm_agp_head
451 * structure.
452 */
drm_agp_init(struct drm_device * dev)453 struct drm_agp_head *drm_agp_init(struct drm_device *dev)
454 {
455 struct drm_agp_head *head = NULL;
456 int ret, rval;
457
458 if (!(head = kmalloc(sizeof(*head), GFP_KERNEL)))
459 return NULL;
460 (void) memset((void *)head, 0, sizeof(*head));
461 ret = ldi_ident_from_dip(dev->devinfo, &head->agpgart_li);
462 if (ret) {
463 DRM_ERROR("failed to get layerd ident, ret=%d", ret);
464 goto err_1;
465 }
466
467 ret = ldi_open_by_name(AGP_DEVICE, FEXCL, kcred,
468 &head->agpgart_lh, head->agpgart_li);
469 if (ret) {
470 DRM_ERROR("failed to open %s, ret=%d", AGP_DEVICE, ret);
471 goto err_2;
472 }
473
474 ret = ldi_ioctl(head->agpgart_lh, AGPIOC_INFO,
475 (intptr_t)&head->agp_info, FKIOCTL, kcred, &rval);
476 if (ret) {
477 DRM_ERROR("failed to get agpinfo, ret=%d", ret);
478 goto err_3;
479 }
480 INIT_LIST_HEAD(&head->memory);
481 head->base = head->agp_info.agpi_aperbase;
482 return head;
483
484 err_3:
485 (void) ldi_close(head->agpgart_lh, FEXCL, kcred);
486 err_2:
487 ldi_ident_release(head->agpgart_li);
488 err_1:
489 kfree(head, sizeof(*head));
490 return NULL;
491 }
492
493 /* LINTED */
drm_agp_allocate_memory(size_t pages,uint32_t type,struct drm_device * dev)494 void *drm_agp_allocate_memory(size_t pages, uint32_t type, struct drm_device *dev)
495 {
496 return NULL;
497 }
498
499 /* LINTED */
drm_agp_free_memory(agp_allocate_t * handle,struct drm_device * dev)500 int drm_agp_free_memory(agp_allocate_t *handle, struct drm_device *dev)
501 {
502 return 1;
503 }
504
drm_agp_bind_memory(unsigned int key,uint32_t start,struct drm_device * dev)505 int drm_agp_bind_memory(unsigned int key, uint32_t start, struct drm_device *dev)
506 {
507 agp_bind_t bind;
508 int ret, rval;
509
510 bind.agpb_pgstart = start;
511 bind.agpb_key = key;
512 if (ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_BIND,
513 (intptr_t)&bind, FKIOCTL, kcred, &rval)) {
514 DRM_DEBUG("AGPIOC_BIND failed");
515 return -ret;
516 }
517 return 0;
518 }
519
drm_agp_unbind_memory(unsigned long handle,struct drm_device * dev)520 int drm_agp_unbind_memory(unsigned long handle, struct drm_device *dev)
521 {
522 struct drm_agp_mem *entry;
523 agp_unbind_t unbind;
524 int ret, rval;
525
526 if (!dev->agp || !dev->agp->acquired)
527 return -EINVAL;
528
529 entry = drm_agp_lookup_entry(dev, handle);
530 if (!entry || !entry->bound)
531 return -EINVAL;
532
533 unbind.agpu_pri = 0;
534 unbind.agpu_key = (uintptr_t)entry->handle - DRM_AGP_KEY_OFFSET;
535 if (ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_UNBIND,
536 (intptr_t)&unbind, FKIOCTL, kcred, &rval)) {
537 DRM_ERROR("AGPIO_UNBIND failed");
538 return -ret;
539 }
540 entry->bound = 0;
541 return 0;
542 }
543
544 /**
545 * Binds a collection of pages into AGP memory at the given offset, returning
546 * the AGP memory structure containing them.
547 *
548 * No reference is held on the pages during this time -- it is up to the
549 * caller to handle that.
550 */
551 int
drm_agp_bind_pages(struct drm_device * dev,pfn_t * pages,unsigned long num_pages,uint32_t gtt_offset,unsigned int agp_type)552 drm_agp_bind_pages(struct drm_device *dev,
553 pfn_t *pages,
554 unsigned long num_pages,
555 uint32_t gtt_offset,
556 unsigned int agp_type)
557 {
558 agp_bind_pages_t bind;
559 int ret, rval;
560
561 bind.agpb_pgstart = gtt_offset / AGP_PAGE_SIZE;
562 bind.agpb_pgcount = num_pages;
563 bind.agpb_pages = pages;
564 bind.agpb_type = agp_type;
565
566 ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_PAGES_BIND,
567 (intptr_t)&bind, FKIOCTL, kcred, &rval);
568 if (ret) {
569 DRM_ERROR("AGPIOC_PAGES_BIND failed ret %d", ret);
570 return -ret;
571 }
572 return 0;
573 }
574
575 int
drm_agp_unbind_pages(struct drm_device * dev,pfn_t * pages,unsigned long num_pages,uint32_t gtt_offset,pfn_t scratch,uint32_t ignored)576 drm_agp_unbind_pages(struct drm_device *dev,
577 pfn_t *pages, /* NULL */
578 unsigned long num_pages,
579 uint32_t gtt_offset,
580 pfn_t scratch,
581 uint32_t ignored) /* old "VT_switch" flag */
582 {
583 agp_unbind_pages_t unbind;
584 int ret, rval;
585
586 unbind.agpu_pgstart = gtt_offset / AGP_PAGE_SIZE;
587 unbind.agpu_pgcount = num_pages;
588 unbind.agpu_scratch = scratch;
589 unbind.agpu_flags = 0;
590
591 ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_PAGES_UNBIND,
592 (intptr_t)&unbind, FKIOCTL, kcred, &rval);
593 if (ret) {
594 DRM_ERROR("AGPIOC_PAGES_UNBIND failed %d", ret);
595 return -ret;
596 }
597 return 0;
598 }
599
drm_agp_chipset_flush(struct drm_device * dev)600 void drm_agp_chipset_flush(struct drm_device *dev)
601 {
602 int ret, rval;
603
604 ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_FLUSHCHIPSET,
605 (intptr_t)0, FKIOCTL, kcred, &rval);
606 if (ret)
607 DRM_ERROR("AGPIOC_FLUSHCHIPSET failed, ret=%d", ret);
608 }
609
610 int
drm_agp_rw_gtt(struct drm_device * dev,unsigned long num_pages,uint32_t gtt_offset,void * gttp,uint32_t rw_flag)611 drm_agp_rw_gtt(struct drm_device *dev,
612 unsigned long num_pages,
613 uint32_t gtt_offset,
614 void *gttp,
615 uint32_t rw_flag) /* read = 0 write = 1 */
616 {
617 agp_rw_gtt_t rw;
618 int ret, rval;
619
620 rw.agprw_pgstart = gtt_offset / AGP_PAGE_SIZE;
621 rw.agprw_pgcount = num_pages;
622 rw.agprw_addr = gttp;
623 rw.agprw_flags = rw_flag;
624
625 ret = ldi_ioctl(dev->agp->agpgart_lh, AGPIOC_RW_GTT,
626 (intptr_t)&rw, FKIOCTL, kcred, &rval);
627 if (ret) {
628 DRM_ERROR("AGPIOC_RW_GTT failed %d", ret);
629 return -ret;
630 }
631 return 0;
632 }
633