diff options
author | Dave Kleikamp <shaggy@austin.ibm.com> | 2006-01-24 15:34:47 -0500 |
---|---|---|
committer | Dave Kleikamp <shaggy@austin.ibm.com> | 2006-01-24 15:34:47 -0500 |
commit | 0a0fc0ddbe732779366ab6b1b879f62195e65967 (patch) | |
tree | 7b42490a676cf39ae0691b6859ecf7fd410f229b /fs/compat_ioctl.c | |
parent | 4d5dbd0945d9e0833dd7964a3d6ee33157f7cc7a (diff) | |
parent | 3ee68c4af3fd7228c1be63254b9f884614f9ebb2 (diff) |
Merge with /home/shaggy/git/linus-clean/
Diffstat (limited to 'fs/compat_ioctl.c')
-rw-r--r-- | fs/compat_ioctl.c | 498 |
1 files changed, 268 insertions, 230 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 26300fccb4fc..5dd0207ffd46 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -10,11 +10,11 @@ | |||
10 | * ioctls. | 10 | * ioctls. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifdef INCLUDES | ||
14 | #include <linux/config.h> | 13 | #include <linux/config.h> |
15 | #include <linux/types.h> | 14 | #include <linux/types.h> |
16 | #include <linux/compat.h> | 15 | #include <linux/compat.h> |
17 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/capability.h> | ||
18 | #include <linux/compiler.h> | 18 | #include <linux/compiler.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
@@ -49,6 +49,8 @@ | |||
49 | #include <linux/vt_kern.h> | 49 | #include <linux/vt_kern.h> |
50 | #include <linux/fb.h> | 50 | #include <linux/fb.h> |
51 | #include <linux/ext2_fs.h> | 51 | #include <linux/ext2_fs.h> |
52 | #include <linux/ext3_jbd.h> | ||
53 | #include <linux/ext3_fs.h> | ||
52 | #include <linux/videodev.h> | 54 | #include <linux/videodev.h> |
53 | #include <linux/netdevice.h> | 55 | #include <linux/netdevice.h> |
54 | #include <linux/raw.h> | 56 | #include <linux/raw.h> |
@@ -79,13 +81,9 @@ | |||
79 | #include <linux/capi.h> | 81 | #include <linux/capi.h> |
80 | 82 | ||
81 | #include <scsi/scsi.h> | 83 | #include <scsi/scsi.h> |
82 | /* Ugly hack. */ | ||
83 | #undef __KERNEL__ | ||
84 | #include <scsi/scsi_ioctl.h> | 84 | #include <scsi/scsi_ioctl.h> |
85 | #define __KERNEL__ | ||
86 | #include <scsi/sg.h> | 85 | #include <scsi/sg.h> |
87 | 86 | ||
88 | #include <asm/types.h> | ||
89 | #include <asm/uaccess.h> | 87 | #include <asm/uaccess.h> |
90 | #include <linux/ethtool.h> | 88 | #include <linux/ethtool.h> |
91 | #include <linux/mii.h> | 89 | #include <linux/mii.h> |
@@ -93,7 +91,6 @@ | |||
93 | #include <linux/watchdog.h> | 91 | #include <linux/watchdog.h> |
94 | #include <linux/dm-ioctl.h> | 92 | #include <linux/dm-ioctl.h> |
95 | 93 | ||
96 | #include <asm/module.h> | ||
97 | #include <linux/soundcard.h> | 94 | #include <linux/soundcard.h> |
98 | #include <linux/lp.h> | 95 | #include <linux/lp.h> |
99 | #include <linux/ppdev.h> | 96 | #include <linux/ppdev.h> |
@@ -121,17 +118,33 @@ | |||
121 | 118 | ||
122 | #include <linux/hiddev.h> | 119 | #include <linux/hiddev.h> |
123 | 120 | ||
124 | #undef INCLUDES | 121 | #include <linux/dvb/audio.h> |
125 | #endif | 122 | #include <linux/dvb/dmx.h> |
126 | 123 | #include <linux/dvb/frontend.h> | |
127 | #ifdef CODE | 124 | #include <linux/dvb/video.h> |
125 | #include <linux/lp.h> | ||
128 | 126 | ||
129 | /* Aiee. Someone does not find a difference between int and long */ | 127 | /* Aiee. Someone does not find a difference between int and long */ |
130 | #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) | 128 | #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) |
131 | #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) | 129 | #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) |
130 | #define EXT3_IOC32_GETVERSION _IOR('f', 3, int) | ||
131 | #define EXT3_IOC32_SETVERSION _IOW('f', 4, int) | ||
132 | #define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) | ||
133 | #define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) | ||
134 | #define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) | ||
135 | #ifdef CONFIG_JBD_DEBUG | ||
136 | #define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) | ||
137 | #endif | ||
138 | |||
132 | #define EXT2_IOC32_GETVERSION _IOR('v', 1, int) | 139 | #define EXT2_IOC32_GETVERSION _IOR('v', 1, int) |
133 | #define EXT2_IOC32_SETVERSION _IOW('v', 2, int) | 140 | #define EXT2_IOC32_SETVERSION _IOW('v', 2, int) |
134 | 141 | ||
142 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, | ||
143 | unsigned long arg, struct file *f) | ||
144 | { | ||
145 | return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); | ||
146 | } | ||
147 | |||
135 | static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) | 148 | static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) |
136 | { | 149 | { |
137 | mm_segment_t old_fs = get_fs(); | 150 | mm_segment_t old_fs = get_fs(); |
@@ -175,241 +188,141 @@ static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
175 | return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); | 188 | return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); |
176 | } | 189 | } |
177 | 190 | ||
178 | struct video_tuner32 { | 191 | static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) |
179 | compat_int_t tuner; | ||
180 | char name[32]; | ||
181 | compat_ulong_t rangelow, rangehigh; | ||
182 | u32 flags; /* It is really u32 in videodev.h */ | ||
183 | u16 mode, signal; | ||
184 | }; | ||
185 | |||
186 | static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) | ||
187 | { | ||
188 | int i; | ||
189 | |||
190 | if(get_user(kp->tuner, &up->tuner)) | ||
191 | return -EFAULT; | ||
192 | for(i = 0; i < 32; i++) | ||
193 | __get_user(kp->name[i], &up->name[i]); | ||
194 | __get_user(kp->rangelow, &up->rangelow); | ||
195 | __get_user(kp->rangehigh, &up->rangehigh); | ||
196 | __get_user(kp->flags, &up->flags); | ||
197 | __get_user(kp->mode, &up->mode); | ||
198 | __get_user(kp->signal, &up->signal); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) | ||
203 | { | 192 | { |
204 | int i; | 193 | /* These are just misnamed, they actually get/put from/to user an int */ |
205 | 194 | switch (cmd) { | |
206 | if(put_user(kp->tuner, &up->tuner)) | 195 | case EXT3_IOC32_GETVERSION: cmd = EXT3_IOC_GETVERSION; break; |
207 | return -EFAULT; | 196 | case EXT3_IOC32_SETVERSION: cmd = EXT3_IOC_SETVERSION; break; |
208 | for(i = 0; i < 32; i++) | 197 | case EXT3_IOC32_GETRSVSZ: cmd = EXT3_IOC_GETRSVSZ; break; |
209 | __put_user(kp->name[i], &up->name[i]); | 198 | case EXT3_IOC32_SETRSVSZ: cmd = EXT3_IOC_SETRSVSZ; break; |
210 | __put_user(kp->rangelow, &up->rangelow); | 199 | case EXT3_IOC32_GROUP_EXTEND: cmd = EXT3_IOC_GROUP_EXTEND; break; |
211 | __put_user(kp->rangehigh, &up->rangehigh); | 200 | #ifdef CONFIG_JBD_DEBUG |
212 | __put_user(kp->flags, &up->flags); | 201 | case EXT3_IOC32_WAIT_FOR_READONLY: cmd = EXT3_IOC_WAIT_FOR_READONLY; break; |
213 | __put_user(kp->mode, &up->mode); | 202 | #endif |
214 | __put_user(kp->signal, &up->signal); | 203 | } |
215 | return 0; | 204 | return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); |
216 | } | 205 | } |
217 | 206 | ||
218 | struct video_buffer32 { | 207 | struct compat_dmx_event { |
219 | compat_caddr_t base; | 208 | dmx_event_t event; |
220 | compat_int_t height, width, depth, bytesperline; | 209 | compat_time_t timeStamp; |
210 | union | ||
211 | { | ||
212 | dmx_scrambling_status_t scrambling; | ||
213 | } u; | ||
221 | }; | 214 | }; |
222 | 215 | ||
223 | static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) | 216 | static int do_dmx_get_event(unsigned int fd, unsigned int cmd, unsigned long arg) |
224 | { | 217 | { |
225 | u32 tmp; | 218 | struct dmx_event kevent; |
226 | 219 | mm_segment_t old_fs = get_fs(); | |
227 | if (get_user(tmp, &up->base)) | 220 | int err; |
228 | return -EFAULT; | ||
229 | 221 | ||
230 | /* This is actually a physical address stored | 222 | set_fs(KERNEL_DS); |
231 | * as a void pointer. | 223 | err = sys_ioctl(fd, cmd, (unsigned long) &kevent); |
232 | */ | 224 | set_fs(old_fs); |
233 | kp->base = (void *)(unsigned long) tmp; | ||
234 | 225 | ||
235 | __get_user(kp->height, &up->height); | 226 | if (!err) { |
236 | __get_user(kp->width, &up->width); | 227 | struct compat_dmx_event __user *up = compat_ptr(arg); |
237 | __get_user(kp->depth, &up->depth); | ||
238 | __get_user(kp->bytesperline, &up->bytesperline); | ||
239 | return 0; | ||
240 | } | ||
241 | 228 | ||
242 | static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) | 229 | err = put_user(kevent.event, &up->event); |
243 | { | 230 | err |= put_user(kevent.timeStamp, &up->timeStamp); |
244 | u32 tmp = (u32)((unsigned long)kp->base); | 231 | err |= put_user(kevent.u.scrambling, &up->u.scrambling); |
232 | if (err) | ||
233 | err = -EFAULT; | ||
234 | } | ||
245 | 235 | ||
246 | if(put_user(tmp, &up->base)) | 236 | return err; |
247 | return -EFAULT; | ||
248 | __put_user(kp->height, &up->height); | ||
249 | __put_user(kp->width, &up->width); | ||
250 | __put_user(kp->depth, &up->depth); | ||
251 | __put_user(kp->bytesperline, &up->bytesperline); | ||
252 | return 0; | ||
253 | } | 237 | } |
254 | 238 | ||
255 | struct video_clip32 { | 239 | struct compat_video_event { |
256 | s32 x, y, width, height; /* Its really s32 in videodev.h */ | 240 | int32_t type; |
257 | compat_caddr_t next; | 241 | compat_time_t timestamp; |
258 | }; | 242 | union { |
259 | 243 | video_size_t size; | |
260 | struct video_window32 { | 244 | unsigned int frame_rate; |
261 | u32 x, y, width, height, chromakey, flags; | 245 | } u; |
262 | compat_caddr_t clips; | ||
263 | compat_int_t clipcount; | ||
264 | }; | 246 | }; |
265 | 247 | ||
266 | /* You get back everything except the clips... */ | 248 | static int do_video_get_event(unsigned int fd, unsigned int cmd, unsigned long arg) |
267 | static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) | ||
268 | { | 249 | { |
269 | if(put_user(kp->x, &up->x)) | 250 | struct video_event kevent; |
270 | return -EFAULT; | 251 | mm_segment_t old_fs = get_fs(); |
271 | __put_user(kp->y, &up->y); | 252 | int err; |
272 | __put_user(kp->width, &up->width); | ||
273 | __put_user(kp->height, &up->height); | ||
274 | __put_user(kp->chromakey, &up->chromakey); | ||
275 | __put_user(kp->flags, &up->flags); | ||
276 | __put_user(kp->clipcount, &up->clipcount); | ||
277 | return 0; | ||
278 | } | ||
279 | 253 | ||
280 | #define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) | 254 | set_fs(KERNEL_DS); |
281 | #define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) | 255 | err = sys_ioctl(fd, cmd, (unsigned long) &kevent); |
282 | #define VIDIOCGWIN32 _IOR('v',9, struct video_window32) | 256 | set_fs(old_fs); |
283 | #define VIDIOCSWIN32 _IOW('v',10, struct video_window32) | ||
284 | #define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32) | ||
285 | #define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) | ||
286 | #define VIDIOCGFREQ32 _IOR('v',14, u32) | ||
287 | #define VIDIOCSFREQ32 _IOW('v',15, u32) | ||
288 | 257 | ||
289 | enum { | 258 | if (!err) { |
290 | MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) | 259 | struct compat_video_event __user *up = compat_ptr(arg); |
260 | |||
261 | err = put_user(kevent.type, &up->type); | ||
262 | err |= put_user(kevent.timestamp, &up->timestamp); | ||
263 | err |= put_user(kevent.u.size.w, &up->u.size.w); | ||
264 | err |= put_user(kevent.u.size.h, &up->u.size.h); | ||
265 | err |= put_user(kevent.u.size.aspect_ratio, | ||
266 | &up->u.size.aspect_ratio); | ||
267 | if (err) | ||
268 | err = -EFAULT; | ||
269 | } | ||
270 | |||
271 | return err; | ||
272 | } | ||
273 | |||
274 | struct compat_video_still_picture { | ||
275 | compat_uptr_t iFrame; | ||
276 | int32_t size; | ||
291 | }; | 277 | }; |
292 | 278 | ||
293 | static int do_set_window(unsigned int fd, unsigned int cmd, unsigned long arg) | 279 | static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned long arg) |
294 | { | 280 | { |
295 | struct video_window32 __user *up = compat_ptr(arg); | 281 | struct compat_video_still_picture __user *up; |
296 | struct video_window __user *vw; | 282 | struct video_still_picture __user *up_native; |
297 | struct video_clip __user *p; | 283 | compat_uptr_t fp; |
298 | int nclips; | 284 | int32_t size; |
299 | u32 n; | 285 | int err; |
300 | 286 | ||
301 | if (get_user(nclips, &up->clipcount)) | 287 | up = (struct compat_video_still_picture __user *) arg; |
288 | err = get_user(fp, &up->iFrame); | ||
289 | err |= get_user(size, &up->size); | ||
290 | if (err) | ||
302 | return -EFAULT; | 291 | return -EFAULT; |
303 | 292 | ||
304 | /* Peculiar interface... */ | 293 | up_native = |
305 | if (nclips < 0) | 294 | compat_alloc_user_space(sizeof(struct video_still_picture)); |
306 | nclips = VIDEO_CLIPMAP_SIZE; | ||
307 | |||
308 | if (nclips > MaxClips) | ||
309 | return -ENOMEM; | ||
310 | 295 | ||
311 | vw = compat_alloc_user_space(sizeof(struct video_window) + | 296 | put_user(compat_ptr(fp), &up_native->iFrame); |
312 | nclips * sizeof(struct video_clip)); | 297 | put_user(size, &up_native->size); |
313 | 298 | ||
314 | p = nclips ? (struct video_clip __user *)(vw + 1) : NULL; | 299 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); |
315 | 300 | ||
316 | if (get_user(n, &up->x) || put_user(n, &vw->x) || | 301 | return err; |
317 | get_user(n, &up->y) || put_user(n, &vw->y) || | ||
318 | get_user(n, &up->width) || put_user(n, &vw->width) || | ||
319 | get_user(n, &up->height) || put_user(n, &vw->height) || | ||
320 | get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) || | ||
321 | get_user(n, &up->flags) || put_user(n, &vw->flags) || | ||
322 | get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) || | ||
323 | get_user(n, &up->clips) || put_user(p, &vw->clips)) | ||
324 | return -EFAULT; | ||
325 | |||
326 | if (nclips) { | ||
327 | struct video_clip32 __user *u = compat_ptr(n); | ||
328 | int i; | ||
329 | if (!u) | ||
330 | return -EINVAL; | ||
331 | for (i = 0; i < nclips; i++, u++, p++) { | ||
332 | s32 v; | ||
333 | if (get_user(v, &u->x) || | ||
334 | put_user(v, &p->x) || | ||
335 | get_user(v, &u->y) || | ||
336 | put_user(v, &p->y) || | ||
337 | get_user(v, &u->width) || | ||
338 | put_user(v, &p->width) || | ||
339 | get_user(v, &u->height) || | ||
340 | put_user(v, &p->height) || | ||
341 | put_user(NULL, &p->next)) | ||
342 | return -EFAULT; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | return sys_ioctl(fd, VIDIOCSWIN, (unsigned long)p); | ||
347 | } | 302 | } |
348 | 303 | ||
349 | static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | 304 | struct compat_video_spu_palette { |
350 | { | 305 | int length; |
351 | union { | 306 | compat_uptr_t palette; |
352 | struct video_tuner vt; | 307 | }; |
353 | struct video_buffer vb; | ||
354 | struct video_window vw; | ||
355 | unsigned long vx; | ||
356 | } karg; | ||
357 | mm_segment_t old_fs = get_fs(); | ||
358 | void __user *up = compat_ptr(arg); | ||
359 | int err = 0; | ||
360 | |||
361 | /* First, convert the command. */ | ||
362 | switch(cmd) { | ||
363 | case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; | ||
364 | case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; | ||
365 | case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; | ||
366 | case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break; | ||
367 | case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; | ||
368 | case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; | ||
369 | case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; | ||
370 | }; | ||
371 | |||
372 | switch(cmd) { | ||
373 | case VIDIOCSTUNER: | ||
374 | case VIDIOCGTUNER: | ||
375 | err = get_video_tuner32(&karg.vt, up); | ||
376 | break; | ||
377 | |||
378 | case VIDIOCSFBUF: | ||
379 | err = get_video_buffer32(&karg.vb, up); | ||
380 | break; | ||
381 | |||
382 | case VIDIOCSFREQ: | ||
383 | err = get_user(karg.vx, (u32 __user *)up); | ||
384 | break; | ||
385 | }; | ||
386 | if(err) | ||
387 | goto out; | ||
388 | 308 | ||
389 | set_fs(KERNEL_DS); | 309 | static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned long arg) |
390 | err = sys_ioctl(fd, cmd, (unsigned long)&karg); | 310 | { |
391 | set_fs(old_fs); | 311 | struct compat_video_spu_palette __user *up; |
312 | struct video_spu_palette __user *up_native; | ||
313 | compat_uptr_t palp; | ||
314 | int length, err; | ||
392 | 315 | ||
393 | if(err == 0) { | 316 | up = (struct compat_video_spu_palette __user *) arg; |
394 | switch(cmd) { | 317 | err = get_user(palp, &up->palette); |
395 | case VIDIOCGTUNER: | 318 | err |= get_user(length, &up->length); |
396 | err = put_video_tuner32(&karg.vt, up); | ||
397 | break; | ||
398 | 319 | ||
399 | case VIDIOCGWIN: | 320 | up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); |
400 | err = put_video_window32(&karg.vw, up); | 321 | put_user(compat_ptr(palp), &up_native->palette); |
401 | break; | 322 | put_user(length, &up_native->length); |
402 | 323 | ||
403 | case VIDIOCGFBUF: | 324 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); |
404 | err = put_video_buffer32(&karg.vb, up); | ||
405 | break; | ||
406 | 325 | ||
407 | case VIDIOCGFREQ: | ||
408 | err = put_user(((u32)karg.vx), (u32 __user *)up); | ||
409 | break; | ||
410 | }; | ||
411 | } | ||
412 | out: | ||
413 | return err; | 326 | return err; |
414 | } | 327 | } |
415 | 328 | ||
@@ -532,7 +445,8 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
532 | 445 | ||
533 | ifr = ifc.ifc_req; | 446 | ifr = ifc.ifc_req; |
534 | ifr32 = compat_ptr(ifc32.ifcbuf); | 447 | ifr32 = compat_ptr(ifc32.ifcbuf); |
535 | for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len; | 448 | for (i = 0, j = 0; |
449 | i + sizeof (struct ifreq32) < ifc32.ifc_len && j < ifc.ifc_len; | ||
536 | i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { | 450 | i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { |
537 | if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32))) | 451 | if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32))) |
538 | return -EFAULT; | 452 | return -EFAULT; |
@@ -548,10 +462,7 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
548 | i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32)); | 462 | i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32)); |
549 | ifc32.ifc_len = i; | 463 | ifc32.ifc_len = i; |
550 | } else { | 464 | } else { |
551 | if (i <= ifc32.ifc_len) | 465 | ifc32.ifc_len = i; |
552 | ifc32.ifc_len = i; | ||
553 | else | ||
554 | ifc32.ifc_len = i - sizeof (struct ifreq32); | ||
555 | } | 466 | } |
556 | if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32))) | 467 | if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32))) |
557 | return -EFAULT; | 468 | return -EFAULT; |
@@ -1006,6 +917,40 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
1006 | return err; | 917 | return err; |
1007 | } | 918 | } |
1008 | 919 | ||
920 | struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ | ||
921 | char req_state; | ||
922 | char orphan; | ||
923 | char sg_io_owned; | ||
924 | char problem; | ||
925 | int pack_id; | ||
926 | compat_uptr_t usr_ptr; | ||
927 | unsigned int duration; | ||
928 | int unused; | ||
929 | }; | ||
930 | |||
931 | static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
932 | { | ||
933 | int err, i; | ||
934 | sg_req_info_t *r; | ||
935 | struct compat_sg_req_info *o = (struct compat_sg_req_info *)arg; | ||
936 | r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); | ||
937 | err = sys_ioctl(fd,cmd,(unsigned long)r); | ||
938 | if (err < 0) | ||
939 | return err; | ||
940 | for (i = 0; i < SG_MAX_QUEUE; i++) { | ||
941 | void __user *ptr; | ||
942 | int d; | ||
943 | |||
944 | if (copy_in_user(o + i, r + i, offsetof(sg_req_info_t, usr_ptr)) || | ||
945 | get_user(ptr, &r[i].usr_ptr) || | ||
946 | get_user(d, &r[i].duration) || | ||
947 | put_user((u32)(unsigned long)(ptr), &o[i].usr_ptr) || | ||
948 | put_user(d, &o[i].duration)) | ||
949 | return -EFAULT; | ||
950 | } | ||
951 | return err; | ||
952 | } | ||
953 | |||
1009 | struct sock_fprog32 { | 954 | struct sock_fprog32 { |
1010 | unsigned short len; | 955 | unsigned short len; |
1011 | compat_caddr_t filter; | 956 | compat_caddr_t filter; |
@@ -2561,6 +2506,49 @@ static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg | |||
2561 | return -EINVAL; | 2506 | return -EINVAL; |
2562 | } | 2507 | } |
2563 | 2508 | ||
2509 | #define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) | ||
2510 | #define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) | ||
2511 | #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) | ||
2512 | #define RTC_EPOCH_SET32 _IOW('p', 0x0e, compat_ulong_t) | ||
2513 | |||
2514 | static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | ||
2515 | { | ||
2516 | mm_segment_t oldfs = get_fs(); | ||
2517 | compat_ulong_t val32; | ||
2518 | unsigned long kval; | ||
2519 | int ret; | ||
2520 | |||
2521 | switch (cmd) { | ||
2522 | case RTC_IRQP_READ32: | ||
2523 | case RTC_EPOCH_READ32: | ||
2524 | set_fs(KERNEL_DS); | ||
2525 | ret = sys_ioctl(fd, (cmd == RTC_IRQP_READ32) ? | ||
2526 | RTC_IRQP_READ : RTC_EPOCH_READ, | ||
2527 | (unsigned long)&kval); | ||
2528 | set_fs(oldfs); | ||
2529 | if (ret) | ||
2530 | return ret; | ||
2531 | val32 = kval; | ||
2532 | return put_user(val32, (unsigned int __user *)arg); | ||
2533 | case RTC_IRQP_SET32: | ||
2534 | case RTC_EPOCH_SET32: | ||
2535 | ret = get_user(val32, (unsigned int __user *)arg); | ||
2536 | if (ret) | ||
2537 | return ret; | ||
2538 | kval = val32; | ||
2539 | |||
2540 | set_fs(KERNEL_DS); | ||
2541 | ret = sys_ioctl(fd, (cmd == RTC_IRQP_SET32) ? | ||
2542 | RTC_IRQP_SET : RTC_EPOCH_SET, | ||
2543 | (unsigned long)&kval); | ||
2544 | set_fs(oldfs); | ||
2545 | return ret; | ||
2546 | default: | ||
2547 | /* unreached */ | ||
2548 | return -ENOIOCTLCMD; | ||
2549 | } | ||
2550 | } | ||
2551 | |||
2564 | #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) | 2552 | #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) |
2565 | struct ncp_ioctl_request_32 { | 2553 | struct ncp_ioctl_request_32 { |
2566 | u32 function; | 2554 | u32 function; |
@@ -2748,10 +2736,34 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon | |||
2748 | } | 2736 | } |
2749 | #endif | 2737 | #endif |
2750 | 2738 | ||
2751 | #undef CODE | 2739 | static int |
2752 | #endif | 2740 | lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) |
2741 | { | ||
2742 | struct compat_timeval *tc = (struct compat_timeval *)arg; | ||
2743 | struct timeval *tn = compat_alloc_user_space(sizeof(struct timeval)); | ||
2744 | struct timeval ts; | ||
2745 | if (get_user(ts.tv_sec, &tc->tv_sec) || | ||
2746 | get_user(ts.tv_usec, &tc->tv_usec) || | ||
2747 | put_user(ts.tv_sec, &tn->tv_sec) || | ||
2748 | put_user(ts.tv_usec, &tn->tv_usec)) | ||
2749 | return -EFAULT; | ||
2750 | return sys_ioctl(fd, cmd, (unsigned long)tn); | ||
2751 | } | ||
2753 | 2752 | ||
2754 | #ifdef DECLARES | 2753 | #define HANDLE_IOCTL(cmd,handler) \ |
2754 | { (cmd), (ioctl_trans_handler_t)(handler) }, | ||
2755 | |||
2756 | /* pointer to compatible structure or no argument */ | ||
2757 | #define COMPATIBLE_IOCTL(cmd) \ | ||
2758 | { (cmd), do_ioctl32_pointer }, | ||
2759 | |||
2760 | /* argument is an unsigned long integer, not a pointer */ | ||
2761 | #define ULONG_IOCTL(cmd) \ | ||
2762 | { (cmd), (ioctl_trans_handler_t)sys_ioctl }, | ||
2763 | |||
2764 | |||
2765 | struct ioctl_trans ioctl_start[] = { | ||
2766 | #include <linux/compat_ioctl.h> | ||
2755 | HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) | 2767 | HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) |
2756 | HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) | 2768 | HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) |
2757 | #ifdef CONFIG_NET | 2769 | #ifdef CONFIG_NET |
@@ -2831,6 +2843,7 @@ HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans) | |||
2831 | HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans) | 2843 | HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans) |
2832 | HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans) | 2844 | HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans) |
2833 | HANDLE_IOCTL(SG_IO,sg_ioctl_trans) | 2845 | HANDLE_IOCTL(SG_IO,sg_ioctl_trans) |
2846 | HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans) | ||
2834 | HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans) | 2847 | HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans) |
2835 | HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) | 2848 | HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) |
2836 | HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) | 2849 | HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) |
@@ -2854,14 +2867,15 @@ HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl) | |||
2854 | HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) | 2867 | HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) |
2855 | HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) | 2868 | HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) |
2856 | HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl) | 2869 | HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl) |
2857 | HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl) | 2870 | HANDLE_IOCTL(EXT3_IOC32_GETVERSION, do_ext3_ioctl) |
2858 | HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl) | 2871 | HANDLE_IOCTL(EXT3_IOC32_SETVERSION, do_ext3_ioctl) |
2859 | HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl) | 2872 | HANDLE_IOCTL(EXT3_IOC32_GETRSVSZ, do_ext3_ioctl) |
2860 | HANDLE_IOCTL(VIDIOCSWIN32, do_set_window) | 2873 | HANDLE_IOCTL(EXT3_IOC32_SETRSVSZ, do_ext3_ioctl) |
2861 | HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl) | 2874 | HANDLE_IOCTL(EXT3_IOC32_GROUP_EXTEND, do_ext3_ioctl) |
2862 | HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl) | 2875 | COMPATIBLE_IOCTL(EXT3_IOC_GROUP_ADD) |
2863 | HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl) | 2876 | #ifdef CONFIG_JBD_DEBUG |
2864 | HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl) | 2877 | HANDLE_IOCTL(EXT3_IOC32_WAIT_FOR_READONLY, do_ext3_ioctl) |
2878 | #endif | ||
2865 | /* One SMB ioctl needs translations. */ | 2879 | /* One SMB ioctl needs translations. */ |
2866 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) | 2880 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) |
2867 | HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) | 2881 | HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) |
@@ -2943,6 +2957,10 @@ HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) | |||
2943 | HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) | 2957 | HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) |
2944 | HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) | 2958 | HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) |
2945 | HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) | 2959 | HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) |
2960 | HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl) | ||
2961 | HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) | ||
2962 | HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) | ||
2963 | HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) | ||
2946 | 2964 | ||
2947 | #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) | 2965 | #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) |
2948 | HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) | 2966 | HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) |
@@ -2954,5 +2972,25 @@ HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata) | |||
2954 | HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) | 2972 | HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) |
2955 | #endif | 2973 | #endif |
2956 | 2974 | ||
2957 | #undef DECLARES | 2975 | /* dvb */ |
2958 | #endif | 2976 | HANDLE_IOCTL(DMX_GET_EVENT, do_dmx_get_event) |
2977 | HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) | ||
2978 | HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture) | ||
2979 | HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette) | ||
2980 | |||
2981 | /* parport */ | ||
2982 | COMPATIBLE_IOCTL(LPTIME) | ||
2983 | COMPATIBLE_IOCTL(LPCHAR) | ||
2984 | COMPATIBLE_IOCTL(LPABORTOPEN) | ||
2985 | COMPATIBLE_IOCTL(LPCAREFUL) | ||
2986 | COMPATIBLE_IOCTL(LPWAIT) | ||
2987 | COMPATIBLE_IOCTL(LPSETIRQ) | ||
2988 | COMPATIBLE_IOCTL(LPGETSTATUS) | ||
2989 | COMPATIBLE_IOCTL(LPGETSTATUS) | ||
2990 | COMPATIBLE_IOCTL(LPRESET) | ||
2991 | /*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/ | ||
2992 | COMPATIBLE_IOCTL(LPGETFLAGS) | ||
2993 | HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans) | ||
2994 | }; | ||
2995 | |||
2996 | int ioctl_table_size = ARRAY_SIZE(ioctl_start); | ||