File: /usr/src/linux/arch/s390x/kernel/ioctl32.c
1 /*
2 * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
3 *
4 * S390 version
5 * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Gerhard Tonn (ton@de.ibm.com)
7 *
8 * Heavily inspired by the 32-bit Sparc compat code which is
9 * Copyright (C) 2000 Silicon Graphics, Inc.
10 * Written by Ulf Carlsson (ulfc@engr.sgi.com)
11 *
12 */
13
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <linux/fs.h>
17 #include <linux/sched.h>
18 #include <linux/mm.h>
19 #include <linux/init.h>
20 #include <linux/file.h>
21 #include <linux/vt.h>
22 #include <linux/kd.h>
23 #include <linux/netdevice.h>
24 #include <linux/route.h>
25 #include <linux/ext2_fs.h>
26 #include <linux/hdreg.h>
27 #include <asm/types.h>
28 #include <asm/uaccess.h>
29 #include <asm/dasd.h>
30
31 #include "linux32.h"
32
33 long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
34
35 struct hd_geometry32 {
36 unsigned char heads;
37 unsigned char sectors;
38 unsigned short cylinders;
39 __u32 start;
40 };
41
42 static inline int hd_geometry_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
43 {
44 struct hd_geometry32 *hg32 = (struct hd_geometry32 *) A(arg);
45 struct hd_geometry hg;
46 int ret;
47 mm_segment_t old_fs = get_fs();
48
49 set_fs (KERNEL_DS);
50 ret = sys_ioctl (fd, cmd, (long)&hg);
51 set_fs (old_fs);
52
53 if (ret)
54 return ret;
55
56 ret = put_user (hg.heads, &(hg32->heads));
57 ret |= __put_user (hg.sectors, &(hg32->sectors));
58 ret |= __put_user (hg.cylinders, &(hg32->cylinders));
59 ret |= __put_user (hg.start, &(hg32->start));
60
61 return ret;
62 }
63
64 struct timeval32 {
65 int tv_sec;
66 int tv_usec;
67 };
68
69 #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
70 #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)
71 #define EXT2_IOC32_GETVERSION _IOR('v', 1, int)
72 #define EXT2_IOC32_SETVERSION _IOW('v', 2, int)
73
74 struct ifmap32 {
75 unsigned int mem_start;
76 unsigned int mem_end;
77 unsigned short base_addr;
78 unsigned char irq;
79 unsigned char dma;
80 unsigned char port;
81 };
82
83 struct ifreq32 {
84 #define IFHWADDRLEN 6
85 #define IFNAMSIZ 16
86 union {
87 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
88 } ifr_ifrn;
89 union {
90 struct sockaddr ifru_addr;
91 struct sockaddr ifru_dstaddr;
92 struct sockaddr ifru_broadaddr;
93 struct sockaddr ifru_netmask;
94 struct sockaddr ifru_hwaddr;
95 short ifru_flags;
96 int ifru_ivalue;
97 int ifru_mtu;
98 struct ifmap32 ifru_map;
99 char ifru_slave[IFNAMSIZ]; /* Just fits the size */
100 char ifru_newname[IFNAMSIZ];
101 __u32 ifru_data;
102 } ifr_ifru;
103 };
104
105 struct ifconf32 {
106 int ifc_len; /* size of buffer */
107 __u32 ifcbuf;
108 };
109
110 static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
111 {
112 struct ireq32 *uir32 = (struct ireq32 *) A(arg);
113 struct net_device *dev;
114 struct ifreq32 ifr32;
115
116 if (copy_from_user(&ifr32, uir32, sizeof(struct ifreq32)))
117 return -EFAULT;
118
119 read_lock(&dev_base_lock);
120 dev = __dev_get_by_index(ifr32.ifr_ifindex);
121 if (!dev) {
122 read_unlock(&dev_base_lock);
123 return -ENODEV;
124 }
125
126 strcpy(ifr32.ifr_name, dev->name);
127 read_unlock(&dev_base_lock);
128
129 if (copy_to_user(uir32, &ifr32, sizeof(struct ifreq32)))
130 return -EFAULT;
131
132 return 0;
133 }
134
135 static inline int dev_ifconf(unsigned int fd, unsigned int cmd,
136 unsigned long arg)
137 {
138 struct ioconf32 *uifc32 = (struct ioconf32 *) A(arg);
139 struct ifconf32 ifc32;
140 struct ifconf ifc;
141 struct ifreq32 *ifr32;
142 struct ifreq *ifr;
143 mm_segment_t old_fs;
144 int len;
145 int err;
146
147 if (copy_from_user(&ifc32, uifc32, sizeof(struct ifconf32)))
148 return -EFAULT;
149
150 if(ifc32.ifcbuf == 0) {
151 ifc32.ifc_len = 0;
152 ifc.ifc_len = 0;
153 ifc.ifc_buf = NULL;
154 } else {
155 ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32))) *
156 sizeof (struct ifreq);
157 ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
158 if (!ifc.ifc_buf)
159 return -ENOMEM;
160 }
161 ifr = ifc.ifc_req;
162 ifr32 = (struct ifreq32 *) A(ifc32.ifcbuf);
163 len = ifc32.ifc_len / sizeof (struct ifreq32);
164 while (len--) {
165 if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
166 err = -EFAULT;
167 goto out;
168 }
169 }
170
171 old_fs = get_fs();
172 set_fs (KERNEL_DS);
173 err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
174 set_fs (old_fs);
175 if (err)
176 goto out;
177
178 ifr = ifc.ifc_req;
179 ifr32 = (struct ifreq32 *) A(ifc32.ifcbuf);
180 len = ifc.ifc_len / sizeof (struct ifreq);
181 ifc32.ifc_len = len * sizeof (struct ifreq32);
182
183 while (len--) {
184 if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
185 err = -EFAULT;
186 goto out;
187 }
188 }
189
190 if (copy_to_user(uifc32, &ifc32, sizeof(struct ifconf32))) {
191 err = -EFAULT;
192 goto out;
193 }
194 out:
195 if(ifc.ifc_buf != NULL)
196 kfree (ifc.ifc_buf);
197 return err;
198 }
199
200 static inline int dev_ifsioc(unsigned int fd, unsigned int cmd,
201 unsigned long arg)
202 {
203 struct ifreq32 *uifr = (struct ifreq32 *) A(arg);
204 struct ifreq ifr;
205 mm_segment_t old_fs;
206 int err;
207
208 switch (cmd) {
209 case SIOCSIFMAP:
210 err = copy_from_user(&ifr, uifr, sizeof(ifr.ifr_name));
211 err |= __get_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));
212 err |= __get_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));
213 err |= __get_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));
214 err |= __get_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));
215 err |= __get_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));
216 err |= __get_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));
217 if (err)
218 return -EFAULT;
219 break;
220 default:
221 if (copy_from_user(&ifr, uifr, sizeof(struct ifreq32)))
222 return -EFAULT;
223 break;
224 }
225 old_fs = get_fs();
226 set_fs (KERNEL_DS);
227 err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
228 set_fs (old_fs);
229 if (!err) {
230 switch (cmd) {
231 case SIOCGIFFLAGS:
232 case SIOCGIFMETRIC:
233 case SIOCGIFMTU:
234 case SIOCGIFMEM:
235 case SIOCGIFHWADDR:
236 case SIOCGIFINDEX:
237 case SIOCGIFADDR:
238 case SIOCGIFBRDADDR:
239 case SIOCGIFDSTADDR:
240 case SIOCGIFNETMASK:
241 case SIOCGIFTXQLEN:
242 if (copy_to_user(uifr, &ifr, sizeof(struct ifreq32)))
243 return -EFAULT;
244 break;
245 case SIOCGIFMAP:
246 err = copy_to_user(uifr, &ifr, sizeof(ifr.ifr_name));
247 err |= __put_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));
248 err |= __put_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));
249 err |= __put_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));
250 err |= __put_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));
251 err |= __put_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));
252 err |= __put_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));
253 if (err)
254 err = -EFAULT;
255 break;
256 }
257 }
258 return err;
259 }
260
261 struct rtentry32
262 {
263 unsigned int rt_pad1;
264 struct sockaddr rt_dst; /* target address */
265 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
266 struct sockaddr rt_genmask; /* target network mask (IP) */
267 unsigned short rt_flags;
268 short rt_pad2;
269 unsigned int rt_pad3;
270 unsigned int rt_pad4;
271 short rt_metric; /* +1 for binary compatibility! */
272 unsigned int rt_dev; /* forcing the device at add */
273 unsigned int rt_mtu; /* per route MTU/Window */
274 #ifndef __KERNEL__
275 #define rt_mss rt_mtu /* Compatibility :-( */
276 #endif
277 unsigned int rt_window; /* Window clamping */
278 unsigned short rt_irtt; /* Initial RTT */
279 };
280
281 static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
282 {
283 struct rtentry32 *ur = (struct rtentry32 *) A(arg);
284 struct rtentry r;
285 char devname[16];
286 u32 rtdev;
287 int ret;
288 mm_segment_t old_fs = get_fs();
289
290 ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr));
291 ret |= __get_user (r.rt_flags, &(ur->rt_flags));
292 ret |= __get_user (r.rt_metric, &(ur->rt_metric));
293 ret |= __get_user (r.rt_mtu, &(ur->rt_mtu));
294 ret |= __get_user (r.rt_window, &(ur->rt_window));
295 ret |= __get_user (r.rt_irtt, &(ur->rt_irtt));
296 ret |= __get_user (rtdev, &(ur->rt_dev));
297 if (rtdev) {
298 ret |= copy_from_user (devname, (char *) A(rtdev), 15);
299 r.rt_dev = devname; devname[15] = 0;
300 } else
301 r.rt_dev = 0;
302 if (ret)
303 return -EFAULT;
304 set_fs (KERNEL_DS);
305 ret = sys_ioctl (fd, cmd, (long)&r);
306 set_fs (old_fs);
307 return ret;
308 }
309
310 static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
311 {
312 /* These are just misnamed, they actually get/put from/to user an int */
313 switch (cmd) {
314 case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
315 case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
316 case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
317 case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
318 }
319 return sys_ioctl(fd, cmd, arg);
320 }
321
322 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
323 {
324 mm_segment_t old_fs = get_fs();
325 int err;
326 unsigned long val;
327
328 set_fs (KERNEL_DS);
329 err = sys_ioctl(fd, cmd, (unsigned long)&val);
330 set_fs (old_fs);
331 if (!err && put_user((unsigned int) val, (u32 *)arg))
332 return -EFAULT;
333 return err;
334 }
335
336 struct ioctl32_handler {
337 unsigned int cmd;
338 int (*function)(unsigned int, unsigned int, unsigned long);
339 };
340
341 struct ioctl32_list {
342 struct ioctl32_handler handler;
343 struct ioctl32_list *next;
344 };
345
346 #define IOCTL32_DEFAULT(cmd) { { cmd, (void *) sys_ioctl }, 0 }
347 #define IOCTL32_HANDLER(cmd, handler) { { cmd, (void *) handler }, 0 }
348
349 static struct ioctl32_list ioctl32_handler_table[] = {
350 IOCTL32_DEFAULT(FIBMAP),
351 IOCTL32_DEFAULT(FIGETBSZ),
352
353 IOCTL32_DEFAULT(DASDAPIVER),
354 IOCTL32_DEFAULT(BIODASDDISABLE),
355 IOCTL32_DEFAULT(BIODASDENABLE),
356 IOCTL32_DEFAULT(BIODASDRSRV),
357 IOCTL32_DEFAULT(BIODASDRLSE),
358 IOCTL32_DEFAULT(BIODASDSLCK),
359 IOCTL32_DEFAULT(BIODASDINFO),
360 IOCTL32_DEFAULT(BIODASDFMT),
361
362 IOCTL32_DEFAULT(BLKRRPART),
363
364 IOCTL32_HANDLER(HDIO_GETGEO, hd_geometry_ioctl),
365
366 IOCTL32_DEFAULT(TCGETA),
367 IOCTL32_DEFAULT(TCSETA),
368 IOCTL32_DEFAULT(TCSETAW),
369 IOCTL32_DEFAULT(TCSETAF),
370 IOCTL32_DEFAULT(TCSBRK),
371 IOCTL32_DEFAULT(TCXONC),
372 IOCTL32_DEFAULT(TCFLSH),
373 IOCTL32_DEFAULT(TCGETS),
374 IOCTL32_DEFAULT(TCSETS),
375 IOCTL32_DEFAULT(TCSETSW),
376 IOCTL32_DEFAULT(TCSETSF),
377 IOCTL32_DEFAULT(TIOCLINUX),
378
379 IOCTL32_DEFAULT(TIOCGETD),
380 IOCTL32_DEFAULT(TIOCSETD),
381 IOCTL32_DEFAULT(TIOCEXCL),
382 IOCTL32_DEFAULT(TIOCNXCL),
383 IOCTL32_DEFAULT(TIOCCONS),
384 IOCTL32_DEFAULT(TIOCGSOFTCAR),
385 IOCTL32_DEFAULT(TIOCSSOFTCAR),
386 IOCTL32_DEFAULT(TIOCSWINSZ),
387 IOCTL32_DEFAULT(TIOCGWINSZ),
388 IOCTL32_DEFAULT(TIOCMGET),
389 IOCTL32_DEFAULT(TIOCMBIC),
390 IOCTL32_DEFAULT(TIOCMBIS),
391 IOCTL32_DEFAULT(TIOCMSET),
392 IOCTL32_DEFAULT(TIOCPKT),
393 IOCTL32_DEFAULT(TIOCNOTTY),
394 IOCTL32_DEFAULT(TIOCSTI),
395 IOCTL32_DEFAULT(TIOCOUTQ),
396 IOCTL32_DEFAULT(TIOCSPGRP),
397 IOCTL32_DEFAULT(TIOCGPGRP),
398 IOCTL32_DEFAULT(TIOCSCTTY),
399 IOCTL32_DEFAULT(TIOCGPTN),
400 IOCTL32_DEFAULT(TIOCSPTLCK),
401 IOCTL32_DEFAULT(TIOCGSERIAL),
402 IOCTL32_DEFAULT(TIOCSSERIAL),
403 IOCTL32_DEFAULT(TIOCSERGETLSR),
404
405 IOCTL32_DEFAULT(FIOCLEX),
406 IOCTL32_DEFAULT(FIONCLEX),
407 IOCTL32_DEFAULT(FIOASYNC),
408 IOCTL32_DEFAULT(FIONBIO),
409 IOCTL32_DEFAULT(FIONREAD),
410
411 IOCTL32_DEFAULT(PIO_FONT),
412 IOCTL32_DEFAULT(GIO_FONT),
413 IOCTL32_DEFAULT(KDSIGACCEPT),
414 IOCTL32_DEFAULT(KDGETKEYCODE),
415 IOCTL32_DEFAULT(KDSETKEYCODE),
416 IOCTL32_DEFAULT(KIOCSOUND),
417 IOCTL32_DEFAULT(KDMKTONE),
418 IOCTL32_DEFAULT(KDGKBTYPE),
419 IOCTL32_DEFAULT(KDSETMODE),
420 IOCTL32_DEFAULT(KDGETMODE),
421 IOCTL32_DEFAULT(KDSKBMODE),
422 IOCTL32_DEFAULT(KDGKBMODE),
423 IOCTL32_DEFAULT(KDSKBMETA),
424 IOCTL32_DEFAULT(KDGKBMETA),
425 IOCTL32_DEFAULT(KDGKBENT),
426 IOCTL32_DEFAULT(KDSKBENT),
427 IOCTL32_DEFAULT(KDGKBSENT),
428 IOCTL32_DEFAULT(KDSKBSENT),
429 IOCTL32_DEFAULT(KDGKBDIACR),
430 IOCTL32_DEFAULT(KDSKBDIACR),
431 IOCTL32_DEFAULT(KDGKBLED),
432 IOCTL32_DEFAULT(KDSKBLED),
433 IOCTL32_DEFAULT(KDGETLED),
434 IOCTL32_DEFAULT(KDSETLED),
435 IOCTL32_DEFAULT(GIO_SCRNMAP),
436 IOCTL32_DEFAULT(PIO_SCRNMAP),
437 IOCTL32_DEFAULT(GIO_UNISCRNMAP),
438 IOCTL32_DEFAULT(PIO_UNISCRNMAP),
439 IOCTL32_DEFAULT(PIO_FONTRESET),
440 IOCTL32_DEFAULT(PIO_UNIMAPCLR),
441
442 IOCTL32_DEFAULT(VT_SETMODE),
443 IOCTL32_DEFAULT(VT_GETMODE),
444 IOCTL32_DEFAULT(VT_GETSTATE),
445 IOCTL32_DEFAULT(VT_OPENQRY),
446 IOCTL32_DEFAULT(VT_ACTIVATE),
447 IOCTL32_DEFAULT(VT_WAITACTIVE),
448 IOCTL32_DEFAULT(VT_RELDISP),
449 IOCTL32_DEFAULT(VT_DISALLOCATE),
450 IOCTL32_DEFAULT(VT_RESIZE),
451 IOCTL32_DEFAULT(VT_RESIZEX),
452 IOCTL32_DEFAULT(VT_LOCKSWITCH),
453 IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
454
455 IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
456 IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
457 IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
458 IOCTL32_HANDLER(SIOCSIFFLAGS, dev_ifsioc),
459 IOCTL32_HANDLER(SIOCGIFMETRIC, dev_ifsioc),
460 IOCTL32_HANDLER(SIOCSIFMETRIC, dev_ifsioc),
461 IOCTL32_HANDLER(SIOCGIFMTU, dev_ifsioc),
462 IOCTL32_HANDLER(SIOCSIFMTU, dev_ifsioc),
463 IOCTL32_HANDLER(SIOCGIFMEM, dev_ifsioc),
464 IOCTL32_HANDLER(SIOCSIFMEM, dev_ifsioc),
465 IOCTL32_HANDLER(SIOCGIFHWADDR, dev_ifsioc),
466 IOCTL32_HANDLER(SIOCSIFHWADDR, dev_ifsioc),
467 IOCTL32_HANDLER(SIOCADDMULTI, dev_ifsioc),
468 IOCTL32_HANDLER(SIOCDELMULTI, dev_ifsioc),
469 IOCTL32_HANDLER(SIOCGIFINDEX, dev_ifsioc),
470 IOCTL32_HANDLER(SIOCGIFMAP, dev_ifsioc),
471 IOCTL32_HANDLER(SIOCSIFMAP, dev_ifsioc),
472 IOCTL32_HANDLER(SIOCGIFADDR, dev_ifsioc),
473 IOCTL32_HANDLER(SIOCSIFADDR, dev_ifsioc),
474 IOCTL32_HANDLER(SIOCGIFBRDADDR, dev_ifsioc),
475 IOCTL32_HANDLER(SIOCSIFBRDADDR, dev_ifsioc),
476 IOCTL32_HANDLER(SIOCGIFDSTADDR, dev_ifsioc),
477 IOCTL32_HANDLER(SIOCSIFDSTADDR, dev_ifsioc),
478 IOCTL32_HANDLER(SIOCGIFNETMASK, dev_ifsioc),
479 IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc),
480 IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc),
481 IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc),
482 IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc),
483 IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc),
484 IOCTL32_HANDLER(SIOCADDRT, routing_ioctl),
485 IOCTL32_HANDLER(SIOCDELRT, routing_ioctl),
486
487 IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
488 IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
489 IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
490 IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
491
492 IOCTL32_HANDLER(BLKGETSIZE, w_long)
493
494 };
495
496 #define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \
497 sizeof(ioctl32_handler_table[0]))
498
499 static struct ioctl32_list *ioctl32_hash_table[1024];
500
501 static inline int ioctl32_hash(unsigned int cmd)
502 {
503 return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
504 }
505
506 int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
507 {
508 int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
509 struct file *filp;
510 struct ioctl32_list *l;
511 int error;
512
513 l = ioctl32_hash_table[ioctl32_hash(cmd)];
514
515 error = -EBADF;
516
517 filp = fget(fd);
518 if (!filp)
519 return error;
520
521 if (!filp->f_op || !filp->f_op->ioctl) {
522 error = sys_ioctl (fd, cmd, arg);
523 goto out;
524 }
525
526 while (l && l->handler.cmd != cmd)
527 l = l->next;
528
529 if (l) {
530 handler = (void *)l->handler.function;
531 error = handler(fd, cmd, arg, filp);
532 } else {
533 error = -EINVAL;
534 printk("unknown ioctl: %08x\n", cmd);
535 }
536 out:
537 fput(filp);
538 return error;
539 }
540
541 static void ioctl32_insert(struct ioctl32_list *entry)
542 {
543 int hash = ioctl32_hash(entry->handler.cmd);
544 if (!ioctl32_hash_table[hash])
545 ioctl32_hash_table[hash] = entry;
546 else {
547 struct ioctl32_list *l;
548 l = ioctl32_hash_table[hash];
549 while (l->next)
550 l = l->next;
551 l->next = entry;
552 entry->next = 0;
553 }
554 }
555
556 static int __init init_ioctl32(void)
557 {
558 int i;
559 for (i = 0; i < NR_IOCTL32_HANDLERS; i++)
560 ioctl32_insert(&ioctl32_handler_table[i]);
561 return 0;
562 }
563
564 __initcall(init_ioctl32);
565