From: Tom Hughes Date: Wed, 7 Mar 2012 10:21:33 +0000 (+0000) Subject: Add support for the I2C_RDWR ioctl. X-Git-Tag: svn/VALGRIND_3_8_0~433 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=137aace5a314504f3e73ec949d2057cea09e3ced;p=thirdparty%2Fvalgrind.git Add support for the I2C_RDWR ioctl. Patch from arnaud mouiche to fix BZ#286261. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12420 --- diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 82bb8ab9f0..e8fe844f73 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -5197,6 +5197,21 @@ PRE(sys_ioctl) case VKI_I2C_FUNCS: PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) ); break; + case VKI_I2C_RDWR: + if ( ARG3 ) { + struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3; + UInt i; + PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data)); + for (i=0; i < vkui->nmsgs; i++) { + struct vki_i2c_msg *msg = vkui->msgs + i; + PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg)); + if (msg->flags & VKI_I2C_M_RD) + PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len); + else + PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len); + } + } + break; /* Wireless extensions ioctls */ case VKI_SIOCSIWCOMMIT: @@ -6193,6 +6208,17 @@ POST(sys_ioctl) case VKI_I2C_FUNCS: POST_MEM_WRITE( ARG3, sizeof(unsigned long) ); break; + case VKI_I2C_RDWR: + if ( ARG3 ) { + struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3; + UInt i; + for (i=0; i < vkui->nmsgs; i++) { + struct vki_i2c_msg *msg = vkui->msgs + i; + if (msg->flags & VKI_I2C_M_RD) + POST_MEM_WRITE((Addr)msg->buf, msg->len); + } + } + break; /* Wireless extensions ioctls */ case VKI_SIOCSIWCOMMIT: diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index e2cc8b3863..cf0da7c2bd 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -2468,8 +2468,28 @@ struct vki_usbdevfs_setuppacket { /* is already taken! */ #define VKI_I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */ #define VKI_I2C_FUNCS 0x0705 /* Get the adapter functionality */ +#define VKI_I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */ #define VKI_I2C_PEC 0x0708 /* != 0 for SMBus PEC */ +struct vki_i2c_msg { + __vki_u16 addr; /* slave address */ + __vki_u16 flags; +#define VKI_I2C_M_TEN 0x0010 /* this is a ten bit chip address */ +#define VKI_I2C_M_RD 0x0001 /* read data, from slave to master */ +#define VKI_I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define VKI_I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define VKI_I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define VKI_I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define VKI_I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ + __vki_u16 len; /* msg length */ + __vki_u8 *buf; /* pointer to msg data */ +}; + +struct vki_i2c_rdwr_ioctl_data { + struct vki_i2c_msg *msgs; /* pointers to i2c_msgs */ + __vki_u32 nmsgs; /* number of i2c_msgs */ +}; + //---------------------------------------------------------------------- // From linux-2.6.20.1/include/linux/keyctl.h //----------------------------------------------------------------------