Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1ecac07abaca1a4084d0259d4a15b55188852a2e
Commit:     1ecac07abaca1a4084d0259d4a15b55188852a2e
Parent:     ef2c8321f5a27ff9ecdae1ee587430cafa495586
Author:     Jean Delvare <[EMAIL PROTECTED]>
AuthorDate: Tue May 1 23:26:28 2007 +0200
Committer:  Jean Delvare <[EMAIL PROTECTED]>
CommitDate: Tue May 1 23:26:28 2007 +0200

    i2c-algo-bit: Always send a stop condition before leaving
    
    The i2c-algo-bit driver doesn't behave well on read errors: it'll
    bail out without even sending a stop condition on the bus, so the bus
    will be stuck. So make sure that we always send a stop condition on
    the bus before we leave. The best way to make sure is to always send
    it at the end of function bit_xfer.
    
    Signed-off-by: Jean Delvare <[EMAIL PROTECTED]>
---
 drivers/i2c/algos/i2c-algo-bit.c |   27 +++++++++++++++------------
 1 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index 95aa539..28b7e25 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -312,12 +312,10 @@ static int try_address(struct i2c_adapter *i2c_adap,
        int i,ret = -1;
        for (i=0;i<=retries;i++) {
                ret = i2c_outb(i2c_adap,addr);
-               if (ret==1)
-                       break;  /* success! */
+               if (ret == 1 || i == retries)
+                       break;
                i2c_stop(adap);
                udelay(5/*adap->udelay*/);
-               if (i==retries)  /* no success */
-                       break;
                i2c_start(adap);
                udelay(adap->udelay);
        }
@@ -331,7 +329,6 @@ static int try_address(struct i2c_adapter *i2c_adap,
 
 static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
 {
-       struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
        char c;
        const char *temp = msg->buf;
        int count = msg->len;
@@ -349,7 +346,6 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct 
i2c_msg *msg)
                        wrcount++;
                } else { /* arbitration or no acknowledge */
                        dev_err(&i2c_adap->dev, "sendbytes: error - 
bailout.\n");
-                       i2c_stop(adap);
                        return (retval<0)? retval : -EFAULT;
                                /* got a better one ?? */
                }
@@ -480,27 +476,34 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
                        if ((ret != 0) && !nak_ok) {
                            DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from 
device addr %2.2x msg #%d\n"
                                        ,msgs[i].addr,i));
-                           return (ret<0) ? ret : -EREMOTEIO;
+                               goto bailout;
                        }
                }
                if (pmsg->flags & I2C_M_RD ) {
                        /* read bytes into buffer*/
                        ret = readbytes(i2c_adap, pmsg);
                        DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d 
bytes.\n",ret));
-                       if (ret < pmsg->len ) {
-                               return (ret<0)? ret : -EREMOTEIO;
+                       if (ret < pmsg->len) {
+                               if (ret >= 0)
+                                       ret = -EREMOTEIO;
+                               goto bailout;
                        }
                } else {
                        /* write bytes from buffer */
                        ret = sendbytes(i2c_adap, pmsg);
                        DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d 
bytes.\n",ret));
-                       if (ret < pmsg->len ) {
-                               return (ret<0) ? ret : -EREMOTEIO;
+                       if (ret < pmsg->len) {
+                               if (ret >= 0)
+                                       ret = -EREMOTEIO;
+                               goto bailout;
                        }
                }
        }
+       ret = i;
+
+bailout:
        i2c_stop(adap);
-       return num;
+       return ret;
 }
 
 static u32 bit_func(struct i2c_adapter *adap)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to