Fix a bug in the ioctl mapping (written by me), which basically failed
authorSimon Schubert <corecode@dragonflybsd.org>
Tue, 1 Mar 2005 00:43:02 +0000 (00:43 +0000)
committerSimon Schubert <corecode@dragonflybsd.org>
Tue, 1 Mar 2005 00:43:02 +0000 (00:43 +0000)
to provide the neccessary infrastructure for linux drm to work.

This changes DRM and sound handling in the linuxulator to make use of
the new code.

API compatibility is retained in wide parts; nevertheless modules using
ioctl maps (nvidia) need to be recompiled.

Discovered-and-fixed-by: Brock Johnson <wildefire@isentry.homelinux.org>
Reviewed-by: corecode, joerg
sys/conf/options
sys/dev/drm/drm_drv.h
sys/emulation/linux/linux_ioctl.c
sys/emulation/linux/linux_ioctl.h
sys/kern/sys_generic.c
sys/sys/mapped_ioctl.h

index 9d51423..9ced4d7 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/sys/conf/options,v 1.191.2.53 2003/06/04 17:56:58 sam Exp $
-# $DragonFly: src/sys/conf/options,v 1.30 2005/02/11 22:25:56 joerg Exp $
+# $DragonFly: src/sys/conf/options,v 1.31 2005/03/01 00:43:02 corecode Exp $
 #
 #        On the handling of kernel options
 #
@@ -354,6 +354,7 @@ NETGRAPH_VJC                opt_netgraph.h
 
 # DRM options
 DRM_DEBUG              opt_drm.h
+DRM_LINUX              opt_drm.h
 
 # ATM (HARP version)
 ATM_CORE               opt_atm.h
index 9bde4c1..e88044d 100644 (file)
@@ -29,7 +29,7 @@
  *    Gareth Hughes <gareth@valinux.com>
  *
  * $FreeBSD: src/sys/dev/drm/drm_drv.h,v 1.13.2.1 2003/04/26 07:05:28 anholt Exp $
- * $DragonFly: src/sys/dev/drm/Attic/drm_drv.h,v 1.10 2004/09/18 16:25:54 joerg Exp $
+ * $DragonFly: src/sys/dev/drm/Attic/drm_drv.h,v 1.11 2005/03/01 00:43:02 corecode Exp $
  */
 
 /*
@@ -1144,10 +1144,9 @@ MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1);
 #define LINUX_IOCTL_DRM_MIN            0x6400
 #define LINUX_IOCTL_DRM_MAX            0x64ff
 
-static ioctl_map_func DRM(ioctl_dirmap);
 static struct ioctl_map_range DRM(ioctl_cmds)[] = {
-       /* XXX: we should have a BSD #define for the range */
-       MAPPED_IOCTL_MAPRANGE(LINUX_IOCTL_DRM_MIN, LINUX_IOCTL_DRM_MAX, LINUX_IOCTL_DRM_MIN, DRM(ioctl_dirmap)),
+       MAPPED_IOCTL_MAPRANGE(LINUX_IOCTL_DRM_MIN, LINUX_IOCTL_DRM_MAX, LINUX_IOCTL_DRM_MIN,
+                             LINUX_IOCTL_DRM_MAX, NULL, linux_gen_dirmap),
        MAPPED_IOCTL_MAPF(0, 0, NULL)
 };
 
@@ -1162,11 +1161,4 @@ SYSINIT(DRM(register), SI_SUB_KLD, SI_ORDER_MIDDLE,
 SYSUNINIT(DRM(unregister), SI_SUB_KLD, SI_ORDER_MIDDLE, 
     mapped_ioctl_unregister_handler, &DRM(ioctl_handler));
 
-static int
-DRM(ioctl_dirmap)(struct file *fp, u_long cmd, u_long ocmd, caddr_t data, struct thread *td)
-{
-       return(linux_ioctl_dirmap(fp, cmd + (ocmd - LINUX_IOCTL_DRM_MIN),
-                                 ocmd, data, td));
-}
-
 #endif /* DRM_LINUX */
index e192f26..3c8c032 100644 (file)
@@ -27,7 +27,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/compat/linux/linux_ioctl.c,v 1.55.2.11 2003/05/01 20:16:09 anholt Exp $
- * $DragonFly: src/sys/emulation/linux/linux_ioctl.c,v 1.16 2005/02/17 13:59:36 joerg Exp $
+ * $DragonFly: src/sys/emulation/linux/linux_ioctl.c,v 1.17 2005/03/01 00:43:02 corecode Exp $
  */
 
 #include <sys/param.h>
@@ -1190,12 +1190,12 @@ clean_ifname:
 /*
  * generic linux -> BSD syscall direction mapper
  */
-int
-linux_ioctl_dirmap(struct file *fp, u_long cmd, u_long ocmd, caddr_t data, struct thread *td)
+u_long
+linux_gen_dirmap(u_long lstart, u_long lend, u_long bstart, u_long bend, u_long cmd, u_long ocmd)
 {
        static u_int32_t dirbits[4] = { IOC_VOID, IOC_IN, IOC_OUT, IOC_INOUT };
 
-       return (fo_ioctl(fp, (cmd & ~IOC_DIRMASK) | dirbits[ocmd >> 30], data, td));
+       return ((cmd & ~IOC_DIRMASK) | dirbits[ocmd >> 30]);
 }
 
 
@@ -1247,60 +1247,15 @@ static struct ioctl_map_range linux_ioctl_map_entries[] = {
        MAPPED_IOCTL_IOWR(LINUX_CDROMSUBCHNL, linux_ioctl_CDROMSUBCHNL, struct linux_cdrom_subchnl),
        MAPPED_IOCTL_MAP(LINUX_CDROMRESET, CDIOCRESET),
        /* sound ioctl */
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_VOLUME, SOUND_MIXER_WRITE_VOLUME, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_BASS, SOUND_MIXER_WRITE_BASS, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_TREBLE, SOUND_MIXER_WRITE_TREBLE, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_SYNTH, SOUND_MIXER_WRITE_SYNTH, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_PCM, SOUND_MIXER_WRITE_PCM, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_SPEAKER, SOUND_MIXER_WRITE_SPEAKER, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_LINE, SOUND_MIXER_WRITE_LINE, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_MIC, SOUND_MIXER_WRITE_MIC, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_CD, SOUND_MIXER_WRITE_CD, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_IMIX, SOUND_MIXER_WRITE_IMIX, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_ALTPCM, SOUND_MIXER_WRITE_ALTPCM, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_RECLEV, SOUND_MIXER_WRITE_RECLEV, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_IGAIN, SOUND_MIXER_WRITE_IGAIN, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_OGAIN, SOUND_MIXER_WRITE_OGAIN, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_LINE1, SOUND_MIXER_WRITE_LINE1, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_LINE2, SOUND_MIXER_WRITE_LINE2, linux_ioctl_dirmap),
-       MAPPED_IOCTL_MAPF(LINUX_SOUND_MIXER_WRITE_LINE3, SOUND_MIXER_WRITE_LINE3, linux_ioctl_dirmap),
+       MAPPED_IOCTL_MAPRANGE(LINUX_SOUND_MIXER_WRITE_MIN, LINUX_SOUND_MIXER_WRITE_MAX,
+                             LINUX_SOUND_MIXER_WRITE_MIN, LINUX_SOUND_MIXER_WRITE_MAX,
+                             NULL, linux_gen_dirmap),
        MAPPED_IOCTL_IOR(LINUX_OSS_GETVERSION, linux_ioctl_OSS_GETVERSION, int),
        MAPPED_IOCTL_MAP(LINUX_SOUND_MIXER_READ_DEVMASK, SOUND_MIXER_READ_DEVMASK),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_RESET, SNDCTL_DSP_RESET),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_SYNC, SNDCTL_DSP_SYNC),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_SPEED, SNDCTL_DSP_SPEED),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_STEREO, SNDCTL_DSP_STEREO),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_GETBLKSIZE, SNDCTL_DSP_GETBLKSIZE),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_SETFMT, SNDCTL_DSP_SETFMT),
-       MAPPED_IOCTL_MAP(LINUX_SOUND_PCM_WRITE_CHANNELS, SOUND_PCM_WRITE_CHANNELS),
-       MAPPED_IOCTL_MAP(LINUX_SOUND_PCM_WRITE_FILTER, SOUND_PCM_WRITE_FILTER),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_POST, SNDCTL_DSP_POST),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_SUBDIVIDE, SNDCTL_DSP_SUBDIVIDE),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_SETFRAGMENT, SNDCTL_DSP_SETFRAGMENT),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_GETFMTS, SNDCTL_DSP_GETFMTS),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_GETOSPACE, SNDCTL_DSP_GETOSPACE),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_GETISPACE, SNDCTL_DSP_GETISPACE),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_NONBLOCK, SNDCTL_DSP_NONBLOCK),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_GETCAPS, SNDCTL_DSP_GETCAPS),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_SETTRIGGER, SNDCTL_DSP_SETTRIGGER),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_GETIPTR, SNDCTL_DSP_GETIPTR),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_GETOPTR, SNDCTL_DSP_GETOPTR),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_DSP_GETODELAY, SNDCTL_DSP_GETODELAY),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_RESET, SNDCTL_SEQ_RESET),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_SYNC, SNDCTL_SEQ_SYNC),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SYNTH_INFO, SNDCTL_SYNTH_INFO),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_CTRLRATE, SNDCTL_SEQ_CTRLRATE),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_GETOUTCOUNT, SNDCTL_SEQ_GETOUTCOUNT),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_GETINCOUNT, SNDCTL_SEQ_GETINCOUNT),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_PERCMODE, SNDCTL_SEQ_PERCMODE),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_FM_LOAD_INSTR, SNDCTL_FM_LOAD_INSTR),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_TESTMIDI, SNDCTL_SEQ_TESTMIDI),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_RESETSAMPLES, SNDCTL_SEQ_RESETSAMPLES),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_NRSYNTHS, SNDCTL_SEQ_NRSYNTHS),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_NRMIDIS, SNDCTL_SEQ_NRMIDIS),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_MIDI_INFO, SNDCTL_MIDI_INFO),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SEQ_TRESHOLD, SNDCTL_SEQ_TRESHOLD),
-       MAPPED_IOCTL_MAP(LINUX_SNDCTL_SYNTH_MEMAVL, SNDCTL_SYNTH_MEMAVL),
+       MAPPED_IOCTL_MAPRANGE(LINUX_SNDCTL_DSP_MIN, LINUX_SNDCTL_DSP_MAX, LINUX_SNDCTL_DSP_MIN,
+                             LINUX_SNDCTL_DSP_MAX, NULL, linux_gen_dirmap),
+       MAPPED_IOCTL_MAPRANGE(LINUX_SNDCTL_SEQ_MIN, LINUX_SNDCTL_SEQ_MAX, LINUX_SNDCTL_SEQ_MIN,
+                             LINUX_SNDCTL_SEQ_MAX, NULL, linux_gen_dirmap),
        /* console ioctl */
        MAPPED_IOCTL_MAP(LINUX_KIOCSOUND, KIOCSOUND),
        MAPPED_IOCTL_MAP(LINUX_KDMKTONE, KDMKTONE),
index abe2fb2..78b9d35 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/compat/linux/linux_ioctl.h,v 1.4.2.4 2003/05/01 20:16:09 anholt Exp $
- * $DragonFly: src/sys/emulation/linux/linux_ioctl.h,v 1.4 2004/08/15 14:15:00 joerg Exp $
+ * $DragonFly: src/sys/emulation/linux/linux_ioctl.h,v 1.5 2005/03/01 00:43:02 corecode Exp $
  */
 
 #ifndef _LINUX_IOCTL_H_
 /*
  * sound
  */
-#define        LINUX_SOUND_MIXER_WRITE_VOLUME  0x4d00
-#define        LINUX_SOUND_MIXER_WRITE_BASS    0x4d01
-#define        LINUX_SOUND_MIXER_WRITE_TREBLE  0x4d02
-#define        LINUX_SOUND_MIXER_WRITE_SYNTH   0x4d03
-#define        LINUX_SOUND_MIXER_WRITE_PCM     0x4d04
-#define        LINUX_SOUND_MIXER_WRITE_SPEAKER 0x4d05
-#define        LINUX_SOUND_MIXER_WRITE_LINE    0x4d06
-#define        LINUX_SOUND_MIXER_WRITE_MIC     0x4d07
-#define        LINUX_SOUND_MIXER_WRITE_CD      0x4d08
-#define        LINUX_SOUND_MIXER_WRITE_IMIX    0x4d09
-#define        LINUX_SOUND_MIXER_WRITE_ALTPCM  0x4d0A
-#define        LINUX_SOUND_MIXER_WRITE_RECLEV  0x4d0B
-#define        LINUX_SOUND_MIXER_WRITE_IGAIN   0x4d0C
-#define        LINUX_SOUND_MIXER_WRITE_OGAIN   0x4d0D
-#define        LINUX_SOUND_MIXER_WRITE_LINE1   0x4d0E
-#define        LINUX_SOUND_MIXER_WRITE_LINE2   0x4d0F
-#define        LINUX_SOUND_MIXER_WRITE_LINE3   0x4d10
+#define        LINUX_SOUND_MIXER_WRITE_MIN     0x4d00
+#define        LINUX_SOUND_MIXER_WRITE_MAX     0x4d18
 #define        LINUX_OSS_GETVERSION            0x4d76
 #define        LINUX_SOUND_MIXER_READ_DEVMASK  0x4dfe
-#define        LINUX_SNDCTL_DSP_RESET          0x5000
-#define        LINUX_SNDCTL_DSP_SYNC           0x5001
-#define        LINUX_SNDCTL_DSP_SPEED          0x5002
-#define        LINUX_SNDCTL_DSP_STEREO         0x5003
-#define        LINUX_SNDCTL_DSP_GETBLKSIZE     0x5004
-#define        LINUX_SNDCTL_DSP_SETBLKSIZE     LINUX_SNDCTL_DSP_GETBLKSIZE
-#define        LINUX_SNDCTL_DSP_SETFMT         0x5005
-#define        LINUX_SOUND_PCM_WRITE_CHANNELS  0x5006
-#define        LINUX_SOUND_PCM_WRITE_FILTER    0x5007
-#define        LINUX_SNDCTL_DSP_POST           0x5008
-#define        LINUX_SNDCTL_DSP_SUBDIVIDE      0x5009
-#define        LINUX_SNDCTL_DSP_SETFRAGMENT    0x500A
-#define        LINUX_SNDCTL_DSP_GETFMTS        0x500B
-#define        LINUX_SNDCTL_DSP_GETOSPACE      0x500C
-#define        LINUX_SNDCTL_DSP_GETISPACE      0x500D
-#define        LINUX_SNDCTL_DSP_NONBLOCK       0x500E
-#define        LINUX_SNDCTL_DSP_GETCAPS        0x500F
-#define        LINUX_SNDCTL_DSP_GETTRIGGER     0x5010
-#define        LINUX_SNDCTL_DSP_SETTRIGGER     LINUX_SNDCTL_DSP_GETTRIGGER
-#define        LINUX_SNDCTL_DSP_GETIPTR        0x5011
-#define        LINUX_SNDCTL_DSP_GETOPTR        0x5012
-#define        LINUX_SNDCTL_DSP_GETODELAY      0x5017
-#define        LINUX_SNDCTL_SEQ_RESET          0x5100
-#define        LINUX_SNDCTL_SEQ_SYNC           0x5101
-#define        LINUX_SNDCTL_SYNTH_INFO         0x5102
-#define        LINUX_SNDCTL_SEQ_CTRLRATE       0x5103
-#define        LINUX_SNDCTL_SEQ_GETOUTCOUNT    0x5104
-#define        LINUX_SNDCTL_SEQ_GETINCOUNT     0x5105
-#define        LINUX_SNDCTL_SEQ_PERCMODE       0x5106
-#define        LINUX_SNDCTL_FM_LOAD_INSTR      0x5107
-#define        LINUX_SNDCTL_SEQ_TESTMIDI       0x5108
-#define        LINUX_SNDCTL_SEQ_RESETSAMPLES   0x5109
-#define        LINUX_SNDCTL_SEQ_NRSYNTHS       0x510A
-#define        LINUX_SNDCTL_SEQ_NRMIDIS        0x510B
-#define        LINUX_SNDCTL_MIDI_INFO          0x510C
-#define        LINUX_SNDCTL_SEQ_TRESHOLD       0x510D
-#define        LINUX_SNDCTL_SYNTH_MEMAVL       0x510E
-
-#define        LINUX_IOCTL_SOUND_MIN   LINUX_SOUND_MIXER_WRITE_VOLUME
-#define        LINUX_IOCTL_SOUND_MAX   LINUX_SNDCTL_SYNTH_MEMAVL
+#define        LINUX_SNDCTL_DSP_MIN            0x5000
+#define        LINUX_SNDCTL_DSP_MAX            0x5017
+#define        LINUX_SNDCTL_SEQ_MIN            0x5100
+#define        LINUX_SNDCTL_SEQ_MAX            0x5116
+
+#define        LINUX_IOCTL_SOUND_MIN   LINUX_SOUND_MIXER_WRITE_MIN
+#define        LINUX_IOCTL_SOUND_MAX   LINUX_SNDCTL_SEQ_MAX
 
 /*
  * termio
 #define        LINUX_ASYNC_CALLOUT_NOHUP       0x0400
 #define        LINUX_ASYNC_FLAGS               0x0FFF
 
-#define        LINUX_IOCTL_DRM_MIN     0x6400
-#define        LINUX_IOCTL_DRM_MAX     0x64ff
-
 /*
  * This doesn't really belong here, but I can't think of a better
  * place to put it.
  */
 struct ifnet;
 int             linux_ifname(struct ifnet *, char *, size_t);
-int             linux_ioctl_dirmap(struct file *, u_long, u_long, caddr_t, struct thread *);
+u_long          linux_gen_dirmap(u_long, u_long, u_long, u_long, u_long, u_long);
 
 #endif /* !_LINUX_IOCTL_H_ */
index 84a7d6c..e8bf55e 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)sys_generic.c       8.5 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/kern/sys_generic.c,v 1.55.2.10 2001/03/17 10:39:32 peter Exp $
- * $DragonFly: src/sys/kern/sys_generic.c,v 1.18 2004/09/13 23:41:18 drhodus Exp $
+ * $DragonFly: src/sys/kern/sys_generic.c,v 1.19 2005/03/01 00:43:02 corecode Exp $
  */
 
 #include "opt_ktrace.h"
@@ -398,6 +398,11 @@ struct ioctl_map_entry {
        LIST_ENTRY(ioctl_map_entry) entries;
 };
 
+/*
+ * The true heart of all ioctl syscall handlers (native, emulation).
+ * If map != NULL, it will be searched for a matching entry for com,
+ * and appropriate conversions/conversion functions will be utilized.
+ */
 int
 mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map)
 {
@@ -434,7 +439,8 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map)
 
                LIST_FOREACH(e, &map->mapping, entries) {
                        for (iomc = e->cmd_ranges; iomc->start != 0 ||
-                            iomc->maptocmd != 0 || iomc->func != NULL;
+                            iomc->maptocmd != 0 || iomc->wrapfunc != NULL ||
+                            iomc->mapfunc != NULL;
                             iomc++) {
                                if (maskcmd >= iomc->start &&
                                    maskcmd <= iomc->end)
@@ -443,13 +449,13 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map)
 
                        /* Did we find a match? */
                        if (iomc->start != 0 || iomc->maptocmd != 0 ||
-                           iomc->func != NULL)
+                           iomc->wrapfunc != NULL || iomc->mapfunc != NULL)
                                break;
                }
 
                if (iomc == NULL ||
                    (iomc->start == 0 && iomc->maptocmd == 0
-                    && iomc->func == NULL)) {
+                    && iomc->wrapfunc == NULL && iomc->mapfunc == NULL)) {
                        printf("%s: 'ioctl' fd=%d, cmd=0x%lx ('%c',%d) not implemented\n",
                               map->sys, fd, maskcmd,
                               (int)((maskcmd >> 8) & 0xff),
@@ -457,7 +463,33 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map)
                        return(EINVAL);
                }
 
-               com = iomc->maptocmd;
+               /*
+                * If it's a non-range one to one mapping, maptocmd should be
+                * correct. If it's a ranged one to one mapping, we pass the
+                * original value of com, and for a range mapped to a different
+                * range, we always need a mapping function to translate the
+                * ioctl to our native ioctl. Ex. 6500-65ff <-> 9500-95ff
+                */
+               if (iomc->start == iomc->end && iomc->maptocmd == iomc->maptoend) {
+                       com = iomc->maptocmd;
+               } else if (iomc->start == iomc->maptocmd && iomc->end == iomc->maptoend) {
+                       if (iomc->mapfunc != NULL)
+                               com = iomc->mapfunc(iomc->start, iomc->end,
+                                                   iomc->start, iomc->end,
+                                                   com, com);
+               } else {
+                       if (iomc->mapfunc != NULL) {
+                               com = iomc->mapfunc(iomc->start, iomc->end,
+                                                   iomc->maptocmd, iomc->maptoend,
+                                                   com, ocom);
+                       } else {
+                               printf("%s: Invalid mapping for fd=%d, cmd=%#lx ('%c',%d)\n",
+                                      map->sys, fd, maskcmd,
+                                      (int)((maskcmd >> 8) & 0xff),
+                                      (int)(maskcmd & 0xff));
+                               return(EINVAL);
+                       }
+               }
        }
 
        switch (com) {
@@ -531,8 +563,8 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map)
                 *  If there is a override function,
                 *  call it instead of directly routing the call
                 */
-               if (map != NULL && iomc->func != NULL)
-                       error = iomc->func(fp, com, ocom, data, td);
+               if (map != NULL && iomc->wrapfunc != NULL)
+                       error = iomc->wrapfunc(fp, com, ocom, data, td);
                else
                        error = fo_ioctl(fp, com, data, td);
                /*
index d5c79af..d1d267b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
+ * Copyright (c) 2004, 2005 The DragonFly Project.  All rights reserved.
  * 
  * This code is derived from software contributed to The DragonFly Project
  * by Simon 'corecode' Schubert <corecode@fs.ei.tum.de>.
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/sys/mapped_ioctl.h,v 1.1 2004/08/13 11:59:00 joerg Exp $
+ * $DragonFly: src/sys/sys/mapped_ioctl.h,v 1.2 2005/03/01 00:43:02 corecode Exp $
  */
 #ifndef _SYS_MAPPED_IOCTL_H_
 #define _SYS_MAPPED_IOCTL_H_
@@ -42,23 +42,26 @@ struct file;
 struct thread;
 struct ioctl_map_entry;
 
-typedef int    (ioctl_map_func)(struct file *, u_long, u_long, caddr_t,
+typedef int    (ioctl_wrap_func)(struct file *, u_long, u_long, caddr_t,
                                 struct thread *);
+typedef u_long (ioctl_map_func)(u_long, u_long, u_long, u_long, u_long, u_long);
 
 struct ioctl_map_range {
-       u_long          start;
-       u_long          end;
-       u_long          maptocmd;
-       ioctl_map_func *func;
+       u_long          start;          /* Start of source range; inclusive */
+       u_long          end;            /* End of source range; inclusive */
+       u_long          maptocmd;       /* Start of destination range */
+       u_long          maptoend;       /* End of destination range */
+       ioctl_wrap_func *wrapfunc;      /* Ioctl handler to use */
+       ioctl_map_func  *mapfunc;       /* Handler to map source to dest */
 };
 
-#define MAPPED_IOCTL_MAPRANGE(c,e,t,f) { (c), (e), (t), (f) }
-#define MAPPED_IOCTL_MAPF(c,t,f)    MAPPED_IOCTL_MAPRANGE((c), (c), (t), (f))
-#define MAPPED_IOCTL_MAP(c,t)      MAPPED_IOCTL_MAPF((c), (t), NULL)
-#define MAPPED_IOCTL_IO(c,f)       MAPPED_IOCTL_MAPF((c), _IO(0, 0), (f))
-#define MAPPED_IOCTL_IOR(c,f,t)            MAPPED_IOCTL_MAPF((c), _IOR(0, 0, t), (f))
-#define MAPPED_IOCTL_IOW(c,f,t)            MAPPED_IOCTL_MAPF((c), _IOW(0, 0, t), (f))
-#define MAPPED_IOCTL_IOWR(c,f,t)    MAPPED_IOCTL_MAPF((c), _IOWR(0, 0, t), (f))
+#define MAPPED_IOCTL_MAPRANGE(c,e,t,r,f,m)     { (c), (e), (t), (r), (f), (m) }
+#define MAPPED_IOCTL_MAPF(c,t,f)               MAPPED_IOCTL_MAPRANGE((c), (c), (t), (t), (f), NULL)
+#define MAPPED_IOCTL_MAP(c,t)                  MAPPED_IOCTL_MAPF((c), (t), NULL)
+#define MAPPED_IOCTL_IO(c,f)                   MAPPED_IOCTL_MAPF((c), _IO(0, 0), (f))
+#define MAPPED_IOCTL_IOR(c,f,t)                MAPPED_IOCTL_MAPF((c), _IOR(0, 0, t), (f))
+#define MAPPED_IOCTL_IOW(c,f,t)                MAPPED_IOCTL_MAPF((c), _IOW(0, 0, t), (f))
+#define MAPPED_IOCTL_IOWR(c,f,t)               MAPPED_IOCTL_MAPF((c), _IOWR(0, 0, t), (f))
 
 struct ioctl_map {
        u_long mask;