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 <asm/uaccess.h>
35 #include "compat_ioctl.h"
37 static int compat_agpioc_info_wrap(struct agp_file_private
*priv
, void __user
*arg
)
39 struct agp_info32 userinfo
;
40 struct agp_kern_info kerninfo
;
42 agp_copy_info(agp_bridge
, &kerninfo
);
44 userinfo
.version
.major
= kerninfo
.version
.major
;
45 userinfo
.version
.minor
= kerninfo
.version
.minor
;
46 userinfo
.bridge_id
= kerninfo
.device
->vendor
|
47 (kerninfo
.device
->device
<< 16);
48 userinfo
.agp_mode
= kerninfo
.mode
;
49 userinfo
.aper_base
= (compat_long_t
)kerninfo
.aper_base
;
50 userinfo
.aper_size
= kerninfo
.aper_size
;
51 userinfo
.pg_total
= userinfo
.pg_system
= kerninfo
.max_memory
;
52 userinfo
.pg_used
= kerninfo
.current_memory
;
54 if (copy_to_user(arg
, &userinfo
, sizeof(userinfo
)))
60 static int compat_agpioc_reserve_wrap(struct agp_file_private
*priv
, void __user
*arg
)
62 struct agp_region32 ureserve
;
63 struct agp_region kreserve
;
64 struct agp_client
*client
;
65 struct agp_file_private
*client_priv
;
68 if (copy_from_user(&ureserve
, arg
, sizeof(ureserve
)))
71 if ((unsigned) ureserve
.seg_count
>= ~0U/sizeof(struct agp_segment32
))
74 kreserve
.pid
= ureserve
.pid
;
75 kreserve
.seg_count
= ureserve
.seg_count
;
77 client
= agp_find_client_by_pid(kreserve
.pid
);
79 if (kreserve
.seg_count
== 0) {
81 client_priv
= agp_find_private(kreserve
.pid
);
83 if (client_priv
!= NULL
) {
84 set_bit(AGP_FF_IS_CLIENT
, &client_priv
->access_flags
);
85 set_bit(AGP_FF_IS_VALID
, &client_priv
->access_flags
);
88 /* client is already removed */
91 return agp_remove_client(kreserve
.pid
);
93 struct agp_segment32
*usegment
;
94 struct agp_segment
*ksegment
;
97 if (ureserve
.seg_count
>= 16384)
100 usegment
= kmalloc(sizeof(*usegment
) * ureserve
.seg_count
, GFP_KERNEL
);
104 ksegment
= kmalloc(sizeof(*ksegment
) * kreserve
.seg_count
, GFP_KERNEL
);
110 if (copy_from_user(usegment
, (void __user
*) ureserve
.seg_list
,
111 sizeof(*usegment
) * ureserve
.seg_count
)) {
117 for (seg
= 0; seg
< ureserve
.seg_count
; seg
++) {
118 ksegment
[seg
].pg_start
= usegment
[seg
].pg_start
;
119 ksegment
[seg
].pg_count
= usegment
[seg
].pg_count
;
120 ksegment
[seg
].prot
= usegment
[seg
].prot
;
124 kreserve
.seg_list
= ksegment
;
126 if (client
== NULL
) {
127 /* Create the client and add the segment */
128 client
= agp_create_client(kreserve
.pid
);
130 if (client
== NULL
) {
134 client_priv
= agp_find_private(kreserve
.pid
);
136 if (client_priv
!= NULL
) {
137 set_bit(AGP_FF_IS_CLIENT
, &client_priv
->access_flags
);
138 set_bit(AGP_FF_IS_VALID
, &client_priv
->access_flags
);
141 return agp_create_segment(client
, &kreserve
);
143 /* Will never really happen */
147 static int compat_agpioc_allocate_wrap(struct agp_file_private
*priv
, void __user
*arg
)
149 struct agp_memory
*memory
;
150 struct agp_allocate32 alloc
;
153 if (copy_from_user(&alloc
, arg
, sizeof(alloc
)))
156 memory
= agp_allocate_memory_wrap(alloc
.pg_count
, alloc
.type
);
161 alloc
.key
= memory
->key
;
162 alloc
.physical
= memory
->physical
;
164 if (copy_to_user(arg
, &alloc
, sizeof(alloc
))) {
165 agp_free_memory_wrap(memory
);
171 static int compat_agpioc_bind_wrap(struct agp_file_private
*priv
, void __user
*arg
)
173 struct agp_bind32 bind_info
;
174 struct agp_memory
*memory
;
177 if (copy_from_user(&bind_info
, arg
, sizeof(bind_info
)))
180 memory
= agp_find_mem_by_key(bind_info
.key
);
185 return agp_bind_memory(memory
, bind_info
.pg_start
);
188 static int compat_agpioc_unbind_wrap(struct agp_file_private
*priv
, void __user
*arg
)
190 struct agp_memory
*memory
;
191 struct agp_unbind32 unbind
;
194 if (copy_from_user(&unbind
, arg
, sizeof(unbind
)))
197 memory
= agp_find_mem_by_key(unbind
.key
);
202 return agp_unbind_memory(memory
);
205 long compat_agp_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
207 struct agp_file_private
*curr_priv
= file
->private_data
;
208 int ret_val
= -ENOTTY
;
210 mutex_lock(&(agp_fe
.agp_mutex
));
212 if ((agp_fe
.current_controller
== NULL
) &&
213 (cmd
!= AGPIOC_ACQUIRE32
)) {
217 if ((agp_fe
.backend_acquired
!= TRUE
) &&
218 (cmd
!= AGPIOC_ACQUIRE32
)) {
222 if (cmd
!= AGPIOC_ACQUIRE32
) {
223 if (!(test_bit(AGP_FF_IS_CONTROLLER
, &curr_priv
->access_flags
))) {
227 /* Use the original pid of the controller,
228 * in case it's threaded */
230 if (agp_fe
.current_controller
->pid
!= curr_priv
->my_pid
) {
238 ret_val
= compat_agpioc_info_wrap(curr_priv
, (void __user
*) arg
);
241 case AGPIOC_ACQUIRE32
:
242 ret_val
= agpioc_acquire_wrap(curr_priv
);
245 case AGPIOC_RELEASE32
:
246 ret_val
= agpioc_release_wrap(curr_priv
);
250 ret_val
= agpioc_setup_wrap(curr_priv
, (void __user
*) arg
);
253 case AGPIOC_RESERVE32
:
254 ret_val
= compat_agpioc_reserve_wrap(curr_priv
, (void __user
*) arg
);
257 case AGPIOC_PROTECT32
:
258 ret_val
= agpioc_protect_wrap(curr_priv
);
261 case AGPIOC_ALLOCATE32
:
262 ret_val
= compat_agpioc_allocate_wrap(curr_priv
, (void __user
*) arg
);
265 case AGPIOC_DEALLOCATE32
:
266 ret_val
= agpioc_deallocate_wrap(curr_priv
, (int) arg
);
270 ret_val
= compat_agpioc_bind_wrap(curr_priv
, (void __user
*) arg
);
273 case AGPIOC_UNBIND32
:
274 ret_val
= compat_agpioc_unbind_wrap(curr_priv
, (void __user
*) arg
);
277 case AGPIOC_CHIPSET_FLUSH32
:
278 ret_val
= agpioc_chipset_flush_wrap(curr_priv
);
283 DBG("ioctl returns %d\n", ret_val
);
284 mutex_unlock(&(agp_fe
.agp_mutex
));