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 ) { 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 = (vir_bytes)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