diff for duplicates of <41FA5633.2050202@acm.org> diff --git a/a/1.txt b/N1/1.txt index e975541..f41b7ff 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -5,781 +5,3 @@ Like the core I2C changes, this is mostly breaking the functions into smaller pieces and calling them from the appropriate places. -Corey --------------- next part -------------- -Index: linux-2.6.11-rc2/drivers/i2c/busses/i2c-i801.c -=================================--- linux-2.6.11-rc2.orig/drivers/i2c/busses/i2c-i801.c 2005-01-27 13:09:12.000000000 -0600 -+++ linux-2.6.11-rc2/drivers/i2c/busses/i2c-i801.c 2005-01-27 13:46:23.000000000 -0600 -@@ -79,7 +79,8 @@ - #define SMBHSTCFG_I2C_EN 4 - - /* Other settings */ --#define MAX_TIMEOUT 100 -+#define MAX_TIMEOUT_US 100000 -+#define RETRY_TIME_US 500 /* Retry minimum is 500us */ - #define ENABLE_INT9 0 /* set to 0x01 to enable - untested */ - - /* I801 command constants */ -@@ -105,21 +106,31 @@ - "Forcibly enable the I801 at the given address. " - "EXTREMELY DANGEROUS!"); - --static int i801_transaction(void); --static int i801_block_transaction(union i2c_smbus_data *data, -- char read_write, int command); -- - static unsigned short i801_smba; - static struct pci_dev *I801_dev; - static int isich4; - -+struct i801_i2c_data -+{ -+ int i; -+ int len; -+ unsigned char hostc; -+ int block; -+ int hwpec; -+ int xact; -+ int hststs; -+ int wait_intr; -+ int finished; -+}; -+struct i801_i2c_data i801_data; -+ - static int i801_setup(struct pci_dev *dev) - { - int error_return = 0; - unsigned char temp; - - /* Note: we keep on searching until we have found 'function 3' */ -- if(PCI_FUNC(dev->devfn) != 3) -+ if (PCI_FUNC(dev->devfn) != 3) - return -ENODEV; - - I801_dev = dev; -@@ -136,7 +147,7 @@ - } else { - pci_read_config_word(I801_dev, SMBBA, &i801_smba); - i801_smba &= 0xfff0; -- if(i801_smba = 0) { -+ if (i801_smba = 0) { - dev_err(&dev->dev, "SMB base address uninitialized" - "- upgrade BIOS or use force_addr=0xaddr\n"); - return -ENODEV; -@@ -180,12 +191,93 @@ - return error_return; - } - --static int i801_transaction(void) -+static void i801_check_hststs(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) -+{ -+ if (d->hststs & 0x10) { -+ entry->result = -EIO; -+ dev_dbg(&I801_dev->dev, -+ "Error: Failed bus transaction\n"); -+ } else if (d->hststs & 0x08) { -+ entry->result = -EIO; -+ dev_err(&I801_dev->dev, "Bus collision!\n"); -+ /* Clock stops and slave is stuck in mid-transmission */ -+ } else if (d->hststs & 0x04) { -+ entry->result = -EIO; -+ dev_dbg(&I801_dev->dev, "Error: no response!\n"); -+ } -+} -+ -+static void i801_finish(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) -+{ -+ d->finished = 1; -+ -+#ifdef HAVE_PEC -+ if (isich4 && d->hwpec) { -+ if (entry->smbus.size != I2C_SMBUS_QUICK && -+ entry->smbus.size != I2C_SMBUS_I2C_BLOCK_DATA) -+ outb_p(0, SMBAUXCTL); -+ } -+#endif -+ -+ if (d->block || (entry->result < 0) || -+ ((entry->smbus.read_write = I2C_SMBUS_WRITE) -+ || (d->xact = I801_QUICK))) -+ return; -+ -+ switch (d->xact & 0x7f) { -+ case I801_BYTE: /* Result put in SMBHSTDAT0 */ -+ case I801_BYTE_DATA: -+ entry->smbus.data->byte = inb_p(SMBHSTDAT0); -+ break; -+ case I801_WORD_DATA: -+ entry->smbus.data->word = inb_p(SMBHSTDAT0) -+ + (inb_p(SMBHSTDAT1) << 8); -+ break; -+ } -+} -+ -+static void i801_transaction_final_check(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) -+{ -+ i801_check_hststs(adap, entry, d); -+ -+ if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) -+ outb_p(inb(SMBHSTSTS), SMBHSTSTS); -+ -+ if ((d->hststs = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { -+ dev_dbg(&I801_dev->dev, "Failed reset at end of transaction" -+ "(%02x)\n", d->hststs); -+ } -+ dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " -+ "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), -+ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), -+ inb_p(SMBHSTDAT1)); -+} -+ -+static void i801_transaction_poll(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) - { -- int temp; -- int result = 0; -- int timeout = 0; -+ d->hststs = inb_p(SMBHSTSTS); -+ if (!(d->hststs & 0x01)) { -+ i801_transaction_final_check(adap, entry, d); -+ i801_finish(adap, entry, d); -+ } else if (entry->time_left <= 0) { -+ dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); -+ entry->result = -EIO; -+ i801_transaction_final_check(adap, entry, d); -+ } -+} - -+static void i801_transaction_start(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) -+{ - dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x," - "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), - inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), -@@ -193,331 +285,347 @@ - - /* Make sure the SMBus host is ready to start transmitting */ - /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ -- if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { -+ if ((d->hststs = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { - dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting... \n", -- temp); -- outb_p(temp, SMBHSTSTS); -- if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { -- dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp); -- return -1; -+ d->hststs); -+ outb_p(d->hststs, SMBHSTSTS); -+ if ((d->hststs = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { -+ dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", d->hststs); -+ entry->result = -EIO; -+ return; - } else { - dev_dbg(&I801_dev->dev, "Successfull!\n"); - } - } - - outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); -+} - -- /* We will always wait for a fraction of a second! */ -- do { -- msleep(1); -- temp = inb_p(SMBHSTSTS); -- } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); -- -- /* If the SMBus is still busy, we give up */ -- if (timeout >= MAX_TIMEOUT) { -- dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); -- result = -1; -+static void i801_block_finish(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) -+{ -+ if (entry->smbus.command = I2C_SMBUS_I2C_BLOCK_DATA) { -+ /* restore saved configuration register value */ -+ pci_write_config_byte(I801_dev, SMBHSTCFG, d->hostc); - } - -- if (temp & 0x10) { -- result = -1; -- dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); -- } -+ i801_finish(adap, entry, d); -+} - -- if (temp & 0x08) { -- result = -1; -- dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked " -- "until next hard reset. (sorry!)\n"); -- /* Clock stops and slave is stuck in mid-transmission */ -- } -+static void i801_block_poll_wait_intr(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) -+{ -+#ifdef HAVE_PEC -+ if (entry->result >= 0 && -+ isich4 && -+ entry->smbus.command = I2C_SMBUS_BLOCK_DATA_PEC) -+ { -+ /* wait for INTR bit as advised by Intel */ -+ d->hststs = inb_p(SMBHSTSTS); -+ if (d->hststs & 0x02) { -+ outb_p(d->hststs, SMBHSTSTS); -+ i801_block_finish(adap, entry, d); -+ } else if (entry->time_left <= 0) { -+ /* Timed out */ -+ outb_p(d->hststs, SMBHSTSTS); -+ entry->result = -EIO; -+ dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); -+ } -+ } else -+#endif -+ i801_block_finish(adap, entry, d); -+} - -- if (temp & 0x04) { -- result = -1; -- dev_dbg(&I801_dev->dev, "Error: no response!\n"); -+static void i801_block_next_byte(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) -+{ -+ int smbcmd; -+ unsigned char errmask; -+ -+ if (d->i > d->len) { -+ d->wait_intr = 1; -+ entry->time_left = MAX_TIMEOUT_US; -+ i801_block_poll_wait_intr(adap, entry, d); -+ return; - } - -- if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) -- outb_p(inb(SMBHSTSTS), SMBHSTSTS); -+ if (d->i = d->len && entry->smbus.read_write = I2C_SMBUS_READ) -+ smbcmd = I801_BLOCK_LAST; -+ else -+ smbcmd = I801_BLOCK_DATA; -+ outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); - -- if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { -- dev_dbg(&I801_dev->dev, "Failed reset at end of transaction" -- "(%02x)\n", temp); -+ dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, " -+ "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", d->i, -+ inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), -+ inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); -+ -+ /* Make sure the SMBus host is ready to start transmitting */ -+ d->hststs = inb_p(SMBHSTSTS); -+ if (d->i = 1) { -+ /* Erronenous conditions before transaction: -+ * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ -+ errmask=0x9f; -+ } else { -+ /* Erronenous conditions during transaction: -+ * Failed, Bus_Err, Dev_Err, Intr */ -+ errmask=0x1e; -+ } -+ if (d->hststs & errmask) { -+ dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " -+ "Resetting... \n", d->hststs); -+ outb_p(d->hststs, SMBHSTSTS); -+ if (((d->hststs = inb_p(SMBHSTSTS)) & errmask) != 0x00) { -+ dev_err(&I801_dev->dev, -+ "Reset failed! (%02x)\n", d->hststs); -+ entry->result = -EIO; -+ return; -+ } -+ if (d->i != 1) { -+ /* if die in middle of block transaction, fail */ -+ entry->result = -EIO; -+ return; -+ } - } -- dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " -- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), -- inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), -- inb_p(SMBHSTDAT1)); -- return result; -+ -+ if (d->i = 1) -+ outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); - } - --/* All-inclusive block transaction function */ --static int i801_block_transaction(union i2c_smbus_data *data, char read_write, -- int command) -+/* Called after a timeout. This checks the result of the -+ transaction */ -+static void i801_block_poll(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) - { -- int i, len; -- int smbcmd; -- int temp; -- int result = 0; -- int timeout; -- unsigned char hostc, errmask; -+ d->hststs = inb_p(SMBHSTSTS); -+ if (!(d->hststs & 0x80)) { -+ /* Not ready yet */ -+ if (entry->time_left <= 0) { -+ dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); -+ entry->result = -EIO; -+ } -+ return; -+ } - -- if (command = I2C_SMBUS_I2C_BLOCK_DATA) { -- if (read_write = I2C_SMBUS_WRITE) { -+ i801_check_hststs(adap, entry, d); -+ if (entry->result) -+ return; -+ -+ if (d->i = 1 && entry->smbus.read_write = I2C_SMBUS_READ) { -+ d->len = inb_p(SMBHSTDAT0); -+ if (d->len < 1) -+ d->len = 1; -+ if (d->len > 32) -+ d->len = 32; -+ entry->smbus.data->block[0] = d->len; -+ } -+ -+ /* Retrieve/store value in SMBBLKDAT */ -+ if (entry->smbus.read_write = I2C_SMBUS_READ) -+ entry->smbus.data->block[d->i] = inb_p(SMBBLKDAT); -+ if (entry->smbus.read_write = I2C_SMBUS_WRITE && d->i+1 <= d->len) -+ outb_p(entry->smbus.data->block[d->i+1], SMBBLKDAT); -+ if ((d->hststs & 0x9e) != 0x00) -+ outb_p(d->hststs, SMBHSTSTS); /* signals SMBBLKDAT ready */ -+ -+ if ((d->hststs = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { -+ dev_dbg(&I801_dev->dev, -+ "Bad status (%02x) at end of transaction\n", -+ d->hststs); -+ } -+ dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, " -+ "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", d->i, -+ inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), -+ inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); -+ -+ d->i++; -+ i801_block_next_byte(adap, entry, d); -+} -+ -+static void i801_block_start(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ struct i801_i2c_data *d) -+{ -+ if (entry->smbus.command = I2C_SMBUS_I2C_BLOCK_DATA) { -+ if (entry->smbus.read_write = I2C_SMBUS_WRITE) { - /* set I2C_EN bit in configuration register */ -- pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc); -+ pci_read_config_byte(I801_dev, SMBHSTCFG, &d->hostc); - pci_write_config_byte(I801_dev, SMBHSTCFG, -- hostc | SMBHSTCFG_I2C_EN); -+ d->hostc | SMBHSTCFG_I2C_EN); - } else { - dev_err(&I801_dev->dev, - "I2C_SMBUS_I2C_BLOCK_READ not DB!\n"); -- return -1; -+ entry->result = -EINVAL; -+ return; - } - } - -- if (read_write = I2C_SMBUS_WRITE) { -- len = data->block[0]; -- if (len < 1) -- len = 1; -- if (len > 32) -- len = 32; -- outb_p(len, SMBHSTDAT0); -- outb_p(data->block[1], SMBBLKDAT); -+ if (entry->smbus.read_write = I2C_SMBUS_WRITE) { -+ d->len = entry->smbus.data->block[0]; -+ if (d->len < 1) -+ d->len = 1; -+ if (d->len > 32) -+ d->len = 32; -+ outb_p(d->len, SMBHSTDAT0); -+ outb_p(entry->smbus.data->block[1], SMBBLKDAT); - } else { -- len = 32; /* max for reads */ -+ d->len = 32; /* max for reads */ - } - -- if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) { -+ if(isich4 && entry->smbus.command != I2C_SMBUS_I2C_BLOCK_DATA) { - /* set 32 byte buffer */ - } - -- for (i = 1; i <= len; i++) { -- if (i = len && read_write = I2C_SMBUS_READ) -- smbcmd = I801_BLOCK_LAST; -- else -- smbcmd = I801_BLOCK_DATA; -- outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); -- -- dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, " -- "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, -- inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), -- inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); -- -- /* Make sure the SMBus host is ready to start transmitting */ -- temp = inb_p(SMBHSTSTS); -- if (i = 1) { -- /* Erronenous conditions before transaction: -- * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ -- errmask=0x9f; -- } else { -- /* Erronenous conditions during transaction: -- * Failed, Bus_Err, Dev_Err, Intr */ -- errmask=0x1e; -- } -- if (temp & errmask) { -- dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " -- "Resetting... \n", temp); -- outb_p(temp, SMBHSTSTS); -- if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { -- dev_err(&I801_dev->dev, -- "Reset failed! (%02x)\n", temp); -- result = -1; -- goto END; -- } -- if (i != 1) { -- /* if die in middle of block transaction, fail */ -- result = -1; -- goto END; -- } -- } -+ d->i = 1; -+ i801_block_next_byte(adap, entry, d); -+} - -- if (i = 1) -- outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); -+/* General poll routine. Called periodically by the i2c code. */ -+static void i801_poll(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry, -+ unsigned int us_since_last_poll) -+{ -+ struct i801_i2c_data *d = entry->data; - -- /* We will always wait for a fraction of a second! */ -- timeout = 0; -- do { -- temp = inb_p(SMBHSTSTS); -- msleep(1); -- } -- while ((!(temp & 0x80)) -- && (timeout++ < MAX_TIMEOUT)); -+ dev_dbg(&I801_dev->dev, "Poll call for %p %p at %ld\n", adap, entry, -+ jiffies); - -- /* If the SMBus is still busy, we give up */ -- if (timeout >= MAX_TIMEOUT) { -- result = -1; -- dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); -- } -+ if (!d) -+ /* The entry hasn't been started yet. */ -+ return; - -- if (temp & 0x10) { -- result = -1; -- dev_dbg(&I801_dev->dev, -- "Error: Failed bus transaction\n"); -- } else if (temp & 0x08) { -- result = -1; -- dev_err(&I801_dev->dev, "Bus collision!\n"); -- } else if (temp & 0x04) { -- result = -1; -- dev_dbg(&I801_dev->dev, "Error: no response!\n"); -- } -+ /* Decrement timeout */ -+ entry->time_left -= us_since_last_poll; - -- if (i = 1 && read_write = I2C_SMBUS_READ) { -- len = inb_p(SMBHSTDAT0); -- if (len < 1) -- len = 1; -- if (len > 32) -- len = 32; -- data->block[0] = len; -- } -+ /* Wait a jiffie normally. */ -+ entry->call_again_us = RETRY_TIME_US; - -- /* Retrieve/store value in SMBBLKDAT */ -- if (read_write = I2C_SMBUS_READ) -- data->block[i] = inb_p(SMBBLKDAT); -- if (read_write = I2C_SMBUS_WRITE && i+1 <= len) -- outb_p(data->block[i+1], SMBBLKDAT); -- if ((temp & 0x9e) != 0x00) -- outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */ -- -- if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { -- dev_dbg(&I801_dev->dev, -- "Bad status (%02x) at end of transaction\n", -- temp); -+ if (d->block) { -+ if (d->wait_intr) { -+ i801_block_poll_wait_intr(adap, entry, d); -+ } else { -+ i801_block_poll(adap, entry, d); - } -- dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, " -- "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, -- inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), -- inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); -- -- if (result < 0) -- goto END; -+ if (entry->result < 0) -+ /* Error, finish the transaction */ -+ i801_block_finish(adap, entry, d); -+ } else { -+ i801_transaction_poll(adap, entry, d); -+ if (entry->result < 0) -+ /* Error, finish the transaction */ -+ i801_finish(adap, entry, d); - } - --#ifdef HAVE_PEC -- if(isich4 && command = I2C_SMBUS_BLOCK_DATA_PEC) { -- /* wait for INTR bit as advised by Intel */ -- timeout = 0; -- do { -- temp = inb_p(SMBHSTSTS); -- msleep(1); -- } while ((!(temp & 0x02)) -- && (timeout++ < MAX_TIMEOUT)); -- -- if (timeout >= MAX_TIMEOUT) { -- dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); -- } -- outb_p(temp, SMBHSTSTS); -- } --#endif -- result = 0; --END: -- if (command = I2C_SMBUS_I2C_BLOCK_DATA) { -- /* restore saved configuration register value */ -- pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); -- } -- return result; -+ if (d->finished) -+ i2c_op_done(adap, entry); - } - --/* Return -1 on error. */ --static s32 i801_access(struct i2c_adapter * adap, u16 addr, -- unsigned short flags, char read_write, u8 command, -- int size, union i2c_smbus_data * data) -+/* Start a general SMBUS transaction on the i801. Figure out what -+ kind of transaction it is, set it up, and start it. */ -+static void i801_start(struct i2c_adapter *adap, -+ struct i2c_op_q_entry *entry) - { -- int hwpec = 0; -- int block = 0; -- int ret, xact = 0; -+ struct i801_i2c_data *d = adap->algo_data; -+ -+ d->block = 0; -+ d->hwpec = 0; -+ d->xact = 0; -+ d->wait_intr = 0; -+ d->finished = 0; - - #ifdef HAVE_PEC -- if(isich4) -- hwpec = (flags & I2C_CLIENT_PEC) != 0; -+ if (isich4) -+ d->hwpec = (entry->smbus.flags & I2C_CLIENT_PEC) != 0; - #endif - -- switch (size) { -+ switch (entry->smbus.size) { - case I2C_SMBUS_QUICK: -- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), -+ outb_p(((entry->smbus.addr & 0x7f) << 1) -+ | (entry->smbus.read_write & 0x01), - SMBHSTADD); -- xact = I801_QUICK; -+ d->xact = I801_QUICK; - break; - case I2C_SMBUS_BYTE: -- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), -+ outb_p(((entry->smbus.addr & 0x7f) << 1) -+ | (entry->smbus.read_write & 0x01), - SMBHSTADD); -- if (read_write = I2C_SMBUS_WRITE) -- outb_p(command, SMBHSTCMD); -- xact = I801_BYTE; -+ if (entry->smbus.read_write = I2C_SMBUS_WRITE) -+ outb_p(entry->smbus.command, SMBHSTCMD); -+ d->xact = I801_BYTE; - break; - case I2C_SMBUS_BYTE_DATA: -- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), -+ outb_p(((entry->smbus.addr & 0x7f) << 1) -+ | (entry->smbus.read_write & 0x01), - SMBHSTADD); -- outb_p(command, SMBHSTCMD); -- if (read_write = I2C_SMBUS_WRITE) -- outb_p(data->byte, SMBHSTDAT0); -- xact = I801_BYTE_DATA; -+ outb_p(entry->smbus.command, SMBHSTCMD); -+ if (entry->smbus.read_write = I2C_SMBUS_WRITE) -+ outb_p(entry->smbus.data->byte, SMBHSTDAT0); -+ d->xact = I801_BYTE_DATA; - break; - case I2C_SMBUS_WORD_DATA: -- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), -+ outb_p(((entry->smbus.addr & 0x7f) << 1) -+ | (entry->smbus.read_write & 0x01), - SMBHSTADD); -- outb_p(command, SMBHSTCMD); -- if (read_write = I2C_SMBUS_WRITE) { -- outb_p(data->word & 0xff, SMBHSTDAT0); -- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); -+ outb_p(entry->smbus.command, SMBHSTCMD); -+ if (entry->smbus.read_write = I2C_SMBUS_WRITE) { -+ outb_p(entry->smbus.data->word & 0xff, SMBHSTDAT0); -+ outb_p((entry->smbus.data->word & 0xff00) >> 8, -+ SMBHSTDAT1); - } -- xact = I801_WORD_DATA; -+ d->xact = I801_WORD_DATA; - break; - case I2C_SMBUS_BLOCK_DATA: - case I2C_SMBUS_I2C_BLOCK_DATA: - #ifdef HAVE_PEC - case I2C_SMBUS_BLOCK_DATA_PEC: -- if(hwpec && size = I2C_SMBUS_BLOCK_DATA) -- size = I2C_SMBUS_BLOCK_DATA_PEC; -+ if (d->hwpec && entry->smbus.size = I2C_SMBUS_BLOCK_DATA) -+ entry->smbus.size = I2C_SMBUS_BLOCK_DATA_PEC; - #endif -- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), -+ outb_p(((entry->smbus.addr & 0x7f) << 1) -+ | (entry->smbus.read_write & 0x01), - SMBHSTADD); -- outb_p(command, SMBHSTCMD); -- block = 1; -+ outb_p(entry->smbus.command, SMBHSTCMD); -+ d->block = 1; - break; - case I2C_SMBUS_PROC_CALL: - default: -- dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); -- return -1; -+ dev_err(&I801_dev->dev, "Unsupported transaction %d\n", -+ entry->smbus.size); -+ entry->result = -EINVAL; -+ return; - } - - #ifdef HAVE_PEC -- if(isich4 && hwpec) { -- if(size != I2C_SMBUS_QUICK && -- size != I2C_SMBUS_I2C_BLOCK_DATA) -+ if (isich4 && d->hwpec) { -+ if (entry->smbus.size != I2C_SMBUS_QUICK && -+ entry->smbus.size != I2C_SMBUS_I2C_BLOCK_DATA) - outb_p(1, SMBAUXCTL); /* enable HW PEC */ - } - #endif -- if(block) -- ret = i801_block_transaction(data, read_write, size); -- else { -- outb_p(xact | ENABLE_INT9, SMBHSTCNT); -- ret = i801_transaction(); -- } -- --#ifdef HAVE_PEC -- if(isich4 && hwpec) { -- if(size != I2C_SMBUS_QUICK && -- size != I2C_SMBUS_I2C_BLOCK_DATA) -- outb_p(0, SMBAUXCTL); -+ if (d->block) { -+ i801_block_start(adap, entry, d); -+ if (entry->result < 0) -+ /* Error, finish the transaction */ -+ i801_block_finish(adap, entry, d); -+ } else { -+ outb_p(d->xact | ENABLE_INT9, SMBHSTCNT); -+ i801_transaction_start(adap, entry, d); -+ if (entry->result < 0) -+ /* Error, finish the transaction */ -+ i801_finish(adap, entry, d); - } --#endif - -- if(block) -- return ret; -- if(ret) -- return -1; -- if ((read_write = I2C_SMBUS_WRITE) || (xact = I801_QUICK)) -- return 0; -+ entry->call_again_us = RETRY_TIME_US; -+ entry->time_left = MAX_TIMEOUT_US; - -- switch (xact & 0x7f) { -- case I801_BYTE: /* Result put in SMBHSTDAT0 */ -- case I801_BYTE_DATA: -- data->byte = inb_p(SMBHSTDAT0); -- break; -- case I801_WORD_DATA: -- data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); -- break; -- } -- return 0; -+ if (d->finished) -+ i2c_op_done(adap, entry); -+ else -+ entry->data = d; - } - - -@@ -537,7 +645,8 @@ - static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", - .id = I2C_ALGO_SMBUS, -- .smbus_xfer = i801_access, -+ .smbus_start = i801_start, -+ .poll = i801_poll, - .functionality = i801_func, - }; - -@@ -545,6 +654,7 @@ - .owner = THIS_MODULE, - .class = I2C_CLASS_HWMON, - .algo = &smbus_algorithm, -+ .algo_data = &i801_data, - .name = "unset", - }; - -@@ -563,7 +673,8 @@ - - MODULE_DEVICE_TABLE (pci, i801_ids); - --static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) -+static int __devinit i801_probe(struct pci_dev *dev, -+ const struct pci_device_id *id) - { - - if (i801_setup(dev)) { diff --git a/N1/2.hdr b/N1/2.hdr new file mode 100644 index 0000000..7b06c2c --- /dev/null +++ b/N1/2.hdr @@ -0,0 +1,5 @@ +Content-Type: text/plain; + name="i2c_async_i801.diff" +Content-Transfer-Encoding: 7bit +Content-Disposition: inline; + filename="i2c_async_i801.diff" diff --git a/N1/2.txt b/N1/2.txt new file mode 100644 index 0000000..6f3604c --- /dev/null +++ b/N1/2.txt @@ -0,0 +1,778 @@ +Index: linux-2.6.11-rc2/drivers/i2c/busses/i2c-i801.c +=================================================================== +--- linux-2.6.11-rc2.orig/drivers/i2c/busses/i2c-i801.c 2005-01-27 13:09:12.000000000 -0600 ++++ linux-2.6.11-rc2/drivers/i2c/busses/i2c-i801.c 2005-01-27 13:46:23.000000000 -0600 +@@ -79,7 +79,8 @@ + #define SMBHSTCFG_I2C_EN 4 + + /* Other settings */ +-#define MAX_TIMEOUT 100 ++#define MAX_TIMEOUT_US 100000 ++#define RETRY_TIME_US 500 /* Retry minimum is 500us */ + #define ENABLE_INT9 0 /* set to 0x01 to enable - untested */ + + /* I801 command constants */ +@@ -105,21 +106,31 @@ + "Forcibly enable the I801 at the given address. " + "EXTREMELY DANGEROUS!"); + +-static int i801_transaction(void); +-static int i801_block_transaction(union i2c_smbus_data *data, +- char read_write, int command); +- + static unsigned short i801_smba; + static struct pci_dev *I801_dev; + static int isich4; + ++struct i801_i2c_data ++{ ++ int i; ++ int len; ++ unsigned char hostc; ++ int block; ++ int hwpec; ++ int xact; ++ int hststs; ++ int wait_intr; ++ int finished; ++}; ++struct i801_i2c_data i801_data; ++ + static int i801_setup(struct pci_dev *dev) + { + int error_return = 0; + unsigned char temp; + + /* Note: we keep on searching until we have found 'function 3' */ +- if(PCI_FUNC(dev->devfn) != 3) ++ if (PCI_FUNC(dev->devfn) != 3) + return -ENODEV; + + I801_dev = dev; +@@ -136,7 +147,7 @@ + } else { + pci_read_config_word(I801_dev, SMBBA, &i801_smba); + i801_smba &= 0xfff0; +- if(i801_smba == 0) { ++ if (i801_smba == 0) { + dev_err(&dev->dev, "SMB base address uninitialized" + "- upgrade BIOS or use force_addr=0xaddr\n"); + return -ENODEV; +@@ -180,12 +191,93 @@ + return error_return; + } + +-static int i801_transaction(void) ++static void i801_check_hststs(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) ++{ ++ if (d->hststs & 0x10) { ++ entry->result = -EIO; ++ dev_dbg(&I801_dev->dev, ++ "Error: Failed bus transaction\n"); ++ } else if (d->hststs & 0x08) { ++ entry->result = -EIO; ++ dev_err(&I801_dev->dev, "Bus collision!\n"); ++ /* Clock stops and slave is stuck in mid-transmission */ ++ } else if (d->hststs & 0x04) { ++ entry->result = -EIO; ++ dev_dbg(&I801_dev->dev, "Error: no response!\n"); ++ } ++} ++ ++static void i801_finish(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) ++{ ++ d->finished = 1; ++ ++#ifdef HAVE_PEC ++ if (isich4 && d->hwpec) { ++ if (entry->smbus.size != I2C_SMBUS_QUICK && ++ entry->smbus.size != I2C_SMBUS_I2C_BLOCK_DATA) ++ outb_p(0, SMBAUXCTL); ++ } ++#endif ++ ++ if (d->block || (entry->result < 0) || ++ ((entry->smbus.read_write == I2C_SMBUS_WRITE) ++ || (d->xact == I801_QUICK))) ++ return; ++ ++ switch (d->xact & 0x7f) { ++ case I801_BYTE: /* Result put in SMBHSTDAT0 */ ++ case I801_BYTE_DATA: ++ entry->smbus.data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case I801_WORD_DATA: ++ entry->smbus.data->word = inb_p(SMBHSTDAT0) ++ + (inb_p(SMBHSTDAT1) << 8); ++ break; ++ } ++} ++ ++static void i801_transaction_final_check(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) ++{ ++ i801_check_hststs(adap, entry, d); ++ ++ if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) ++ outb_p(inb(SMBHSTSTS), SMBHSTSTS); ++ ++ if ((d->hststs = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { ++ dev_dbg(&I801_dev->dev, "Failed reset at end of transaction" ++ "(%02x)\n", d->hststs); ++ } ++ dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), ++ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), ++ inb_p(SMBHSTDAT1)); ++} ++ ++static void i801_transaction_poll(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) + { +- int temp; +- int result = 0; +- int timeout = 0; ++ d->hststs = inb_p(SMBHSTSTS); ++ if (!(d->hststs & 0x01)) { ++ i801_transaction_final_check(adap, entry, d); ++ i801_finish(adap, entry, d); ++ } else if (entry->time_left <= 0) { ++ dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); ++ entry->result = -EIO; ++ i801_transaction_final_check(adap, entry, d); ++ } ++} + ++static void i801_transaction_start(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) ++{ + dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x," + "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), + inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), +@@ -193,331 +285,347 @@ + + /* Make sure the SMBus host is ready to start transmitting */ + /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ +- if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { ++ if ((d->hststs = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { + dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting... \n", +- temp); +- outb_p(temp, SMBHSTSTS); +- if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { +- dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp); +- return -1; ++ d->hststs); ++ outb_p(d->hststs, SMBHSTSTS); ++ if ((d->hststs = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { ++ dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", d->hststs); ++ entry->result = -EIO; ++ return; + } else { + dev_dbg(&I801_dev->dev, "Successfull!\n"); + } + } + + outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); ++} + +- /* We will always wait for a fraction of a second! */ +- do { +- msleep(1); +- temp = inb_p(SMBHSTSTS); +- } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); +- +- /* If the SMBus is still busy, we give up */ +- if (timeout >= MAX_TIMEOUT) { +- dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); +- result = -1; ++static void i801_block_finish(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) ++{ ++ if (entry->smbus.command == I2C_SMBUS_I2C_BLOCK_DATA) { ++ /* restore saved configuration register value */ ++ pci_write_config_byte(I801_dev, SMBHSTCFG, d->hostc); + } + +- if (temp & 0x10) { +- result = -1; +- dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); +- } ++ i801_finish(adap, entry, d); ++} + +- if (temp & 0x08) { +- result = -1; +- dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked " +- "until next hard reset. (sorry!)\n"); +- /* Clock stops and slave is stuck in mid-transmission */ +- } ++static void i801_block_poll_wait_intr(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) ++{ ++#ifdef HAVE_PEC ++ if (entry->result >= 0 && ++ isich4 && ++ entry->smbus.command == I2C_SMBUS_BLOCK_DATA_PEC) ++ { ++ /* wait for INTR bit as advised by Intel */ ++ d->hststs = inb_p(SMBHSTSTS); ++ if (d->hststs & 0x02) { ++ outb_p(d->hststs, SMBHSTSTS); ++ i801_block_finish(adap, entry, d); ++ } else if (entry->time_left <= 0) { ++ /* Timed out */ ++ outb_p(d->hststs, SMBHSTSTS); ++ entry->result = -EIO; ++ dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); ++ } ++ } else ++#endif ++ i801_block_finish(adap, entry, d); ++} + +- if (temp & 0x04) { +- result = -1; +- dev_dbg(&I801_dev->dev, "Error: no response!\n"); ++static void i801_block_next_byte(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) ++{ ++ int smbcmd; ++ unsigned char errmask; ++ ++ if (d->i > d->len) { ++ d->wait_intr = 1; ++ entry->time_left = MAX_TIMEOUT_US; ++ i801_block_poll_wait_intr(adap, entry, d); ++ return; + } + +- if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) +- outb_p(inb(SMBHSTSTS), SMBHSTSTS); ++ if (d->i == d->len && entry->smbus.read_write == I2C_SMBUS_READ) ++ smbcmd = I801_BLOCK_LAST; ++ else ++ smbcmd = I801_BLOCK_DATA; ++ outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); + +- if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { +- dev_dbg(&I801_dev->dev, "Failed reset at end of transaction" +- "(%02x)\n", temp); ++ dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", d->i, ++ inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), ++ inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ d->hststs = inb_p(SMBHSTSTS); ++ if (d->i == 1) { ++ /* Erronenous conditions before transaction: ++ * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ ++ errmask=0x9f; ++ } else { ++ /* Erronenous conditions during transaction: ++ * Failed, Bus_Err, Dev_Err, Intr */ ++ errmask=0x1e; ++ } ++ if (d->hststs & errmask) { ++ dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " ++ "Resetting... \n", d->hststs); ++ outb_p(d->hststs, SMBHSTSTS); ++ if (((d->hststs = inb_p(SMBHSTSTS)) & errmask) != 0x00) { ++ dev_err(&I801_dev->dev, ++ "Reset failed! (%02x)\n", d->hststs); ++ entry->result = -EIO; ++ return; ++ } ++ if (d->i != 1) { ++ /* if die in middle of block transaction, fail */ ++ entry->result = -EIO; ++ return; ++ } + } +- dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " +- "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), +- inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), +- inb_p(SMBHSTDAT1)); +- return result; ++ ++ if (d->i == 1) ++ outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); + } + +-/* All-inclusive block transaction function */ +-static int i801_block_transaction(union i2c_smbus_data *data, char read_write, +- int command) ++/* Called after a timeout. This checks the result of the ++ transaction */ ++static void i801_block_poll(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) + { +- int i, len; +- int smbcmd; +- int temp; +- int result = 0; +- int timeout; +- unsigned char hostc, errmask; ++ d->hststs = inb_p(SMBHSTSTS); ++ if (!(d->hststs & 0x80)) { ++ /* Not ready yet */ ++ if (entry->time_left <= 0) { ++ dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); ++ entry->result = -EIO; ++ } ++ return; ++ } + +- if (command == I2C_SMBUS_I2C_BLOCK_DATA) { +- if (read_write == I2C_SMBUS_WRITE) { ++ i801_check_hststs(adap, entry, d); ++ if (entry->result) ++ return; ++ ++ if (d->i == 1 && entry->smbus.read_write == I2C_SMBUS_READ) { ++ d->len = inb_p(SMBHSTDAT0); ++ if (d->len < 1) ++ d->len = 1; ++ if (d->len > 32) ++ d->len = 32; ++ entry->smbus.data->block[0] = d->len; ++ } ++ ++ /* Retrieve/store value in SMBBLKDAT */ ++ if (entry->smbus.read_write == I2C_SMBUS_READ) ++ entry->smbus.data->block[d->i] = inb_p(SMBBLKDAT); ++ if (entry->smbus.read_write == I2C_SMBUS_WRITE && d->i+1 <= d->len) ++ outb_p(entry->smbus.data->block[d->i+1], SMBBLKDAT); ++ if ((d->hststs & 0x9e) != 0x00) ++ outb_p(d->hststs, SMBHSTSTS); /* signals SMBBLKDAT ready */ ++ ++ if ((d->hststs = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { ++ dev_dbg(&I801_dev->dev, ++ "Bad status (%02x) at end of transaction\n", ++ d->hststs); ++ } ++ dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", d->i, ++ inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), ++ inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); ++ ++ d->i++; ++ i801_block_next_byte(adap, entry, d); ++} ++ ++static void i801_block_start(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ struct i801_i2c_data *d) ++{ ++ if (entry->smbus.command == I2C_SMBUS_I2C_BLOCK_DATA) { ++ if (entry->smbus.read_write == I2C_SMBUS_WRITE) { + /* set I2C_EN bit in configuration register */ +- pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc); ++ pci_read_config_byte(I801_dev, SMBHSTCFG, &d->hostc); + pci_write_config_byte(I801_dev, SMBHSTCFG, +- hostc | SMBHSTCFG_I2C_EN); ++ d->hostc | SMBHSTCFG_I2C_EN); + } else { + dev_err(&I801_dev->dev, + "I2C_SMBUS_I2C_BLOCK_READ not DB!\n"); +- return -1; ++ entry->result = -EINVAL; ++ return; + } + } + +- if (read_write == I2C_SMBUS_WRITE) { +- len = data->block[0]; +- if (len < 1) +- len = 1; +- if (len > 32) +- len = 32; +- outb_p(len, SMBHSTDAT0); +- outb_p(data->block[1], SMBBLKDAT); ++ if (entry->smbus.read_write == I2C_SMBUS_WRITE) { ++ d->len = entry->smbus.data->block[0]; ++ if (d->len < 1) ++ d->len = 1; ++ if (d->len > 32) ++ d->len = 32; ++ outb_p(d->len, SMBHSTDAT0); ++ outb_p(entry->smbus.data->block[1], SMBBLKDAT); + } else { +- len = 32; /* max for reads */ ++ d->len = 32; /* max for reads */ + } + +- if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) { ++ if(isich4 && entry->smbus.command != I2C_SMBUS_I2C_BLOCK_DATA) { + /* set 32 byte buffer */ + } + +- for (i = 1; i <= len; i++) { +- if (i == len && read_write == I2C_SMBUS_READ) +- smbcmd = I801_BLOCK_LAST; +- else +- smbcmd = I801_BLOCK_DATA; +- outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); +- +- dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, " +- "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, +- inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), +- inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); +- +- /* Make sure the SMBus host is ready to start transmitting */ +- temp = inb_p(SMBHSTSTS); +- if (i == 1) { +- /* Erronenous conditions before transaction: +- * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ +- errmask=0x9f; +- } else { +- /* Erronenous conditions during transaction: +- * Failed, Bus_Err, Dev_Err, Intr */ +- errmask=0x1e; +- } +- if (temp & errmask) { +- dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " +- "Resetting... \n", temp); +- outb_p(temp, SMBHSTSTS); +- if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { +- dev_err(&I801_dev->dev, +- "Reset failed! (%02x)\n", temp); +- result = -1; +- goto END; +- } +- if (i != 1) { +- /* if die in middle of block transaction, fail */ +- result = -1; +- goto END; +- } +- } ++ d->i = 1; ++ i801_block_next_byte(adap, entry, d); ++} + +- if (i == 1) +- outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); ++/* General poll routine. Called periodically by the i2c code. */ ++static void i801_poll(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry, ++ unsigned int us_since_last_poll) ++{ ++ struct i801_i2c_data *d = entry->data; + +- /* We will always wait for a fraction of a second! */ +- timeout = 0; +- do { +- temp = inb_p(SMBHSTSTS); +- msleep(1); +- } +- while ((!(temp & 0x80)) +- && (timeout++ < MAX_TIMEOUT)); ++ dev_dbg(&I801_dev->dev, "Poll call for %p %p at %ld\n", adap, entry, ++ jiffies); + +- /* If the SMBus is still busy, we give up */ +- if (timeout >= MAX_TIMEOUT) { +- result = -1; +- dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); +- } ++ if (!d) ++ /* The entry hasn't been started yet. */ ++ return; + +- if (temp & 0x10) { +- result = -1; +- dev_dbg(&I801_dev->dev, +- "Error: Failed bus transaction\n"); +- } else if (temp & 0x08) { +- result = -1; +- dev_err(&I801_dev->dev, "Bus collision!\n"); +- } else if (temp & 0x04) { +- result = -1; +- dev_dbg(&I801_dev->dev, "Error: no response!\n"); +- } ++ /* Decrement timeout */ ++ entry->time_left -= us_since_last_poll; + +- if (i == 1 && read_write == I2C_SMBUS_READ) { +- len = inb_p(SMBHSTDAT0); +- if (len < 1) +- len = 1; +- if (len > 32) +- len = 32; +- data->block[0] = len; +- } ++ /* Wait a jiffie normally. */ ++ entry->call_again_us = RETRY_TIME_US; + +- /* Retrieve/store value in SMBBLKDAT */ +- if (read_write == I2C_SMBUS_READ) +- data->block[i] = inb_p(SMBBLKDAT); +- if (read_write == I2C_SMBUS_WRITE && i+1 <= len) +- outb_p(data->block[i+1], SMBBLKDAT); +- if ((temp & 0x9e) != 0x00) +- outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */ +- +- if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { +- dev_dbg(&I801_dev->dev, +- "Bad status (%02x) at end of transaction\n", +- temp); ++ if (d->block) { ++ if (d->wait_intr) { ++ i801_block_poll_wait_intr(adap, entry, d); ++ } else { ++ i801_block_poll(adap, entry, d); + } +- dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, " +- "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, +- inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), +- inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); +- +- if (result < 0) +- goto END; ++ if (entry->result < 0) ++ /* Error, finish the transaction */ ++ i801_block_finish(adap, entry, d); ++ } else { ++ i801_transaction_poll(adap, entry, d); ++ if (entry->result < 0) ++ /* Error, finish the transaction */ ++ i801_finish(adap, entry, d); + } + +-#ifdef HAVE_PEC +- if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) { +- /* wait for INTR bit as advised by Intel */ +- timeout = 0; +- do { +- temp = inb_p(SMBHSTSTS); +- msleep(1); +- } while ((!(temp & 0x02)) +- && (timeout++ < MAX_TIMEOUT)); +- +- if (timeout >= MAX_TIMEOUT) { +- dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); +- } +- outb_p(temp, SMBHSTSTS); +- } +-#endif +- result = 0; +-END: +- if (command == I2C_SMBUS_I2C_BLOCK_DATA) { +- /* restore saved configuration register value */ +- pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); +- } +- return result; ++ if (d->finished) ++ i2c_op_done(adap, entry); + } + +-/* Return -1 on error. */ +-static s32 i801_access(struct i2c_adapter * adap, u16 addr, +- unsigned short flags, char read_write, u8 command, +- int size, union i2c_smbus_data * data) ++/* Start a general SMBUS transaction on the i801. Figure out what ++ kind of transaction it is, set it up, and start it. */ ++static void i801_start(struct i2c_adapter *adap, ++ struct i2c_op_q_entry *entry) + { +- int hwpec = 0; +- int block = 0; +- int ret, xact = 0; ++ struct i801_i2c_data *d = adap->algo_data; ++ ++ d->block = 0; ++ d->hwpec = 0; ++ d->xact = 0; ++ d->wait_intr = 0; ++ d->finished = 0; + + #ifdef HAVE_PEC +- if(isich4) +- hwpec = (flags & I2C_CLIENT_PEC) != 0; ++ if (isich4) ++ d->hwpec = (entry->smbus.flags & I2C_CLIENT_PEC) != 0; + #endif + +- switch (size) { ++ switch (entry->smbus.size) { + case I2C_SMBUS_QUICK: +- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ outb_p(((entry->smbus.addr & 0x7f) << 1) ++ | (entry->smbus.read_write & 0x01), + SMBHSTADD); +- xact = I801_QUICK; ++ d->xact = I801_QUICK; + break; + case I2C_SMBUS_BYTE: +- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ outb_p(((entry->smbus.addr & 0x7f) << 1) ++ | (entry->smbus.read_write & 0x01), + SMBHSTADD); +- if (read_write == I2C_SMBUS_WRITE) +- outb_p(command, SMBHSTCMD); +- xact = I801_BYTE; ++ if (entry->smbus.read_write == I2C_SMBUS_WRITE) ++ outb_p(entry->smbus.command, SMBHSTCMD); ++ d->xact = I801_BYTE; + break; + case I2C_SMBUS_BYTE_DATA: +- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ outb_p(((entry->smbus.addr & 0x7f) << 1) ++ | (entry->smbus.read_write & 0x01), + SMBHSTADD); +- outb_p(command, SMBHSTCMD); +- if (read_write == I2C_SMBUS_WRITE) +- outb_p(data->byte, SMBHSTDAT0); +- xact = I801_BYTE_DATA; ++ outb_p(entry->smbus.command, SMBHSTCMD); ++ if (entry->smbus.read_write == I2C_SMBUS_WRITE) ++ outb_p(entry->smbus.data->byte, SMBHSTDAT0); ++ d->xact = I801_BYTE_DATA; + break; + case I2C_SMBUS_WORD_DATA: +- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ outb_p(((entry->smbus.addr & 0x7f) << 1) ++ | (entry->smbus.read_write & 0x01), + SMBHSTADD); +- outb_p(command, SMBHSTCMD); +- if (read_write == I2C_SMBUS_WRITE) { +- outb_p(data->word & 0xff, SMBHSTDAT0); +- outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); ++ outb_p(entry->smbus.command, SMBHSTCMD); ++ if (entry->smbus.read_write == I2C_SMBUS_WRITE) { ++ outb_p(entry->smbus.data->word & 0xff, SMBHSTDAT0); ++ outb_p((entry->smbus.data->word & 0xff00) >> 8, ++ SMBHSTDAT1); + } +- xact = I801_WORD_DATA; ++ d->xact = I801_WORD_DATA; + break; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + #ifdef HAVE_PEC + case I2C_SMBUS_BLOCK_DATA_PEC: +- if(hwpec && size == I2C_SMBUS_BLOCK_DATA) +- size = I2C_SMBUS_BLOCK_DATA_PEC; ++ if (d->hwpec && entry->smbus.size == I2C_SMBUS_BLOCK_DATA) ++ entry->smbus.size = I2C_SMBUS_BLOCK_DATA_PEC; + #endif +- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ outb_p(((entry->smbus.addr & 0x7f) << 1) ++ | (entry->smbus.read_write & 0x01), + SMBHSTADD); +- outb_p(command, SMBHSTCMD); +- block = 1; ++ outb_p(entry->smbus.command, SMBHSTCMD); ++ d->block = 1; + break; + case I2C_SMBUS_PROC_CALL: + default: +- dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); +- return -1; ++ dev_err(&I801_dev->dev, "Unsupported transaction %d\n", ++ entry->smbus.size); ++ entry->result = -EINVAL; ++ return; + } + + #ifdef HAVE_PEC +- if(isich4 && hwpec) { +- if(size != I2C_SMBUS_QUICK && +- size != I2C_SMBUS_I2C_BLOCK_DATA) ++ if (isich4 && d->hwpec) { ++ if (entry->smbus.size != I2C_SMBUS_QUICK && ++ entry->smbus.size != I2C_SMBUS_I2C_BLOCK_DATA) + outb_p(1, SMBAUXCTL); /* enable HW PEC */ + } + #endif +- if(block) +- ret = i801_block_transaction(data, read_write, size); +- else { +- outb_p(xact | ENABLE_INT9, SMBHSTCNT); +- ret = i801_transaction(); +- } +- +-#ifdef HAVE_PEC +- if(isich4 && hwpec) { +- if(size != I2C_SMBUS_QUICK && +- size != I2C_SMBUS_I2C_BLOCK_DATA) +- outb_p(0, SMBAUXCTL); ++ if (d->block) { ++ i801_block_start(adap, entry, d); ++ if (entry->result < 0) ++ /* Error, finish the transaction */ ++ i801_block_finish(adap, entry, d); ++ } else { ++ outb_p(d->xact | ENABLE_INT9, SMBHSTCNT); ++ i801_transaction_start(adap, entry, d); ++ if (entry->result < 0) ++ /* Error, finish the transaction */ ++ i801_finish(adap, entry, d); + } +-#endif + +- if(block) +- return ret; +- if(ret) +- return -1; +- if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK)) +- return 0; ++ entry->call_again_us = RETRY_TIME_US; ++ entry->time_left = MAX_TIMEOUT_US; + +- switch (xact & 0x7f) { +- case I801_BYTE: /* Result put in SMBHSTDAT0 */ +- case I801_BYTE_DATA: +- data->byte = inb_p(SMBHSTDAT0); +- break; +- case I801_WORD_DATA: +- data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); +- break; +- } +- return 0; ++ if (d->finished) ++ i2c_op_done(adap, entry); ++ else ++ entry->data = d; + } + + +@@ -537,7 +645,8 @@ + static struct i2c_algorithm smbus_algorithm = { + .name = "Non-I2C SMBus adapter", + .id = I2C_ALGO_SMBUS, +- .smbus_xfer = i801_access, ++ .smbus_start = i801_start, ++ .poll = i801_poll, + .functionality = i801_func, + }; + +@@ -545,6 +654,7 @@ + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo = &smbus_algorithm, ++ .algo_data = &i801_data, + .name = "unset", + }; + +@@ -563,7 +673,8 @@ + + MODULE_DEVICE_TABLE (pci, i801_ids); + +-static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ++static int __devinit i801_probe(struct pci_dev *dev, ++ const struct pci_device_id *id) + { + + if (i801_setup(dev)) { diff --git a/a/content_digest b/N1/content_digest index 3d3be45..215f878 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -2,16 +2,16 @@ "ref\041F984D4.5030306@verizon.net\0" "ref\041F9C2EC.5070806@acm.org\0" "ref\041F9E183.5A9B1BA2@gte.net\0" - "From\0minyard@acm.org (Corey Minyard)\0" - "Subject\0[PATCH] Updates for the i801 driver to support the I2C non-blocking\0" - "Date\0Thu, 19 May 2005 06:25:33 +0000\0" + "From\0Corey Minyard <minyard@acm.org>\0" + "Subject\0[PATCH] Updates for the i801 driver to support the I2C non-blocking interface\0" + "Date\0Fri, 28 Jan 2005 09:11:47 -0600\0" "To\0Bukie Mabayoje <bukiemab@gte.net>\0" "Cc\0Mark Studebaker <mds4@verizon.net>" Sensors <sensors@stimpy.netroedge.com> lkml <linux-kernel@vger.kernel.org> Frodo Looijaard <frodol@dds.nl> " Philip Edelbrock <phil@netroedge.com>\0" - "\00:1\0" + "\01:1\0" "b\0" "Here's the changes required for the i801 driver. See the previous post \n" "for the patch to add a non-blocking interface to the I2C driver.\n" @@ -19,10 +19,13 @@ "Like the core I2C changes, this is mostly breaking the functions into \n" "smaller pieces and calling them from the appropriate places.\n" "\n" - "-Corey\n" - "-------------- next part --------------\n" + -Corey + "\01:2\0" + "fn\0i2c_async_i801.diff\0" + "b\0" "Index: linux-2.6.11-rc2/drivers/i2c/busses/i2c-i801.c\n" - "=================================--- linux-2.6.11-rc2.orig/drivers/i2c/busses/i2c-i801.c\t2005-01-27 13:09:12.000000000 -0600\n" + "===================================================================\n" + "--- linux-2.6.11-rc2.orig/drivers/i2c/busses/i2c-i801.c\t2005-01-27 13:09:12.000000000 -0600\n" "+++ linux-2.6.11-rc2/drivers/i2c/busses/i2c-i801.c\t2005-01-27 13:46:23.000000000 -0600\n" "@@ -79,7 +79,8 @@\n" " #define SMBHSTCFG_I2C_EN\t4\n" @@ -75,8 +78,8 @@ " \t} else {\n" " \t\tpci_read_config_word(I801_dev, SMBBA, &i801_smba);\n" " \t\ti801_smba &= 0xfff0;\n" - "-\t\tif(i801_smba = 0) {\n" - "+\t\tif (i801_smba = 0) {\n" + "-\t\tif(i801_smba == 0) {\n" + "+\t\tif (i801_smba == 0) {\n" " \t\t\tdev_err(&dev->dev, \"SMB base address uninitialized\"\n" " \t\t\t\t\"- upgrade BIOS or use force_addr=0xaddr\\n\");\n" " \t\t\treturn -ENODEV;\n" @@ -118,8 +121,8 @@ "+#endif\n" "+\n" "+\tif (d->block || (entry->result < 0) ||\n" - "+\t ((entry->smbus.read_write = I2C_SMBUS_WRITE)\n" - "+\t || (d->xact = I801_QUICK)))\n" + "+\t ((entry->smbus.read_write == I2C_SMBUS_WRITE)\n" + "+\t || (d->xact == I801_QUICK)))\n" "+\t\treturn;\n" "+\n" "+\tswitch (d->xact & 0x7f) {\n" @@ -218,7 +221,7 @@ "+\t\t\t struct i2c_op_q_entry *entry,\n" "+\t\t\t struct i801_i2c_data *d)\n" "+{\n" - "+\tif (entry->smbus.command = I2C_SMBUS_I2C_BLOCK_DATA) {\n" + "+\tif (entry->smbus.command == I2C_SMBUS_I2C_BLOCK_DATA) {\n" "+\t\t/* restore saved configuration register value */\n" "+\t\tpci_write_config_byte(I801_dev, SMBHSTCFG, d->hostc);\n" " \t}\n" @@ -243,7 +246,7 @@ "+#ifdef HAVE_PEC\n" "+\tif (entry->result >= 0 &&\n" "+\t isich4 &&\n" - "+\t entry->smbus.command = I2C_SMBUS_BLOCK_DATA_PEC)\n" + "+\t entry->smbus.command == I2C_SMBUS_BLOCK_DATA_PEC)\n" "+\t{\n" "+\t\t/* wait for INTR bit as advised by Intel */\n" "+\t\td->hststs = inb_p(SMBHSTSTS);\n" @@ -280,7 +283,7 @@ " \n" "-\tif ((inb_p(SMBHSTSTS) & 0x1f) != 0x00)\n" "-\t\toutb_p(inb(SMBHSTSTS), SMBHSTSTS);\n" - "+\tif (d->i = d->len && entry->smbus.read_write = I2C_SMBUS_READ)\n" + "+\tif (d->i == d->len && entry->smbus.read_write == I2C_SMBUS_READ)\n" "+\t\tsmbcmd = I801_BLOCK_LAST;\n" "+\telse\n" "+\t\tsmbcmd = I801_BLOCK_DATA;\n" @@ -296,7 +299,7 @@ "+\n" "+\t/* Make sure the SMBus host is ready to start transmitting */\n" "+\td->hststs = inb_p(SMBHSTSTS);\n" - "+\tif (d->i = 1) {\n" + "+\tif (d->i == 1) {\n" "+\t\t/* Erronenous conditions before transaction: \n" "+\t\t * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */\n" "+\t\terrmask=0x9f; \n" @@ -327,7 +330,7 @@ "-\t\tinb_p(SMBHSTDAT1));\n" "-\treturn result;\n" "+\n" - "+\tif (d->i = 1)\n" + "+\tif (d->i == 1)\n" "+\t\toutb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);\n" " }\n" " \n" @@ -356,13 +359,13 @@ "+\t\treturn;\n" "+\t}\n" " \n" - "-\tif (command = I2C_SMBUS_I2C_BLOCK_DATA) {\n" - "-\t\tif (read_write = I2C_SMBUS_WRITE) {\n" + "-\tif (command == I2C_SMBUS_I2C_BLOCK_DATA) {\n" + "-\t\tif (read_write == I2C_SMBUS_WRITE) {\n" "+\ti801_check_hststs(adap, entry, d);\n" "+\tif (entry->result)\n" "+\t\treturn;\n" "+\n" - "+\tif (d->i = 1 && entry->smbus.read_write = I2C_SMBUS_READ) {\n" + "+\tif (d->i == 1 && entry->smbus.read_write == I2C_SMBUS_READ) {\n" "+\t\td->len = inb_p(SMBHSTDAT0);\n" "+\t\tif (d->len < 1)\n" "+\t\t\td->len = 1;\n" @@ -372,9 +375,9 @@ "+\t}\n" "+\n" "+\t/* Retrieve/store value in SMBBLKDAT */\n" - "+\tif (entry->smbus.read_write = I2C_SMBUS_READ)\n" + "+\tif (entry->smbus.read_write == I2C_SMBUS_READ)\n" "+\t\tentry->smbus.data->block[d->i] = inb_p(SMBBLKDAT);\n" - "+\tif (entry->smbus.read_write = I2C_SMBUS_WRITE && d->i+1 <= d->len)\n" + "+\tif (entry->smbus.read_write == I2C_SMBUS_WRITE && d->i+1 <= d->len)\n" "+\t\toutb_p(entry->smbus.data->block[d->i+1], SMBBLKDAT);\n" "+\tif ((d->hststs & 0x9e) != 0x00)\n" "+\t\toutb_p(d->hststs, SMBHSTSTS); /* signals SMBBLKDAT ready */\n" @@ -397,8 +400,8 @@ "+\t\t\t struct i2c_op_q_entry *entry,\n" "+\t\t\t struct i801_i2c_data *d)\n" "+{\n" - "+\tif (entry->smbus.command = I2C_SMBUS_I2C_BLOCK_DATA) {\n" - "+\t\tif (entry->smbus.read_write = I2C_SMBUS_WRITE) {\n" + "+\tif (entry->smbus.command == I2C_SMBUS_I2C_BLOCK_DATA) {\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_WRITE) {\n" " \t\t\t/* set I2C_EN bit in configuration register */\n" "-\t\t\tpci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);\n" "+\t\t\tpci_read_config_byte(I801_dev, SMBHSTCFG, &d->hostc);\n" @@ -414,7 +417,7 @@ " \t\t}\n" " \t}\n" " \n" - "-\tif (read_write = I2C_SMBUS_WRITE) {\n" + "-\tif (read_write == I2C_SMBUS_WRITE) {\n" "-\t\tlen = data->block[0];\n" "-\t\tif (len < 1)\n" "-\t\t\tlen = 1;\n" @@ -422,7 +425,7 @@ "-\t\t\tlen = 32;\n" "-\t\toutb_p(len, SMBHSTDAT0);\n" "-\t\toutb_p(data->block[1], SMBBLKDAT);\n" - "+\tif (entry->smbus.read_write = I2C_SMBUS_WRITE) {\n" + "+\tif (entry->smbus.read_write == I2C_SMBUS_WRITE) {\n" "+\t\td->len = entry->smbus.data->block[0];\n" "+\t\tif (d->len < 1)\n" "+\t\t\td->len = 1;\n" @@ -441,7 +444,7 @@ " \t}\n" " \n" "-\tfor (i = 1; i <= len; i++) {\n" - "-\t\tif (i = len && read_write = I2C_SMBUS_READ)\n" + "-\t\tif (i == len && read_write == I2C_SMBUS_READ)\n" "-\t\t\tsmbcmd = I801_BLOCK_LAST;\n" "-\t\telse\n" "-\t\t\tsmbcmd = I801_BLOCK_DATA;\n" @@ -454,7 +457,7 @@ "-\n" "-\t\t/* Make sure the SMBus host is ready to start transmitting */\n" "-\t\ttemp = inb_p(SMBHSTSTS);\n" - "-\t\tif (i = 1) {\n" + "-\t\tif (i == 1) {\n" "-\t\t\t/* Erronenous conditions before transaction: \n" "-\t\t\t * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */\n" "-\t\t\terrmask=0x9f; \n" @@ -483,7 +486,7 @@ "+\ti801_block_next_byte(adap, entry, d);\n" "+}\n" " \n" - "-\t\tif (i = 1)\n" + "-\t\tif (i == 1)\n" "-\t\t\toutb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);\n" "+/* General poll routine. Called periodically by the i2c code. */\n" "+static void i801_poll(struct i2c_adapter *adap,\n" @@ -526,7 +529,7 @@ "+\t/* Decrement timeout */\n" "+\tentry->time_left -= us_since_last_poll;\n" " \n" - "-\t\tif (i = 1 && read_write = I2C_SMBUS_READ) {\n" + "-\t\tif (i == 1 && read_write == I2C_SMBUS_READ) {\n" "-\t\t\tlen = inb_p(SMBHSTDAT0);\n" "-\t\t\tif (len < 1)\n" "-\t\t\t\tlen = 1;\n" @@ -538,9 +541,9 @@ "+\tentry->call_again_us = RETRY_TIME_US;\n" " \n" "-\t\t/* Retrieve/store value in SMBBLKDAT */\n" - "-\t\tif (read_write = I2C_SMBUS_READ)\n" + "-\t\tif (read_write == I2C_SMBUS_READ)\n" "-\t\t\tdata->block[i] = inb_p(SMBBLKDAT);\n" - "-\t\tif (read_write = I2C_SMBUS_WRITE && i+1 <= len)\n" + "-\t\tif (read_write == I2C_SMBUS_WRITE && i+1 <= len)\n" "-\t\t\toutb_p(data->block[i+1], SMBBLKDAT);\n" "-\t\tif ((temp & 0x9e) != 0x00)\n" "-\t\t\toutb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */\n" @@ -573,7 +576,7 @@ " \t}\n" " \n" "-#ifdef HAVE_PEC\n" - "-\tif(isich4 && command = I2C_SMBUS_BLOCK_DATA_PEC) {\n" + "-\tif(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) {\n" "-\t\t/* wait for INTR bit as advised by Intel */\n" "-\t\ttimeout = 0;\n" "-\t\tdo {\n" @@ -590,7 +593,7 @@ "-#endif\n" "-\tresult = 0;\n" "-END:\n" - "-\tif (command = I2C_SMBUS_I2C_BLOCK_DATA) {\n" + "-\tif (command == I2C_SMBUS_I2C_BLOCK_DATA) {\n" "-\t\t/* restore saved configuration register value */\n" "-\t\tpci_write_config_byte(I801_dev, SMBHSTCFG, hostc);\n" "-\t}\n" @@ -641,10 +644,10 @@ "+\t\toutb_p(((entry->smbus.addr & 0x7f) << 1)\n" "+\t\t | (entry->smbus.read_write & 0x01),\n" " \t\t SMBHSTADD);\n" - "-\t\tif (read_write = I2C_SMBUS_WRITE)\n" + "-\t\tif (read_write == I2C_SMBUS_WRITE)\n" "-\t\t\toutb_p(command, SMBHSTCMD);\n" "-\t\txact = I801_BYTE;\n" - "+\t\tif (entry->smbus.read_write = I2C_SMBUS_WRITE)\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_WRITE)\n" "+\t\t\toutb_p(entry->smbus.command, SMBHSTCMD);\n" "+\t\td->xact = I801_BYTE;\n" " \t\tbreak;\n" @@ -654,11 +657,11 @@ "+\t\t | (entry->smbus.read_write & 0x01),\n" " \t\t SMBHSTADD);\n" "-\t\toutb_p(command, SMBHSTCMD);\n" - "-\t\tif (read_write = I2C_SMBUS_WRITE)\n" + "-\t\tif (read_write == I2C_SMBUS_WRITE)\n" "-\t\t\toutb_p(data->byte, SMBHSTDAT0);\n" "-\t\txact = I801_BYTE_DATA;\n" "+\t\toutb_p(entry->smbus.command, SMBHSTCMD);\n" - "+\t\tif (entry->smbus.read_write = I2C_SMBUS_WRITE)\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_WRITE)\n" "+\t\t\toutb_p(entry->smbus.data->byte, SMBHSTDAT0);\n" "+\t\td->xact = I801_BYTE_DATA;\n" " \t\tbreak;\n" @@ -668,11 +671,11 @@ "+\t\t | (entry->smbus.read_write & 0x01),\n" " \t\t SMBHSTADD);\n" "-\t\toutb_p(command, SMBHSTCMD);\n" - "-\t\tif (read_write = I2C_SMBUS_WRITE) {\n" + "-\t\tif (read_write == I2C_SMBUS_WRITE) {\n" "-\t\t\toutb_p(data->word & 0xff, SMBHSTDAT0);\n" "-\t\t\toutb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);\n" "+\t\toutb_p(entry->smbus.command, SMBHSTCMD);\n" - "+\t\tif (entry->smbus.read_write = I2C_SMBUS_WRITE) {\n" + "+\t\tif (entry->smbus.read_write == I2C_SMBUS_WRITE) {\n" "+\t\t\toutb_p(entry->smbus.data->word & 0xff, SMBHSTDAT0);\n" "+\t\t\toutb_p((entry->smbus.data->word & 0xff00) >> 8,\n" "+\t\t\t SMBHSTDAT1);\n" @@ -684,9 +687,9 @@ " \tcase I2C_SMBUS_I2C_BLOCK_DATA:\n" " #ifdef HAVE_PEC\n" " \tcase I2C_SMBUS_BLOCK_DATA_PEC:\n" - "-\t\tif(hwpec && size = I2C_SMBUS_BLOCK_DATA)\n" + "-\t\tif(hwpec && size == I2C_SMBUS_BLOCK_DATA)\n" "-\t\t\tsize = I2C_SMBUS_BLOCK_DATA_PEC;\n" - "+\t\tif (d->hwpec && entry->smbus.size = I2C_SMBUS_BLOCK_DATA)\n" + "+\t\tif (d->hwpec && entry->smbus.size == I2C_SMBUS_BLOCK_DATA)\n" "+\t\t\tentry->smbus.size = I2C_SMBUS_BLOCK_DATA_PEC;\n" " #endif\n" "-\t\toutb_p(((addr & 0x7f) << 1) | (read_write & 0x01),\n" @@ -748,7 +751,7 @@ "-\t\treturn ret;\n" "-\tif(ret)\n" "-\t\treturn -1;\n" - "-\tif ((read_write = I2C_SMBUS_WRITE) || (xact = I801_QUICK))\n" + "-\tif ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))\n" "-\t\treturn 0;\n" "+\tentry->call_again_us = RETRY_TIME_US;\n" "+\tentry->time_left = MAX_TIMEOUT_US;\n" @@ -799,4 +802,4 @@ " \n" " \tif (i801_setup(dev)) {" -a8b7faa2eebe48c3cefa735f505dba1f7dc8726369efbc18a439d33b08accd59 +609f88ee37d673ece313ff50ae0a9277eecaf6196a148f32644d503aa6c851a6
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.