1433d6423SLionel Sambuc #include <sys/cdefs.h>
2433d6423SLionel Sambuc #include "namespace.h"
3433d6423SLionel Sambuc #include <lib.h>
4433d6423SLionel Sambuc #include <stdarg.h>
5433d6423SLionel Sambuc
6433d6423SLionel Sambuc #include <sys/ioctl.h>
7433d6423SLionel Sambuc #include <minix/i2c.h>
8433d6423SLionel Sambuc #include <string.h>
9433d6423SLionel Sambuc #include <sys/ioccom.h>
10433d6423SLionel Sambuc #include <stdarg.h>
11ed223591SDavid van Moolenbroek #include <fcntl.h>
12*ef8d499eSDavid van Moolenbroek #include <stdlib.h>
13*ef8d499eSDavid van Moolenbroek #include <minix/if.h>
14*ef8d499eSDavid van Moolenbroek #include <minix/bpf.h>
15*ef8d499eSDavid van Moolenbroek #include <assert.h>
16433d6423SLionel Sambuc
17433d6423SLionel Sambuc static void rewrite_i2c_netbsd_to_minix(minix_i2c_ioctl_exec_t *out,
18433d6423SLionel Sambuc i2c_ioctl_exec_t *in);
19433d6423SLionel Sambuc static void rewrite_i2c_minix_to_netbsd(i2c_ioctl_exec_t *out,
20433d6423SLionel Sambuc minix_i2c_ioctl_exec_t *in);
21433d6423SLionel Sambuc
rewrite_i2c_netbsd_to_minix(minix_i2c_ioctl_exec_t * out,i2c_ioctl_exec_t * in)22433d6423SLionel Sambuc static void rewrite_i2c_netbsd_to_minix(minix_i2c_ioctl_exec_t *out,
23433d6423SLionel Sambuc i2c_ioctl_exec_t *in)
24433d6423SLionel Sambuc {
25433d6423SLionel Sambuc memset(out, '\0', sizeof(minix_i2c_ioctl_exec_t));
26433d6423SLionel Sambuc
27433d6423SLionel Sambuc out->iie_op = in->iie_op;
28433d6423SLionel Sambuc out->iie_addr = in->iie_addr;
29433d6423SLionel Sambuc out->iie_cmdlen = I2C_EXEC_MAX_CMDLEN < in->iie_cmdlen ?
30433d6423SLionel Sambuc I2C_EXEC_MAX_CMDLEN : in->iie_cmdlen;
31433d6423SLionel Sambuc out->iie_buflen = I2C_EXEC_MAX_BUFLEN < in->iie_buflen ?
32433d6423SLionel Sambuc I2C_EXEC_MAX_BUFLEN : in->iie_buflen;
33433d6423SLionel Sambuc
34433d6423SLionel Sambuc if (in->iie_cmdlen > 0 && in->iie_cmd != NULL) {
35433d6423SLionel Sambuc memcpy(out->iie_cmd, in->iie_cmd, in->iie_cmdlen);
36433d6423SLionel Sambuc }
37433d6423SLionel Sambuc
38433d6423SLionel Sambuc if (in->iie_buflen > 0 && in->iie_buf != NULL) {
39433d6423SLionel Sambuc memcpy(out->iie_buf, in->iie_buf, in->iie_buflen);
40433d6423SLionel Sambuc }
41433d6423SLionel Sambuc }
42433d6423SLionel Sambuc
rewrite_i2c_minix_to_netbsd(i2c_ioctl_exec_t * out,minix_i2c_ioctl_exec_t * in)43433d6423SLionel Sambuc static void rewrite_i2c_minix_to_netbsd(i2c_ioctl_exec_t *out,
44433d6423SLionel Sambuc minix_i2c_ioctl_exec_t *in)
45433d6423SLionel Sambuc {
46433d6423SLionel Sambuc /* the only field that changes is iie_buf, everything else is the same */
4754841c01SEmmanuel Blot if (in->iie_buflen > 0 ) {
48433d6423SLionel Sambuc memcpy(out->iie_buf, in->iie_buf, in->iie_buflen);
49433d6423SLionel Sambuc }
50433d6423SLionel Sambuc }
51433d6423SLionel Sambuc
52ed223591SDavid van Moolenbroek /*
53*ef8d499eSDavid van Moolenbroek * Convert a network interface related IOCTL with pointers to a flat format
54*ef8d499eSDavid van Moolenbroek * suitable for MINIX3. Return a pointer to the new data on success, or zero
55*ef8d499eSDavid van Moolenbroek * (with errno set) on failure. The original request code is given in
56*ef8d499eSDavid van Moolenbroek * 'request' and must be replaced by the new request code to be used.
57*ef8d499eSDavid van Moolenbroek */
58*ef8d499eSDavid van Moolenbroek static vir_bytes
ioctl_convert_if_to_minix(void * data,unsigned long * request)59*ef8d499eSDavid van Moolenbroek ioctl_convert_if_to_minix(void * data, unsigned long * request)
60*ef8d499eSDavid van Moolenbroek {
61*ef8d499eSDavid van Moolenbroek struct minix_ifmediareq *mifm;
62*ef8d499eSDavid van Moolenbroek struct ifmediareq *ifm;
63*ef8d499eSDavid van Moolenbroek struct minix_if_clonereq *mifcr;
64*ef8d499eSDavid van Moolenbroek struct if_clonereq *ifcr;
65*ef8d499eSDavid van Moolenbroek
66*ef8d499eSDavid van Moolenbroek switch (*request) {
67*ef8d499eSDavid van Moolenbroek case SIOCGIFMEDIA:
68*ef8d499eSDavid van Moolenbroek ifm = (struct ifmediareq *)data;
69*ef8d499eSDavid van Moolenbroek
70*ef8d499eSDavid van Moolenbroek mifm = (struct minix_ifmediareq *)malloc(sizeof(*mifm));
71*ef8d499eSDavid van Moolenbroek if (mifm != NULL) {
72*ef8d499eSDavid van Moolenbroek /*
73*ef8d499eSDavid van Moolenbroek * The count may exceed MINIX_IF_MAXMEDIA, and should
74*ef8d499eSDavid van Moolenbroek * be truncated as needed by the IF implementation.
75*ef8d499eSDavid van Moolenbroek */
76*ef8d499eSDavid van Moolenbroek memcpy(&mifm->mifm_ifm, ifm, sizeof(*ifm));
77*ef8d499eSDavid van Moolenbroek
78*ef8d499eSDavid van Moolenbroek *request = MINIX_SIOCGIFMEDIA;
79*ef8d499eSDavid van Moolenbroek } else
80*ef8d499eSDavid van Moolenbroek errno = ENOMEM;
81*ef8d499eSDavid van Moolenbroek
82*ef8d499eSDavid van Moolenbroek return (vir_bytes)mifm;
83*ef8d499eSDavid van Moolenbroek
84*ef8d499eSDavid van Moolenbroek case SIOCIFGCLONERS:
85*ef8d499eSDavid van Moolenbroek ifcr = (struct if_clonereq *)data;
86*ef8d499eSDavid van Moolenbroek
87*ef8d499eSDavid van Moolenbroek mifcr = (struct minix_if_clonereq *)malloc(sizeof(*mifcr));
88*ef8d499eSDavid van Moolenbroek if (mifcr != NULL) {
89*ef8d499eSDavid van Moolenbroek /*
90*ef8d499eSDavid van Moolenbroek * The count may exceed MINIX_IF_MAXCLONERS, and should
91*ef8d499eSDavid van Moolenbroek * be truncated as needed by the IF implementation.
92*ef8d499eSDavid van Moolenbroek */
93*ef8d499eSDavid van Moolenbroek memcpy(&mifcr->mifcr_ifcr, ifcr, sizeof(*ifcr));
94*ef8d499eSDavid van Moolenbroek
95*ef8d499eSDavid van Moolenbroek *request = MINIX_SIOCIFGCLONERS;
96*ef8d499eSDavid van Moolenbroek } else
97*ef8d499eSDavid van Moolenbroek errno = ENOMEM;
98*ef8d499eSDavid van Moolenbroek
99*ef8d499eSDavid van Moolenbroek return (vir_bytes)mifcr;
100*ef8d499eSDavid van Moolenbroek
101*ef8d499eSDavid van Moolenbroek default:
102*ef8d499eSDavid van Moolenbroek assert(0);
103*ef8d499eSDavid van Moolenbroek
104*ef8d499eSDavid van Moolenbroek errno = ENOTTY;
105*ef8d499eSDavid van Moolenbroek return 0;
106*ef8d499eSDavid van Moolenbroek }
107*ef8d499eSDavid van Moolenbroek }
108*ef8d499eSDavid van Moolenbroek
109*ef8d499eSDavid van Moolenbroek /*
110*ef8d499eSDavid van Moolenbroek * Convert a the result of a network interface related IOCTL with pointers from
111*ef8d499eSDavid van Moolenbroek * the flat format used to make the call to MINIX3. Called on success only.
112*ef8d499eSDavid van Moolenbroek * The given request code is that of the (NetBSD-type) original.
113*ef8d499eSDavid van Moolenbroek */
114*ef8d499eSDavid van Moolenbroek static void
ioctl_convert_if_from_minix(vir_bytes addr,void * data,unsigned long request)115*ef8d499eSDavid van Moolenbroek ioctl_convert_if_from_minix(vir_bytes addr, void * data, unsigned long request)
116*ef8d499eSDavid van Moolenbroek {
117*ef8d499eSDavid van Moolenbroek struct minix_ifmediareq *mifm;
118*ef8d499eSDavid van Moolenbroek struct ifmediareq *ifm;
119*ef8d499eSDavid van Moolenbroek struct minix_if_clonereq *mifcr;
120*ef8d499eSDavid van Moolenbroek struct if_clonereq *ifcr;
121*ef8d499eSDavid van Moolenbroek int count;
122*ef8d499eSDavid van Moolenbroek
123*ef8d499eSDavid van Moolenbroek switch (request) {
124*ef8d499eSDavid van Moolenbroek case SIOCGIFMEDIA:
125*ef8d499eSDavid van Moolenbroek mifm = (struct minix_ifmediareq *)addr;
126*ef8d499eSDavid van Moolenbroek ifm = (struct ifmediareq *)data;
127*ef8d499eSDavid van Moolenbroek
128*ef8d499eSDavid van Moolenbroek memcpy(ifm, &mifm->mifm_ifm, sizeof(*ifm));
129*ef8d499eSDavid van Moolenbroek
130*ef8d499eSDavid van Moolenbroek if (ifm->ifm_ulist != NULL && ifm->ifm_count > 0)
131*ef8d499eSDavid van Moolenbroek memcpy(ifm->ifm_ulist, mifm->mifm_list,
132*ef8d499eSDavid van Moolenbroek ifm->ifm_count * sizeof(ifm->ifm_ulist[0]));
133*ef8d499eSDavid van Moolenbroek
134*ef8d499eSDavid van Moolenbroek break;
135*ef8d499eSDavid van Moolenbroek
136*ef8d499eSDavid van Moolenbroek case SIOCIFGCLONERS:
137*ef8d499eSDavid van Moolenbroek mifcr = (struct minix_if_clonereq *)addr;
138*ef8d499eSDavid van Moolenbroek ifcr = (struct if_clonereq *)data;
139*ef8d499eSDavid van Moolenbroek
140*ef8d499eSDavid van Moolenbroek memcpy(ifcr, &mifcr->mifcr_ifcr, sizeof(*ifcr));
141*ef8d499eSDavid van Moolenbroek
142*ef8d499eSDavid van Moolenbroek count = (ifcr->ifcr_count < ifcr->ifcr_total) ?
143*ef8d499eSDavid van Moolenbroek ifcr->ifcr_count : ifcr->ifcr_total;
144*ef8d499eSDavid van Moolenbroek if (ifcr->ifcr_buffer != NULL && count > 0)
145*ef8d499eSDavid van Moolenbroek memcpy(ifcr->ifcr_buffer, mifcr->mifcr_buffer,
146*ef8d499eSDavid van Moolenbroek count * IFNAMSIZ);
147*ef8d499eSDavid van Moolenbroek
148*ef8d499eSDavid van Moolenbroek break;
149*ef8d499eSDavid van Moolenbroek
150*ef8d499eSDavid van Moolenbroek default:
151*ef8d499eSDavid van Moolenbroek assert(0);
152*ef8d499eSDavid van Moolenbroek }
153*ef8d499eSDavid van Moolenbroek }
154*ef8d499eSDavid van Moolenbroek
155*ef8d499eSDavid van Moolenbroek /*
156*ef8d499eSDavid van Moolenbroek * Convert a BPF (Berkeley Packet Filter) related IOCTL with pointers to a flat
157*ef8d499eSDavid van Moolenbroek * format suitable for MINIX3. Return a pointer to the new data on success, or
158*ef8d499eSDavid van Moolenbroek * zero (with errno set) on failure. The original request code is given in
159*ef8d499eSDavid van Moolenbroek * 'request' and must be replaced by the new request code to be used.
160*ef8d499eSDavid van Moolenbroek */
161*ef8d499eSDavid van Moolenbroek static vir_bytes
ioctl_convert_bpf_to_minix(void * data,unsigned long * request)162*ef8d499eSDavid van Moolenbroek ioctl_convert_bpf_to_minix(void * data, unsigned long * request)
163*ef8d499eSDavid van Moolenbroek {
164*ef8d499eSDavid van Moolenbroek struct minix_bpf_program *mbf;
165*ef8d499eSDavid van Moolenbroek struct bpf_program *bf;
166*ef8d499eSDavid van Moolenbroek struct minix_bpf_dltlist *mbfl;
167*ef8d499eSDavid van Moolenbroek struct bpf_dltlist *bfl;
168*ef8d499eSDavid van Moolenbroek
169*ef8d499eSDavid van Moolenbroek switch (*request) {
170*ef8d499eSDavid van Moolenbroek case BIOCSETF:
171*ef8d499eSDavid van Moolenbroek bf = (struct bpf_program *)data;
172*ef8d499eSDavid van Moolenbroek
173*ef8d499eSDavid van Moolenbroek if (bf->bf_len > __arraycount(mbf->mbf_insns)) {
174*ef8d499eSDavid van Moolenbroek errno = EINVAL;
175*ef8d499eSDavid van Moolenbroek return 0;
176*ef8d499eSDavid van Moolenbroek }
177*ef8d499eSDavid van Moolenbroek
178*ef8d499eSDavid van Moolenbroek mbf = (struct minix_bpf_program *)malloc(sizeof(*mbf));
179*ef8d499eSDavid van Moolenbroek if (mbf != NULL) {
180*ef8d499eSDavid van Moolenbroek mbf->mbf_len = bf->bf_len;
181*ef8d499eSDavid van Moolenbroek memcpy(mbf->mbf_insns, bf->bf_insns,
182*ef8d499eSDavid van Moolenbroek bf->bf_len * sizeof(mbf->mbf_insns[0]));
183*ef8d499eSDavid van Moolenbroek
184*ef8d499eSDavid van Moolenbroek *request = MINIX_BIOCSETF;
185*ef8d499eSDavid van Moolenbroek } else
186*ef8d499eSDavid van Moolenbroek errno = ENOMEM;
187*ef8d499eSDavid van Moolenbroek
188*ef8d499eSDavid van Moolenbroek return (vir_bytes)mbf;
189*ef8d499eSDavid van Moolenbroek
190*ef8d499eSDavid van Moolenbroek case BIOCGDLTLIST:
191*ef8d499eSDavid van Moolenbroek bfl = (struct bpf_dltlist *)data;
192*ef8d499eSDavid van Moolenbroek
193*ef8d499eSDavid van Moolenbroek mbfl = (struct minix_bpf_dltlist *)malloc(sizeof(*mbfl));
194*ef8d499eSDavid van Moolenbroek if (mbfl != NULL) {
195*ef8d499eSDavid van Moolenbroek /*
196*ef8d499eSDavid van Moolenbroek * The length may exceed MINIX_BPF_MAXDLT, and should
197*ef8d499eSDavid van Moolenbroek * be truncated as needed by the BPF implementation.
198*ef8d499eSDavid van Moolenbroek */
199*ef8d499eSDavid van Moolenbroek memcpy(&mbfl->mbfl_dltlist, bfl, sizeof(*bfl));
200*ef8d499eSDavid van Moolenbroek
201*ef8d499eSDavid van Moolenbroek *request = MINIX_BIOCGDLTLIST;
202*ef8d499eSDavid van Moolenbroek } else
203*ef8d499eSDavid van Moolenbroek errno = ENOMEM;
204*ef8d499eSDavid van Moolenbroek
205*ef8d499eSDavid van Moolenbroek return (vir_bytes)mbfl;
206*ef8d499eSDavid van Moolenbroek
207*ef8d499eSDavid van Moolenbroek default:
208*ef8d499eSDavid van Moolenbroek assert(0);
209*ef8d499eSDavid van Moolenbroek
210*ef8d499eSDavid van Moolenbroek errno = ENOTTY;
211*ef8d499eSDavid van Moolenbroek return 0;
212*ef8d499eSDavid van Moolenbroek }
213*ef8d499eSDavid van Moolenbroek }
214*ef8d499eSDavid van Moolenbroek
215*ef8d499eSDavid van Moolenbroek /*
216*ef8d499eSDavid van Moolenbroek * Convert a the result of BPF (Berkeley Packet Filter) related IOCTL with
217*ef8d499eSDavid van Moolenbroek * pointers from the flat format used to make the call to MINIX3. Called on
218*ef8d499eSDavid van Moolenbroek * success only. The given request code is that of the (NetBSD-type) original.
219*ef8d499eSDavid van Moolenbroek */
220*ef8d499eSDavid van Moolenbroek static void
ioctl_convert_bpf_from_minix(vir_bytes addr,void * data,unsigned long request)221*ef8d499eSDavid van Moolenbroek ioctl_convert_bpf_from_minix(vir_bytes addr, void * data,
222*ef8d499eSDavid van Moolenbroek unsigned long request)
223*ef8d499eSDavid van Moolenbroek {
224*ef8d499eSDavid van Moolenbroek struct minix_bpf_dltlist *mbfl;
225*ef8d499eSDavid van Moolenbroek struct bpf_dltlist *bfl;
226*ef8d499eSDavid van Moolenbroek
227*ef8d499eSDavid van Moolenbroek switch (request) {
228*ef8d499eSDavid van Moolenbroek case BIOCGDLTLIST:
229*ef8d499eSDavid van Moolenbroek mbfl = (struct minix_bpf_dltlist *)addr;
230*ef8d499eSDavid van Moolenbroek bfl = (struct bpf_dltlist *)data;
231*ef8d499eSDavid van Moolenbroek
232*ef8d499eSDavid van Moolenbroek memcpy(bfl, &mbfl->mbfl_dltlist, sizeof(*bfl));
233*ef8d499eSDavid van Moolenbroek
234*ef8d499eSDavid van Moolenbroek if (bfl->bfl_list != NULL && bfl->bfl_len > 0)
235*ef8d499eSDavid van Moolenbroek memcpy(bfl->bfl_list, mbfl->mbfl_list,
236*ef8d499eSDavid van Moolenbroek bfl->bfl_len * sizeof(bfl->bfl_list[0]));
237*ef8d499eSDavid van Moolenbroek
238*ef8d499eSDavid van Moolenbroek break;
239*ef8d499eSDavid van Moolenbroek
240*ef8d499eSDavid van Moolenbroek default:
241*ef8d499eSDavid van Moolenbroek assert(0);
242*ef8d499eSDavid van Moolenbroek }
243*ef8d499eSDavid van Moolenbroek }
244*ef8d499eSDavid van Moolenbroek
245*ef8d499eSDavid van Moolenbroek /*
246ed223591SDavid van Moolenbroek * Library implementation of FIOCLEX and FIONCLEX.
247ed223591SDavid van Moolenbroek */
248ed223591SDavid van Moolenbroek static int
ioctl_to_setfd(int fd,int mask,int val)249ed223591SDavid van Moolenbroek ioctl_to_setfd(int fd, int mask, int val)
250ed223591SDavid van Moolenbroek {
251ed223591SDavid van Moolenbroek int fl;
252ed223591SDavid van Moolenbroek
253ed223591SDavid van Moolenbroek if ((fl = fcntl(fd, F_GETFD)) == -1)
254ed223591SDavid van Moolenbroek return -1;
255ed223591SDavid van Moolenbroek
256ed223591SDavid van Moolenbroek fl = (fl & ~mask) | val;
257ed223591SDavid van Moolenbroek
258ed223591SDavid van Moolenbroek return fcntl(fd, F_SETFD, fl);
259ed223591SDavid van Moolenbroek }
260ed223591SDavid van Moolenbroek
261ed223591SDavid van Moolenbroek /*
262ed223591SDavid van Moolenbroek * Library implementation of FIONBIO and FIOASYNC.
263ed223591SDavid van Moolenbroek */
264ed223591SDavid van Moolenbroek static int
ioctl_to_setfl(int fd,void * data,int sfl)265ed223591SDavid van Moolenbroek ioctl_to_setfl(int fd, void * data, int sfl)
266ed223591SDavid van Moolenbroek {
267ed223591SDavid van Moolenbroek int arg, fl;
268ed223591SDavid van Moolenbroek
269ed223591SDavid van Moolenbroek arg = *(int *)data;
270ed223591SDavid van Moolenbroek
271ed223591SDavid van Moolenbroek if ((fl = fcntl(fd, F_GETFL)) == -1)
272ed223591SDavid van Moolenbroek return -1;
273ed223591SDavid van Moolenbroek
274ed223591SDavid van Moolenbroek if (arg)
275ed223591SDavid van Moolenbroek fl |= sfl;
276ed223591SDavid van Moolenbroek else
277ed223591SDavid van Moolenbroek fl &= ~sfl;
278ed223591SDavid van Moolenbroek
279ed223591SDavid van Moolenbroek return fcntl(fd, F_SETFL, fl & ~O_ACCMODE);
280ed223591SDavid van Moolenbroek }
281ed223591SDavid van Moolenbroek
282ed223591SDavid van Moolenbroek /*
283ed223591SDavid van Moolenbroek * Library implementation of various deprecated IOCTLs. These particular IOCTL
284ed223591SDavid van Moolenbroek * calls change how the file descriptors behave, and have nothing to do with
285ed223591SDavid van Moolenbroek * the actual open file. They should therefore be handled by VFS rather than
286ed223591SDavid van Moolenbroek * individual device drivers. We rewrite them to use fcntl(2) instead here.
287ed223591SDavid van Moolenbroek */
288ed223591SDavid van Moolenbroek static int
ioctl_to_fcntl(int fd,unsigned long request,void * data)289ed223591SDavid van Moolenbroek ioctl_to_fcntl(int fd, unsigned long request, void * data)
290ed223591SDavid van Moolenbroek {
291ed223591SDavid van Moolenbroek switch (request) {
292ed223591SDavid van Moolenbroek case FIOCLEX:
293ed223591SDavid van Moolenbroek return ioctl_to_setfd(fd, FD_CLOEXEC, FD_CLOEXEC);
294ed223591SDavid van Moolenbroek case FIONCLEX:
295ed223591SDavid van Moolenbroek return ioctl_to_setfd(fd, FD_CLOEXEC, 0);
296ed223591SDavid van Moolenbroek case FIONBIO:
297ed223591SDavid van Moolenbroek return ioctl_to_setfl(fd, data, O_NONBLOCK);
298ed223591SDavid van Moolenbroek case FIOASYNC:
299ed223591SDavid van Moolenbroek return ioctl_to_setfl(fd, data, O_ASYNC);
300ed223591SDavid van Moolenbroek case FIOSETOWN: /* XXX TODO */
301ed223591SDavid van Moolenbroek case FIOGETOWN: /* XXX TODO */
302ed223591SDavid van Moolenbroek default:
303ed223591SDavid van Moolenbroek errno = ENOTTY;
304ed223591SDavid van Moolenbroek return -1;
305ed223591SDavid van Moolenbroek }
306ed223591SDavid van Moolenbroek }
307ed223591SDavid van Moolenbroek
ioctl(int fd,unsigned long request,...)308433d6423SLionel Sambuc int ioctl(int fd, unsigned long request, ...)
309433d6423SLionel Sambuc {
310*ef8d499eSDavid van Moolenbroek minix_i2c_ioctl_exec_t i2c;
311433d6423SLionel Sambuc int r, request_save;
312433d6423SLionel Sambuc message m;
313433d6423SLionel Sambuc vir_bytes addr;
314433d6423SLionel Sambuc void *data;
315433d6423SLionel Sambuc va_list ap;
316433d6423SLionel Sambuc
317433d6423SLionel Sambuc va_start(ap, request);
318433d6423SLionel Sambuc data = va_arg(ap, void *);
319ed223591SDavid van Moolenbroek va_end(ap);
320433d6423SLionel Sambuc
321433d6423SLionel Sambuc /*
322433d6423SLionel Sambuc * To support compatibility with interfaces on other systems, certain
323433d6423SLionel Sambuc * requests are re-written to flat structures (i.e. without pointers).
324433d6423SLionel Sambuc */
325433d6423SLionel Sambuc request_save = request;
326433d6423SLionel Sambuc
327433d6423SLionel Sambuc switch (request) {
328ed223591SDavid van Moolenbroek case FIOCLEX:
329ed223591SDavid van Moolenbroek case FIONCLEX:
330ed223591SDavid van Moolenbroek case FIONBIO:
331ed223591SDavid van Moolenbroek case FIOASYNC:
332ed223591SDavid van Moolenbroek case FIOSETOWN:
333ed223591SDavid van Moolenbroek case FIOGETOWN:
334ed223591SDavid van Moolenbroek return ioctl_to_fcntl(fd, request, data);
335ed223591SDavid van Moolenbroek
336433d6423SLionel Sambuc case I2C_IOCTL_EXEC:
337433d6423SLionel Sambuc rewrite_i2c_netbsd_to_minix(&i2c, data);
338433d6423SLionel Sambuc addr = (vir_bytes) &i2c;
339433d6423SLionel Sambuc request = MINIX_I2C_IOCTL_EXEC;
340433d6423SLionel Sambuc break;
341*ef8d499eSDavid van Moolenbroek
342*ef8d499eSDavid van Moolenbroek case SIOCGIFMEDIA:
343*ef8d499eSDavid van Moolenbroek case SIOCIFGCLONERS:
344*ef8d499eSDavid van Moolenbroek if ((addr = ioctl_convert_if_to_minix(data, &request)) == 0)
345*ef8d499eSDavid van Moolenbroek return -1; /* errno has already been set */
346*ef8d499eSDavid van Moolenbroek break;
347*ef8d499eSDavid van Moolenbroek
348*ef8d499eSDavid van Moolenbroek case BIOCSETF:
349*ef8d499eSDavid van Moolenbroek case BIOCGDLTLIST:
350*ef8d499eSDavid van Moolenbroek if ((addr = ioctl_convert_bpf_to_minix(data, &request)) == 0)
351*ef8d499eSDavid van Moolenbroek return -1; /* errno has already been set */
352*ef8d499eSDavid van Moolenbroek break;
353*ef8d499eSDavid van Moolenbroek
354433d6423SLionel Sambuc default:
355433d6423SLionel Sambuc /* Keep original as-is */
3565dd8da10SDavid van Moolenbroek addr = (vir_bytes)data;
357433d6423SLionel Sambuc break;
358433d6423SLionel Sambuc }
359433d6423SLionel Sambuc
360433d6423SLionel Sambuc memset(&m, 0, sizeof(m));
361433d6423SLionel Sambuc m.m_lc_vfs_ioctl.fd = fd;
362433d6423SLionel Sambuc m.m_lc_vfs_ioctl.req = request;
363433d6423SLionel Sambuc m.m_lc_vfs_ioctl.arg = addr;
364433d6423SLionel Sambuc
365433d6423SLionel Sambuc r = _syscall(VFS_PROC_NR, VFS_IOCTL, &m);
366433d6423SLionel Sambuc
367*ef8d499eSDavid van Moolenbroek /*
368*ef8d499eSDavid van Moolenbroek * Translate back to original form. Do this on failure as well, as
369*ef8d499eSDavid van Moolenbroek * temporarily allocated resources may have to be freed up again.
370*ef8d499eSDavid van Moolenbroek */
371433d6423SLionel Sambuc switch (request_save) {
372433d6423SLionel Sambuc case I2C_IOCTL_EXEC:
373433d6423SLionel Sambuc rewrite_i2c_minix_to_netbsd(data, &i2c);
374433d6423SLionel Sambuc break;
375*ef8d499eSDavid van Moolenbroek
376*ef8d499eSDavid van Moolenbroek case SIOCGIFMEDIA:
377*ef8d499eSDavid van Moolenbroek case SIOCIFGCLONERS:
378*ef8d499eSDavid van Moolenbroek if (r == 0)
379*ef8d499eSDavid van Moolenbroek ioctl_convert_if_from_minix(addr, data, request_save);
380*ef8d499eSDavid van Moolenbroek free((void *)addr);
381*ef8d499eSDavid van Moolenbroek break;
382*ef8d499eSDavid van Moolenbroek
383*ef8d499eSDavid van Moolenbroek case BIOCGDLTLIST:
384*ef8d499eSDavid van Moolenbroek if (r == 0)
385*ef8d499eSDavid van Moolenbroek ioctl_convert_bpf_from_minix(addr, data, request_save);
386*ef8d499eSDavid van Moolenbroek /* FALLTHROUGH */
387*ef8d499eSDavid van Moolenbroek case BIOCSETF:
388*ef8d499eSDavid van Moolenbroek free((void *)addr);
389*ef8d499eSDavid van Moolenbroek break;
390*ef8d499eSDavid van Moolenbroek
391433d6423SLionel Sambuc default:
392433d6423SLionel Sambuc /* Nothing to do */
393433d6423SLionel Sambuc break;
394433d6423SLionel Sambuc }
395433d6423SLionel Sambuc
396433d6423SLionel Sambuc return r;
397433d6423SLionel Sambuc }
398