The I2C non-blocking patch would incorrectly return success in some cases because it wasn't updating the proper result variable. This patch fixes the problem. The bttv driver now works properly with the I2C non-blocking patch. Signed-off-by: Corey Minyard Index: linux-2.6.11-rc3/drivers/i2c/i2c-core.c =================================================================== --- linux-2.6.11-rc3.orig/drivers/i2c/i2c-core.c +++ linux-2.6.11-rc3/drivers/i2c/i2c-core.c @@ -899,9 +899,11 @@ entry->i2c.num); up(&adap->bus_lock); + entry->result = ret; return ret; } else { dev_dbg(&adap->dev, "I2C level transfers not supported\n"); + entry->result = -ENOSYS; return -ENOSYS; } } @@ -1491,7 +1493,7 @@ msg[0].len = 1; msg[1].addr = entry->smbus.addr; msg[1].flags = entry->smbus.flags | I2C_M_RD; - msg[1].len = 1; + msg[1].len = 0; msgbuf0[0] = entry->smbus.command; switch(entry->smbus.size) { @@ -1593,17 +1595,17 @@ /* Simulate a SMBus command using the i2c protocol No checking of parameters is done! */ -static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adap, - struct i2c_op_q_entry * entry) +static void i2c_smbus_xfer_emulated(struct i2c_adapter * adap, + struct i2c_op_q_entry * entry) { - if (i2c_smbus_emu_format(adap, entry)) - return -EINVAL; - - if (i2c_transfer_entry(adap, entry) < 0) - return -EINVAL; + if (i2c_smbus_emu_format(adap, entry)) { + entry->result = -EINVAL; + return; + } - return entry->result; + /* Return value will be put into entry->result. */ + i2c_transfer_entry(adap, entry); } s32 i2c_smbus_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,