| @@ -1,746 +1,746 @@ | | | @@ -1,746 +1,746 @@ |
1 | /* $NetBSD: netbsd32_ioctl.c,v 1.52 2011/01/18 19:52:24 matt Exp $ */ | | 1 | /* $NetBSD: netbsd32_ioctl.c,v 1.53 2011/01/22 20:51:21 matt Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1998, 2001 Matthew R. Green | | 4 | * Copyright (c) 1998, 2001 Matthew R. Green |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * | | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | /* | | 29 | /* |
30 | * handle ioctl conversions from netbsd32 -> 64-bit kernel | | 30 | * handle ioctl conversions from netbsd32 -> 64-bit kernel |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.52 2011/01/18 19:52:24 matt Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.53 2011/01/22 20:51:21 matt Exp $"); |
35 | | | 35 | |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/systm.h> | | 37 | #include <sys/systm.h> |
38 | #include <sys/filedesc.h> | | 38 | #include <sys/filedesc.h> |
39 | #include <sys/ioctl.h> | | 39 | #include <sys/ioctl.h> |
40 | #include <sys/file.h> | | 40 | #include <sys/file.h> |
41 | #include <sys/proc.h> | | 41 | #include <sys/proc.h> |
42 | #include <sys/socketvar.h> | | 42 | #include <sys/socketvar.h> |
43 | #include <sys/audioio.h> | | 43 | #include <sys/audioio.h> |
44 | #include <sys/disklabel.h> | | 44 | #include <sys/disklabel.h> |
45 | #include <sys/dkio.h> | | 45 | #include <sys/dkio.h> |
46 | #include <sys/sockio.h> | | 46 | #include <sys/sockio.h> |
47 | #include <sys/socket.h> | | 47 | #include <sys/socket.h> |
48 | #include <sys/ttycom.h> | | 48 | #include <sys/ttycom.h> |
49 | #include <sys/mount.h> | | 49 | #include <sys/mount.h> |
50 | #include <sys/syscallargs.h> | | 50 | #include <sys/syscallargs.h> |
51 | #include <sys/ktrace.h> | | 51 | #include <sys/ktrace.h> |
52 | #include <sys/kmem.h> | | 52 | #include <sys/kmem.h> |
53 | #include <sys/envsys.h> | | 53 | #include <sys/envsys.h> |
54 | | | 54 | |
55 | #ifdef __sparc__ | | 55 | #ifdef __sparc__ |
56 | #include <dev/sun/fbio.h> | | 56 | #include <dev/sun/fbio.h> |
57 | #include <machine/openpromio.h> | | 57 | #include <machine/openpromio.h> |
58 | #endif | | 58 | #endif |
59 | | | 59 | |
60 | #include <net/if.h> | | 60 | #include <net/if.h> |
61 | #include <net/route.h> | | 61 | #include <net/route.h> |
62 | | | 62 | |
63 | #include <netinet/in.h> | | 63 | #include <netinet/in.h> |
64 | #include <netinet/in_var.h> | | 64 | #include <netinet/in_var.h> |
65 | #include <netinet/igmp.h> | | 65 | #include <netinet/igmp.h> |
66 | #include <netinet/igmp_var.h> | | 66 | #include <netinet/igmp_var.h> |
67 | #include <netinet/ip_mroute.h> | | 67 | #include <netinet/ip_mroute.h> |
68 | | | 68 | |
69 | #include <compat/sys/sockio.h> | | 69 | #include <compat/sys/sockio.h> |
70 | | | 70 | |
71 | #include <compat/netbsd32/netbsd32.h> | | 71 | #include <compat/netbsd32/netbsd32.h> |
72 | #include <compat/netbsd32/netbsd32_ioctl.h> | | 72 | #include <compat/netbsd32/netbsd32_ioctl.h> |
73 | #include <compat/netbsd32/netbsd32_syscallargs.h> | | 73 | #include <compat/netbsd32/netbsd32_syscallargs.h> |
74 | | | 74 | |
75 | #include <dev/vndvar.h> | | 75 | #include <dev/vndvar.h> |
76 | | | 76 | |
77 | /* prototypes for the converters */ | | 77 | /* prototypes for the converters */ |
78 | static inline void netbsd32_to_partinfo(struct netbsd32_partinfo *, | | 78 | static inline void netbsd32_to_partinfo(struct netbsd32_partinfo *, |
79 | struct partinfo *, u_long); | | 79 | struct partinfo *, u_long); |
80 | #if 0 | | 80 | #if 0 |
81 | static inline void netbsd32_to_format_op(struct netbsd32_format_op *, | | 81 | static inline void netbsd32_to_format_op(struct netbsd32_format_op *, |
82 | struct format_op *, u_long); | | 82 | struct format_op *, u_long); |
83 | #endif | | 83 | #endif |
84 | static inline void netbsd32_to_oifreq(struct netbsd32_oifreq *, struct oifreq *, | | 84 | static inline void netbsd32_to_oifreq(struct netbsd32_oifreq *, struct oifreq *, |
85 | u_long cmd); | | 85 | u_long cmd); |
86 | static inline void netbsd32_to_ifreq(struct netbsd32_ifreq *, struct ifreq *, | | 86 | static inline void netbsd32_to_ifreq(struct netbsd32_ifreq *, struct ifreq *, |
87 | u_long cmd); | | 87 | u_long cmd); |
88 | static inline void netbsd32_to_ifconf(struct netbsd32_ifconf *, | | 88 | static inline void netbsd32_to_ifconf(struct netbsd32_ifconf *, |
89 | struct ifconf *, u_long); | | 89 | struct ifconf *, u_long); |
90 | static inline void netbsd32_to_ifmediareq(struct netbsd32_ifmediareq *, | | 90 | static inline void netbsd32_to_ifmediareq(struct netbsd32_ifmediareq *, |
91 | struct ifmediareq *, u_long); | | 91 | struct ifmediareq *, u_long); |
92 | static inline void netbsd32_to_ifdrv(struct netbsd32_ifdrv *, struct ifdrv *, | | 92 | static inline void netbsd32_to_ifdrv(struct netbsd32_ifdrv *, struct ifdrv *, |
93 | u_long); | | 93 | u_long); |
94 | static inline void netbsd32_to_sioc_vif_req(struct netbsd32_sioc_vif_req *, | | 94 | static inline void netbsd32_to_sioc_vif_req(struct netbsd32_sioc_vif_req *, |
95 | struct sioc_vif_req *, u_long); | | 95 | struct sioc_vif_req *, u_long); |
96 | static inline void netbsd32_to_sioc_sg_req(struct netbsd32_sioc_sg_req *, | | 96 | static inline void netbsd32_to_sioc_sg_req(struct netbsd32_sioc_sg_req *, |
97 | struct sioc_sg_req *, u_long); | | 97 | struct sioc_sg_req *, u_long); |
98 | static inline void netbsd32_from_partinfo(struct partinfo *, | | 98 | static inline void netbsd32_from_partinfo(struct partinfo *, |
99 | struct netbsd32_partinfo *, u_long); | | 99 | struct netbsd32_partinfo *, u_long); |
100 | #if 0 | | 100 | #if 0 |
101 | static inline void netbsd32_from_format_op(struct format_op *, | | 101 | static inline void netbsd32_from_format_op(struct format_op *, |
102 | struct netbsd32_format_op *, | | 102 | struct netbsd32_format_op *, |
103 | u_long); | | 103 | u_long); |
104 | #endif | | 104 | #endif |
105 | static inline void netbsd32_from_ifreq(struct ifreq *, | | 105 | static inline void netbsd32_from_ifreq(struct ifreq *, |
106 | struct netbsd32_ifreq *, u_long); | | 106 | struct netbsd32_ifreq *, u_long); |
107 | static inline void netbsd32_from_oifreq(struct oifreq *, | | 107 | static inline void netbsd32_from_oifreq(struct oifreq *, |
108 | struct netbsd32_oifreq *, u_long); | | 108 | struct netbsd32_oifreq *, u_long); |
109 | static inline void netbsd32_from_ifconf(struct ifconf *, | | 109 | static inline void netbsd32_from_ifconf(struct ifconf *, |
110 | struct netbsd32_ifconf *, u_long); | | 110 | struct netbsd32_ifconf *, u_long); |
111 | static inline void netbsd32_from_ifmediareq(struct ifmediareq *, | | 111 | static inline void netbsd32_from_ifmediareq(struct ifmediareq *, |
112 | struct netbsd32_ifmediareq *, | | 112 | struct netbsd32_ifmediareq *, |
113 | u_long); | | 113 | u_long); |
114 | static inline void netbsd32_from_ifdrv(struct ifdrv *, | | 114 | static inline void netbsd32_from_ifdrv(struct ifdrv *, |
115 | struct netbsd32_ifdrv *, u_long); | | 115 | struct netbsd32_ifdrv *, u_long); |
116 | static inline void netbsd32_from_sioc_vif_req(struct sioc_vif_req *, | | 116 | static inline void netbsd32_from_sioc_vif_req(struct sioc_vif_req *, |
117 | struct netbsd32_sioc_vif_req *, | | 117 | struct netbsd32_sioc_vif_req *, |
118 | u_long); | | 118 | u_long); |
119 | static inline void netbsd32_from_sioc_sg_req(struct sioc_sg_req *, | | 119 | static inline void netbsd32_from_sioc_sg_req(struct sioc_sg_req *, |
120 | struct netbsd32_sioc_sg_req *, | | 120 | struct netbsd32_sioc_sg_req *, |
121 | u_long); | | 121 | u_long); |
122 | | | 122 | |
123 | /* convert to/from different structures */ | | 123 | /* convert to/from different structures */ |
124 | | | 124 | |
125 | static inline void | | 125 | static inline void |
126 | netbsd32_to_partinfo(struct netbsd32_partinfo *s32p, struct partinfo *p, u_long cmd) | | 126 | netbsd32_to_partinfo(struct netbsd32_partinfo *s32p, struct partinfo *p, u_long cmd) |
127 | { | | 127 | { |
128 | | | 128 | |
129 | p->disklab = (struct disklabel *)NETBSD32PTR64(s32p->disklab); | | 129 | p->disklab = (struct disklabel *)NETBSD32PTR64(s32p->disklab); |
130 | p->part = (struct partition *)NETBSD32PTR64(s32p->part); | | 130 | p->part = (struct partition *)NETBSD32PTR64(s32p->part); |
131 | } | | 131 | } |
132 | | | 132 | |
133 | #if 0 | | 133 | #if 0 |
134 | static inline void | | 134 | static inline void |
135 | netbsd32_to_format_op(struct netbsd32_format_op *s32p, struct format_op *p, u_long cmd) | | 135 | netbsd32_to_format_op(struct netbsd32_format_op *s32p, struct format_op *p, u_long cmd) |
136 | { | | 136 | { |
137 | | | 137 | |
138 | p->df_buf = (char *)NETBSD32PTR64(s32p->df_buf); | | 138 | p->df_buf = (char *)NETBSD32PTR64(s32p->df_buf); |
139 | p->df_count = s32p->df_count; | | 139 | p->df_count = s32p->df_count; |
140 | p->df_startblk = s32p->df_startblk; | | 140 | p->df_startblk = s32p->df_startblk; |
141 | memcpy(p->df_reg, s32p->df_reg, sizeof(s32p->df_reg)); | | 141 | memcpy(p->df_reg, s32p->df_reg, sizeof(s32p->df_reg)); |
142 | } | | 142 | } |
143 | #endif | | 143 | #endif |
144 | | | 144 | |
145 | static inline void | | 145 | static inline void |
146 | netbsd32_to_ifreq(struct netbsd32_ifreq *s32p, struct ifreq *p, u_long cmd) | | 146 | netbsd32_to_ifreq(struct netbsd32_ifreq *s32p, struct ifreq *p, u_long cmd) |
147 | { | | 147 | { |
148 | | | 148 | |
149 | memcpy(p, s32p, sizeof *s32p); | | 149 | memcpy(p, s32p, sizeof *s32p); |
150 | /* | | 150 | /* |
151 | * XXX | | 151 | * XXX |
152 | * struct ifreq says the same, but sometimes the ifr_data | | 152 | * struct ifreq says the same, but sometimes the ifr_data |
153 | * union member needs to be converted to 64 bits... this | | 153 | * union member needs to be converted to 64 bits... this |
154 | * is very driver specific and so we ignore it for now.. | | 154 | * is very driver specific and so we ignore it for now.. |
155 | */ | | 155 | */ |
156 | if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) | | 156 | if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) |
157 | p->ifr_data = (void *)NETBSD32PTR64(s32p->ifr_data); | | 157 | p->ifr_data = (void *)NETBSD32PTR64(s32p->ifr_data); |
158 | } | | 158 | } |
159 | | | 159 | |
160 | static inline void | | 160 | static inline void |
161 | netbsd32_to_oifreq(struct netbsd32_oifreq *s32p, struct oifreq *p, u_long cmd) | | 161 | netbsd32_to_oifreq(struct netbsd32_oifreq *s32p, struct oifreq *p, u_long cmd) |
162 | { | | 162 | { |
163 | | | 163 | |
164 | memcpy(p, s32p, sizeof *s32p); | | 164 | memcpy(p, s32p, sizeof *s32p); |
165 | /* | | 165 | /* |
166 | * XXX | | 166 | * XXX |
167 | * struct ifreq says the same, but sometimes the ifr_data | | 167 | * struct ifreq says the same, but sometimes the ifr_data |
168 | * union member needs to be converted to 64 bits... this | | 168 | * union member needs to be converted to 64 bits... this |
169 | * is very driver specific and so we ignore it for now.. | | 169 | * is very driver specific and so we ignore it for now.. |
170 | */ | | 170 | */ |
171 | if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) | | 171 | if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) |
172 | p->ifr_data = (void *)NETBSD32PTR64(s32p->ifr_data); | | 172 | p->ifr_data = (void *)NETBSD32PTR64(s32p->ifr_data); |
173 | } | | 173 | } |
174 | | | 174 | |
175 | static inline void | | 175 | static inline void |
176 | netbsd32_to_ifconf(struct netbsd32_ifconf *s32p, struct ifconf *p, u_long cmd) | | 176 | netbsd32_to_ifconf(struct netbsd32_ifconf *s32p, struct ifconf *p, u_long cmd) |
177 | { | | 177 | { |
178 | | | 178 | |
179 | p->ifc_len = s32p->ifc_len; | | 179 | p->ifc_len = s32p->ifc_len; |
180 | /* ifc_buf & ifc_req are the same size so this works */ | | 180 | /* ifc_buf & ifc_req are the same size so this works */ |
181 | p->ifc_buf = (void *)NETBSD32PTR64(s32p->ifc_buf); | | 181 | p->ifc_buf = (void *)NETBSD32PTR64(s32p->ifc_buf); |
182 | } | | 182 | } |
183 | | | 183 | |
184 | static inline void | | 184 | static inline void |
185 | netbsd32_to_ifmediareq(struct netbsd32_ifmediareq *s32p, struct ifmediareq *p, u_long cmd) | | 185 | netbsd32_to_ifmediareq(struct netbsd32_ifmediareq *s32p, struct ifmediareq *p, u_long cmd) |
186 | { | | 186 | { |
187 | | | 187 | |
188 | memcpy(p, s32p, sizeof *s32p); | | 188 | memcpy(p, s32p, sizeof *s32p); |
189 | p->ifm_ulist = (int *)NETBSD32PTR64(s32p->ifm_ulist); | | 189 | p->ifm_ulist = (int *)NETBSD32PTR64(s32p->ifm_ulist); |
190 | } | | 190 | } |
191 | | | 191 | |
192 | static inline void | | 192 | static inline void |
193 | netbsd32_to_ifdrv(struct netbsd32_ifdrv *s32p, struct ifdrv *p, u_long cmd) | | 193 | netbsd32_to_ifdrv(struct netbsd32_ifdrv *s32p, struct ifdrv *p, u_long cmd) |
194 | { | | 194 | { |
195 | | | 195 | |
196 | memcpy(p, s32p, sizeof *s32p); | | 196 | memcpy(p, s32p, sizeof *s32p); |
197 | p->ifd_data = (void *)NETBSD32PTR64(s32p->ifd_data); | | 197 | p->ifd_data = (void *)NETBSD32PTR64(s32p->ifd_data); |
198 | } | | 198 | } |
199 | | | 199 | |
200 | static inline void | | 200 | static inline void |
201 | netbsd32_to_sioc_vif_req(struct netbsd32_sioc_vif_req *s32p, struct sioc_vif_req *p, u_long cmd) | | 201 | netbsd32_to_sioc_vif_req(struct netbsd32_sioc_vif_req *s32p, struct sioc_vif_req *p, u_long cmd) |
202 | { | | 202 | { |
203 | | | 203 | |
204 | p->vifi = s32p->vifi; | | 204 | p->vifi = s32p->vifi; |
205 | p->icount = (u_long)s32p->icount; | | 205 | p->icount = (u_long)s32p->icount; |
206 | p->ocount = (u_long)s32p->ocount; | | 206 | p->ocount = (u_long)s32p->ocount; |
207 | p->ibytes = (u_long)s32p->ibytes; | | 207 | p->ibytes = (u_long)s32p->ibytes; |
208 | p->obytes = (u_long)s32p->obytes; | | 208 | p->obytes = (u_long)s32p->obytes; |
209 | } | | 209 | } |
210 | | | 210 | |
211 | static inline void | | 211 | static inline void |
212 | netbsd32_to_sioc_sg_req(struct netbsd32_sioc_sg_req *s32p, struct sioc_sg_req *p, u_long cmd) | | 212 | netbsd32_to_sioc_sg_req(struct netbsd32_sioc_sg_req *s32p, struct sioc_sg_req *p, u_long cmd) |
213 | { | | 213 | { |
214 | | | 214 | |
215 | p->src = s32p->src; | | 215 | p->src = s32p->src; |
216 | p->grp = s32p->grp; | | 216 | p->grp = s32p->grp; |
217 | p->pktcnt = (u_long)s32p->pktcnt; | | 217 | p->pktcnt = (u_long)s32p->pktcnt; |
218 | p->bytecnt = (u_long)s32p->bytecnt; | | 218 | p->bytecnt = (u_long)s32p->bytecnt; |
219 | p->wrong_if = (u_long)s32p->wrong_if; | | 219 | p->wrong_if = (u_long)s32p->wrong_if; |
220 | } | | 220 | } |
221 | | | 221 | |
222 | static inline void | | 222 | static inline void |
223 | netbsd32_to_vnd_ioctl(struct netbsd32_vnd_ioctl *s32p, struct vnd_ioctl *p, u_long cmd) | | 223 | netbsd32_to_vnd_ioctl(struct netbsd32_vnd_ioctl *s32p, struct vnd_ioctl *p, u_long cmd) |
224 | { | | 224 | { |
225 | | | 225 | |
226 | p->vnd_file = (char *)NETBSD32PTR64(s32p->vnd_file); | | 226 | p->vnd_file = (char *)NETBSD32PTR64(s32p->vnd_file); |
227 | p->vnd_flags = s32p->vnd_flags; | | 227 | p->vnd_flags = s32p->vnd_flags; |
228 | p->vnd_geom = s32p->vnd_geom; | | 228 | p->vnd_geom = s32p->vnd_geom; |
229 | p->vnd_osize = s32p->vnd_osize; | | 229 | p->vnd_osize = s32p->vnd_osize; |
230 | p->vnd_size = s32p->vnd_size; | | 230 | p->vnd_size = s32p->vnd_size; |
231 | } | | 231 | } |
232 | | | 232 | |
233 | static inline void | | 233 | static inline void |
234 | netbsd32_to_vnd_user(struct netbsd32_vnd_user *s32p, struct vnd_user *p, u_long cmd) | | 234 | netbsd32_to_vnd_user(struct netbsd32_vnd_user *s32p, struct vnd_user *p, u_long cmd) |
235 | { | | 235 | { |
236 | | | 236 | |
237 | p->vnu_unit = s32p->vnu_unit; | | 237 | p->vnu_unit = s32p->vnu_unit; |
238 | p->vnu_dev = s32p->vnu_dev; | | 238 | p->vnu_dev = s32p->vnu_dev; |
239 | p->vnu_ino = s32p->vnu_ino; | | 239 | p->vnu_ino = s32p->vnu_ino; |
240 | } | | 240 | } |
241 | | | 241 | |
242 | static inline void | | 242 | static inline void |
243 | netbsd32_to_vnd_ioctl50(struct netbsd32_vnd_ioctl50 *s32p, struct vnd_ioctl50 *p, u_long cmd) | | 243 | netbsd32_to_vnd_ioctl50(struct netbsd32_vnd_ioctl50 *s32p, struct vnd_ioctl50 *p, u_long cmd) |
244 | { | | 244 | { |
245 | | | 245 | |
246 | p->vnd_file = (char *)NETBSD32PTR64(s32p->vnd_file); | | 246 | p->vnd_file = (char *)NETBSD32PTR64(s32p->vnd_file); |
247 | p->vnd_flags = s32p->vnd_flags; | | 247 | p->vnd_flags = s32p->vnd_flags; |
248 | p->vnd_geom = s32p->vnd_geom; | | 248 | p->vnd_geom = s32p->vnd_geom; |
249 | p->vnd_size = s32p->vnd_size; | | 249 | p->vnd_size = s32p->vnd_size; |
250 | } | | 250 | } |
251 | | | 251 | |
252 | static inline void | | 252 | static inline void |
253 | netbsd32_to_plistref(struct netbsd32_plistref *s32p, struct plistref *p, u_long cmd) | | 253 | netbsd32_to_plistref(struct netbsd32_plistref *s32p, struct plistref *p, u_long cmd) |
254 | { | | 254 | { |
255 | | | 255 | |
256 | p->pref_plist = NETBSD32PTR64(s32p->pref_plist); | | 256 | p->pref_plist = NETBSD32PTR64(s32p->pref_plist); |
257 | p->pref_len = s32p->pref_len; | | 257 | p->pref_len = s32p->pref_len; |
258 | } | | 258 | } |
259 | | | 259 | |
260 | static inline void | | 260 | static inline void |
261 | netbsd32_to_u_long(netbsd32_u_long *s32p, u_long *p, u_long cmd) | | 261 | netbsd32_to_u_long(netbsd32_u_long *s32p, u_long *p, u_long cmd) |
262 | { | | 262 | { |
263 | | | 263 | |
264 | *p = (u_long)*s32p; | | 264 | *p = (u_long)*s32p; |
265 | } | | 265 | } |
266 | | | 266 | |
267 | /* | | 267 | /* |
268 | * handle ioctl conversions from 64-bit kernel -> netbsd32 | | 268 | * handle ioctl conversions from 64-bit kernel -> netbsd32 |
269 | */ | | 269 | */ |
270 | | | 270 | |
271 | static inline void | | 271 | static inline void |
272 | netbsd32_from_partinfo(struct partinfo *p, struct netbsd32_partinfo *s32p, u_long cmd) | | 272 | netbsd32_from_partinfo(struct partinfo *p, struct netbsd32_partinfo *s32p, u_long cmd) |
273 | { | | 273 | { |
274 | | | 274 | |
275 | NETBSD32PTR32(s32p->disklab, p->disklab); | | 275 | NETBSD32PTR32(s32p->disklab, p->disklab); |
276 | NETBSD32PTR32(s32p->part, p->part); | | 276 | NETBSD32PTR32(s32p->part, p->part); |
277 | } | | 277 | } |
278 | | | 278 | |
279 | #if 0 | | 279 | #if 0 |
280 | static inline void | | 280 | static inline void |
281 | netbsd32_from_format_op(struct format_op *p, struct netbsd32_format_op *s32p, u_long cmd) | | 281 | netbsd32_from_format_op(struct format_op *p, struct netbsd32_format_op *s32p, u_long cmd) |
282 | { | | 282 | { |
283 | | | 283 | |
284 | /* filled in */ | | 284 | /* filled in */ |
285 | #if 0 | | 285 | #if 0 |
286 | s32p->df_buf = (netbsd32_charp)p->df_buf; | | 286 | s32p->df_buf = (netbsd32_charp)p->df_buf; |
287 | #endif | | 287 | #endif |
288 | s32p->df_count = p->df_count; | | 288 | s32p->df_count = p->df_count; |
289 | s32p->df_startblk = p->df_startblk; | | 289 | s32p->df_startblk = p->df_startblk; |
290 | memcpy(s32p->df_reg, p->df_reg, sizeof(p->df_reg)); | | 290 | memcpy(s32p->df_reg, p->df_reg, sizeof(p->df_reg)); |
291 | } | | 291 | } |
292 | #endif | | 292 | #endif |
293 | | | 293 | |
294 | static inline void | | 294 | static inline void |
295 | netbsd32_from_ifreq(struct ifreq *p, struct netbsd32_ifreq *s32p, u_long cmd) | | 295 | netbsd32_from_ifreq(struct ifreq *p, struct netbsd32_ifreq *s32p, u_long cmd) |
296 | { | | 296 | { |
297 | | | 297 | |
298 | /* | | 298 | /* |
299 | * XXX | | 299 | * XXX |
300 | * struct ifreq says the same, but sometimes the ifr_data | | 300 | * struct ifreq says the same, but sometimes the ifr_data |
301 | * union member needs to be converted to 64 bits... this | | 301 | * union member needs to be converted to 64 bits... this |
302 | * is very driver specific and so we ignore it for now.. | | 302 | * is very driver specific and so we ignore it for now.. |
303 | */ | | 303 | */ |
304 | memcpy(s32p, p, sizeof *s32p); | | 304 | memcpy(s32p, p, sizeof *s32p); |
305 | if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) | | 305 | if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) |
306 | NETBSD32PTR32(s32p->ifr_data, p->ifr_data); | | 306 | NETBSD32PTR32(s32p->ifr_data, p->ifr_data); |
307 | } | | 307 | } |
308 | | | 308 | |
309 | static inline void | | 309 | static inline void |
310 | netbsd32_from_oifreq(struct oifreq *p, struct netbsd32_oifreq *s32p, u_long cmd) | | 310 | netbsd32_from_oifreq(struct oifreq *p, struct netbsd32_oifreq *s32p, u_long cmd) |
311 | { | | 311 | { |
312 | | | 312 | |
313 | /* | | 313 | /* |
314 | * XXX | | 314 | * XXX |
315 | * struct ifreq says the same, but sometimes the ifr_data | | 315 | * struct ifreq says the same, but sometimes the ifr_data |
316 | * union member needs to be converted to 64 bits... this | | 316 | * union member needs to be converted to 64 bits... this |
317 | * is very driver specific and so we ignore it for now.. | | 317 | * is very driver specific and so we ignore it for now.. |
318 | */ | | 318 | */ |
319 | memcpy(s32p, p, sizeof *s32p); | | 319 | memcpy(s32p, p, sizeof *s32p); |
320 | if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) | | 320 | if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA) |
321 | NETBSD32PTR32(s32p->ifr_data, p->ifr_data); | | 321 | NETBSD32PTR32(s32p->ifr_data, p->ifr_data); |
322 | } | | 322 | } |
323 | | | 323 | |
324 | static inline void | | 324 | static inline void |
325 | netbsd32_from_ifconf(struct ifconf *p, struct netbsd32_ifconf *s32p, u_long cmd) | | 325 | netbsd32_from_ifconf(struct ifconf *p, struct netbsd32_ifconf *s32p, u_long cmd) |
326 | { | | 326 | { |
327 | | | 327 | |
328 | s32p->ifc_len = p->ifc_len; | | 328 | s32p->ifc_len = p->ifc_len; |
329 | /* ifc_buf & ifc_req are the same size so this works */ | | 329 | /* ifc_buf & ifc_req are the same size so this works */ |
330 | NETBSD32PTR32(s32p->ifc_buf, p->ifc_buf); | | 330 | NETBSD32PTR32(s32p->ifc_buf, p->ifc_buf); |
331 | } | | 331 | } |
332 | | | 332 | |
333 | static inline void | | 333 | static inline void |
334 | netbsd32_from_ifmediareq(struct ifmediareq *p, struct netbsd32_ifmediareq *s32p, u_long cmd) | | 334 | netbsd32_from_ifmediareq(struct ifmediareq *p, struct netbsd32_ifmediareq *s32p, u_long cmd) |
335 | { | | 335 | { |
336 | | | 336 | |
337 | memcpy(s32p, p, sizeof *p); | | 337 | memcpy(s32p, p, sizeof *p); |
338 | /* filled in? */ | | 338 | /* filled in? */ |
339 | #if 0 | | 339 | #if 0 |
340 | s32p->ifm_ulist = (netbsd32_intp_t)p->ifm_ulist; | | 340 | s32p->ifm_ulist = (netbsd32_intp_t)p->ifm_ulist; |
341 | #endif | | 341 | #endif |
342 | } | | 342 | } |
343 | | | 343 | |
344 | static inline void | | 344 | static inline void |
345 | netbsd32_from_ifdrv(struct ifdrv *p, struct netbsd32_ifdrv *s32p, u_long cmd) | | 345 | netbsd32_from_ifdrv(struct ifdrv *p, struct netbsd32_ifdrv *s32p, u_long cmd) |
346 | { | | 346 | { |
347 | | | 347 | |
348 | memcpy(s32p, p, sizeof *p); | | 348 | memcpy(s32p, p, sizeof *p); |
349 | /* filled in? */ | | 349 | /* filled in? */ |
350 | #if 0 | | 350 | #if 0 |
351 | s32p->ifm_data = (netbsd32_u_longp_t)p->ifm_data; | | 351 | s32p->ifm_data = (netbsd32_u_longp_t)p->ifm_data; |
352 | #endif | | 352 | #endif |
353 | } | | 353 | } |
354 | | | 354 | |
355 | static inline void | | 355 | static inline void |
356 | netbsd32_from_sioc_vif_req(struct sioc_vif_req *p, struct netbsd32_sioc_vif_req *s32p, u_long cmd) | | 356 | netbsd32_from_sioc_vif_req(struct sioc_vif_req *p, struct netbsd32_sioc_vif_req *s32p, u_long cmd) |
357 | { | | 357 | { |
358 | | | 358 | |
359 | s32p->vifi = p->vifi; | | 359 | s32p->vifi = p->vifi; |
360 | s32p->icount = (netbsd32_u_long)p->icount; | | 360 | s32p->icount = (netbsd32_u_long)p->icount; |
361 | s32p->ocount = (netbsd32_u_long)p->ocount; | | 361 | s32p->ocount = (netbsd32_u_long)p->ocount; |
362 | s32p->ibytes = (netbsd32_u_long)p->ibytes; | | 362 | s32p->ibytes = (netbsd32_u_long)p->ibytes; |
363 | s32p->obytes = (netbsd32_u_long)p->obytes; | | 363 | s32p->obytes = (netbsd32_u_long)p->obytes; |
364 | } | | 364 | } |
365 | | | 365 | |
366 | static inline void | | 366 | static inline void |
367 | netbsd32_from_sioc_sg_req(struct sioc_sg_req *p, struct netbsd32_sioc_sg_req *s32p, u_long cmd) | | 367 | netbsd32_from_sioc_sg_req(struct sioc_sg_req *p, struct netbsd32_sioc_sg_req *s32p, u_long cmd) |
368 | { | | 368 | { |
369 | | | 369 | |
370 | s32p->src = p->src; | | 370 | s32p->src = p->src; |
371 | s32p->grp = p->grp; | | 371 | s32p->grp = p->grp; |
372 | s32p->pktcnt = (netbsd32_u_long)p->pktcnt; | | 372 | s32p->pktcnt = (netbsd32_u_long)p->pktcnt; |
373 | s32p->bytecnt = (netbsd32_u_long)p->bytecnt; | | 373 | s32p->bytecnt = (netbsd32_u_long)p->bytecnt; |
374 | s32p->wrong_if = (netbsd32_u_long)p->wrong_if; | | 374 | s32p->wrong_if = (netbsd32_u_long)p->wrong_if; |
375 | } | | 375 | } |
376 | | | 376 | |
377 | static inline void | | 377 | static inline void |
378 | netbsd32_from_vnd_ioctl(struct vnd_ioctl *p, struct netbsd32_vnd_ioctl *s32p, u_long cmd) | | 378 | netbsd32_from_vnd_ioctl(struct vnd_ioctl *p, struct netbsd32_vnd_ioctl *s32p, u_long cmd) |
379 | { | | 379 | { |
380 | | | 380 | |
381 | s32p->vnd_flags = p->vnd_flags; | | 381 | s32p->vnd_flags = p->vnd_flags; |
382 | s32p->vnd_geom = p->vnd_geom; | | 382 | s32p->vnd_geom = p->vnd_geom; |
383 | s32p->vnd_osize = p->vnd_osize; | | 383 | s32p->vnd_osize = p->vnd_osize; |
384 | s32p->vnd_size = p->vnd_size; | | 384 | s32p->vnd_size = p->vnd_size; |
385 | } | | 385 | } |
386 | | | 386 | |
387 | static inline void | | 387 | static inline void |
388 | netbsd32_from_vnd_user(struct vnd_user *p, struct netbsd32_vnd_user *s32p, u_long cmd) | | 388 | netbsd32_from_vnd_user(struct vnd_user *p, struct netbsd32_vnd_user *s32p, u_long cmd) |
389 | { | | 389 | { |
390 | | | 390 | |
391 | s32p->vnu_unit = p->vnu_unit; | | 391 | s32p->vnu_unit = p->vnu_unit; |
392 | s32p->vnu_dev = p->vnu_dev; | | 392 | s32p->vnu_dev = p->vnu_dev; |
393 | s32p->vnu_ino = p->vnu_ino; | | 393 | s32p->vnu_ino = p->vnu_ino; |
394 | } | | 394 | } |
395 | | | 395 | |
396 | static inline void | | 396 | static inline void |
397 | netbsd32_from_vnd_ioctl50(struct vnd_ioctl50 *p, struct netbsd32_vnd_ioctl50 *s32p, u_long cmd) | | 397 | netbsd32_from_vnd_ioctl50(struct vnd_ioctl50 *p, struct netbsd32_vnd_ioctl50 *s32p, u_long cmd) |
398 | { | | 398 | { |
399 | | | 399 | |
400 | s32p->vnd_flags = p->vnd_flags; | | 400 | s32p->vnd_flags = p->vnd_flags; |
401 | s32p->vnd_geom = p->vnd_geom; | | 401 | s32p->vnd_geom = p->vnd_geom; |
402 | s32p->vnd_size = p->vnd_size; | | 402 | s32p->vnd_size = p->vnd_size; |
403 | } | | 403 | } |
404 | | | 404 | |
405 | static inline void | | 405 | static inline void |
406 | netbsd32_from_plistref(struct plistref *p, struct netbsd32_plistref *s32p, u_long cmd) | | 406 | netbsd32_from_plistref(struct plistref *p, struct netbsd32_plistref *s32p, u_long cmd) |
407 | { | | 407 | { |
408 | | | 408 | |
409 | NETBSD32PTR32(s32p->pref_plist, p->pref_plist); | | 409 | NETBSD32PTR32(s32p->pref_plist, p->pref_plist); |
410 | s32p->pref_len = p->pref_len; | | 410 | s32p->pref_len = p->pref_len; |
411 | } | | 411 | } |
412 | | | 412 | |
413 | static inline void | | 413 | static inline void |
414 | netbsd32_from_u_long(u_long *p, netbsd32_u_long *s32p, u_long cmd) | | 414 | netbsd32_from_u_long(u_long *p, netbsd32_u_long *s32p, u_long cmd) |
415 | { | | 415 | { |
416 | | | 416 | |
417 | *s32p = (netbsd32_u_long)*p; | | 417 | *s32p = (netbsd32_u_long)*p; |
418 | } | | 418 | } |
419 | | | 419 | |
420 | | | 420 | |
421 | /* | | 421 | /* |
422 | * main ioctl syscall. | | 422 | * main ioctl syscall. |
423 | * | | 423 | * |
424 | * ok, here we are in the biggy. we have to do fix ups depending | | 424 | * ok, here we are in the biggy. we have to do fix ups depending |
425 | * on the ioctl command before and afterwards. | | 425 | * on the ioctl command before and afterwards. |
426 | */ | | 426 | */ |
427 | int | | 427 | int |
428 | netbsd32_ioctl(struct lwp *l, const struct netbsd32_ioctl_args *uap, register_t *retval) | | 428 | netbsd32_ioctl(struct lwp *l, const struct netbsd32_ioctl_args *uap, register_t *retval) |
429 | { | | 429 | { |
430 | /* { | | 430 | /* { |
431 | syscallarg(int) fd; | | 431 | syscallarg(int) fd; |
432 | syscallarg(netbsd32_u_long) com; | | 432 | syscallarg(netbsd32_u_long) com; |
433 | syscallarg(netbsd32_voidp) data; | | 433 | syscallarg(netbsd32_voidp) data; |
434 | } */ | | 434 | } */ |
435 | struct proc *p = l->l_proc; | | 435 | struct proc *p = l->l_proc; |
436 | struct file *fp; | | 436 | struct file *fp; |
437 | struct filedesc *fdp; | | 437 | struct filedesc *fdp; |
438 | u_long com; | | 438 | u_long com; |
439 | int error = 0; | | 439 | int error = 0; |
440 | size_t size; | | 440 | size_t size; |
441 | size_t alloc_size32, size32; | | 441 | size_t alloc_size32, size32; |
442 | void *data, *memp = NULL; | | 442 | void *data, *memp = NULL; |
443 | void *data32, *memp32 = NULL; | | 443 | void *data32, *memp32 = NULL; |
444 | unsigned int fd; | | 444 | unsigned int fd; |
445 | fdfile_t *ff; | | 445 | fdfile_t *ff; |
446 | int tmp; | | 446 | int tmp; |
447 | #define STK_PARAMS 128 | | 447 | #define STK_PARAMS 128 |
448 | u_long stkbuf[STK_PARAMS/sizeof(u_long)]; | | 448 | u_long stkbuf[STK_PARAMS/sizeof(u_long)]; |
449 | u_long stkbuf32[STK_PARAMS/sizeof(u_long)]; | | 449 | u_long stkbuf32[STK_PARAMS/sizeof(u_long)]; |
450 | | | 450 | |
451 | /* | | 451 | /* |
452 | * we need to translate some commands (_IOW) before calling sys_ioctl, | | 452 | * we need to translate some commands (_IOW) before calling sys_ioctl, |
453 | * some after (_IOR), and some both (_IOWR). | | 453 | * some after (_IOR), and some both (_IOWR). |
454 | */ | | 454 | */ |
455 | #if 0 | | 455 | #if 0 |
456 | { | | 456 | { |
457 | const char * const dirs[8] = { | | 457 | const char * const dirs[8] = { |
458 | "NONE!", "VOID", "OUT", "VOID|OUT!", "IN", "VOID|IN!", | | 458 | "NONE!", "VOID", "OUT", "VOID|OUT!", "IN", "VOID|IN!", |
459 | "INOUT", "VOID|IN|OUT!" | | 459 | "INOUT", "VOID|IN|OUT!" |
460 | }; | | 460 | }; |
461 | | | 461 | |
462 | printf("netbsd32_ioctl(%d, %x, %x): " | | 462 | printf("netbsd32_ioctl(%d, %x, %x): " |
463 | "%s group %c base %d len %d\n", | | 463 | "%s group %c base %d len %d\n", |
464 | SCARG(uap, fd), SCARG(uap, com), SCARG(uap, data).i32, | | 464 | SCARG(uap, fd), SCARG(uap, com), SCARG(uap, data).i32, |
465 | dirs[((SCARG(uap, com) & IOC_DIRMASK)>>29)], | | 465 | dirs[((SCARG(uap, com) & IOC_DIRMASK)>>29)], |
466 | IOCGROUP(SCARG(uap, com)), IOCBASECMD(SCARG(uap, com)), | | 466 | IOCGROUP(SCARG(uap, com)), IOCBASECMD(SCARG(uap, com)), |
467 | IOCPARM_LEN(SCARG(uap, com))); | | 467 | IOCPARM_LEN(SCARG(uap, com))); |
468 | } | | 468 | } |
469 | #endif | | 469 | #endif |
470 | | | 470 | |
471 | memp = NULL; | | 471 | memp = NULL; |
472 | memp32 = NULL; | | 472 | memp32 = NULL; |
473 | alloc_size32 = 0; | | 473 | alloc_size32 = 0; |
474 | size32 = 0; | | 474 | size32 = 0; |
475 | size = 0; | | 475 | size = 0; |
476 | | | 476 | |
477 | fdp = p->p_fd; | | 477 | fdp = p->p_fd; |
478 | fd = SCARG(uap, fd); | | 478 | fd = SCARG(uap, fd); |
479 | if ((fp = fd_getfile(fd)) == NULL) | | 479 | if ((fp = fd_getfile(fd)) == NULL) |
480 | return (EBADF); | | 480 | return (EBADF); |
481 | if ((fp->f_flag & (FREAD | FWRITE)) == 0) { | | 481 | if ((fp->f_flag & (FREAD | FWRITE)) == 0) { |
482 | error = EBADF; | | 482 | error = EBADF; |
483 | goto out; | | 483 | goto out; |
484 | } | | 484 | } |
485 | | | 485 | |
486 | ff = fdp->fd_dt->dt_ff[SCARG(uap, fd)]; | | 486 | ff = fdp->fd_dt->dt_ff[SCARG(uap, fd)]; |
487 | switch (com = SCARG(uap, com)) { | | 487 | switch (com = SCARG(uap, com)) { |
488 | case FIOCLEX: | | 488 | case FIOCLEX: |
489 | ff->ff_exclose = true; | | 489 | ff->ff_exclose = true; |
490 | fdp->fd_exclose = true; | | 490 | fdp->fd_exclose = true; |
491 | goto out; | | 491 | goto out; |
492 | | | 492 | |
493 | case FIONCLEX: | | 493 | case FIONCLEX: |
494 | ff->ff_exclose = false; | | 494 | ff->ff_exclose = false; |
495 | goto out; | | 495 | goto out; |
496 | } | | 496 | } |
497 | | | 497 | |
498 | /* | | 498 | /* |
499 | * Interpret high order word to find amount of data to be | | 499 | * Interpret high order word to find amount of data to be |
500 | * copied to/from the user's address space. | | 500 | * copied to/from the user's address space. |
501 | */ | | 501 | */ |
502 | size32 = IOCPARM_LEN(com); | | 502 | size32 = IOCPARM_LEN(com); |
503 | alloc_size32 = size32; | | 503 | alloc_size32 = size32; |
504 | | | 504 | |
505 | /* | | 505 | /* |
506 | * The disklabel is now padded to a multiple of 8 bytes however the old | | 506 | * The disklabel is now padded to a multiple of 8 bytes however the old |
507 | * disklabel on 32bit platforms wasn't. This leaves a difference in | | 507 | * disklabel on 32bit platforms wasn't. This leaves a difference in |
508 | * size of 4 bytes between the two but are otherwise identical. | | 508 | * size of 4 bytes between the two but are otherwise identical. |
509 | * To deal with this, we allocate enough space for the new disklabel | | 509 | * To deal with this, we allocate enough space for the new disklabel |
510 | * but only copyin/out the smaller amount. | | 510 | * but only copyin/out the smaller amount. |
511 | */ | | 511 | */ |
512 | if (IOCGROUP(com) == 'd') { | | 512 | if (IOCGROUP(com) == 'd') { |
513 | u_long ncom = com ^ (DIOCGDINFO ^ DIOCGDINFO32); | | 513 | u_long ncom = com ^ (DIOCGDINFO ^ DIOCGDINFO32); |
514 | switch (ncom) { | | 514 | switch (ncom) { |
515 | case DIOCGDINFO: | | 515 | case DIOCGDINFO: |
516 | case DIOCWDINFO: | | 516 | case DIOCWDINFO: |
517 | case DIOCSDINFO: | | 517 | case DIOCSDINFO: |
518 | case DIOCGDEFLABEL: | | 518 | case DIOCGDEFLABEL: |
519 | com = ncom; | | 519 | com = ncom; |
520 | if (IOCPARM_LEN(DIOCGDINFO32) < IOCPARM_LEN(DIOCGDINFO)) | | 520 | if (IOCPARM_LEN(DIOCGDINFO32) < IOCPARM_LEN(DIOCGDINFO)) |
521 | alloc_size32 = IOCPARM_LEN(DIOCGDINFO); | | 521 | alloc_size32 = IOCPARM_LEN(DIOCGDINFO); |
522 | break; | | 522 | break; |
523 | } | | 523 | } |
524 | } | | 524 | } |
525 | if (alloc_size32 > IOCPARM_MAX) { | | 525 | if (alloc_size32 > IOCPARM_MAX) { |
526 | error = ENOTTY; | | 526 | error = ENOTTY; |
527 | goto out; | | 527 | goto out; |
528 | } | | 528 | } |
529 | if (alloc_size32 > sizeof(stkbuf)) { | | 529 | if (alloc_size32 > sizeof(stkbuf)) { |
530 | memp32 = kmem_alloc(alloc_size32, KM_SLEEP); | | 530 | memp32 = kmem_alloc(alloc_size32, KM_SLEEP); |
531 | data32 = memp32; | | 531 | data32 = memp32; |
532 | } else | | 532 | } else |
533 | data32 = (void *)stkbuf32; | | 533 | data32 = (void *)stkbuf32; |
534 | if ((com >> IOCPARM_SHIFT) == 0) { | | 534 | if ((com >> IOCPARM_SHIFT) == 0) { |
535 | /* UNIX-style ioctl. */ | | 535 | /* UNIX-style ioctl. */ |
536 | data32 = SCARG_P32(uap, data); | | 536 | data32 = SCARG_P32(uap, data); |
537 | } else { | | 537 | } else { |
538 | if (com&IOC_IN) { | | 538 | if (com&IOC_IN) { |
539 | if (size32) { | | 539 | if (size32) { |
540 | error = copyin(SCARG_P32(uap, data), data32, | | 540 | error = copyin(SCARG_P32(uap, data), data32, |
541 | size32); | | 541 | size32); |
542 | if (error) { | | 542 | if (error) { |
543 | goto out; | | 543 | goto out; |
544 | } | | 544 | } |
545 | /* | | 545 | /* |
546 | * The data between size and alloc_size has | | 546 | * The data between size and alloc_size has |
547 | * not been overwritten. It shouldn't matter | | 547 | * not been overwritten. It shouldn't matter |
548 | * but let's clear that anyway. | | 548 | * but let's clear that anyway. |
549 | */ | | 549 | */ |
550 | if (__predict_false(size32 < alloc_size32)) { | | 550 | if (__predict_false(size32 < alloc_size32)) { |
551 | memset((char *)data32+size32, 0, | | 551 | memset((char *)data32+size32, 0, |
552 | alloc_size32 - size32); | | 552 | alloc_size32 - size32); |
553 | } | | 553 | } |
554 | ktrgenio(fd, UIO_WRITE, SCARG_P32(uap, data), | | 554 | ktrgenio(fd, UIO_WRITE, SCARG_P32(uap, data), |
555 | size32, 0); | | 555 | size32, 0); |
556 | } else | | 556 | } else |
557 | *(void **)data32 = SCARG_P32(uap, data); | | 557 | *(void **)data32 = SCARG_P32(uap, data); |
558 | } else if ((com&IOC_OUT) && size32) { | | 558 | } else if ((com&IOC_OUT) && size32) { |
559 | /* | | 559 | /* |
560 | * Zero the buffer so the user always | | 560 | * Zero the buffer so the user always |
561 | * gets back something deterministic. | | 561 | * gets back something deterministic. |
562 | */ | | 562 | */ |
563 | memset(data32, 0, alloc_size32); | | 563 | memset(data32, 0, alloc_size32); |
564 | } else if (com&IOC_VOID) { | | 564 | } else if (com&IOC_VOID) { |
565 | *(void **)data32 = SCARG_P32(uap, data); | | 565 | *(void **)data32 = SCARG_P32(uap, data); |
566 | } | | 566 | } |
567 | } | | 567 | } |
568 | | | 568 | |
569 | /* | | 569 | /* |
570 | * convert various structures, pointers, and other objects that | | 570 | * convert various structures, pointers, and other objects that |
571 | * change size from 32 bit -> 64 bit, for all ioctl commands. | | 571 | * change size from 32 bit -> 64 bit, for all ioctl commands. |
572 | */ | | 572 | */ |
573 | switch (SCARG(uap, com)) { | | 573 | switch (SCARG(uap, com)) { |
574 | case FIONBIO: | | 574 | case FIONBIO: |
575 | mutex_enter(&fp->f_lock); | | 575 | mutex_enter(&fp->f_lock); |
576 | if ((tmp = *(int *)data32) != 0) | | 576 | if ((tmp = *(int *)data32) != 0) |
577 | fp->f_flag |= FNONBLOCK; | | 577 | fp->f_flag |= FNONBLOCK; |
578 | else | | 578 | else |
579 | fp->f_flag &= ~FNONBLOCK; | | 579 | fp->f_flag &= ~FNONBLOCK; |
580 | mutex_exit(&fp->f_lock); | | 580 | mutex_exit(&fp->f_lock); |
581 | error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (void *)&tmp); | | 581 | error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (void *)&tmp); |
582 | break; | | 582 | break; |
583 | | | 583 | |
584 | case FIOASYNC: | | 584 | case FIOASYNC: |
585 | mutex_enter(&fp->f_lock); | | 585 | mutex_enter(&fp->f_lock); |
586 | if ((tmp = *(int *)data32) != 0) | | 586 | if ((tmp = *(int *)data32) != 0) |
587 | fp->f_flag |= FASYNC; | | 587 | fp->f_flag |= FASYNC; |
588 | else | | 588 | else |
589 | fp->f_flag &= ~FASYNC; | | 589 | fp->f_flag &= ~FASYNC; |
590 | mutex_exit(&fp->f_lock); | | 590 | mutex_exit(&fp->f_lock); |
591 | error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (void *)&tmp); | | 591 | error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (void *)&tmp); |
592 | break; | | 592 | break; |
593 | | | 593 | |
594 | case AUDIO_WSEEK32: | | 594 | case AUDIO_WSEEK32: |
595 | IOCTL_CONV_TO(AUDIO_WSEEK, u_long); | | 595 | IOCTL_CONV_TO(AUDIO_WSEEK, u_long); |
596 | | | 596 | |
597 | case DIOCGPART32: | | 597 | case DIOCGPART32: |
598 | IOCTL_STRUCT_CONV_TO(DIOCGPART, partinfo); | | 598 | IOCTL_STRUCT_CONV_TO(DIOCGPART, partinfo); |
599 | #if 0 /* not implemented by anything */ | | 599 | #if 0 /* not implemented by anything */ |
600 | case DIOCRFORMAT32: | | 600 | case DIOCRFORMAT32: |
601 | IOCTL_STRUCT_CONV_TO(DIOCRFORMAT, format_op); | | 601 | IOCTL_STRUCT_CONV_TO(DIOCRFORMAT, format_op); |
602 | case DIOCWFORMAT32: | | 602 | case DIOCWFORMAT32: |
603 | IOCTL_STRUCT_CONV_TO(DIOCWFORMAT, format_op); | | 603 | IOCTL_STRUCT_CONV_TO(DIOCWFORMAT, format_op); |
604 | #endif | | 604 | #endif |
605 | | | 605 | |
606 | /* | | 606 | /* |
607 | * only a few ifreq syscalls need conversion and those are | | 607 | * only a few ifreq syscalls need conversion and those are |
608 | * all driver specific... XXX | | 608 | * all driver specific... XXX |
609 | */ | | 609 | */ |
610 | #if 0 | | 610 | #if 0 |
611 | case SIOCGADDRROM3232: | | 611 | case SIOCGADDRROM3232: |
612 | IOCTL_STRUCT_CONV_TO(SIOCGADDRROM32, ifreq); | | 612 | IOCTL_STRUCT_CONV_TO(SIOCGADDRROM32, ifreq); |
613 | case SIOCGCHIPID32: | | 613 | case SIOCGCHIPID32: |
614 | IOCTL_STRUCT_CONV_TO(SIOCGCHIPID, ifreq); | | 614 | IOCTL_STRUCT_CONV_TO(SIOCGCHIPID, ifreq); |
615 | case SIOCSIFADDR32: | | 615 | case SIOCSIFADDR32: |
616 | IOCTL_STRUCT_CONV_TO(SIOCSIFADDR, ifreq); | | 616 | IOCTL_STRUCT_CONV_TO(SIOCSIFADDR, ifreq); |
617 | case OSIOCGIFADDR32: | | 617 | case OSIOCGIFADDR32: |
618 | IOCTL_STRUCT_CONV_TO(OSIOCGIFADDR, ifreq); | | 618 | IOCTL_STRUCT_CONV_TO(OSIOCGIFADDR, ifreq); |
619 | case SIOCGIFADDR32: | | 619 | case SIOCGIFADDR32: |
620 | IOCTL_STRUCT_CONV_TO(SIOCGIFADDR, ifreq); | | 620 | IOCTL_STRUCT_CONV_TO(SIOCGIFADDR, ifreq); |
621 | case SIOCSIFDSTADDR32: | | 621 | case SIOCSIFDSTADDR32: |
622 | IOCTL_STRUCT_CONV_TO(SIOCSIFDSTADDR, ifreq); | | 622 | IOCTL_STRUCT_CONV_TO(SIOCSIFDSTADDR, ifreq); |
623 | case OSIOCGIFDSTADDR32: | | 623 | case OSIOCGIFDSTADDR32: |
624 | IOCTL_STRUCT_CONV_TO(OSIOCGIFDSTADDR, ifreq); | | 624 | IOCTL_STRUCT_CONV_TO(OSIOCGIFDSTADDR, ifreq); |
625 | case SIOCGIFDSTADDR32: | | 625 | case SIOCGIFDSTADDR32: |
626 | IOCTL_STRUCT_CONV_TO(SIOCGIFDSTADDR, ifreq); | | 626 | IOCTL_STRUCT_CONV_TO(SIOCGIFDSTADDR, ifreq); |
627 | case OSIOCGIFBRDADDR32: | | 627 | case OSIOCGIFBRDADDR32: |
628 | IOCTL_STRUCT_CONV_TO(OSIOCGIFBRDADDR, ifreq); | | 628 | IOCTL_STRUCT_CONV_TO(OSIOCGIFBRDADDR, ifreq); |
629 | case SIOCGIFBRDADDR32: | | 629 | case SIOCGIFBRDADDR32: |
630 | IOCTL_STRUCT_CONV_TO(SIOCGIFBRDADDR, ifreq); | | 630 | IOCTL_STRUCT_CONV_TO(SIOCGIFBRDADDR, ifreq); |
631 | case SIOCSIFBRDADDR32: | | 631 | case SIOCSIFBRDADDR32: |
632 | IOCTL_STRUCT_CONV_TO(SIOCSIFBRDADDR, ifreq); | | 632 | IOCTL_STRUCT_CONV_TO(SIOCSIFBRDADDR, ifreq); |
633 | case OSIOCGIFNETMASK32: | | 633 | case OSIOCGIFNETMASK32: |
634 | IOCTL_STRUCT_CONV_TO(OSIOCGIFNETMASK, ifreq); | | 634 | IOCTL_STRUCT_CONV_TO(OSIOCGIFNETMASK, ifreq); |
635 | case SIOCGIFNETMASK32: | | 635 | case SIOCGIFNETMASK32: |
636 | IOCTL_STRUCT_CONV_TO(SIOCGIFNETMASK, ifreq); | | 636 | IOCTL_STRUCT_CONV_TO(SIOCGIFNETMASK, ifreq); |
637 | case SIOCSIFNETMASK32: | | 637 | case SIOCSIFNETMASK32: |
638 | IOCTL_STRUCT_CONV_TO(SIOCSIFNETMASK, ifreq); | | 638 | IOCTL_STRUCT_CONV_TO(SIOCSIFNETMASK, ifreq); |
639 | case SIOCGIFMETRIC32: | | 639 | case SIOCGIFMETRIC32: |
640 | IOCTL_STRUCT_CONV_TO(SIOCGIFMETRIC, ifreq); | | 640 | IOCTL_STRUCT_CONV_TO(SIOCGIFMETRIC, ifreq); |
641 | case SIOCSIFMETRIC32: | | 641 | case SIOCSIFMETRIC32: |
642 | IOCTL_STRUCT_CONV_TO(SIOCSIFMETRIC, ifreq); | | 642 | IOCTL_STRUCT_CONV_TO(SIOCSIFMETRIC, ifreq); |
643 | case SIOCDIFADDR32: | | 643 | case SIOCDIFADDR32: |
644 | IOCTL_STRUCT_CONV_TO(SIOCDIFADDR, ifreq); | | 644 | IOCTL_STRUCT_CONV_TO(SIOCDIFADDR, ifreq); |
645 | case SIOCADDMULTI32: | | 645 | case SIOCADDMULTI32: |
646 | IOCTL_STRUCT_CONV_TO(SIOCADDMULTI, ifreq); | | 646 | IOCTL_STRUCT_CONV_TO(SIOCADDMULTI, ifreq); |
647 | case SIOCDELMULTI32: | | 647 | case SIOCDELMULTI32: |
648 | IOCTL_STRUCT_CONV_TO(SIOCDELMULTI, ifreq); | | 648 | IOCTL_STRUCT_CONV_TO(SIOCDELMULTI, ifreq); |
649 | case SIOCSIFMEDIA32: | | 649 | case SIOCSIFMEDIA32: |
650 | IOCTL_STRUCT_CONV_TO(SIOCSIFMEDIA, ifreq); | | 650 | IOCTL_STRUCT_CONV_TO(SIOCSIFMEDIA, ifreq); |
651 | case SIOCSIFMTU32: | | 651 | case SIOCSIFMTU32: |
652 | IOCTL_STRUCT_CONV_TO(SIOCSIFMTU, ifreq); | | 652 | IOCTL_STRUCT_CONV_TO(SIOCSIFMTU, ifreq); |
653 | case SIOCGIFMTU32: | | 653 | case SIOCGIFMTU32: |
654 | IOCTL_STRUCT_CONV_TO(SIOCGIFMTU, ifreq); | | 654 | IOCTL_STRUCT_CONV_TO(SIOCGIFMTU, ifreq); |
655 | case BIOCGETIF32: | | 655 | case BIOCGETIF32: |
656 | IOCTL_STRUCT_CONV_TO(BIOCGETIF, ifreq); | | 656 | IOCTL_STRUCT_CONV_TO(BIOCGETIF, ifreq); |
657 | case BIOCSETIF32: | | 657 | case BIOCSETIF32: |
658 | IOCTL_STRUCT_CONV_TO(BIOCSETIF, ifreq); | | 658 | IOCTL_STRUCT_CONV_TO(BIOCSETIF, ifreq); |
659 | case SIOCPHASE132: | | 659 | case SIOCPHASE132: |
660 | IOCTL_STRUCT_CONV_TO(SIOCPHASE1, ifreq); | | 660 | IOCTL_STRUCT_CONV_TO(SIOCPHASE1, ifreq); |
661 | case SIOCPHASE232: | | 661 | case SIOCPHASE232: |
662 | IOCTL_STRUCT_CONV_TO(SIOCPHASE2, ifreq); | | 662 | IOCTL_STRUCT_CONV_TO(SIOCPHASE2, ifreq); |
663 | #endif | | 663 | #endif |
664 | | | 664 | |
665 | case OOSIOCGIFCONF32: | | 665 | case OOSIOCGIFCONF32: |
666 | IOCTL_STRUCT_CONV_TO(OOSIOCGIFCONF, ifconf); | | 666 | IOCTL_STRUCT_CONV_TO(OOSIOCGIFCONF, ifconf); |
667 | case OSIOCGIFCONF32: | | 667 | case OSIOCGIFCONF32: |
668 | IOCTL_STRUCT_CONV_TO(OSIOCGIFCONF, ifconf); | | 668 | IOCTL_STRUCT_CONV_TO(OSIOCGIFCONF, ifconf); |
669 | case SIOCGIFCONF32: | | 669 | case SIOCGIFCONF32: |
670 | IOCTL_STRUCT_CONV_TO(SIOCGIFCONF, ifconf); | | 670 | IOCTL_STRUCT_CONV_TO(SIOCGIFCONF, ifconf); |
671 | | | 671 | |
672 | case SIOCGIFFLAGS32: | | 672 | case SIOCGIFFLAGS32: |
673 | IOCTL_STRUCT_CONV_TO(SIOCGIFFLAGS, ifreq); | | 673 | IOCTL_STRUCT_CONV_TO(SIOCGIFFLAGS, ifreq); |
674 | case SIOCSIFFLAGS32: | | 674 | case SIOCSIFFLAGS32: |
675 | IOCTL_STRUCT_CONV_TO(SIOCSIFFLAGS, ifreq); | | 675 | IOCTL_STRUCT_CONV_TO(SIOCSIFFLAGS, ifreq); |
676 | | | 676 | |
677 | case OSIOCGIFFLAGS32: | | 677 | case OSIOCGIFFLAGS32: |
678 | IOCTL_STRUCT_CONV_TO(OSIOCGIFFLAGS, oifreq); | | 678 | IOCTL_STRUCT_CONV_TO(OSIOCGIFFLAGS, oifreq); |
679 | case OSIOCSIFFLAGS32: | | 679 | case OSIOCSIFFLAGS32: |
680 | IOCTL_STRUCT_CONV_TO(OSIOCSIFFLAGS, oifreq); | | 680 | IOCTL_STRUCT_CONV_TO(OSIOCSIFFLAGS, oifreq); |
681 | | | 681 | |
682 | case SIOCGIFMEDIA32: | | 682 | case SIOCGIFMEDIA32: |
683 | IOCTL_STRUCT_CONV_TO(SIOCGIFMEDIA, ifmediareq); | | 683 | IOCTL_STRUCT_CONV_TO(SIOCGIFMEDIA, ifmediareq); |
684 | | | 684 | |
685 | case SIOCSDRVSPEC32: | | 685 | case SIOCSDRVSPEC32: |
686 | IOCTL_STRUCT_CONV_TO(SIOCSDRVSPEC, ifdrv); | | 686 | IOCTL_STRUCT_CONV_TO(SIOCSDRVSPEC, ifdrv); |
687 | | | 687 | |
688 | case SIOCGETVIFCNT32: | | 688 | case SIOCGETVIFCNT32: |
689 | IOCTL_STRUCT_CONV_TO(SIOCGETVIFCNT, sioc_vif_req); | | 689 | IOCTL_STRUCT_CONV_TO(SIOCGETVIFCNT, sioc_vif_req); |
690 | | | 690 | |
691 | case SIOCGETSGCNT32: | | 691 | case SIOCGETSGCNT32: |
692 | IOCTL_STRUCT_CONV_TO(SIOCGETSGCNT, sioc_sg_req); | | 692 | IOCTL_STRUCT_CONV_TO(SIOCGETSGCNT, sioc_sg_req); |
693 | | | 693 | |
694 | case VNDIOCSET32: | | 694 | case VNDIOCSET32: |
695 | IOCTL_STRUCT_CONV_TO(VNDIOCSET, vnd_ioctl); | | 695 | IOCTL_STRUCT_CONV_TO(VNDIOCSET, vnd_ioctl); |
696 | | | 696 | |
697 | case VNDIOCCLR32: | | 697 | case VNDIOCCLR32: |
698 | IOCTL_STRUCT_CONV_TO(VNDIOCCLR, vnd_ioctl); | | 698 | IOCTL_STRUCT_CONV_TO(VNDIOCCLR, vnd_ioctl); |
699 | | | 699 | |
700 | case VNDIOCGET32: | | 700 | case VNDIOCGET32: |
701 | IOCTL_STRUCT_CONV_TO(VNDIOCGET, vnd_user); | | 701 | IOCTL_STRUCT_CONV_TO(VNDIOCGET, vnd_user); |
702 | | | 702 | |
703 | case VNDIOCSET5032: | | 703 | case VNDIOCSET5032: |
704 | IOCTL_STRUCT_CONV_TO(VNDIOCSET50, vnd_ioctl50); | | 704 | IOCTL_STRUCT_CONV_TO(VNDIOCSET50, vnd_ioctl50); |
705 | | | 705 | |
706 | case VNDIOCCLR5032: | | 706 | case VNDIOCCLR5032: |
707 | IOCTL_STRUCT_CONV_TO(VNDIOCCLR50, vnd_ioctl50); | | 707 | IOCTL_STRUCT_CONV_TO(VNDIOCCLR50, vnd_ioctl50); |
708 | | | 708 | |
709 | case ENVSYS_GETDICTIONARY32: | | 709 | case ENVSYS_GETDICTIONARY32: |
710 | IOCTL_STRUCT_CONV_TO(ENVSYS_GETDICTIONARY, plistref); | | 710 | IOCTL_STRUCT_CONV_TO(ENVSYS_GETDICTIONARY, plistref); |
711 | case ENVSYS_SETDICTIONARY32: | | 711 | case ENVSYS_SETDICTIONARY32: |
712 | IOCTL_STRUCT_CONV_TO(ENVSYS_SETDICTIONARY, plistref); | | 712 | IOCTL_STRUCT_CONV_TO(ENVSYS_SETDICTIONARY, plistref); |
713 | case ENVSYS_REMOVEPROPS32: | | 713 | case ENVSYS_REMOVEPROPS32: |
714 | IOCTL_STRUCT_CONV_TO(ENVSYS_REMOVEPROPS, plistref); | | 714 | IOCTL_STRUCT_CONV_TO(ENVSYS_REMOVEPROPS, plistref); |
715 | | | 715 | |
716 | default: | | 716 | default: |
717 | #ifdef NETBSD32_MD_IOCTL | | 717 | #ifdef NETBSD32_MD_IOCTL |
718 | error = netbsd32_md_ioctl(fp, com, data32, l); | | 718 | error = netbsd32_md_ioctl(fp, com, data32, l); |
719 | #else | | 719 | #else |
720 | error = (*fp->f_ops->fo_ioctl)(fp, com, data32); | | 720 | error = (*fp->f_ops->fo_ioctl)(fp, com, data32); |
721 | #endif | | 721 | #endif |
722 | break; | | 722 | break; |
723 | } | | 723 | } |
724 | | | 724 | |
725 | if (error == EPASSTHROUGH) | | 725 | if (error == EPASSTHROUGH) |
726 | error = ENOTTY; | | 726 | error = ENOTTY; |
727 | | | 727 | |
728 | /* | | 728 | /* |
729 | * Copy any data to user, size was | | 729 | * Copy any data to user, size was |
730 | * already set and checked above. | | 730 | * already set and checked above. |
731 | */ | | 731 | */ |
732 | if (error == 0 && (com&IOC_OUT) && size32) { | | 732 | if (error == 0 && (com&IOC_OUT) && size32) { |
733 | error = copyout(data32, SCARG_P32(uap, data), size32); | | 733 | error = copyout(data32, SCARG_P32(uap, data), size32); |
734 | ktrgenio(fd, UIO_READ, SCARG_P32(uap, data), | | 734 | ktrgenio(fd, UIO_READ, SCARG_P32(uap, data), |
735 | size32, error); | | 735 | size32, error); |
736 | } | | 736 | } |
737 | | | 737 | |
738 | out: | | 738 | out: |
739 | /* If we allocated data, free it here. */ | | 739 | /* If we allocated data, free it here. */ |
740 | if (memp32) | | 740 | if (memp32) |
741 | kmem_free(memp32, alloc_size32); | | 741 | kmem_free(memp32, alloc_size32); |
742 | if (memp) | | 742 | if (memp) |
743 | kmem_free(memp32, size); | | 743 | kmem_free(memp, size); |
744 | fd_putfile(fd); | | 744 | fd_putfile(fd); |
745 | return (error); | | 745 | return (error); |
746 | } | | 746 | } |