diff for duplicates of <42418D47.1070605@acm.org> diff --git a/a/1.txt b/N1/1.txt index b2f9c16..8b13789 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,8 +1 @@ --------------- next part -------------- -A non-text attachment was scrubbed... -Name: i2c_add_op_q.diff -Type: text/x-patch -Size: 17639 bytes -Desc: not available -Url : http://lists.lm-sensors.org/pipermail/lm-sensors/attachments/20050323/d78096be/i2c_add_op_q.bin diff --git a/N1/2.hdr b/N1/2.hdr new file mode 100644 index 0000000..72d8f51 --- /dev/null +++ b/N1/2.hdr @@ -0,0 +1,5 @@ +Content-Type: text/x-patch; + name="i2c_add_op_q.diff" +Content-Transfer-Encoding: 7bit +Content-Disposition: inline; + filename="i2c_add_op_q.diff" diff --git a/N1/2.txt b/N1/2.txt new file mode 100644 index 0000000..2201829 --- /dev/null +++ b/N1/2.txt @@ -0,0 +1,574 @@ +This patch adds an operation queue structure and converts over the +passing around of data to use the operation queue. The op queue +entry will be used for queueing in the non-blocking case. + +Signed-off-by: Corey Minyard <minyard@acm.org> + +Index: linux-2.6.11-mm1/drivers/i2c/i2c-core.c +=================================================================== +--- linux-2.6.11-mm1.orig/drivers/i2c/i2c-core.c ++++ linux-2.6.11-mm1/drivers/i2c/i2c-core.c +@@ -582,24 +582,45 @@ + * ---------------------------------------------------- + */ + +-int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) ++static void i2c_transfer_entry(struct i2c_adapter * adap, ++ struct i2c_op_q_entry * entry) + { +- int ret; +- ++ entry->xfer_type = I2C_OP_I2C; ++ entry->complete = NULL; + if (adap->algo->master_xfer) { +- dev_dbg(&adap->dev, "master_xfer: with %d msgs.\n", num); ++ dev_dbg(&adap->dev, "master_xfer: with %d msgs.\n", ++ entry->i2c.num); + + down(&adap->bus_lock); +- ret = adap->algo->master_xfer(adap,msgs,num); ++ entry->result = adap->algo->master_xfer(adap, entry->i2c.msgs, ++ entry->i2c.num); + up(&adap->bus_lock); +- +- return ret; ++ if (entry->complete) ++ entry->complete(adap, entry); + } else { + dev_dbg(&adap->dev, "I2C level transfers not supported\n"); +- return -ENOSYS; ++ entry->result = -ENOSYS; + } + } + ++int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) ++{ ++ struct i2c_op_q_entry *entry; ++ int rv; ++ ++ entry = kmalloc(sizeof(*entry), GFP_KERNEL); ++ if (!entry) ++ return -ENOMEM; ++ ++ entry->i2c.msgs = msgs; ++ entry->i2c.num = num; ++ ++ i2c_transfer_entry(adap, entry); ++ rv = entry->result; ++ kfree(entry); ++ return rv; ++} ++ + int i2c_master_send(struct i2c_client *client,const char *buf ,int count) + { + int ret; +@@ -1038,185 +1059,181 @@ + } + } + +-static int i2c_smbus_complete_entry(struct i2c_adapter * adapter, u16 addr, +- unsigned short flags, char read_write, +- u8 command, int size, +- union i2c_smbus_data * data, +- int swpec, u8 partial, +- int result) +-{ +- if (result < 0) +- return result; +- +- if(swpec && +- size != I2C_SMBUS_QUICK && +- size != I2C_SMBUS_I2C_BLOCK_DATA && +- (read_write == I2C_SMBUS_READ || +- size == I2C_SMBUS_PROC_CALL_PEC || +- size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) { +- if(i2c_smbus_check_pec(addr, +- command, +- size, +- partial, +- data)) +- return -EINVAL; +- } ++static void i2c_smbus_complete_entry(struct i2c_adapter * adapter, ++ struct i2c_op_q_entry * entry) ++{ ++ if (entry->result < 0) ++ return; + +- return 0; ++ if(entry->swpec && ++ entry->smbus.size != I2C_SMBUS_QUICK && ++ entry->smbus.size != I2C_SMBUS_I2C_BLOCK_DATA && ++ (entry->smbus.read_write == I2C_SMBUS_READ || ++ entry->smbus.size == I2C_SMBUS_PROC_CALL_PEC || ++ entry->smbus.size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) { ++ if(i2c_smbus_check_pec(entry->smbus.addr, ++ entry->smbus.command, ++ entry->smbus.size, ++ entry->partial, ++ entry->smbus.data)) ++ entry->result = -EINVAL; ++ } + } + +-static void i2c_smbus_format_entry(struct i2c_adapter * adapter, u16 addr, +- unsigned short *flags, char read_write, +- u8 command, int *size, +- union i2c_smbus_data * data, +- int *swpec, u8 *partial) +-{ +- *swpec = 0; +- *partial = 0; +- *flags &= I2C_M_TEN | I2C_CLIENT_PEC; +- if((*flags & I2C_CLIENT_PEC) && ++static void i2c_smbus_format_entry(struct i2c_adapter * adapter, ++ struct i2c_op_q_entry * entry) ++{ ++ entry->swpec = 0; ++ entry->partial = 0; ++ entry->smbus.flags &= I2C_M_TEN | I2C_CLIENT_PEC; ++ if((entry->smbus.flags & I2C_CLIENT_PEC) && + !(i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HWPEC_CALC))) { +- *swpec = 1; +- if(read_write == I2C_SMBUS_READ && +- *size == I2C_SMBUS_BLOCK_DATA) +- *size = I2C_SMBUS_BLOCK_DATA_PEC; +- else if(*size == I2C_SMBUS_PROC_CALL) +- *size = I2C_SMBUS_PROC_CALL_PEC; +- else if(*size == I2C_SMBUS_BLOCK_PROC_CALL) { +- unsigned char *sdata = data->block; +- i2c_smbus_add_pec(addr, command, I2C_SMBUS_BLOCK_DATA, +- data); +- *partial = sdata[sdata[0] + 1]; +- *size = I2C_SMBUS_BLOCK_PROC_CALL_PEC; +- } else if(read_write == I2C_SMBUS_WRITE && +- *size != I2C_SMBUS_QUICK && +- *size != I2C_SMBUS_I2C_BLOCK_DATA) +- *size = i2c_smbus_add_pec(addr, command, *size, data); ++ entry->swpec = 1; ++ if(entry->smbus.read_write == I2C_SMBUS_READ && ++ entry->smbus.size == I2C_SMBUS_BLOCK_DATA) ++ entry->smbus.size = I2C_SMBUS_BLOCK_DATA_PEC; ++ else if(entry->smbus.size == I2C_SMBUS_PROC_CALL) ++ entry->smbus.size = I2C_SMBUS_PROC_CALL_PEC; ++ else if(entry->smbus.size == I2C_SMBUS_BLOCK_PROC_CALL) { ++ unsigned char *data = entry->smbus.data->block; ++ i2c_smbus_add_pec(entry->smbus.addr, ++ entry->smbus.command, ++ I2C_SMBUS_BLOCK_DATA, ++ entry->smbus.data); ++ entry->partial = data[data[0] + 1]; ++ entry->smbus.size = I2C_SMBUS_BLOCK_PROC_CALL_PEC; ++ } else if(entry->smbus.read_write == I2C_SMBUS_WRITE && ++ entry->smbus.size != I2C_SMBUS_QUICK && ++ entry->smbus.size != I2C_SMBUS_I2C_BLOCK_DATA) ++ entry->smbus.size = ++ i2c_smbus_add_pec(entry->smbus.addr, ++ entry->smbus.command, ++ entry->smbus.size, ++ entry->smbus.data); + } ++ ++ entry->complete = i2c_smbus_complete_entry; + } + +-static int i2c_smbus_emu_complete(struct i2c_adapter * adapter, u16 addr, +- unsigned short flags, char read_write, +- u8 command, int size, +- union i2c_smbus_data * data, +- struct i2c_msg *msg, +- int swpec, u8 partial, +- int result) ++static void i2c_smbus_emu_complete(struct i2c_adapter * adapter, ++ struct i2c_op_q_entry * entry) + { +- unsigned char *msgbuf0 = msg[0].buf; +- unsigned char *msgbuf1 = msg[1].buf; ++ unsigned char *msgbuf0 = entry->i2c.msgs[0].buf; ++ unsigned char *msgbuf1 = entry->i2c.msgs[1].buf; + int i; + ++ if (entry->result < 0) ++ return; + +- if (result < 0) +- return result; ++ if (entry->smbus.read_write != I2C_SMBUS_READ) ++ return; + +- if (read_write != I2C_SMBUS_READ) +- return result; +- +- switch(size) { ++ switch(entry->smbus.size) { + case I2C_SMBUS_BYTE: +- data->byte = msgbuf0[0]; ++ entry->smbus.data->byte = msgbuf0[0]; + break; + case I2C_SMBUS_BYTE_DATA: +- data->byte = msgbuf1[0]; ++ entry->smbus.data->byte = msgbuf1[0]; + break; + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_PROC_CALL: +- data->word = msgbuf1[0]|(msgbuf1[1] << 8); ++ entry->smbus.data->word = msgbuf1[0]|(msgbuf1[1] << 8); + break; + case I2C_SMBUS_I2C_BLOCK_DATA: + /* fixed at 32 for now */ +- data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX; ++ entry->smbus.data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX; + for (i = 0; i < I2C_SMBUS_I2C_BLOCK_MAX; i++) +- data->block[i+1] = msgbuf1[i]; ++ entry->smbus.data->block[i+1] = msgbuf1[i]; + break; + } + +- return i2c_smbus_complete_entry(adapter, addr, flags, +- read_write, command, +- size, data, swpec, partial, result); ++ entry->xfer_type = I2C_OP_SMBUS; ++ i2c_smbus_complete_entry(adapter, entry); + } + +-static int i2c_smbus_emu_format(struct i2c_adapter *adapter, u16 addr, +- unsigned short flags, char read_write, +- u8 command, int size, +- union i2c_smbus_data * data, +- struct i2c_msg *msg) ++static int i2c_smbus_emu_format(struct i2c_adapter *adapter, ++ struct i2c_op_q_entry * entry) + { + /* So we need to generate a series of msgs. In the case of + writing, we need to use only one message; when reading, we + need two. We initialize most things with sane defaults, to + keep the code below somewhat simpler. */ +- unsigned char *msgbuf0 = msg[0].buf; +- int num = read_write == I2C_SMBUS_READ?2:1; ++ unsigned char *msgbuf0 = entry->msgbuf0; ++ int num = entry->smbus.read_write == I2C_SMBUS_READ?2:1; ++ struct i2c_msg *msg = entry->msg; + int i; + +- msg[0].addr = addr; +- msg[0].flags = flags; ++ entry->i2c.msgs = msg; ++ entry->i2c.msgs[0].buf = msgbuf0; ++ entry->i2c.msgs[1].buf = entry->msgbuf1; ++ ++ msg[0].addr = entry->smbus.addr; ++ msg[0].flags = entry->smbus.flags; + msg[0].len = 1; +- msg[1].addr = addr; +- msg[1].flags = flags | I2C_M_RD; ++ msg[1].addr = entry->smbus.addr; ++ msg[1].flags = entry->smbus.flags | I2C_M_RD; + msg[1].len = 0; + +- msgbuf0[0] = command; +- switch(size) { ++ msgbuf0[0] = entry->smbus.command; ++ switch(entry->smbus.size) { + case I2C_SMBUS_QUICK: + msg[0].len = 0; + /* Special case: The read/write field is used as data */ +- msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; ++ msg[0].flags = (entry->smbus.flags | ++ ((entry->smbus.read_write==I2C_SMBUS_READ) ++ ? I2C_M_RD : 0)); + num = 1; + break; + case I2C_SMBUS_BYTE: +- if (read_write == I2C_SMBUS_READ) { ++ if (entry->smbus.read_write == I2C_SMBUS_READ) { + /* Special case: only a read! */ +- msg[0].flags = I2C_M_RD | flags; ++ msg[0].flags = I2C_M_RD | entry->smbus.flags; + num = 1; + } + break; + case I2C_SMBUS_BYTE_DATA: +- if (read_write == I2C_SMBUS_READ) ++ if (entry->smbus.read_write == I2C_SMBUS_READ) + msg[1].len = 1; + else { + msg[0].len = 2; +- msgbuf0[1] = data->byte; ++ msgbuf0[1] = entry->smbus.data->byte; + } + break; + case I2C_SMBUS_WORD_DATA: +- if (read_write == I2C_SMBUS_READ) ++ if (entry->smbus.read_write == I2C_SMBUS_READ) + msg[1].len = 2; + else { + msg[0].len=3; +- msgbuf0[1] = data->word & 0xff; +- msgbuf0[2] = (data->word >> 8) & 0xff; ++ msgbuf0[1] = entry->smbus.data->word & 0xff; ++ msgbuf0[2] = (entry->smbus.data->word >> 8) & 0xff; + } + break; + case I2C_SMBUS_PROC_CALL: + num = 2; /* Special case */ +- read_write = I2C_SMBUS_READ; ++ entry->smbus.read_write = I2C_SMBUS_READ; + msg[0].len = 3; + msg[1].len = 2; +- msgbuf0[1] = data->word & 0xff; +- msgbuf0[2] = (data->word >> 8) & 0xff; ++ msgbuf0[1] = entry->smbus.data->word & 0xff; ++ msgbuf0[2] = (entry->smbus.data->word >> 8) & 0xff; + break; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_BLOCK_DATA_PEC: +- if (read_write == I2C_SMBUS_READ) { ++ if (entry->smbus.read_write == I2C_SMBUS_READ) { + dev_err(&adapter->dev, "Block read not supported " + "under I2C emulation!\n"); + return -1; + } else { +- msg[0].len = data->block[0] + 2; ++ msg[0].len = entry->smbus.data->block[0] + 2; + if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { + dev_err(&adapter->dev, "smbus_access called with " + "invalid block write size (%d)\n", +- data->block[0]); ++ entry->smbus.data->block[0]); + return -1; + } +- if(size == I2C_SMBUS_BLOCK_DATA_PEC) ++ if(entry->smbus.size == I2C_SMBUS_BLOCK_DATA_PEC) + (msg[0].len)++; + for (i = 1; i <= msg[0].len; i++) +- msgbuf0[i] = data->block[i-1]; ++ msgbuf0[i] = entry->smbus.data->block[i-1]; + } + break; + case I2C_SMBUS_BLOCK_PROC_CALL: +@@ -1225,26 +1242,30 @@ + "under I2C emulation!\n"); + return -1; + case I2C_SMBUS_I2C_BLOCK_DATA: +- if (read_write == I2C_SMBUS_READ) { ++ if (entry->smbus.read_write == I2C_SMBUS_READ) { + msg[1].len = I2C_SMBUS_I2C_BLOCK_MAX; + } else { +- msg[0].len = data->block[0] + 1; ++ msg[0].len = entry->smbus.data->block[0] + 1; + if (msg[0].len > I2C_SMBUS_I2C_BLOCK_MAX + 1) { + dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with " + "invalid block write size (%d)\n", +- data->block[0]); ++ entry->smbus.data->block[0]); + return -1; + } +- for (i = 1; i <= data->block[0]; i++) +- msgbuf0[i] = data->block[i]; ++ for (i = 1; i <= entry->smbus.data->block[0]; i++) ++ msgbuf0[i] = entry->smbus.data->block[i]; + } + break; + default: + dev_err(&adapter->dev, "smbus_access called with invalid size (%d)\n", +- size); ++ entry->smbus.size); + return -1; + } + ++ entry->xfer_type = I2C_OP_I2C; ++ entry->i2c.msgs = msg; ++ entry->i2c.num = num; ++ entry->complete = i2c_smbus_emu_complete; + return 0; + } + +@@ -1253,46 +1274,42 @@ + char read_write, u8 command, int size, + union i2c_smbus_data * data) + { ++ struct i2c_op_q_entry *entry; + s32 res; +- int swpec = 0; +- u8 partial = 0; + struct i2c_algorithm *algo = adapter->algo; + + +- i2c_smbus_format_entry(adapter, addr, &flags, +- read_write, command, +- &size, data, &swpec, &partial); ++ entry = kmalloc(sizeof(*entry), GFP_KERNEL); ++ if (!entry) ++ return -ENOMEM; ++ ++ entry->xfer_type = I2C_OP_SMBUS; ++ entry->smbus.addr = addr; ++ entry->smbus.flags = flags; ++ entry->smbus.read_write = read_write; ++ entry->smbus.command = command; ++ entry->smbus.size = size; ++ entry->smbus.data = data; ++ ++ i2c_smbus_format_entry(adapter, entry); + + if (algo->smbus_xfer) { + down(&adapter->bus_lock); +- res = adapter->algo->smbus_xfer(adapter, addr, flags, +- read_write, command, +- size, data); ++ entry->result = adapter->algo->smbus_xfer ++ (adapter, entry->smbus.addr, entry->smbus.flags, ++ entry->smbus.read_write, entry->smbus.command, ++ entry->smbus.size, entry->smbus.data); + up(&adapter->bus_lock); +- res = i2c_smbus_complete_entry(adapter, addr, flags, +- read_write, command, +- size, data, swpec, partial, +- res); ++ if (entry->complete) ++ entry->complete(adapter, entry); + } else { +- unsigned char msgbuf0[34]; +- unsigned char msgbuf1[34]; +- struct i2c_msg msg[2]; +- +- msg[0].buf = msgbuf0; +- msg[1].buf = msgbuf1; +- if (i2c_smbus_emu_format(adapter, addr, flags, +- read_write, command, +- size, data, msg)) +- res = -EINVAL; +- else { +- res = i2c_transfer(adapter, msg, 2); +- res = i2c_smbus_emu_complete(adapter, addr, flags, +- read_write, command, +- size, data, msg, +- swpec, partial, +- res); +- } ++ if (i2c_smbus_emu_format(adapter, entry)) ++ entry->result = -EINVAL; ++ else ++ i2c_transfer_entry(adapter, entry); + } ++ res = entry->result; ++ kfree(entry); + return res; + } + +Index: linux-2.6.11-mm1/include/linux/i2c.h +=================================================================== +--- linux-2.6.11-mm1.orig/include/linux/i2c.h ++++ linux-2.6.11-mm1/include/linux/i2c.h +@@ -32,7 +32,10 @@ + #include <linux/types.h> + #include <linux/i2c-id.h> + #include <linux/device.h> /* for struct device */ ++#include <linux/completion.h> ++#include <linux/kref.h> + #include <asm/semaphore.h> ++#include <asm/atomic.h> + + /* --- General options ------------------------------------------------ */ + +@@ -43,6 +46,7 @@ + struct i2c_driver; + struct i2c_client_address_data; + union i2c_smbus_data; ++struct i2c_op_q_entry; + + /* + * The master routines are the ones normally used to transmit data to devices +@@ -392,6 +396,92 @@ + __u8 *buf; /* pointer to msg data */ + }; + ++/* ++ * Hold a queue of I2C operations to perform, and used to pass data ++ * around. ++ */ ++typedef void (*i2c_op_done_cb)(struct i2c_op_q_entry *entry); ++ ++#define I2C_OP_I2C 0 ++#define I2C_OP_SMBUS 1 ++struct i2c_op_q_entry { ++ /* The result will be set to the result of the operation when ++ it completes. */ ++ s32 result; ++ ++ /**************************************************************/ ++ /* Public interface. The user should set these up (and the ++ proper structure below). */ ++ int xfer_type; ++ ++ /* Handler may be called from interrupt context, so be ++ careful. */ ++ i2c_op_done_cb handler; ++ void *handler_data; ++ ++ /* Note that this is not a union because an smbus operation ++ may be converted into an i2c operation (thus both ++ structures will be used). The data in these may be changd ++ by the driver. */ ++ struct { ++ struct i2c_msg *msgs; ++ int num; ++ } i2c; ++ struct { ++ /* Addr and flags are filled in by the non-blocking ++ send routine that takes a client. */ ++ u16 addr; ++ unsigned short flags; ++ ++ char read_write; ++ u8 command; ++ ++ /* Note that the size is *not* the length of the data. ++ It is the transaction type, like I2C_SMBUS_QUICK ++ and the ones after that below. If this is a block ++ transaction, the length of the rest of the data is ++ in the first byte of the data, for both transmit ++ and receive. */ ++ int size; ++ union i2c_smbus_data *data; ++ } smbus; ++ ++ /**************************************************************/ ++ /* For use by the bus interface. The bus interface sets the ++ timeout in microseconds until the next poll operation. ++ This *must* be set in the start operation. The time_left ++ and data can be used for anything the bus interface likes. ++ data will be set to NULL before being started so the bus ++ interface can use that to tell if it has been set up ++ yet. */ ++ unsigned int call_again_us; ++ long time_left; ++ void *data; ++ ++ /**************************************************************/ ++ /* Internals */ ++ struct list_head link; ++ struct completion *start; ++ atomic_t completed; ++ unsigned int started : 1; ++ unsigned int use_timer : 1; ++ u8 swpec; ++ u8 partial; ++ void (*complete)(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry); ++ ++ /* It's wierd, but we use a usecount to track if an q entry is ++ in use and when it should be reported back to the user. */ ++ struct kref usecount; ++ ++ /* These are here for SMBus emulation over I2C. I don't like ++ them taking this much room in the data structure, but they ++ need to be available in this case. */ ++ unsigned char msgbuf0[34]; ++ unsigned char msgbuf1[34]; ++ struct i2c_msg msg[2]; ++}; ++ + /* To determine what functionality is present */ + + #define I2C_FUNC_I2C 0x00000001 diff --git a/a/content_digest b/N1/content_digest index 065ccff..1d31845 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,18 +1,587 @@ - "From\0minyard@acm.org (Corey Minyard)\0" + "From\0Corey Minyard <minyard@acm.org>\0" "Subject\0[PATCH] I2C Part 3 - Add an operation queue data structure\0" - "Date\0Thu, 19 May 2005 06:25:45 +0000\0" + "Date\0Wed, 23 Mar 2005 09:37:43 -0600\0" "To\0Greg KH <greg@kroah.com>" lkml <linux-kernel@vger.kernel.org> " Sensors <sensors@stimpy.netroedge.com>\0" - "\00:1\0" + "\01:1\0" "b\0" + "\01:2\0" + "fn\0i2c_add_op_q.diff\0" + "b\0" + "This patch adds an operation queue structure and converts over the\n" + "passing around of data to use the operation queue. The op queue\n" + "entry will be used for queueing in the non-blocking case.\n" + "\n" + "Signed-off-by: Corey Minyard <minyard@acm.org>\n" "\n" - "-------------- next part --------------\n" - "A non-text attachment was scrubbed...\n" - "Name: i2c_add_op_q.diff\n" - "Type: text/x-patch\n" - "Size: 17639 bytes\n" - "Desc: not available\n" - Url : http://lists.lm-sensors.org/pipermail/lm-sensors/attachments/20050323/d78096be/i2c_add_op_q.bin + "Index: linux-2.6.11-mm1/drivers/i2c/i2c-core.c\n" + "===================================================================\n" + "--- linux-2.6.11-mm1.orig/drivers/i2c/i2c-core.c\n" + "+++ linux-2.6.11-mm1/drivers/i2c/i2c-core.c\n" + "@@ -582,24 +582,45 @@\n" + " * ----------------------------------------------------\n" + " */\n" + " \n" + "-int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)\n" + "+static void i2c_transfer_entry(struct i2c_adapter * adap,\n" + "+\t\t\t struct i2c_op_q_entry * entry)\n" + " {\n" + "-\tint ret;\n" + "-\n" + "+\tentry->xfer_type = I2C_OP_I2C;\n" + "+\tentry->complete = NULL;\n" + " \tif (adap->algo->master_xfer) {\n" + "- \t \tdev_dbg(&adap->dev, \"master_xfer: with %d msgs.\\n\", num);\n" + "+ \t \tdev_dbg(&adap->dev, \"master_xfer: with %d msgs.\\n\",\n" + "+\t\t\tentry->i2c.num);\n" + " \n" + " \t\tdown(&adap->bus_lock);\n" + "-\t\tret = adap->algo->master_xfer(adap,msgs,num);\n" + "+\t\tentry->result = adap->algo->master_xfer(adap, entry->i2c.msgs,\n" + "+\t\t\t\t\t\t\tentry->i2c.num);\n" + " \t\tup(&adap->bus_lock);\n" + "-\n" + "-\t\treturn ret;\n" + "+\t\tif (entry->complete)\n" + "+\t\t entry->complete(adap, entry);\n" + " \t} else {\n" + " \t\tdev_dbg(&adap->dev, \"I2C level transfers not supported\\n\");\n" + "-\t\treturn -ENOSYS;\n" + "+\t\tentry->result = -ENOSYS;\n" + " \t}\n" + " }\n" + " \n" + "+int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)\n" + "+{\n" + "+\tstruct i2c_op_q_entry *entry;\n" + "+\tint rv;\n" + "+\n" + "+\tentry = kmalloc(sizeof(*entry), GFP_KERNEL);\n" + "+\tif (!entry)\n" + "+\t return -ENOMEM;\n" + "+\n" + "+\tentry->i2c.msgs = msgs;\n" + "+\tentry->i2c.num = num;\n" + "+\n" + "+\ti2c_transfer_entry(adap, entry);\n" + "+\trv = entry->result;\n" + "+\tkfree(entry);\n" + "+\treturn rv;\n" + "+}\n" + "+\n" + " int i2c_master_send(struct i2c_client *client,const char *buf ,int count)\n" + " {\n" + " \tint ret;\n" + "@@ -1038,185 +1059,181 @@\n" + " \t}\n" + " }\n" + " \n" + "-static int i2c_smbus_complete_entry(struct i2c_adapter * adapter, u16 addr,\n" + "-\t\t\t\t unsigned short flags, char read_write,\n" + "-\t\t\t\t u8 command, int size,\n" + "-\t\t\t\t union i2c_smbus_data * data,\n" + "-\t\t\t\t int swpec, u8 partial,\n" + "-\t\t\t\t int result)\n" + "-{\n" + "-\tif (result < 0)\n" + "-\t\treturn result;\n" + "-\n" + "-\tif(swpec &&\n" + "-\t size != I2C_SMBUS_QUICK &&\n" + "-\t size != I2C_SMBUS_I2C_BLOCK_DATA &&\n" + "-\t (read_write == I2C_SMBUS_READ ||\n" + "-\t size == I2C_SMBUS_PROC_CALL_PEC ||\n" + "-\t size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) {\n" + "-\t\tif(i2c_smbus_check_pec(addr,\n" + "-\t\t\t\t command,\n" + "-\t\t\t\t size,\n" + "-\t\t\t\t partial,\n" + "-\t\t\t\t data))\n" + "-\t\t\treturn -EINVAL;\n" + "-\t}\n" + "+static void i2c_smbus_complete_entry(struct i2c_adapter * adapter,\n" + "+\t\t\t\t struct i2c_op_q_entry * entry)\n" + "+{\n" + "+\tif (entry->result < 0)\n" + "+\t\treturn;\n" + " \n" + "-\treturn 0;\n" + "+\tif(entry->swpec &&\n" + "+\t entry->smbus.size != I2C_SMBUS_QUICK &&\n" + "+\t entry->smbus.size != I2C_SMBUS_I2C_BLOCK_DATA &&\n" + "+\t (entry->smbus.read_write == I2C_SMBUS_READ ||\n" + "+\t entry->smbus.size == I2C_SMBUS_PROC_CALL_PEC ||\n" + "+\t entry->smbus.size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) {\n" + "+\t\tif(i2c_smbus_check_pec(entry->smbus.addr,\n" + "+\t\t\t\t entry->smbus.command,\n" + "+\t\t\t\t entry->smbus.size,\n" + "+\t\t\t\t entry->partial,\n" + "+\t\t\t\t entry->smbus.data))\n" + "+\t\t\tentry->result = -EINVAL;\n" + "+\t}\n" + " }\n" + " \n" + "-static void i2c_smbus_format_entry(struct i2c_adapter * adapter, u16 addr,\n" + "-\t\t\t\t unsigned short *flags, char read_write,\n" + "-\t\t\t\t u8 command, int *size,\n" + "-\t\t\t\t union i2c_smbus_data * data,\n" + "-\t\t\t\t int *swpec, u8 *partial)\n" + "-{\n" + "-\t*swpec = 0;\n" + "-\t*partial = 0;\n" + "-\t*flags &= I2C_M_TEN | I2C_CLIENT_PEC;\n" + "-\tif((*flags & I2C_CLIENT_PEC) &&\n" + "+static void i2c_smbus_format_entry(struct i2c_adapter * adapter,\n" + "+\t\t\t\t struct i2c_op_q_entry * entry)\n" + "+{\n" + "+\tentry->swpec = 0;\n" + "+\tentry->partial = 0;\n" + "+\tentry->smbus.flags &= I2C_M_TEN | I2C_CLIENT_PEC;\n" + "+\tif((entry->smbus.flags & I2C_CLIENT_PEC) &&\n" + " \t !(i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HWPEC_CALC))) {\n" + "-\t\t*swpec = 1;\n" + "-\t\tif(read_write == I2C_SMBUS_READ &&\n" + "-\t\t *size == I2C_SMBUS_BLOCK_DATA)\n" + "-\t\t\t*size = I2C_SMBUS_BLOCK_DATA_PEC;\n" + "-\t\telse if(*size == I2C_SMBUS_PROC_CALL)\n" + "-\t\t\t*size = I2C_SMBUS_PROC_CALL_PEC;\n" + "-\t\telse if(*size == I2C_SMBUS_BLOCK_PROC_CALL) {\n" + "-\t\t\tunsigned char *sdata = data->block;\n" + "-\t\t\ti2c_smbus_add_pec(addr, command, I2C_SMBUS_BLOCK_DATA,\n" + "-\t\t\t\t\t data);\n" + "-\t\t\t*partial = sdata[sdata[0] + 1];\n" + "-\t\t\t*size = I2C_SMBUS_BLOCK_PROC_CALL_PEC;\n" + "-\t\t} else if(read_write == I2C_SMBUS_WRITE &&\n" + "-\t\t *size != I2C_SMBUS_QUICK &&\n" + "-\t\t *size != I2C_SMBUS_I2C_BLOCK_DATA)\n" + "-\t\t\t*size = i2c_smbus_add_pec(addr, command, *size, data);\n" + "+\t\tentry->swpec = 1;\n" + "+\t\tif(entry->smbus.read_write == I2C_SMBUS_READ &&\n" + "+\t\t entry->smbus.size == I2C_SMBUS_BLOCK_DATA)\n" + "+\t\t\tentry->smbus.size = I2C_SMBUS_BLOCK_DATA_PEC;\n" + "+\t\telse if(entry->smbus.size == I2C_SMBUS_PROC_CALL)\n" + "+\t\t\tentry->smbus.size = I2C_SMBUS_PROC_CALL_PEC;\n" + "+\t\telse if(entry->smbus.size == I2C_SMBUS_BLOCK_PROC_CALL) {\n" + "+\t\t\tunsigned char *data = entry->smbus.data->block;\n" + "+\t\t\ti2c_smbus_add_pec(entry->smbus.addr,\n" + "+\t\t\t\t\t entry->smbus.command,\n" + "+\t\t I2C_SMBUS_BLOCK_DATA,\n" + "+\t\t\t\t\t entry->smbus.data);\n" + "+\t\t\tentry->partial = data[data[0] + 1];\n" + "+\t\t\tentry->smbus.size = I2C_SMBUS_BLOCK_PROC_CALL_PEC;\n" + "+\t\t} else if(entry->smbus.read_write == I2C_SMBUS_WRITE &&\n" + "+\t\t entry->smbus.size != I2C_SMBUS_QUICK &&\n" + "+\t\t entry->smbus.size != I2C_SMBUS_I2C_BLOCK_DATA)\n" + "+\t\t\tentry->smbus.size =\n" + "+\t\t\t\ti2c_smbus_add_pec(entry->smbus.addr,\n" + "+\t\t\t\t\t\t entry->smbus.command,\n" + "+\t\t\t\t\t\t entry->smbus.size,\n" + "+\t\t\t\t\t\t entry->smbus.data);\n" + " \t}\n" + "+\n" + "+\tentry->complete = i2c_smbus_complete_entry;\n" + " }\n" + " \n" + "-static int i2c_smbus_emu_complete(struct i2c_adapter * adapter, u16 addr,\n" + "-\t\t\t\t unsigned short flags, char read_write,\n" + "-\t\t\t\t u8 command, int size, \n" + "-\t\t\t\t union i2c_smbus_data * data,\n" + "-\t\t\t\t struct i2c_msg *msg,\n" + "-\t\t\t\t int swpec, u8 partial,\n" + "-\t\t\t\t int result)\n" + "+static void i2c_smbus_emu_complete(struct i2c_adapter * adapter,\n" + "+\t\t\t\t struct i2c_op_q_entry * entry)\n" + " {\n" + "-\tunsigned char *msgbuf0 = msg[0].buf;\n" + "-\tunsigned char *msgbuf1 = msg[1].buf;\n" + "+\tunsigned char *msgbuf0 = entry->i2c.msgs[0].buf;\n" + "+\tunsigned char *msgbuf1 = entry->i2c.msgs[1].buf;\n" + " \tint i;\n" + " \n" + "+\tif (entry->result < 0)\n" + "+\t\treturn;\n" + " \n" + "-\tif (result < 0)\n" + "-\t\treturn result;\n" + "+\tif (entry->smbus.read_write != I2C_SMBUS_READ)\n" + "+\t\treturn;\n" + " \n" + "-\tif (read_write != I2C_SMBUS_READ)\n" + "-\t\treturn result;\n" + "-\n" + "-\tswitch(size) {\n" + "+\tswitch(entry->smbus.size) {\n" + " \tcase I2C_SMBUS_BYTE:\n" + "-\t\tdata->byte = msgbuf0[0];\n" + "+\t\tentry->smbus.data->byte = msgbuf0[0];\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_BYTE_DATA:\n" + "-\t\tdata->byte = msgbuf1[0];\n" + "+\t\tentry->smbus.data->byte = msgbuf1[0];\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_WORD_DATA: \n" + " \tcase I2C_SMBUS_PROC_CALL:\n" + "-\t\tdata->word = msgbuf1[0]|(msgbuf1[1] << 8);\n" + "+\t\tentry->smbus.data->word = msgbuf1[0]|(msgbuf1[1] << 8);\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_I2C_BLOCK_DATA:\n" + " \t\t/* fixed at 32 for now */\n" + "-\t\tdata->block[0] = I2C_SMBUS_I2C_BLOCK_MAX;\n" + "+\t\tentry->smbus.data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX;\n" + " \t\tfor (i = 0; i < I2C_SMBUS_I2C_BLOCK_MAX; i++)\n" + "-\t\t\tdata->block[i+1] = msgbuf1[i];\n" + "+\t\t\tentry->smbus.data->block[i+1] = msgbuf1[i];\n" + " \t\tbreak;\n" + " \t}\n" + " \n" + "-\treturn i2c_smbus_complete_entry(adapter, addr, flags,\n" + "-\t\t\t\t\tread_write, command,\n" + "-\t\t\t\t\tsize, data, swpec, partial, result);\n" + "+\tentry->xfer_type = I2C_OP_SMBUS;\n" + "+\ti2c_smbus_complete_entry(adapter, entry);\n" + " }\n" + " \n" + "-static int i2c_smbus_emu_format(struct i2c_adapter *adapter, u16 addr,\n" + "-\t\t\t\tunsigned short flags, char read_write,\n" + "-\t\t\t\tu8 command, int size, \n" + "-\t\t\t\tunion i2c_smbus_data * data,\n" + "-\t\t\t\tstruct i2c_msg *msg)\n" + "+static int i2c_smbus_emu_format(struct i2c_adapter *adapter,\n" + "+\t\t\t\tstruct i2c_op_q_entry * entry)\n" + " {\n" + " \t/* So we need to generate a series of msgs. In the case of\n" + " \t writing, we need to use only one message; when reading, we\n" + " \t need two. We initialize most things with sane defaults, to\n" + " \t keep the code below somewhat simpler. */\n" + "-\tunsigned char *msgbuf0 = msg[0].buf;\n" + "-\tint num = read_write == I2C_SMBUS_READ?2:1;\n" + "+\tunsigned char *msgbuf0 = entry->msgbuf0;\n" + "+\tint num = entry->smbus.read_write == I2C_SMBUS_READ?2:1;\n" + "+\tstruct i2c_msg *msg = entry->msg;\n" + " \tint i;\n" + " \n" + "-\tmsg[0].addr = addr;\n" + "-\tmsg[0].flags = flags;\n" + "+\tentry->i2c.msgs = msg;\n" + "+\tentry->i2c.msgs[0].buf = msgbuf0;\n" + "+\tentry->i2c.msgs[1].buf = entry->msgbuf1;\n" + "+\n" + "+\tmsg[0].addr = entry->smbus.addr;\n" + "+\tmsg[0].flags = entry->smbus.flags;\n" + " \tmsg[0].len = 1;\n" + "-\tmsg[1].addr = addr;\n" + "-\tmsg[1].flags = flags | I2C_M_RD;\n" + "+\tmsg[1].addr = entry->smbus.addr;\n" + "+\tmsg[1].flags = entry->smbus.flags | I2C_M_RD;\n" + " \tmsg[1].len = 0;\n" + " \n" + "-\tmsgbuf0[0] = command;\n" + "-\tswitch(size) {\n" + "+\tmsgbuf0[0] = entry->smbus.command;\n" + "+\tswitch(entry->smbus.size) {\n" + " \tcase I2C_SMBUS_QUICK:\n" + " \t\tmsg[0].len = 0;\n" + " \t\t/* Special case: The read/write field is used as data */\n" + "-\t\tmsg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0;\n" + "+\t\tmsg[0].flags = (entry->smbus.flags |\n" + "+\t\t\t\t((entry->smbus.read_write==I2C_SMBUS_READ)\n" + "+\t\t\t\t ? I2C_M_RD : 0));\n" + " \t\tnum = 1;\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_BYTE:\n" + "-\t\tif (read_write == I2C_SMBUS_READ) {\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_READ) {\n" + " \t\t\t/* Special case: only a read! */\n" + "-\t\t\tmsg[0].flags = I2C_M_RD | flags;\n" + "+\t\t\tmsg[0].flags = I2C_M_RD | entry->smbus.flags;\n" + " \t\t\tnum = 1;\n" + " \t\t}\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_BYTE_DATA:\n" + "-\t\tif (read_write == I2C_SMBUS_READ)\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_READ)\n" + " \t\t\tmsg[1].len = 1;\n" + " \t\telse {\n" + " \t\t\tmsg[0].len = 2;\n" + "-\t\t\tmsgbuf0[1] = data->byte;\n" + "+\t\t\tmsgbuf0[1] = entry->smbus.data->byte;\n" + " \t\t}\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_WORD_DATA:\n" + "-\t\tif (read_write == I2C_SMBUS_READ)\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_READ)\n" + " \t\t\tmsg[1].len = 2;\n" + " \t\telse {\n" + " \t\t\tmsg[0].len=3;\n" + "-\t\t\tmsgbuf0[1] = data->word & 0xff;\n" + "-\t\t\tmsgbuf0[2] = (data->word >> 8) & 0xff;\n" + "+\t\t\tmsgbuf0[1] = entry->smbus.data->word & 0xff;\n" + "+\t\t\tmsgbuf0[2] = (entry->smbus.data->word >> 8) & 0xff;\n" + " \t\t}\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_PROC_CALL:\n" + " \t\tnum = 2; /* Special case */\n" + "-\t\tread_write = I2C_SMBUS_READ;\n" + "+\t\tentry->smbus.read_write = I2C_SMBUS_READ;\n" + " \t\tmsg[0].len = 3;\n" + " \t\tmsg[1].len = 2;\n" + "-\t\tmsgbuf0[1] = data->word & 0xff;\n" + "-\t\tmsgbuf0[2] = (data->word >> 8) & 0xff;\n" + "+\t\tmsgbuf0[1] = entry->smbus.data->word & 0xff;\n" + "+\t\tmsgbuf0[2] = (entry->smbus.data->word >> 8) & 0xff;\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_BLOCK_DATA:\n" + " \tcase I2C_SMBUS_BLOCK_DATA_PEC:\n" + "-\t\tif (read_write == I2C_SMBUS_READ) {\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_READ) {\n" + " \t\t\tdev_err(&adapter->dev, \"Block read not supported \"\n" + " \t\t\t \"under I2C emulation!\\n\");\n" + " \t\t\treturn -1;\n" + " \t\t} else {\n" + "-\t\t\tmsg[0].len = data->block[0] + 2;\n" + "+\t\t\tmsg[0].len = entry->smbus.data->block[0] + 2;\n" + " \t\t\tif (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {\n" + " \t\t\t\tdev_err(&adapter->dev, \"smbus_access called with \"\n" + " \t\t\t\t \"invalid block write size (%d)\\n\",\n" + "-\t\t\t\t data->block[0]);\n" + "+\t\t\t\t entry->smbus.data->block[0]);\n" + " \t\t\t\treturn -1;\n" + " \t\t\t}\n" + "-\t\t\tif(size == I2C_SMBUS_BLOCK_DATA_PEC)\n" + "+\t\t\tif(entry->smbus.size == I2C_SMBUS_BLOCK_DATA_PEC)\n" + " \t\t\t\t(msg[0].len)++;\n" + " \t\t\tfor (i = 1; i <= msg[0].len; i++)\n" + "-\t\t\t\tmsgbuf0[i] = data->block[i-1];\n" + "+\t\t\t\tmsgbuf0[i] = entry->smbus.data->block[i-1];\n" + " \t\t}\n" + " \t\tbreak;\n" + " \tcase I2C_SMBUS_BLOCK_PROC_CALL:\n" + "@@ -1225,26 +1242,30 @@\n" + " \t\t \"under I2C emulation!\\n\");\n" + " \t\treturn -1;\n" + " \tcase I2C_SMBUS_I2C_BLOCK_DATA:\n" + "-\t\tif (read_write == I2C_SMBUS_READ) {\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_READ) {\n" + " \t\t\tmsg[1].len = I2C_SMBUS_I2C_BLOCK_MAX;\n" + " \t\t} else {\n" + "-\t\t\tmsg[0].len = data->block[0] + 1;\n" + "+\t\t\tmsg[0].len = entry->smbus.data->block[0] + 1;\n" + " \t\t\tif (msg[0].len > I2C_SMBUS_I2C_BLOCK_MAX + 1) {\n" + " \t\t\t\tdev_err(&adapter->dev, \"i2c_smbus_xfer_emulated called with \"\n" + " \t\t\t\t \"invalid block write size (%d)\\n\",\n" + "-\t\t\t\t data->block[0]);\n" + "+\t\t\t\t entry->smbus.data->block[0]);\n" + " \t\t\t\treturn -1;\n" + " \t\t\t}\n" + "-\t\t\tfor (i = 1; i <= data->block[0]; i++)\n" + "-\t\t\t\tmsgbuf0[i] = data->block[i];\n" + "+\t\t\tfor (i = 1; i <= entry->smbus.data->block[0]; i++)\n" + "+\t\t\t\tmsgbuf0[i] = entry->smbus.data->block[i];\n" + " \t\t}\n" + " \t\tbreak;\n" + " \tdefault:\n" + " \t\tdev_err(&adapter->dev, \"smbus_access called with invalid size (%d)\\n\",\n" + "-\t\t size);\n" + "+\t\t entry->smbus.size);\n" + " \t\treturn -1;\n" + " \t}\n" + " \n" + "+\tentry->xfer_type = I2C_OP_I2C;\n" + "+\tentry->i2c.msgs = msg;\n" + "+\tentry->i2c.num = num;\n" + "+\tentry->complete = i2c_smbus_emu_complete;\n" + " \treturn 0;\n" + " }\n" + " \n" + "@@ -1253,46 +1274,42 @@\n" + " char read_write, u8 command, int size, \n" + " union i2c_smbus_data * data)\n" + " {\n" + "+\tstruct i2c_op_q_entry *entry;\n" + " \ts32 res;\n" + "-\tint swpec = 0;\n" + "-\tu8 partial = 0;\n" + " \tstruct i2c_algorithm *algo = adapter->algo;\n" + " \n" + " \n" + "-\ti2c_smbus_format_entry(adapter, addr, &flags,\n" + "-\t\t\t read_write, command,\n" + "-\t\t\t &size, data, &swpec, &partial);\n" + "+\tentry = kmalloc(sizeof(*entry), GFP_KERNEL);\n" + "+\tif (!entry)\n" + "+\t return -ENOMEM;\n" + "+\n" + "+\tentry->xfer_type = I2C_OP_SMBUS;\n" + "+\tentry->smbus.addr = addr;\n" + "+\tentry->smbus.flags = flags;\n" + "+\tentry->smbus.read_write = read_write;\n" + "+\tentry->smbus.command = command;\n" + "+\tentry->smbus.size = size;\n" + "+\tentry->smbus.data = data;\n" + "+\n" + "+\ti2c_smbus_format_entry(adapter, entry);\n" + " \n" + " \tif (algo->smbus_xfer) {\n" + " \t\tdown(&adapter->bus_lock);\n" + "-\t\tres = adapter->algo->smbus_xfer(adapter, addr, flags,\n" + "-\t\t\t\t\t\tread_write, command,\n" + "-\t\t\t\t\t\tsize, data);\n" + "+\t\tentry->result = adapter->algo->smbus_xfer\n" + "+\t\t (adapter, entry->smbus.addr, entry->smbus.flags,\n" + "+\t\t entry->smbus.read_write, entry->smbus.command,\n" + "+\t\t entry->smbus.size, entry->smbus.data);\n" + " \t\tup(&adapter->bus_lock);\n" + "-\t\tres = i2c_smbus_complete_entry(adapter, addr, flags,\n" + "-\t\t\t\t\t read_write, command,\n" + "-\t\t\t\t\t size, data, swpec, partial,\n" + "-\t\t\t\t\t res);\n" + "+\t\tif (entry->complete)\n" + "+\t\t entry->complete(adapter, entry);\n" + " \t} else {\n" + "-\t\tunsigned char msgbuf0[34];\n" + "-\t\tunsigned char msgbuf1[34];\n" + "-\t\tstruct i2c_msg msg[2];\n" + "-\n" + "-\t\tmsg[0].buf = msgbuf0;\n" + "-\t\tmsg[1].buf = msgbuf1;\n" + "-\t\tif (i2c_smbus_emu_format(adapter, addr, flags,\n" + "-\t\t\t\t\t read_write, command,\n" + "-\t\t\t\t\t size, data, msg))\n" + "-\t\t\tres = -EINVAL;\n" + "-\t\telse {\n" + "-\t\t\tres = i2c_transfer(adapter, msg, 2);\n" + "-\t\t\tres = i2c_smbus_emu_complete(adapter, addr, flags,\n" + "-\t\t\t\t\t\t read_write, command,\n" + "-\t\t\t\t\t\t size, data, msg,\n" + "-\t\t\t\t\t\t swpec, partial,\n" + "-\t\t\t\t\t\t res);\n" + "-\t\t}\n" + "+\t\tif (i2c_smbus_emu_format(adapter, entry))\n" + "+\t\t\tentry->result = -EINVAL;\n" + "+\t\telse\n" + "+\t\t\ti2c_transfer_entry(adapter, entry);\n" + " \t}\n" + "+\tres = entry->result;\n" + "+\tkfree(entry);\n" + " \treturn res;\n" + " }\n" + " \n" + "Index: linux-2.6.11-mm1/include/linux/i2c.h\n" + "===================================================================\n" + "--- linux-2.6.11-mm1.orig/include/linux/i2c.h\n" + "+++ linux-2.6.11-mm1/include/linux/i2c.h\n" + "@@ -32,7 +32,10 @@\n" + " #include <linux/types.h>\n" + " #include <linux/i2c-id.h>\n" + " #include <linux/device.h>\t/* for struct device */\n" + "+#include <linux/completion.h>\n" + "+#include <linux/kref.h>\n" + " #include <asm/semaphore.h>\n" + "+#include <asm/atomic.h>\n" + " \n" + " /* --- General options ------------------------------------------------\t*/\n" + " \n" + "@@ -43,6 +46,7 @@\n" + " struct i2c_driver;\n" + " struct i2c_client_address_data;\n" + " union i2c_smbus_data;\n" + "+struct i2c_op_q_entry;\n" + " \n" + " /*\n" + " * The master routines are the ones normally used to transmit data to devices\n" + "@@ -392,6 +396,92 @@\n" + " \t__u8 *buf;\t\t/* pointer to msg data\t\t\t*/\n" + " };\n" + " \n" + "+/*\n" + "+ * Hold a queue of I2C operations to perform, and used to pass data\n" + "+ * around.\n" + "+ */\n" + "+typedef void (*i2c_op_done_cb)(struct i2c_op_q_entry *entry);\n" + "+\n" + "+#define I2C_OP_I2C\t0\n" + "+#define I2C_OP_SMBUS\t1\n" + "+struct i2c_op_q_entry {\n" + "+\t/* The result will be set to the result of the operation when\n" + "+\t it completes. */\n" + "+\ts32 result;\n" + "+\n" + "+\t/**************************************************************/\n" + "+\t/* Public interface. The user should set these up (and the\n" + "+\t proper structure below). */\n" + "+\tint xfer_type;\n" + "+\n" + "+\t/* Handler may be called from interrupt context, so be\n" + "+\t careful. */\n" + "+\ti2c_op_done_cb handler;\n" + "+\tvoid *handler_data;\n" + "+\n" + "+\t/* Note that this is not a union because an smbus operation\n" + "+\t may be converted into an i2c operation (thus both\n" + "+\t structures will be used). The data in these may be changd\n" + "+\t by the driver. */\n" + "+\tstruct {\n" + "+\t\tstruct i2c_msg *msgs;\n" + "+\t\tint num;\n" + "+\t} i2c;\n" + "+\tstruct {\n" + "+\t\t/* Addr and flags are filled in by the non-blocking\n" + "+\t\t send routine that takes a client. */\n" + "+\t\tu16 addr;\n" + "+\t\tunsigned short flags;\n" + "+\n" + "+\t\tchar read_write;\n" + "+\t\tu8 command;\n" + "+\n" + "+\t\t/* Note that the size is *not* the length of the data.\n" + "+\t\t It is the transaction type, like I2C_SMBUS_QUICK\n" + "+\t\t and the ones after that below. If this is a block\n" + "+\t\t transaction, the length of the rest of the data is\n" + "+\t\t in the first byte of the data, for both transmit\n" + "+\t\t and receive. */\n" + "+\t\tint size;\n" + "+\t\tunion i2c_smbus_data *data;\n" + "+\t} smbus;\n" + "+\n" + "+\t/**************************************************************/\n" + "+\t/* For use by the bus interface. The bus interface sets the\n" + "+\t timeout in microseconds until the next poll operation.\n" + "+\t This *must* be set in the start operation. The time_left\n" + "+\t and data can be used for anything the bus interface likes.\n" + "+\t data will be set to NULL before being started so the bus\n" + "+\t interface can use that to tell if it has been set up\n" + "+\t yet. */\n" + "+\tunsigned int call_again_us;\n" + "+\tlong time_left;\n" + "+\tvoid *data;\n" + "+\n" + "+\t/**************************************************************/\n" + "+\t/* Internals */\n" + "+\tstruct list_head link;\n" + "+\tstruct completion *start;\n" + "+\tatomic_t completed;\n" + "+\tunsigned int started : 1;\n" + "+\tunsigned int use_timer : 1;\n" + "+\tu8 swpec;\n" + "+\tu8 partial;\n" + "+\tvoid (*complete)(struct i2c_adapter *adap,\n" + "+\t\t\t struct i2c_op_q_entry *entry);\n" + "+\n" + "+\t/* It's wierd, but we use a usecount to track if an q entry is\n" + "+\t in use and when it should be reported back to the user. */\n" + "+\tstruct kref usecount;\n" + "+\n" + "+\t/* These are here for SMBus emulation over I2C. I don't like\n" + "+\t them taking this much room in the data structure, but they\n" + "+\t need to be available in this case. */\n" + "+\tunsigned char msgbuf0[34];\n" + "+\tunsigned char msgbuf1[34];\n" + "+\tstruct i2c_msg msg[2];\n" + "+};\n" + "+\n" + " /* To determine what functionality is present */\n" + " \n" + " #define I2C_FUNC_I2C\t\t\t0x00000001" -f2a6630276df15f07bd3b937a8a0fb610ab7708fb96ac43905edbcc76ef7d38b +0fb0b4f2b1d1a34b2a209149ad268b57bf3a9a2a0d51c56e5bc0df12f550b8f8
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.