xref: /minix/minix/lib/libc/sys/ioctl.c (revision 83133719)
1 #include <sys/cdefs.h>
2 #include "namespace.h"
3 #include <lib.h>
4 #include <stdarg.h>
5 
6 #include <sys/ioctl.h>
7 #include <minix/i2c.h>
8 #include <string.h>
9 #include <sys/ioccom.h>
10 #include <stdarg.h>
11 
12 static void rewrite_i2c_netbsd_to_minix(minix_i2c_ioctl_exec_t *out,
13     i2c_ioctl_exec_t *in);
14 static void rewrite_i2c_minix_to_netbsd(i2c_ioctl_exec_t *out,
15     minix_i2c_ioctl_exec_t *in);
16 
17 static void rewrite_i2c_netbsd_to_minix(minix_i2c_ioctl_exec_t *out,
18 	i2c_ioctl_exec_t *in)
19 {
20   memset(out, '\0', sizeof(minix_i2c_ioctl_exec_t));
21 
22   out->iie_op = in->iie_op;
23   out->iie_addr = in->iie_addr;
24   out->iie_cmdlen = I2C_EXEC_MAX_CMDLEN < in->iie_cmdlen ?
25   	I2C_EXEC_MAX_CMDLEN : in->iie_cmdlen;
26   out->iie_buflen = I2C_EXEC_MAX_BUFLEN < in->iie_buflen ?
27   	I2C_EXEC_MAX_BUFLEN : in->iie_buflen;
28 
29   if (in->iie_cmdlen > 0 && in->iie_cmd != NULL) {
30 	memcpy(out->iie_cmd, in->iie_cmd, in->iie_cmdlen);
31   }
32 
33   if (in->iie_buflen > 0 && in->iie_buf != NULL) {
34 	memcpy(out->iie_buf, in->iie_buf, in->iie_buflen);
35   }
36 }
37 
38 static void rewrite_i2c_minix_to_netbsd(i2c_ioctl_exec_t *out,
39 	minix_i2c_ioctl_exec_t *in)
40 {
41   /* the only field that changes is iie_buf, everything else is the same */
42   if (in->iie_buflen > 0 && in->iie_buf != NULL) {
43 	memcpy(out->iie_buf, in->iie_buf, in->iie_buflen);
44   }
45 }
46 
47 int     ioctl(int fd, unsigned long request, ...)
48 {
49   int r, request_save;
50   message m;
51   vir_bytes addr;
52   void *data;
53   va_list ap;
54 
55   va_start(ap, request);
56   data = va_arg(ap, void *);
57 
58   /*
59    * To support compatibility with interfaces on other systems, certain
60    * requests are re-written to flat structures (i.e. without pointers).
61    */
62   minix_i2c_ioctl_exec_t i2c;
63 
64   request_save = request;
65 
66   switch (request) {
67 	case I2C_IOCTL_EXEC:
68 		rewrite_i2c_netbsd_to_minix(&i2c, data);
69 		addr = (vir_bytes) &i2c;
70 		request = MINIX_I2C_IOCTL_EXEC;
71 		break;
72 	default:
73 		/* Keep original as-is */
74 		addr = data;
75 		break;
76   }
77 
78   memset(&m, 0, sizeof(m));
79   m.m_lc_vfs_ioctl.fd = fd;
80   m.m_lc_vfs_ioctl.req = request;
81   m.m_lc_vfs_ioctl.arg = addr;
82 
83   r = _syscall(VFS_PROC_NR, VFS_IOCTL, &m);
84 
85   /* Translate back to original form */
86   switch (request_save) {
87 	case I2C_IOCTL_EXEC:
88 		rewrite_i2c_minix_to_netbsd(data, &i2c);
89 		break;
90 	default:
91 		/* Nothing to do */
92 		break;
93   }
94 
95   va_end(ap);
96 
97   return r;
98 }
99