1 #include <linux/config.h>
2 #include <linux/compat.h>
3 #include <linux/videodev.h>
9 compat_ulong_t rangelow
, rangehigh
;
10 u32 flags
; /* It is really u32 in videodev.h */
14 static int get_video_tuner32(struct video_tuner
*kp
, struct video_tuner32 __user
*up
)
18 if(get_user(kp
->tuner
, &up
->tuner
))
20 for(i
= 0; i
< 32; i
++)
21 __get_user(kp
->name
[i
], &up
->name
[i
]);
22 __get_user(kp
->rangelow
, &up
->rangelow
);
23 __get_user(kp
->rangehigh
, &up
->rangehigh
);
24 __get_user(kp
->flags
, &up
->flags
);
25 __get_user(kp
->mode
, &up
->mode
);
26 __get_user(kp
->signal
, &up
->signal
);
30 static int put_video_tuner32(struct video_tuner
*kp
, struct video_tuner32 __user
*up
)
34 if(put_user(kp
->tuner
, &up
->tuner
))
36 for(i
= 0; i
< 32; i
++)
37 __put_user(kp
->name
[i
], &up
->name
[i
]);
38 __put_user(kp
->rangelow
, &up
->rangelow
);
39 __put_user(kp
->rangehigh
, &up
->rangehigh
);
40 __put_user(kp
->flags
, &up
->flags
);
41 __put_user(kp
->mode
, &up
->mode
);
42 __put_user(kp
->signal
, &up
->signal
);
46 struct video_buffer32
{
48 compat_int_t height
, width
, depth
, bytesperline
;
51 static int get_video_buffer32(struct video_buffer
*kp
, struct video_buffer32 __user
*up
)
55 if (get_user(tmp
, &up
->base
))
58 /* This is actually a physical address stored
61 kp
->base
= (void *)(unsigned long) tmp
;
63 __get_user(kp
->height
, &up
->height
);
64 __get_user(kp
->width
, &up
->width
);
65 __get_user(kp
->depth
, &up
->depth
);
66 __get_user(kp
->bytesperline
, &up
->bytesperline
);
70 static int put_video_buffer32(struct video_buffer
*kp
, struct video_buffer32 __user
*up
)
72 u32 tmp
= (u32
)((unsigned long)kp
->base
);
74 if(put_user(tmp
, &up
->base
))
76 __put_user(kp
->height
, &up
->height
);
77 __put_user(kp
->width
, &up
->width
);
78 __put_user(kp
->depth
, &up
->depth
);
79 __put_user(kp
->bytesperline
, &up
->bytesperline
);
84 s32 x
, y
, width
, height
; /* Its really s32 in videodev.h */
88 struct video_window32
{
89 u32 x
, y
, width
, height
, chromakey
, flags
;
91 compat_int_t clipcount
;
94 static int native_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
96 int ret
= -ENOIOCTLCMD
;
98 if (file
->f_ops
->unlocked_ioctl
)
99 ret
= file
->f_ops
->unlocked_ioctl(file
, cmd
, arg
);
100 else if (file
->f_ops
->ioctl
) {
102 ret
= file
->f_ops
->ioctl(file
->f_dentry
->d_inode
, file
, cmd
, arg
);
110 /* You get back everything except the clips... */
111 static int put_video_window32(struct video_window
*kp
, struct video_window32 __user
*up
)
113 if(put_user(kp
->x
, &up
->x
))
115 __put_user(kp
->y
, &up
->y
);
116 __put_user(kp
->width
, &up
->width
);
117 __put_user(kp
->height
, &up
->height
);
118 __put_user(kp
->chromakey
, &up
->chromakey
);
119 __put_user(kp
->flags
, &up
->flags
);
120 __put_user(kp
->clipcount
, &up
->clipcount
);
124 #define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
125 #define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
126 #define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
127 #define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
128 #define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
129 #define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
130 #define VIDIOCGFREQ32 _IOR('v',14, u32)
131 #define VIDIOCSFREQ32 _IOW('v',15, u32)
134 MaxClips
= (~0U-sizeof(struct video_window
))/sizeof(struct video_clip
)
137 static int do_set_window(struct file
*file
, unsigned int cmd
, unsigned long arg
)
139 struct video_window32 __user
*up
= compat_ptr(arg
);
140 struct video_window __user
*vw
;
141 struct video_clip __user
*p
;
145 if (get_user(nclips
, &up
->clipcount
))
148 /* Peculiar interface... */
150 nclips
= VIDEO_CLIPMAP_SIZE
;
152 if (nclips
> MaxClips
)
155 vw
= compat_alloc_user_space(sizeof(struct video_window
) +
156 nclips
* sizeof(struct video_clip
));
158 p
= nclips
? (struct video_clip __user
*)(vw
+ 1) : NULL
;
160 if (get_user(n
, &up
->x
) || put_user(n
, &vw
->x
) ||
161 get_user(n
, &up
->y
) || put_user(n
, &vw
->y
) ||
162 get_user(n
, &up
->width
) || put_user(n
, &vw
->width
) ||
163 get_user(n
, &up
->height
) || put_user(n
, &vw
->height
) ||
164 get_user(n
, &up
->chromakey
) || put_user(n
, &vw
->chromakey
) ||
165 get_user(n
, &up
->flags
) || put_user(n
, &vw
->flags
) ||
166 get_user(n
, &up
->clipcount
) || put_user(n
, &vw
->clipcount
) ||
167 get_user(n
, &up
->clips
) || put_user(p
, &vw
->clips
))
171 struct video_clip32 __user
*u
= compat_ptr(n
);
175 for (i
= 0; i
< nclips
; i
++, u
++, p
++) {
177 if (get_user(v
, &u
->x
) ||
178 put_user(v
, &p
->x
) ||
179 get_user(v
, &u
->y
) ||
180 put_user(v
, &p
->y
) ||
181 get_user(v
, &u
->width
) ||
182 put_user(v
, &p
->width
) ||
183 get_user(v
, &u
->height
) ||
184 put_user(v
, &p
->height
) ||
185 put_user(NULL
, &p
->next
))
190 return native_ioctl(file
, VIDIOCSWIN
, (unsigned long)p
);
193 static int do_video_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
196 struct video_tuner vt
;
197 struct video_buffer vb
;
198 struct video_window vw
;
201 mm_segment_t old_fs
= get_fs();
202 void __user
*up
= compat_ptr(arg
);
205 /* First, convert the command. */
207 case VIDIOCGTUNER32
: cmd
= VIDIOCGTUNER
; break;
208 case VIDIOCSTUNER32
: cmd
= VIDIOCSTUNER
; break;
209 case VIDIOCGWIN32
: cmd
= VIDIOCGWIN
; break;
210 case VIDIOCGFBUF32
: cmd
= VIDIOCGFBUF
; break;
211 case VIDIOCSFBUF32
: cmd
= VIDIOCSFBUF
; break;
212 case VIDIOCGFREQ32
: cmd
= VIDIOCGFREQ
; break;
213 case VIDIOCSFREQ32
: cmd
= VIDIOCSFREQ
; break;
219 err
= get_video_tuner32(&karg
.vt
, up
);
223 err
= get_video_buffer32(&karg
.vb
, up
);
227 err
= get_user(karg
.vx
, (u32 __user
*)up
);
234 err
= native_ioctl(file
, cmd
, (unsigned long)&karg
);
240 err
= put_video_tuner32(&karg
.vt
, up
);
244 err
= put_video_window32(&karg
.vw
, up
);
248 err
= put_video_buffer32(&karg
.vb
, up
);
252 err
= put_user(((u32
)karg
.vx
), (u32 __user
*)up
);
260 long v4l_compat_ioctl32(struct file
*file
, unsigned int cmd
, unsigned long arg
)
262 int ret
= -ENOIOCTLCMD
;
264 if (!file
->f_ops
->ioctl
)
269 ret
= do_set_window(file
, cmd
, arg
);
278 ret
= do_video_ioctl(file
, cmd
, arg
);
281 /* Little v, the video4linux ioctls (conflict?) */
298 /* BTTV specific... */
299 case _IOW('v', BASE_VIDIOCPRIVATE
+0, char [256]):
300 case _IOR('v', BASE_VIDIOCPRIVATE
+1, char [256]):
301 case _IOR('v' , BASE_VIDIOCPRIVATE
+2, unsigned int):
302 case _IOW('v' , BASE_VIDIOCPRIVATE
+3, char [16]): /* struct bttv_pll_info */
303 case _IOR('v' , BASE_VIDIOCPRIVATE
+4, int):
304 case _IOR('v' , BASE_VIDIOCPRIVATE
+5, int):
305 case _IOR('v' , BASE_VIDIOCPRIVATE
+6, int):
306 case _IOR('v' , BASE_VIDIOCPRIVATE
+7, int):
307 ret
= native_ioctl(file
, cmd
, (unsigned long)compat_ptr(arg
));
313 long v4l_compat_ioctl32(struct file
*file
, unsigned int cmd
, unsigned long arg
)
318 EXPORT_SYMBOL_GPL(v4l_compat_ioctl32
);