1 /* $Id: ioctl32.c,v 1.5 2002/10/18 00:21:43 varenet Exp $
2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
4 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
5 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
7 * These routines maintain argument size conversion between 32bit and 64bit
11 #include <linux/syscalls.h>
14 #include "compat_ioctl.c"
17 #include <asm/ioctls.h>
20 #include "compat_ioctl.c"
22 /* Use this to get at 32-bit user passed pointers.
23 See sys_sparc32.c for description about these. */
24 #define A(__x) ((unsigned long)(__x))
25 /* The same for use with copy_from_user() and copy_to_user(). */
26 #define B(__x) ((void *)(unsigned long)(__x))
28 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
29 /* This really belongs in include/linux/drm.h -DaveM */
30 #include "../../../drivers/char/drm/drm.h"
32 typedef struct drm32_version
{
33 int version_major
; /* Major version */
34 int version_minor
; /* Minor version */
35 int version_patchlevel
;/* Patch level */
36 int name_len
; /* Length of name buffer */
37 u32 name
; /* Name of driver */
38 int date_len
; /* Length of date buffer */
39 u32 date
; /* User-space buffer to hold date */
40 int desc_len
; /* Length of desc buffer */
41 u32 desc
; /* User-space buffer to hold desc */
43 #define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
45 static int drm32_version(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
47 drm32_version_t
*uversion
= (drm32_version_t
*)arg
;
48 char *name_ptr
, *date_ptr
, *desc_ptr
;
50 drm_version_t kversion
;
54 memset(&kversion
, 0, sizeof(kversion
));
55 if (get_user(kversion
.name_len
, &uversion
->name_len
) ||
56 get_user(kversion
.date_len
, &uversion
->date_len
) ||
57 get_user(kversion
.desc_len
, &uversion
->desc_len
) ||
58 get_user(tmp1
, &uversion
->name
) ||
59 get_user(tmp2
, &uversion
->date
) ||
60 get_user(tmp3
, &uversion
->desc
))
63 name_ptr
= (char *) A(tmp1
);
64 date_ptr
= (char *) A(tmp2
);
65 desc_ptr
= (char *) A(tmp3
);
68 if (kversion
.name_len
&& name_ptr
) {
69 kversion
.name
= kmalloc(kversion
.name_len
, GFP_KERNEL
);
73 if (kversion
.date_len
&& date_ptr
) {
74 kversion
.date
= kmalloc(kversion
.date_len
, GFP_KERNEL
);
78 if (kversion
.desc_len
&& desc_ptr
) {
79 kversion
.desc
= kmalloc(kversion
.desc_len
, GFP_KERNEL
);
86 ret
= sys_ioctl (fd
, DRM_IOCTL_VERSION
, (unsigned long)&kversion
);
91 copy_to_user(name_ptr
, kversion
.name
, kversion
.name_len
)) ||
93 copy_to_user(date_ptr
, kversion
.date
, kversion
.date_len
)) ||
95 copy_to_user(desc_ptr
, kversion
.desc
, kversion
.desc_len
)))
97 if (put_user(kversion
.version_major
, &uversion
->version_major
) ||
98 put_user(kversion
.version_minor
, &uversion
->version_minor
) ||
99 put_user(kversion
.version_patchlevel
, &uversion
->version_patchlevel
) ||
100 put_user(kversion
.name_len
, &uversion
->name_len
) ||
101 put_user(kversion
.date_len
, &uversion
->date_len
) ||
102 put_user(kversion
.desc_len
, &uversion
->desc_len
))
108 kfree(kversion
.name
);
110 kfree(kversion
.date
);
112 kfree(kversion
.desc
);
116 typedef struct drm32_unique
{
117 int unique_len
; /* Length of unique */
118 u32 unique
; /* Unique name for driver instantiation */
120 #define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
121 #define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
123 static int drm32_getsetunique(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
125 drm32_unique_t
*uarg
= (drm32_unique_t
*)arg
;
132 if (get_user(karg
.unique_len
, &uarg
->unique_len
))
136 if (get_user(tmp
, &uarg
->unique
))
139 uptr
= (char *) A(tmp
);
142 karg
.unique
= kmalloc(karg
.unique_len
, GFP_KERNEL
);
145 if (cmd
== DRM32_IOCTL_SET_UNIQUE
&&
146 copy_from_user(karg
.unique
, uptr
, karg
.unique_len
)) {
154 if (cmd
== DRM32_IOCTL_GET_UNIQUE
)
155 ret
= sys_ioctl (fd
, DRM_IOCTL_GET_UNIQUE
, (unsigned long)&karg
);
157 ret
= sys_ioctl (fd
, DRM_IOCTL_SET_UNIQUE
, (unsigned long)&karg
);
161 if (cmd
== DRM32_IOCTL_GET_UNIQUE
&&
163 copy_to_user(uptr
, karg
.unique
, karg
.unique_len
))
165 if (put_user(karg
.unique_len
, &uarg
->unique_len
))
169 if (karg
.unique
!= NULL
)
175 typedef struct drm32_map
{
176 u32 offset
; /* Requested physical address (0 for SAREA)*/
177 u32 size
; /* Requested physical size (bytes) */
178 drm_map_type_t type
; /* Type of memory to map */
179 drm_map_flags_t flags
; /* Flags */
180 u32 handle
; /* User-space: "Handle" to pass to mmap */
181 /* Kernel-space: kernel-virtual address */
182 int mtrr
; /* MTRR slot used */
185 #define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
187 static int drm32_addmap(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
189 drm32_map_t
*uarg
= (drm32_map_t
*) arg
;
195 ret
= get_user(karg
.offset
, &uarg
->offset
);
196 ret
|= get_user(karg
.size
, &uarg
->size
);
197 ret
|= get_user(karg
.type
, &uarg
->type
);
198 ret
|= get_user(karg
.flags
, &uarg
->flags
);
199 ret
|= get_user(tmp
, &uarg
->handle
);
200 ret
|= get_user(karg
.mtrr
, &uarg
->mtrr
);
204 karg
.handle
= (void *) A(tmp
);
208 ret
= sys_ioctl(fd
, DRM_IOCTL_ADD_MAP
, (unsigned long) &karg
);
212 ret
= put_user(karg
.offset
, &uarg
->offset
);
213 ret
|= put_user(karg
.size
, &uarg
->size
);
214 ret
|= put_user(karg
.type
, &uarg
->type
);
215 ret
|= put_user(karg
.flags
, &uarg
->flags
);
216 tmp
= (u32
) (long)karg
.handle
;
217 ret
|= put_user(tmp
, &uarg
->handle
);
218 ret
|= put_user(karg
.mtrr
, &uarg
->mtrr
);
226 typedef struct drm32_buf_info
{
227 int count
; /* Entries in list */
228 u32 list
; /* (drm_buf_desc_t *) */
230 #define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
232 static int drm32_info_bufs(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
234 drm32_buf_info_t
*uarg
= (drm32_buf_info_t
*)arg
;
235 drm_buf_desc_t
*ulist
;
241 if (get_user(karg
.count
, &uarg
->count
) ||
242 get_user(tmp
, &uarg
->list
))
245 ulist
= (drm_buf_desc_t
*) A(tmp
);
247 orig_count
= karg
.count
;
249 karg
.list
= kmalloc(karg
.count
* sizeof(drm_buf_desc_t
), GFP_KERNEL
);
255 ret
= sys_ioctl(fd
, DRM_IOCTL_INFO_BUFS
, (unsigned long) &karg
);
259 if (karg
.count
<= orig_count
&&
260 (copy_to_user(ulist
, karg
.list
,
261 karg
.count
* sizeof(drm_buf_desc_t
))))
263 if (put_user(karg
.count
, &uarg
->count
))
272 typedef struct drm32_buf_free
{
274 u32 list
; /* (int *) */
276 #define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
278 static int drm32_free_bufs(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
280 drm32_buf_free_t
*uarg
= (drm32_buf_free_t
*)arg
;
287 if (get_user(karg
.count
, &uarg
->count
) ||
288 get_user(tmp
, &uarg
->list
))
291 ulist
= (int *) A(tmp
);
293 karg
.list
= kmalloc(karg
.count
* sizeof(int), GFP_KERNEL
);
298 if (copy_from_user(karg
.list
, ulist
, (karg
.count
* sizeof(int))))
303 ret
= sys_ioctl(fd
, DRM_IOCTL_FREE_BUFS
, (unsigned long) &karg
);
312 typedef struct drm32_buf_pub
{
313 int idx
; /* Index into master buflist */
314 int total
; /* Buffer size */
315 int used
; /* Amount of buffer in use (for DMA) */
316 u32 address
; /* Address of buffer (void *) */
319 typedef struct drm32_buf_map
{
320 int count
; /* Length of buflist */
321 u32
virtual; /* Mmaped area in user-virtual (void *) */
322 u32 list
; /* Buffer information (drm_buf_pub_t *) */
324 #define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
326 static int drm32_map_bufs(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
328 drm32_buf_map_t
*uarg
= (drm32_buf_map_t
*)arg
;
329 drm32_buf_pub_t
*ulist
;
332 int orig_count
, ret
, i
;
335 if (get_user(karg
.count
, &uarg
->count
) ||
336 get_user(tmp1
, &uarg
->virtual) ||
337 get_user(tmp2
, &uarg
->list
))
340 karg
.virtual = (void *) A(tmp1
);
341 ulist
= (drm32_buf_pub_t
*) A(tmp2
);
343 orig_count
= karg
.count
;
345 karg
.list
= kmalloc(karg
.count
* sizeof(drm_buf_pub_t
), GFP_KERNEL
);
350 for (i
= 0; i
< karg
.count
; i
++) {
351 if (get_user(karg
.list
[i
].idx
, &ulist
[i
].idx
) ||
352 get_user(karg
.list
[i
].total
, &ulist
[i
].total
) ||
353 get_user(karg
.list
[i
].used
, &ulist
[i
].used
) ||
354 get_user(tmp1
, &ulist
[i
].address
))
357 karg
.list
[i
].address
= (void *) A(tmp1
);
362 ret
= sys_ioctl(fd
, DRM_IOCTL_MAP_BUFS
, (unsigned long) &karg
);
366 for (i
= 0; i
< orig_count
; i
++) {
367 tmp1
= (u32
) (long) karg
.list
[i
].address
;
368 if (put_user(karg
.list
[i
].idx
, &ulist
[i
].idx
) ||
369 put_user(karg
.list
[i
].total
, &ulist
[i
].total
) ||
370 put_user(karg
.list
[i
].used
, &ulist
[i
].used
) ||
371 put_user(tmp1
, &ulist
[i
].address
)) {
376 if (put_user(karg
.count
, &uarg
->count
))
385 typedef struct drm32_dma
{
386 /* Indices here refer to the offset into
387 buflist in drm_buf_get_t. */
388 int context
; /* Context handle */
389 int send_count
; /* Number of buffers to send */
390 u32 send_indices
; /* List of handles to buffers (int *) */
391 u32 send_sizes
; /* Lengths of data to send (int *) */
392 drm_dma_flags_t flags
; /* Flags */
393 int request_count
; /* Number of buffers requested */
394 int request_size
; /* Desired size for buffers */
395 u32 request_indices
; /* Buffer information (int *) */
396 u32 request_sizes
; /* (int *) */
397 int granted_count
; /* Number of buffers granted */
399 #define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
401 /* RED PEN The DRM layer blindly dereferences the send/request
402 * indice/size arrays even though they are userland
405 static int drm32_dma(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
407 drm32_dma_t
*uarg
= (drm32_dma_t
*) arg
;
408 int *u_si
, *u_ss
, *u_ri
, *u_rs
;
412 u32 tmp1
, tmp2
, tmp3
, tmp4
;
414 karg
.send_indices
= karg
.send_sizes
= NULL
;
415 karg
.request_indices
= karg
.request_sizes
= NULL
;
417 if (get_user(karg
.context
, &uarg
->context
) ||
418 get_user(karg
.send_count
, &uarg
->send_count
) ||
419 get_user(tmp1
, &uarg
->send_indices
) ||
420 get_user(tmp2
, &uarg
->send_sizes
) ||
421 get_user(karg
.flags
, &uarg
->flags
) ||
422 get_user(karg
.request_count
, &uarg
->request_count
) ||
423 get_user(karg
.request_size
, &uarg
->request_size
) ||
424 get_user(tmp3
, &uarg
->request_indices
) ||
425 get_user(tmp4
, &uarg
->request_sizes
) ||
426 get_user(karg
.granted_count
, &uarg
->granted_count
))
429 u_si
= (int *) A(tmp1
);
430 u_ss
= (int *) A(tmp2
);
431 u_ri
= (int *) A(tmp3
);
432 u_rs
= (int *) A(tmp4
);
434 if (karg
.send_count
) {
435 karg
.send_indices
= kmalloc(karg
.send_count
* sizeof(int), GFP_KERNEL
);
436 karg
.send_sizes
= kmalloc(karg
.send_count
* sizeof(int), GFP_KERNEL
);
439 if (!karg
.send_indices
|| !karg
.send_sizes
)
443 if (copy_from_user(karg
.send_indices
, u_si
,
444 (karg
.send_count
* sizeof(int))) ||
445 copy_from_user(karg
.send_sizes
, u_ss
,
446 (karg
.send_count
* sizeof(int))))
450 if (karg
.request_count
) {
451 karg
.request_indices
= kmalloc(karg
.request_count
* sizeof(int), GFP_KERNEL
);
452 karg
.request_sizes
= kmalloc(karg
.request_count
* sizeof(int), GFP_KERNEL
);
455 if (!karg
.request_indices
|| !karg
.request_sizes
)
459 if (copy_from_user(karg
.request_indices
, u_ri
,
460 (karg
.request_count
* sizeof(int))) ||
461 copy_from_user(karg
.request_sizes
, u_rs
,
462 (karg
.request_count
* sizeof(int))))
468 ret
= sys_ioctl(fd
, DRM_IOCTL_DMA
, (unsigned long) &karg
);
472 if (put_user(karg
.context
, &uarg
->context
) ||
473 put_user(karg
.send_count
, &uarg
->send_count
) ||
474 put_user(karg
.flags
, &uarg
->flags
) ||
475 put_user(karg
.request_count
, &uarg
->request_count
) ||
476 put_user(karg
.request_size
, &uarg
->request_size
) ||
477 put_user(karg
.granted_count
, &uarg
->granted_count
))
480 if (karg
.send_count
) {
481 if (copy_to_user(u_si
, karg
.send_indices
,
482 (karg
.send_count
* sizeof(int))) ||
483 copy_to_user(u_ss
, karg
.send_sizes
,
484 (karg
.send_count
* sizeof(int))))
487 if (karg
.request_count
) {
488 if (copy_to_user(u_ri
, karg
.request_indices
,
489 (karg
.request_count
* sizeof(int))) ||
490 copy_to_user(u_rs
, karg
.request_sizes
,
491 (karg
.request_count
* sizeof(int))))
497 if (karg
.send_indices
)
498 kfree(karg
.send_indices
);
500 kfree(karg
.send_sizes
);
501 if (karg
.request_indices
)
502 kfree(karg
.request_indices
);
503 if (karg
.request_sizes
)
504 kfree(karg
.request_sizes
);
509 typedef struct drm32_ctx_res
{
511 u32 contexts
; /* (drm_ctx_t *) */
513 #define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
515 static int drm32_res_ctx(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
517 drm32_ctx_res_t
*uarg
= (drm32_ctx_res_t
*) arg
;
524 karg
.contexts
= NULL
;
525 if (get_user(karg
.count
, &uarg
->count
) ||
526 get_user(tmp
, &uarg
->contexts
))
529 ulist
= (drm_ctx_t
*) A(tmp
);
531 orig_count
= karg
.count
;
532 if (karg
.count
&& ulist
) {
533 karg
.contexts
= kmalloc((karg
.count
* sizeof(drm_ctx_t
)), GFP_KERNEL
);
536 if (copy_from_user(karg
.contexts
, ulist
,
537 (karg
.count
* sizeof(drm_ctx_t
)))) {
538 kfree(karg
.contexts
);
545 ret
= sys_ioctl(fd
, DRM_IOCTL_RES_CTX
, (unsigned long) &karg
);
550 if (copy_to_user(ulist
, karg
.contexts
,
551 (orig_count
* sizeof(drm_ctx_t
))))
554 if (put_user(karg
.count
, &uarg
->count
))
559 kfree(karg
.contexts
);
566 #define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, 0 },
567 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl)
569 #define IOCTL_TABLE_START struct ioctl_trans ioctl_start[] = {
570 #define IOCTL_TABLE_END };
573 #include <linux/compat_ioctl.h>
576 #include "compat_ioctl.c"
578 /* Might be moved to compat_ioctl.h with some ifdefs... */
579 COMPATIBLE_IOCTL(TIOCSTART
)
580 COMPATIBLE_IOCTL(TIOCSTOP
)
581 COMPATIBLE_IOCTL(TIOCSLTC
)
583 /* PA-specific ioctls */
584 COMPATIBLE_IOCTL(PA_PERF_ON
)
585 COMPATIBLE_IOCTL(PA_PERF_OFF
)
586 COMPATIBLE_IOCTL(PA_PERF_VERSION
)
588 /* And these ioctls need translation */
589 HANDLE_IOCTL(SIOCGPPPSTATS
, dev_ifsioc
)
590 HANDLE_IOCTL(SIOCGPPPCSTATS
, dev_ifsioc
)
591 HANDLE_IOCTL(SIOCGPPPVER
, dev_ifsioc
)
593 #if defined(CONFIG_GEN_RTC)
594 COMPATIBLE_IOCTL(RTC_AIE_ON
)
595 COMPATIBLE_IOCTL(RTC_AIE_OFF
)
596 COMPATIBLE_IOCTL(RTC_UIE_ON
)
597 COMPATIBLE_IOCTL(RTC_UIE_OFF
)
598 COMPATIBLE_IOCTL(RTC_PIE_ON
)
599 COMPATIBLE_IOCTL(RTC_PIE_OFF
)
600 COMPATIBLE_IOCTL(RTC_WIE_ON
)
601 COMPATIBLE_IOCTL(RTC_WIE_OFF
)
602 COMPATIBLE_IOCTL(RTC_ALM_SET
) /* struct rtc_time only has ints */
603 COMPATIBLE_IOCTL(RTC_ALM_READ
) /* struct rtc_time only has ints */
604 COMPATIBLE_IOCTL(RTC_RD_TIME
) /* struct rtc_time only has ints */
605 COMPATIBLE_IOCTL(RTC_SET_TIME
) /* struct rtc_time only has ints */
606 HANDLE_IOCTL(RTC_IRQP_READ
, w_long
)
607 COMPATIBLE_IOCTL(RTC_IRQP_SET
)
608 HANDLE_IOCTL(RTC_EPOCH_READ
, w_long
)
609 COMPATIBLE_IOCTL(RTC_EPOCH_SET
)
612 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
613 HANDLE_IOCTL(DRM32_IOCTL_VERSION
, drm32_version
);
614 HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE
, drm32_getsetunique
);
615 HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE
, drm32_getsetunique
);
616 HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP
, drm32_addmap
);
617 HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS
, drm32_info_bufs
);
618 HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS
, drm32_free_bufs
);
619 HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS
, drm32_map_bufs
);
620 HANDLE_IOCTL(DRM32_IOCTL_DMA
, drm32_dma
);
621 HANDLE_IOCTL(DRM32_IOCTL_RES_CTX
, drm32_res_ctx
);
625 int ioctl_table_size
= ARRAY_SIZE(ioctl_start
);