Commit 1ecac07a authored by Jean Delvare's avatar Jean Delvare Committed by Jean Delvare
Browse files

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: default avatarJean Delvare <khali@linux-fr.org>
parent ef2c8321
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -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,7 +476,7 @@ 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 ) {
@@ -488,19 +484,26 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
			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 >= 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 >= 0)
					ret = -EREMOTEIO;
				goto bailout;
			}
		}
	}
	ret = i;

bailout:
	i2c_stop(adap);
	return num;
	return ret;
}

static u32 bit_func(struct i2c_adapter *adap)