Staging: comedi: drivers.c: checkpatch fix
[safe/jmp/linux-2.6] / drivers / staging / comedi / comedi_compat32.c
1 /*
2     comedi/comedi_compat32.c
3     32-bit ioctl compatibility for 64-bit comedi kernel module.
4
5     Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
6     Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
7
8     COMEDI - Linux Control and Measurement Device Interface
9     Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
10
11     This program is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published by
13     the Free Software Foundation; either version 2 of the License, or
14     (at your option) any later version.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     You should have received a copy of the GNU General Public License
22     along with this program; if not, write to the Free Software
23     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25 */
26
27 #define __NO_VERSION__
28 #include "comedi.h"
29 #include <linux/smp_lock.h>
30 #include <asm/uaccess.h>
31
32 #include "comedi_compat32.h"
33
34 #ifdef CONFIG_COMPAT
35
36 #ifndef HAVE_COMPAT_IOCTL
37 #include <linux/ioctl32.h>      /* for (un)register_ioctl32_conversion */
38 #endif
39
40 #define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
41 #define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
42 /* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
43  * It's too late to change it now, but it only affects the command number. */
44 #define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
45 /* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
46  * It's too late to change it now, but it only affects the command number. */
47 #define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
48 #define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
49 #define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
50
51 struct comedi32_chaninfo_struct {
52         unsigned int subdev;
53         compat_uptr_t maxdata_list;     /* 32-bit 'unsigned int *' */
54         compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
55         compat_uptr_t rangelist;        /* 32-bit 'unsigned int *' */
56         unsigned int unused[4];
57 };
58
59 struct comedi32_rangeinfo_struct {
60         unsigned int range_type;
61         compat_uptr_t range_ptr;        /* 32-bit 'void *' */
62 };
63
64 struct comedi32_cmd_struct {
65         unsigned int subdev;
66         unsigned int flags;
67         unsigned int start_src;
68         unsigned int start_arg;
69         unsigned int scan_begin_src;
70         unsigned int scan_begin_arg;
71         unsigned int convert_src;
72         unsigned int convert_arg;
73         unsigned int scan_end_src;
74         unsigned int scan_end_arg;
75         unsigned int stop_src;
76         unsigned int stop_arg;
77         compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
78         unsigned int chanlist_len;
79         compat_uptr_t data;     /* 32-bit 'short *' */
80         unsigned int data_len;
81 };
82
83 struct comedi32_insn_struct {
84         unsigned int insn;
85         unsigned int n;
86         compat_uptr_t data;     /* 32-bit 'unsigned int *' */
87         unsigned int subdev;
88         unsigned int chanspec;
89         unsigned int unused[3];
90 };
91
92 struct comedi32_insnlist_struct {
93         unsigned int n_insns;
94         compat_uptr_t insns;    /* 32-bit 'struct comedi_insn *' */
95 };
96
97 /* Handle translated ioctl. */
98 static int translated_ioctl(struct file *file, unsigned int cmd,
99                             unsigned long arg)
100 {
101         if (!file->f_op)
102                 return -ENOTTY;
103
104 #ifdef HAVE_UNLOCKED_IOCTL
105         if (file->f_op->unlocked_ioctl) {
106                 int rc = (int)(*file->f_op->unlocked_ioctl) (file, cmd, arg);
107                 if (rc == -ENOIOCTLCMD)
108                         rc = -ENOTTY;
109                 return rc;
110         }
111 #endif
112         if (file->f_op->ioctl) {
113                 int rc;
114                 lock_kernel();
115                 rc = (*file->f_op->ioctl) (file->f_dentry->d_inode,
116                                            file, cmd, arg);
117                 unlock_kernel();
118                 return rc;
119         }
120         return -ENOTTY;
121 }
122
123 /* Handle 32-bit COMEDI_CHANINFO ioctl. */
124 static int compat_chaninfo(struct file *file, unsigned long arg)
125 {
126         struct comedi_chaninfo __user *chaninfo;
127         struct comedi32_chaninfo_struct __user *chaninfo32;
128         int err;
129         union {
130                 unsigned int uint;
131                 compat_uptr_t uptr;
132         } temp;
133
134         chaninfo32 = compat_ptr(arg);
135         chaninfo = compat_alloc_user_space(sizeof(*chaninfo));
136
137         /* Copy chaninfo structure.  Ignore unused members. */
138         if (!access_ok(VERIFY_READ, chaninfo32, sizeof(*chaninfo32))
139             || !access_ok(VERIFY_WRITE, chaninfo, sizeof(*chaninfo))) {
140                 return -EFAULT;
141         }
142         err = 0;
143         err |= __get_user(temp.uint, &chaninfo32->subdev);
144         err |= __put_user(temp.uint, &chaninfo->subdev);
145         err |= __get_user(temp.uptr, &chaninfo32->maxdata_list);
146         err |= __put_user(compat_ptr(temp.uptr), &chaninfo->maxdata_list);
147         err |= __get_user(temp.uptr, &chaninfo32->flaglist);
148         err |= __put_user(compat_ptr(temp.uptr), &chaninfo->flaglist);
149         err |= __get_user(temp.uptr, &chaninfo32->rangelist);
150         err |= __put_user(compat_ptr(temp.uptr), &chaninfo->rangelist);
151         if (err)
152                 return -EFAULT;
153
154         return translated_ioctl(file, COMEDI_CHANINFO, (unsigned long)chaninfo);
155 }
156
157 /* Handle 32-bit COMEDI_RANGEINFO ioctl. */
158 static int compat_rangeinfo(struct file *file, unsigned long arg)
159 {
160         struct comedi_rangeinfo __user *rangeinfo;
161         struct comedi32_rangeinfo_struct __user *rangeinfo32;
162         int err;
163         union {
164                 unsigned int uint;
165                 compat_uptr_t uptr;
166         } temp;
167
168         rangeinfo32 = compat_ptr(arg);
169         rangeinfo = compat_alloc_user_space(sizeof(*rangeinfo));
170
171         /* Copy rangeinfo structure. */
172         if (!access_ok(VERIFY_READ, rangeinfo32, sizeof(*rangeinfo32))
173             || !access_ok(VERIFY_WRITE, rangeinfo, sizeof(*rangeinfo))) {
174                 return -EFAULT;
175         }
176         err = 0;
177         err |= __get_user(temp.uint, &rangeinfo32->range_type);
178         err |= __put_user(temp.uint, &rangeinfo->range_type);
179         err |= __get_user(temp.uptr, &rangeinfo32->range_ptr);
180         err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr);
181         if (err)
182                 return -EFAULT;
183
184         return translated_ioctl(file, COMEDI_RANGEINFO,
185                                 (unsigned long)rangeinfo);
186 }
187
188 /* Copy 32-bit cmd structure to native cmd structure. */
189 static int get_compat_cmd(struct comedi_cmd __user * cmd,
190                           struct comedi32_cmd_struct __user * cmd32)
191 {
192         int err;
193         union {
194                 unsigned int uint;
195                 compat_uptr_t uptr;
196         } temp;
197
198         /* Copy cmd structure. */
199         if (!access_ok(VERIFY_READ, cmd32, sizeof(*cmd32))
200             || !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd))) {
201                 return -EFAULT;
202         }
203         err = 0;
204         err |= __get_user(temp.uint, &cmd32->subdev);
205         err |= __put_user(temp.uint, &cmd->subdev);
206         err |= __get_user(temp.uint, &cmd32->flags);
207         err |= __put_user(temp.uint, &cmd->flags);
208         err |= __get_user(temp.uint, &cmd32->start_src);
209         err |= __put_user(temp.uint, &cmd->start_src);
210         err |= __get_user(temp.uint, &cmd32->start_arg);
211         err |= __put_user(temp.uint, &cmd->start_arg);
212         err |= __get_user(temp.uint, &cmd32->scan_begin_src);
213         err |= __put_user(temp.uint, &cmd->scan_begin_src);
214         err |= __get_user(temp.uint, &cmd32->scan_begin_arg);
215         err |= __put_user(temp.uint, &cmd->scan_begin_arg);
216         err |= __get_user(temp.uint, &cmd32->convert_src);
217         err |= __put_user(temp.uint, &cmd->convert_src);
218         err |= __get_user(temp.uint, &cmd32->convert_arg);
219         err |= __put_user(temp.uint, &cmd->convert_arg);
220         err |= __get_user(temp.uint, &cmd32->scan_end_src);
221         err |= __put_user(temp.uint, &cmd->scan_end_src);
222         err |= __get_user(temp.uint, &cmd32->scan_end_arg);
223         err |= __put_user(temp.uint, &cmd->scan_end_arg);
224         err |= __get_user(temp.uint, &cmd32->stop_src);
225         err |= __put_user(temp.uint, &cmd->stop_src);
226         err |= __get_user(temp.uint, &cmd32->stop_arg);
227         err |= __put_user(temp.uint, &cmd->stop_arg);
228         err |= __get_user(temp.uptr, &cmd32->chanlist);
229         err |= __put_user(compat_ptr(temp.uptr), &cmd->chanlist);
230         err |= __get_user(temp.uint, &cmd32->chanlist_len);
231         err |= __put_user(temp.uint, &cmd->chanlist_len);
232         err |= __get_user(temp.uptr, &cmd32->data);
233         err |= __put_user(compat_ptr(temp.uptr), &cmd->data);
234         err |= __get_user(temp.uint, &cmd32->data_len);
235         err |= __put_user(temp.uint, &cmd->data_len);
236         return err ? -EFAULT : 0;
237 }
238
239 /* Copy native cmd structure to 32-bit cmd structure. */
240 static int put_compat_cmd(struct comedi32_cmd_struct __user * cmd32,
241                           struct comedi_cmd __user * cmd)
242 {
243         int err;
244         unsigned int temp;
245
246         /* Copy back most of cmd structure. */
247         /* Assume the pointer values are already valid. */
248         /* (Could use ptr_to_compat() to set them, but that wasn't implemented
249          * until kernel version 2.6.11.) */
250         if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd))
251             || !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) {
252                 return -EFAULT;
253         }
254         err = 0;
255         err |= __get_user(temp, &cmd->subdev);
256         err |= __put_user(temp, &cmd32->subdev);
257         err |= __get_user(temp, &cmd->flags);
258         err |= __put_user(temp, &cmd32->flags);
259         err |= __get_user(temp, &cmd->start_src);
260         err |= __put_user(temp, &cmd32->start_src);
261         err |= __get_user(temp, &cmd->start_arg);
262         err |= __put_user(temp, &cmd32->start_arg);
263         err |= __get_user(temp, &cmd->scan_begin_src);
264         err |= __put_user(temp, &cmd32->scan_begin_src);
265         err |= __get_user(temp, &cmd->scan_begin_arg);
266         err |= __put_user(temp, &cmd32->scan_begin_arg);
267         err |= __get_user(temp, &cmd->convert_src);
268         err |= __put_user(temp, &cmd32->convert_src);
269         err |= __get_user(temp, &cmd->convert_arg);
270         err |= __put_user(temp, &cmd32->convert_arg);
271         err |= __get_user(temp, &cmd->scan_end_src);
272         err |= __put_user(temp, &cmd32->scan_end_src);
273         err |= __get_user(temp, &cmd->scan_end_arg);
274         err |= __put_user(temp, &cmd32->scan_end_arg);
275         err |= __get_user(temp, &cmd->stop_src);
276         err |= __put_user(temp, &cmd32->stop_src);
277         err |= __get_user(temp, &cmd->stop_arg);
278         err |= __put_user(temp, &cmd32->stop_arg);
279         /* Assume chanlist pointer is unchanged. */
280         err |= __get_user(temp, &cmd->chanlist_len);
281         err |= __put_user(temp, &cmd32->chanlist_len);
282         /* Assume data pointer is unchanged. */
283         err |= __get_user(temp, &cmd->data_len);
284         err |= __put_user(temp, &cmd32->data_len);
285         return err ? -EFAULT : 0;
286 }
287
288 /* Handle 32-bit COMEDI_CMD ioctl. */
289 static int compat_cmd(struct file *file, unsigned long arg)
290 {
291         struct comedi_cmd __user *cmd;
292         struct comedi32_cmd_struct __user *cmd32;
293         int rc;
294
295         cmd32 = compat_ptr(arg);
296         cmd = compat_alloc_user_space(sizeof(*cmd));
297
298         rc = get_compat_cmd(cmd, cmd32);
299         if (rc)
300                 return rc;
301
302         return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
303 }
304
305 /* Handle 32-bit COMEDI_CMDTEST ioctl. */
306 static int compat_cmdtest(struct file *file, unsigned long arg)
307 {
308         struct comedi_cmd __user *cmd;
309         struct comedi32_cmd_struct __user *cmd32;
310         int rc, err;
311
312         cmd32 = compat_ptr(arg);
313         cmd = compat_alloc_user_space(sizeof(*cmd));
314
315         rc = get_compat_cmd(cmd, cmd32);
316         if (rc)
317                 return rc;
318
319         rc = translated_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd);
320         if (rc < 0)
321                 return rc;
322
323         err = put_compat_cmd(cmd32, cmd);
324         if (err)
325                 rc = err;
326
327         return rc;
328 }
329
330 /* Copy 32-bit insn structure to native insn structure. */
331 static int get_compat_insn(struct comedi_insn __user * insn,
332                            struct comedi32_insn_struct __user * insn32)
333 {
334         int err;
335         union {
336                 unsigned int uint;
337                 compat_uptr_t uptr;
338         } temp;
339
340         /* Copy insn structure.  Ignore the unused members. */
341         err = 0;
342         if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32))
343             || !access_ok(VERIFY_WRITE, insn, sizeof(*insn)))
344                 return -EFAULT;
345
346         err |= __get_user(temp.uint, &insn32->insn);
347         err |= __put_user(temp.uint, &insn->insn);
348         err |= __get_user(temp.uint, &insn32->n);
349         err |= __put_user(temp.uint, &insn->n);
350         err |= __get_user(temp.uptr, &insn32->data);
351         err |= __put_user(compat_ptr(temp.uptr), &insn->data);
352         err |= __get_user(temp.uint, &insn32->subdev);
353         err |= __put_user(temp.uint, &insn->subdev);
354         err |= __get_user(temp.uint, &insn32->chanspec);
355         err |= __put_user(temp.uint, &insn->chanspec);
356         return err ? -EFAULT : 0;
357 }
358
359 /* Handle 32-bit COMEDI_INSNLIST ioctl. */
360 static int compat_insnlist(struct file *file, unsigned long arg)
361 {
362         struct combined_insnlist {
363                 struct comedi_insnlist insnlist;
364                 struct comedi_insn insn[1];
365         } __user *s;
366         struct comedi32_insnlist_struct __user *insnlist32;
367         struct comedi32_insn_struct __user *insn32;
368         compat_uptr_t uptr;
369         unsigned int n_insns, n;
370         int err, rc;
371
372         insnlist32 = compat_ptr(arg);
373
374         /* Get 32-bit insnlist structure.  */
375         if (!access_ok(VERIFY_READ, insnlist32, sizeof(*insnlist32))) {
376                 return -EFAULT;
377         }
378         err = 0;
379         err |= __get_user(n_insns, &insnlist32->n_insns);
380         err |= __get_user(uptr, &insnlist32->insns);
381         insn32 = compat_ptr(uptr);
382         if (err)
383                 return -EFAULT;
384
385         /* Allocate user memory to copy insnlist and insns into. */
386         s = compat_alloc_user_space(offsetof(struct combined_insnlist,
387                                              insn[n_insns]));
388
389         /* Set native insnlist structure. */
390         if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist))) {
391                 return -EFAULT;
392         }
393         err |= __put_user(n_insns, &s->insnlist.n_insns);
394         err |= __put_user(&s->insn[0], &s->insnlist.insns);
395         if (err)
396                 return -EFAULT;
397
398         /* Copy insn structures. */
399         for (n = 0; n < n_insns; n++) {
400                 rc = get_compat_insn(&s->insn[n], &insn32[n]);
401                 if (rc)
402                         return rc;
403         }
404
405         return translated_ioctl(file, COMEDI_INSNLIST,
406                                 (unsigned long)&s->insnlist);
407 }
408
409 /* Handle 32-bit COMEDI_INSN ioctl. */
410 static int compat_insn(struct file *file, unsigned long arg)
411 {
412         struct comedi_insn __user *insn;
413         struct comedi32_insn_struct __user *insn32;
414         int rc;
415
416         insn32 = compat_ptr(arg);
417         insn = compat_alloc_user_space(sizeof(*insn));
418
419         rc = get_compat_insn(insn, insn32);
420         if (rc)
421                 return rc;
422
423         return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn);
424 }
425
426 /* Process untranslated ioctl. */
427 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
428 static inline int raw_ioctl(struct file *file, unsigned int cmd,
429                             unsigned long arg)
430 {
431         int rc;
432
433         switch (cmd) {
434         case COMEDI_DEVCONFIG:
435         case COMEDI_DEVINFO:
436         case COMEDI_SUBDINFO:
437         case COMEDI_BUFCONFIG:
438         case COMEDI_BUFINFO:
439                 /* Just need to translate the pointer argument. */
440                 arg = (unsigned long)compat_ptr(arg);
441                 rc = translated_ioctl(file, cmd, arg);
442                 break;
443         case COMEDI_LOCK:
444         case COMEDI_UNLOCK:
445         case COMEDI_CANCEL:
446         case COMEDI_POLL:
447                 /* No translation needed. */
448                 rc = translated_ioctl(file, cmd, arg);
449                 break;
450         case COMEDI32_CHANINFO:
451                 rc = compat_chaninfo(file, arg);
452                 break;
453         case COMEDI32_RANGEINFO:
454                 rc = compat_rangeinfo(file, arg);
455                 break;
456         case COMEDI32_CMD:
457                 rc = compat_cmd(file, arg);
458                 break;
459         case COMEDI32_CMDTEST:
460                 rc = compat_cmdtest(file, arg);
461                 break;
462         case COMEDI32_INSNLIST:
463                 rc = compat_insnlist(file, arg);
464                 break;
465         case COMEDI32_INSN:
466                 rc = compat_insn(file, arg);
467                 break;
468         default:
469                 rc = -ENOIOCTLCMD;
470                 break;
471         }
472         return rc;
473 }
474
475 #ifdef HAVE_COMPAT_IOCTL        /* defined in <linux/fs.h> 2.6.11 onwards */
476
477 /* compat_ioctl file operation. */
478 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
479 long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
480 {
481         return raw_ioctl(file, cmd, arg);
482 }
483
484 #else /* HAVE_COMPAT_IOCTL */
485
486 /*
487  * Brain-dead ioctl compatibility for 2.6.10 and earlier.
488  *
489  * It's brain-dead because cmd numbers need to be unique system-wide!
490  * The comedi driver could end up attempting to execute ioctls for non-Comedi
491  * devices because it registered the system-wide cmd code first.  Similarly,
492  * another driver could end up attempting to execute ioctls for a Comedi
493  * device because it registered the cmd code first.  Chaos ensues.
494  */
495
496 /* Handler for all 32-bit ioctl codes registered by this driver. */
497 static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
498                         struct file *file)
499 {
500         int rc;
501
502         /* Make sure we are dealing with a Comedi device. */
503         if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR)
504                 return -ENOTTY;
505
506         rc = raw_ioctl(file, cmd, arg);
507         /* Do not return -ENOIOCTLCMD. */
508         if (rc == -ENOIOCTLCMD)
509                 rc = -ENOTTY;
510
511         return rc;
512 }
513
514 struct ioctl32_map {
515         unsigned int cmd;
516         int (*handler) (unsigned int, unsigned int, unsigned long,
517                         struct file *);
518         int registered;
519 };
520
521 static struct ioctl32_map comedi_ioctl32_map[] = {
522         {COMEDI_DEVCONFIG, mapped_ioctl, 0},
523         {COMEDI_DEVINFO, mapped_ioctl, 0},
524         {COMEDI_SUBDINFO, mapped_ioctl, 0},
525         {COMEDI_BUFCONFIG, mapped_ioctl, 0},
526         {COMEDI_BUFINFO, mapped_ioctl, 0},
527         {COMEDI_LOCK, mapped_ioctl, 0},
528         {COMEDI_UNLOCK, mapped_ioctl, 0},
529         {COMEDI_CANCEL, mapped_ioctl, 0},
530         {COMEDI_POLL, mapped_ioctl, 0},
531         {COMEDI32_CHANINFO, mapped_ioctl, 0},
532         {COMEDI32_RANGEINFO, mapped_ioctl, 0},
533         {COMEDI32_CMD, mapped_ioctl, 0},
534         {COMEDI32_CMDTEST, mapped_ioctl, 0},
535         {COMEDI32_INSNLIST, mapped_ioctl, 0},
536         {COMEDI32_INSN, mapped_ioctl, 0},
537 };
538
539 #define NUM_IOCTL32_MAPS ARRAY_SIZE(comedi_ioctl32_map)
540
541 /* Register system-wide 32-bit ioctl handlers. */
542 void comedi_register_ioctl32(void)
543 {
544         int n, rc;
545
546         for (n = 0; n < NUM_IOCTL32_MAPS; n++) {
547                 rc = register_ioctl32_conversion(comedi_ioctl32_map[n].cmd,
548                                                  comedi_ioctl32_map[n].handler);
549                 if (rc) {
550                         printk(KERN_WARNING
551                                "comedi: failed to register 32-bit "
552                                "compatible ioctl handler for 0x%X - "
553                                "expect bad things to happen!\n",
554                                comedi_ioctl32_map[n].cmd);
555                 }
556                 comedi_ioctl32_map[n].registered = !rc;
557         }
558 }
559
560 /* Unregister system-wide 32-bit ioctl translations. */
561 void comedi_unregister_ioctl32(void)
562 {
563         int n, rc;
564
565         for (n = 0; n < NUM_IOCTL32_MAPS; n++) {
566                 if (comedi_ioctl32_map[n].registered) {
567                         rc = unregister_ioctl32_conversion(comedi_ioctl32_map
568                                                            [n].cmd,
569                                                            comedi_ioctl32_map
570                                                            [n].handler);
571                         if (rc) {
572                                 printk(KERN_ERR
573                                        "comedi: failed to unregister 32-bit "
574                                        "compatible ioctl handler for 0x%X - "
575                                        "expect kernel Oops!\n",
576                                        comedi_ioctl32_map[n].cmd);
577                         } else {
578                                 comedi_ioctl32_map[n].registered = 0;
579                         }
580                 }
581         }
582 }
583
584 #endif /* HAVE_COMPAT_IOCTL */
585
586 #endif /* CONFIG_COMPAT */