2 * AGPGART driver frontend compatibility ioctls
3 * Copyright (C) 2004 Silicon Graphics, Inc.
4 * Copyright (C) 2002-2003 Dave Jones
5 * Copyright (C) 1999 Jeff Hartmann
6 * Copyright (C) 1999 Precision Insight, Inc.
7 * Copyright (C) 1999 Xi Graphics, Inc.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
25 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #include <linux/kernel.h>
30 #include <linux/pci.h>
32 #include <linux/agpgart.h>
33 #include <linux/slab.h>
34 #include <linux/uaccess.h>
36 #include "compat_ioctl.h"
38 static int compat_agpioc_info_wrap(struct agp_file_private
*priv
, void __user
*arg
)
40 struct agp_info32 userinfo
;
41 struct agp_kern_info kerninfo
;
43 agp_copy_info(agp_bridge
, &kerninfo
);
45 userinfo
.version
.major
= kerninfo
.version
.major
;
46 userinfo
.version
.minor
= kerninfo
.version
.minor
;
47 userinfo
.bridge_id
= kerninfo
.device
->vendor
|
48 (kerninfo
.device
->device
<< 16);
49 userinfo
.agp_mode
= kerninfo
.mode
;
50 userinfo
.aper_base
= (compat_long_t
)kerninfo
.aper_base
;
51 userinfo
.aper_size
= kerninfo
.aper_size
;
52 userinfo
.pg_total
= userinfo
.pg_system
= kerninfo
.max_memory
;
53 userinfo
.pg_used
= kerninfo
.current_memory
;
55 if (copy_to_user(arg
, &userinfo
, sizeof(userinfo
)))
61 static int compat_agpioc_reserve_wrap(struct agp_file_private
*priv
, void __user
*arg
)
63 struct agp_region32 ureserve
;
64 struct agp_region kreserve
;
65 struct agp_client
*client
;
66 struct agp_file_private
*client_priv
;
69 if (copy_from_user(&ureserve
, arg
, sizeof(ureserve
)))
72 if ((unsigned) ureserve
.seg_count
>= ~0U/sizeof(struct agp_segment32
))
75 kreserve
.pid
= ureserve
.pid
;
76 kreserve
.seg_count
= ureserve
.seg_count
;
78 client
= agp_find_client_by_pid(kreserve
.pid
);
80 if (kreserve
.seg_count
== 0) {
82 client_priv
= agp_find_private(kreserve
.pid
);
84 if (client_priv
!= NULL
) {
85 set_bit(AGP_FF_IS_CLIENT
, &client_priv
->access_flags
);
86 set_bit(AGP_FF_IS_VALID
, &client_priv
->access_flags
);
89 /* client is already removed */
92 return agp_remove_client(kreserve
.pid
);
94 struct agp_segment32
*usegment
;
95 struct agp_segment
*ksegment
;
98 if (ureserve
.seg_count
>= 16384)
101 usegment
= kmalloc_array(ureserve
.seg_count
,
107 ksegment
= kmalloc_array(kreserve
.seg_count
,
115 if (copy_from_user(usegment
, (void __user
*) ureserve
.seg_list
,
116 sizeof(*usegment
) * ureserve
.seg_count
)) {
122 for (seg
= 0; seg
< ureserve
.seg_count
; seg
++) {
123 ksegment
[seg
].pg_start
= usegment
[seg
].pg_start
;
124 ksegment
[seg
].pg_count
= usegment
[seg
].pg_count
;
125 ksegment
[seg
].prot
= usegment
[seg
].prot
;
129 kreserve
.seg_list
= ksegment
;
131 if (client
== NULL
) {
132 /* Create the client and add the segment */
133 client
= agp_create_client(kreserve
.pid
);
135 if (client
== NULL
) {
139 client_priv
= agp_find_private(kreserve
.pid
);
141 if (client_priv
!= NULL
) {
142 set_bit(AGP_FF_IS_CLIENT
, &client_priv
->access_flags
);
143 set_bit(AGP_FF_IS_VALID
, &client_priv
->access_flags
);
146 return agp_create_segment(client
, &kreserve
);
148 /* Will never really happen */
152 static int compat_agpioc_allocate_wrap(struct agp_file_private
*priv
, void __user
*arg
)
154 struct agp_memory
*memory
;
155 struct agp_allocate32 alloc
;
158 if (copy_from_user(&alloc
, arg
, sizeof(alloc
)))
161 memory
= agp_allocate_memory_wrap(alloc
.pg_count
, alloc
.type
);
166 alloc
.key
= memory
->key
;
167 alloc
.physical
= memory
->physical
;
169 if (copy_to_user(arg
, &alloc
, sizeof(alloc
))) {
170 agp_free_memory_wrap(memory
);
176 static int compat_agpioc_bind_wrap(struct agp_file_private
*priv
, void __user
*arg
)
178 struct agp_bind32 bind_info
;
179 struct agp_memory
*memory
;
182 if (copy_from_user(&bind_info
, arg
, sizeof(bind_info
)))
185 memory
= agp_find_mem_by_key(bind_info
.key
);
190 return agp_bind_memory(memory
, bind_info
.pg_start
);
193 static int compat_agpioc_unbind_wrap(struct agp_file_private
*priv
, void __user
*arg
)
195 struct agp_memory
*memory
;
196 struct agp_unbind32 unbind
;
199 if (copy_from_user(&unbind
, arg
, sizeof(unbind
)))
202 memory
= agp_find_mem_by_key(unbind
.key
);
207 return agp_unbind_memory(memory
);
210 long compat_agp_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
212 struct agp_file_private
*curr_priv
= file
->private_data
;
213 int ret_val
= -ENOTTY
;
215 mutex_lock(&(agp_fe
.agp_mutex
));
217 if ((agp_fe
.current_controller
== NULL
) &&
218 (cmd
!= AGPIOC_ACQUIRE32
)) {
222 if ((agp_fe
.backend_acquired
!= true) &&
223 (cmd
!= AGPIOC_ACQUIRE32
)) {
227 if (cmd
!= AGPIOC_ACQUIRE32
) {
228 if (!(test_bit(AGP_FF_IS_CONTROLLER
, &curr_priv
->access_flags
))) {
232 /* Use the original pid of the controller,
233 * in case it's threaded */
235 if (agp_fe
.current_controller
->pid
!= curr_priv
->my_pid
) {
243 ret_val
= compat_agpioc_info_wrap(curr_priv
, (void __user
*) arg
);
246 case AGPIOC_ACQUIRE32
:
247 ret_val
= agpioc_acquire_wrap(curr_priv
);
250 case AGPIOC_RELEASE32
:
251 ret_val
= agpioc_release_wrap(curr_priv
);
255 ret_val
= agpioc_setup_wrap(curr_priv
, (void __user
*) arg
);
258 case AGPIOC_RESERVE32
:
259 ret_val
= compat_agpioc_reserve_wrap(curr_priv
, (void __user
*) arg
);
262 case AGPIOC_PROTECT32
:
263 ret_val
= agpioc_protect_wrap(curr_priv
);
266 case AGPIOC_ALLOCATE32
:
267 ret_val
= compat_agpioc_allocate_wrap(curr_priv
, (void __user
*) arg
);
270 case AGPIOC_DEALLOCATE32
:
271 ret_val
= agpioc_deallocate_wrap(curr_priv
, (int) arg
);
275 ret_val
= compat_agpioc_bind_wrap(curr_priv
, (void __user
*) arg
);
278 case AGPIOC_UNBIND32
:
279 ret_val
= compat_agpioc_unbind_wrap(curr_priv
, (void __user
*) arg
);
282 case AGPIOC_CHIPSET_FLUSH32
:
287 DBG("ioctl returns %d\n", ret_val
);
288 mutex_unlock(&(agp_fe
.agp_mutex
));