lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Tue, 13 Apr 2010 22:01:31 -0500
From:	H Hartley Sweeten <hartleys@...ionengravers.com>
To:	Linux Kernel <linux-kernel@...r.kernel.org>
CC:	Greg KH <greg@...ah.com>, "ss@....gov.au" <ss@....gov.au>
Subject: [PATCH] staging/dt3155: fix wait_ibsyclr function

The wait_ibsyclr function is supposed to return the status of the I2C
cycle.  Currently it will always return FALSE because the IIC_CSR2
register is not re-read in order to update the cached register value.
This results in the NEW_CYCLE bit still being 1.

The current code actually works correctly only because the return
value of {Read|Write}I2C is not checked in the driver.

Fix wait_ibsyclr by actually reading the IIC_CSR2 register to get the
updated status.  While here, change the return type to be an actual
errno instead of the private TRUE/FALSE define and remove the now
obvious comments about the return value.

Also, remove the local variable 'writestat' in WriteI2C and just
return the result of wait_ibsyclr.

Signed-off-by: H Hartley Sweeten <hsweeten@...ionengravers.com>
Cc: Greg Kroah-Hartman <gregkh@...e.de>
Cc: Scott Smedley <ss@....gov.au>

---

diff --git a/drivers/staging/dt3155/dt3155_io.c b/drivers/staging/dt3155/dt3155_io.c
index 6b9c685..7792e71 100644
--- a/drivers/staging/dt3155/dt3155_io.c
+++ b/drivers/staging/dt3155/dt3155_io.c
@@ -74,23 +74,22 @@ u8 i2c_pm_lut_data;
  * wait_ibsyclr()
  *
  * This function handles read/write timing and r/w timeout error
- *
- * Returns TRUE  if NEW_CYCLE clears
- * Returns FALSE if NEW_CYCLE doesn't clear in roughly 3 msecs, otherwise
- * returns 0
  */
 static int wait_ibsyclr(u8 *lpReg)
 {
 	/* wait 100 microseconds */
 	udelay(100L);
 	/* __delay(loops_per_sec/10000); */
+
+	ReadMReg(lpReg + IIC_CSR2, iic_csr2_r.reg);
 	if (iic_csr2_r.fld.NEW_CYCLE) {
 		/* if NEW_CYCLE didn't clear */
 		/* TIMEOUT ERROR */
 		dt3155_errno = DT_ERR_I2C_TIMEOUT;
-		return FALSE;
-	} else
-		return TRUE;	/* no error */
+		return -ETIMEDOUT;
+	}
+
+	return 0;	/* no error */
 }
 
 /*
@@ -101,14 +100,9 @@ static int wait_ibsyclr(u8 *lpReg)
  * 1st parameter is pointer to 32-bit register base address
  * 2nd parameter is reg. index;
  * 3rd is value to be written
- *
- * Returns TRUE   -  Successful completion
- *         FALSE  -  Timeout error - cycle did not complete!
  */
 int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal)
 {
-	int writestat;	/* status for return */
-
 	/* read 32 bit IIC_CSR2 register data into union */
 
 	ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
@@ -126,8 +120,7 @@ int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal)
 	WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
 
 	/* wait for IIC cycle to finish */
-	writestat = wait_ibsyclr(lpReg);
-	return writestat;
+	return wait_ibsyclr(lpReg);
 }
 
 /*
@@ -138,9 +131,6 @@ int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal)
  * 1st parameter is pointer to 32-bit register base address
  * 2nd parameter is reg. index;
  * 3rd is adrs of value to be read
- *
- * Returns TRUE   -  Successful completion
- *         FALSE  -  Timeout error - cycle did not complete!
  */
 int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal)
 {

Powered by blists - more mailing lists