i2c_adapters: return -Errno not -1
PATCH 1/1 i2c_adapters: return -Errno not -1
Tighten error paths used by various other i2c adapters so they return real fault/errno codes instead of a literal "-1" (which is most often interpreted as "-EPERM"). Build tested.
---
NOTE there are many other adapter drivers to audit and update; and they're not just within the drivers/i2c tree. This patch is a PC oriented start on some bottom-up improvement of fault reporting. The i2c-gpio code looks be good too.
drivers/i2c/algos/i2c-algo-bit.c | 11 +++++--- drivers/i2c/busses/i2c-ali1535.c | 22 +++++++--------- drivers/i2c/busses/i2c-ali1563.c | 4 +-- drivers/i2c/busses/i2c-ali15x3.c | 19 +++++++------- drivers/i2c/busses/i2c-amd756-s4882.c | 4 +-- drivers/i2c/busses/i2c-amd756.c | 18 +++++++------ drivers/i2c/busses/i2c-amd8111.c | 44 +++++++++++++++++++++------------ drivers/i2c/busses/i2c-i801.c | 45 +++++++++++++++++----------------- drivers/i2c/busses/i2c-nforce2.c | 25 +++++++++--------- drivers/i2c/busses/i2c-piix4.c | 20 ++++++++------- drivers/i2c/busses/i2c-sis5595.c | 19 ++++++++------ drivers/i2c/busses/i2c-sis630.c | 43 ++++++++++++++++++-------------- drivers/i2c/busses/i2c-sis96x.c | 20 ++++++++------- drivers/i2c/busses/i2c-stub.c | 4 +-- drivers/i2c/busses/i2c-viapro.c | 20 ++++++++------- 15 files changed, 176 insertions(+), 142 deletions(-)
drivers/i2c/algos/i2c-algo-bit.c +7 -4
@@ -317,10 +317,10 @@ bailout:* -x transmission error */ static int try_address (struct i2c_adapter *i2c_adap, -unsigned char addr,int retries) +unsigned char addr,unsigned retries) {struct i2c_algo_bit_data *adap = i2c_adap->algo_data; -int i, ret =-1 ; +int i, ret;for (i =0 ; i <= retries; i++) { ret =i2c_outb (i2c_adap, addr);
@@ -465,9 +465,12 @@ static int bit_doAddress(struct i2c_adapstruct i2c_algo_bit_data *adap = i2c_adap->algo_data;unsigned char addr; -int ret, retries; +int ret; +unsigned retries; - retries = nak_ok ?0 : i2c_adap->retries; + retries = (nak_ok || i2c_adap->retries <0 ) + ?0 + : i2c_adap->retries;if (flags &I2C_M_TEN ) {/* a ten bit address */
drivers/i2c/busses/i2c-ali1535.c +10 -12
@@ -259,7 +259,7 @@ static int ali1535_transaction(struct i2dev_err (&adap->dev,"SMBus reset failed! (0x%02x) - controller or " "device on bus is probably hung\n" , temp); -return -1 ; +return -EBUSY ; } }else {/* check and clear done bit */
@@ -281,12 +281,12 @@ static int ali1535_transaction(struct i2/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&adap->dev,"SMBus Timeout!\n" ); }if (temp &ALI1535_STS_FAIL ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); }
@@ -295,7 +295,7 @@ static int ali1535_transaction(struct i2* do a printk. This means that bus collisions go unreported. */ if (temp &ALI1535_STS_BUSERR ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"Error: no response or bus collision ADD=%02x\n" ,inb_p (SMBHSTADD ));
@@ -303,13 +303,13 @@ static int ali1535_transaction(struct i2/* haven't ever seen this */ if (temp &ALI1535_STS_DEV ) { - result =-1 ; + result = -EIO ;dev_err (&adap->dev,"Error: device error\n" ); }/* check to see if the "command complete" indication is set */ if (!(temp &ALI1535_STS_DONE )) { - result =-1 ; + result = -EIO ;dev_err (&adap->dev,"Error: command never completed\n" ); }
@@ -332,7 +332,7 @@ static int ali1535_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 ali1535_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data)
@@ -359,7 +359,7 @@ static s32 ali1535_access(struct i2c_adaswitch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); - result =-1 ; + result = -EOPNOTSUPP ; goto EXIT;case I2C_SMBUS_QUICK : outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
@@ -420,11 +420,9 @@ static s32 ali1535_access(struct i2c_adabreak ; } -if (ali1535_transaction (adap)) { -/* Error in transaction */ - result =-1 ; + result =ali1535_transaction (adap); +if (result) goto EXIT; - }if ((read_write ==I2C_SMBUS_WRITE ) || (size ==ALI1535_QUICK )) { result =0 ;
drivers/i2c/busses/i2c-ali1563.c +2 -2
@@ -122,7 +122,7 @@ static int ali1563_transaction(struct i2outb_p (0x0 ,SMB_HST_CNTL2 ); } -return -1 ; +return -EIO ; }static int ali1563_block_start (struct i2c_adapter * a)
@@ -170,7 +170,7 @@ static int ali1563_block_start(struct i2 data &HST_STS_BUSERR ?"No response or Bus Collision " :"" , data &HST_STS_DEVERR ?"Device Error " :"" , !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); -return -1 ; +return -EIO ; }static int ali1563_block (struct i2c_adapter * a,union i2c_smbus_data * data,u8 rw)
drivers/i2c/busses/i2c-ali15x3.c +10 -9
@@ -282,7 +282,7 @@ static int ali15x3_transaction(struct i2dev_err (&adap->dev,"SMBus reset failed! (0x%02x) - " "controller or device on bus is probably hung\n" , temp); -return -1 ; +return -EBUSY ; } }else {/* check and clear done bit */
@@ -304,12 +304,12 @@ static int ali15x3_transaction(struct i2/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&adap->dev,"SMBus Timeout!\n" ); }if (temp &ALI15X3_STS_TERM ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); }
@@ -320,7 +320,7 @@ static int ali15x3_transaction(struct i2This means that bus collisions go unreported. */ if (temp &ALI15X3_STS_COLL ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"Error: no response or bus collision ADD=%02x\n" ,inb_p (SMBHSTADD ));
@@ -328,7 +328,7 @@ static int ali15x3_transaction(struct i2/* haven't ever seen this */ if (temp &ALI15X3_STS_DEV ) { - result =-1 ; + result = -EIO ;dev_err (&adap->dev,"Error: device error\n" ); } dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "
@@ -338,7 +338,7 @@ static int ali15x3_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 ali15x3_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data)
@@ -364,7 +364,7 @@ static s32 ali15x3_access(struct i2c_adaswitch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); -return -1 ; +return -EOPNOTSUPP ;case I2C_SMBUS_QUICK :outb_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMBHSTADD );
@@ -421,8 +421,9 @@ static s32 ali15x3_access(struct i2c_adaoutb_p (size,SMBHSTCNT );/* output command */ -if (ali15x3_transaction (adap))/* Error in transaction */ -return -1 ; + temp =ali15x3_transaction (adap); +if (temp) +return temp;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==ALI15X3_QUICK ))return 0 ;
drivers/i2c/busses/i2c-amd756-s4882.c +2 -2
@@ -58,7 +58,7 @@ static s32 amd756_access_virt0(struct i2/* We exclude the multiplexed addresses */ if (addr ==0x4c || (addr &0xfc ) ==0x50 || (addr &0xfc ) ==0x30 || addr ==0x18 ) -return -1 ; +return -EINVAL ;mutex_lock (&amd756_lock);
@@ -86,7 +86,7 @@ static inline s32 amd756_access_channel(/* We exclude the non-multiplexed addresses */ if (addr !=0x4c && (addr &0xfc ) !=0x50 && (addr &0xfc ) !=0x30 ) -return -1 ; +return -EINVAL ;mutex_lock (&amd756_lock);
drivers/i2c/busses/i2c-amd756.c +10 -8
@@ -151,17 +151,17 @@ static int amd756_transaction(struct i2c }if (temp &GS_PRERR_STS ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"SMBus Protocol error (no response)!\n" ); }if (temp &GS_COL_STS ) { - result =-1 ; + result = -EIO ;dev_warn (&adap->dev,"SMBus collision!\n" ); }if (temp &GS_TO_STS ) { - result =-1 ; + result = -ETIMEDOUT ;dev_dbg (&adap->dev,"SMBus protocol timeout!\n" ); }
@@ -189,22 +189,23 @@ static int amd756_transaction(struct i2coutw_p (inw (SMB_GLOBAL_ENABLE ) |GE_ABORT ,SMB_GLOBAL_ENABLE );msleep (100 );outw_p (GS_CLEAR_STS ,SMB_GLOBAL_STATUS ); -return -1 ; +return -EIO ; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 amd756_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {int i, len; +int status;/** TODO: Should I supporte the 10-bit transfers? */ switch (size) {case I2C_SMBUS_PROC_CALL :dev_dbg (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" );/* TODO: Well... It is supported, I'm just not sure what to do here... */ -return -1 ; +return -EOPNOTSUPP ;case I2C_SMBUS_QUICK :outw_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMB_HOST_ADDRESS );
@@ -256,8 +257,9 @@ static s32 amd756_access(struct i2c_adap/* How about enabling interrupts... */ outw_p (size &GE_CYC_TYPE_MASK ,SMB_GLOBAL_ENABLE ); -if (amd756_transaction (adap))/* Error in transaction */ -return -1 ; + status =amd756_transaction (adap); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==AMD756_QUICK ))return 0 ;
drivers/i2c/busses/i2c-amd8111.c +28 -16
99 lines not on this page · raw message
drivers/i2c/busses/i2c-i801.c +23 -22
155 lines not on this page · raw message
drivers/i2c/busses/i2c-nforce2.c +13 -12
@@ -145,16 +145,16 @@ static int nforce2_check_status(struct idev_dbg (&adap->dev,"SMBus Timeout!\n" );if (smbus->can_abort)nforce2_abort (adap); -return -1 ; +return -ETIMEDOUT ; }if (!(temp &NVIDIA_SMB_STS_DONE ) || (temp &NVIDIA_SMB_STS_STATUS )) {dev_dbg (&adap->dev,"Transaction failed (0x%02x)!\n" , temp); -return -1 ; +return -EIO ; }return 0 ; } -/* Return -1 on error */ +/* Return negative errno on error */ static s32 nforce2_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data)
@@ -162,7 +162,7 @@ static s32 nforce2_access(struct i2c_adastruct nforce2_smbus *smbus = adap->algo_data;unsigned char protocol, pec;u8 len; -int i; +int i, status; protocol = (read_write ==I2C_SMBUS_READ ) ?NVIDIA_SMB_PRTCL_READ :NVIDIA_SMB_PRTCL_WRITE ;
@@ -206,7 +206,7 @@ static s32 nforce2_access(struct i2c_ada"Transaction failed " "(requested block size: %d)\n" , len); -return -1 ; +return -E2BIG ; }outb_p (len,NVIDIA_SMB_BCNT );for (i =0 ; i <I2C_SMBUS_BLOCK_MAX ; i++)
@@ -218,14 +218,15 @@ static s32 nforce2_access(struct i2c_adadefault :dev_err (&adap->dev,"Unsupported transaction %d\n" , size); -return -1 ; +return -EOPNOTSUPP ; }outb_p ((addr &0x7f ) <<1 ,NVIDIA_SMB_ADDR );outb_p (protocol,NVIDIA_SMB_PRTCL ); -if (nforce2_check_status (adap)) -return -1 ; + status =nforce2_check_status (adap); +if (status) +return status;if (read_write ==I2C_SMBUS_WRITE )return 0 ;
@@ -247,7 +248,7 @@ static s32 nforce2_access(struct i2c_adadev_err (&adap->dev,"Transaction failed " "(received block size: 0x%02x)\n" , len); -return -1 ; +return -EILSEQ ; }for (i =0 ; i < len; i++) data->block[i+1 ] =inb_p (NVIDIA_SMB_DATA + i);
@@ -308,7 +309,7 @@ static int __devinit nforce2_probe_smb ( != PCIBIOS_SUCCESSFUL) {dev_err (&dev->dev,"Error reading PCI config for %s\n" , name); -return -1 ; +return -EIO ; } smbus->base = iobase &PCI_BASE_ADDRESS_IO_MASK ;
@@ -318,7 +319,7 @@ static int __devinit nforce2_probe_smb (if (!request_region (smbus->base, smbus->size, nforce2_driver.name)) {dev_err (&smbus->adapter.dev,"Error requesting region %02x .. %02X for %s\n" , smbus->base, smbus->base+smbus->size-1 , name); -return -1 ; +return -EBUSY ; } smbus->adapter.owner =THIS_MODULE ; smbus->adapter.id =I2C_HW_SMBUS_NFORCE2 ;
@@ -333,7 +334,7 @@ static int __devinit nforce2_probe_smb (if (error) {dev_err (&smbus->adapter.dev,"Failed to register adapter.\n" );release_region (smbus->base, smbus->size); -return -1 ; +return error; }dev_info (&smbus->adapter.dev,"nForce2 SMBus adapter at %#x\n" , smbus->base);return 0 ;
drivers/i2c/busses/i2c-piix4.c +11 -9
@@ -220,7 +220,7 @@ static int piix4_transaction(void)outb_p (temp,SMBHSTSTS );if ((temp =inb_p (SMBHSTSTS )) !=0x00 ) {dev_err (&piix4_adapter.dev,"Failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&piix4_adapter.dev,"Successful!\n" ); }
@@ -238,23 +238,23 @@ static int piix4_transaction(void)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_err (&piix4_adapter.dev,"SMBus Timeout!\n" ); - result =-1 ; + result = -ETIMEDOUT ; }if (temp &0x10 ) { - result =-1 ; + result = -EIO ;dev_err (&piix4_adapter.dev,"Error: Failed bus transaction\n" ); }if (temp &0x08 ) { - result =-1 ; + result = -EIO ;dev_dbg (&piix4_adapter.dev,"Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n" );/* Clock stops and slave is stuck in mid-transmission */ }if (temp &0x04 ) { - result =-1 ; + result = -EIO ;dev_dbg (&piix4_adapter.dev,"Error: no response!\n" ); }
@@ -272,17 +272,18 @@ static int piix4_transaction(void)return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 piix4_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {int i, len; +int status;switch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); -return -1 ; +return -EOPNOTSUPP ;case I2C_SMBUS_QUICK :outb_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMBHSTADD );
@@ -334,8 +335,9 @@ static s32 piix4_access(struct i2c_adaptoutb_p ((size &0x1C ) + (ENABLE_INT9 &1 ),SMBHSTCNT ); -if (piix4_transaction ())/* Error in transaction */ -return -1 ; + status =piix4_transaction (); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==PIIX4_QUICK ))return 0 ;
drivers/i2c/busses/i2c-sis5595.c +11 -8
@@ -236,7 +236,7 @@ static int sis5595_transaction(struct i2sis5595_write (SMB_STS_HI , temp >>8 );if ((temp =sis5595_read (SMB_STS_LO ) + (sis5595_read (SMB_STS_HI ) <<8 )) !=0x00 ) {dev_dbg (&adap->dev,"Failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&adap->dev,"Successful!\n" ); }
@@ -254,19 +254,19 @@ static int sis5595_transaction(struct i2/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_dbg (&adap->dev,"SMBus Timeout!\n" ); - result =-1 ; + result = -ETIMEDOUT ; }if (temp &0x10 ) {dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); - result =-1 ; + result = -EIO ; }if (temp &0x20 ) {dev_err (&adap->dev,"Bus collision! SMBus may be locked until " "next hard reset (or not...)\n" );/* Clock stops and slave is stuck in mid-transmission */ - result =-1 ; + result = -EIO ; } temp =sis5595_read (SMB_STS_LO ) + (sis5595_read (SMB_STS_HI ) <<8 );
@@ -282,11 +282,13 @@ static int sis5595_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis5595_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data) { +int status; +switch (size) {case I2C_SMBUS_QUICK :sis5595_write (SMB_ADDR , ((addr &0x7f ) <<1 ) | (read_write &0x01 ));
@@ -318,13 +320,14 @@ static s32 sis5595_access(struct i2c_adabreak ;default :dev_warn (&adap->dev,"Unsupported transaction %d\n" , size); -return -1 ; +return -EOPNOTSUPP ; }sis5595_write (SMB_CTL_LO , ((size &0x0E ))); -if (sis5595_transaction (adap)) -return -1 ; + status =sis5595_transaction (adap); +if (status) +return status;if ((size !=SIS5595_PROC_CALL ) && ((read_write ==I2C_SMBUS_WRITE ) || (size ==SIS5595_QUICK )))
drivers/i2c/busses/i2c-sis630.c +25 -18
109 lines not on this page · raw message
drivers/i2c/busses/i2c-sis96x.c +11 -9
@@ -111,7 +111,7 @@ static int sis96x_transaction(int size)/* check it again */ if (((temp =sis96x_read (SMB_CNT )) &0x03 ) !=0x00 ) {dev_dbg (&sis96x_adapter.dev,"Failed (0x%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&sis96x_adapter.dev,"Successful\n" ); }
@@ -136,19 +136,19 @@ static int sis96x_transaction(int size)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_dbg (&sis96x_adapter.dev,"SMBus Timeout! (0x%02x)\n" , temp); - result =-1 ; + result = -ETIMEDOUT ; }/* device error - probably missing ACK */ if (temp &0x02 ) {dev_dbg (&sis96x_adapter.dev,"Failed bus transaction!\n" ); - result =-1 ; + result = -EIO ; }/* bus collision */ if (temp &0x04 ) {dev_dbg (&sis96x_adapter.dev,"Bus collision!\n" ); - result =-1 ; + result = -EIO ; }/* Finish up by resetting the bus */
@@ -161,11 +161,12 @@ static int sis96x_transaction(int size)return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis96x_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) { +int status;switch (size) {case I2C_SMBUS_QUICK :
@@ -203,17 +204,18 @@ static s32 sis96x_access(struct i2c_adapcase I2C_SMBUS_BLOCK_DATA :/* TO DO: */ dev_info (&adap->dev,"SMBus block not implemented!\n" ); -return -1 ; +return -EOPNOTSUPP ;break ;default :dev_info (&adap->dev,"Unsupported I2C size\n" ); -return -1 ; +return -EMSGSIZE ;break ; } -if (sis96x_transaction (size)) -return -1 ; + status =sis96x_transaction (size); +if (status) +return status;if ((size != SIS96x_PROC_CALL) && ((read_write ==I2C_SMBUS_WRITE ) || (size == SIS96x_QUICK)))
drivers/i2c/busses/i2c-stub.c +2 -2
@@ -43,7 +43,7 @@ struct stub_chip {static struct stub_chip *stub_chips; -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 stub_xfer (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {
@@ -120,7 +120,7 @@ static s32 stub_xfer(struct i2c_adapterdefault :dev_dbg (&adap->dev,"Unsupported I2C/SMBus command\n" ); - ret =-1 ; + ret = -EOPNOTSUPP ;break ; }/* switch (size) */
drivers/i2c/busses/i2c-viapro.c +11 -9
@@ -152,7 +152,7 @@ static int vt596_transaction(u8 size)if ((temp =inb_p (SMBHSTSTS )) &0x1F ) {dev_err (&vt596_adapter.dev,"SMBus reset failed! " "(0x%02x)\n" , temp); -return -1 ; +return -EBUSY ; } }
@@ -167,24 +167,24 @@ static int vt596_transaction(u8 size)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&vt596_adapter.dev,"SMBus timeout!\n" ); }if (temp &0x10 ) { - result =-1 ; + result = -EIO ;dev_err (&vt596_adapter.dev,"Transaction failed (0x%02x)\n" , size); }if (temp &0x08 ) { - result =-1 ; + result = -EIO ;dev_err (&vt596_adapter.dev,"SMBus collision!\n" ); }if (temp &0x04 ) {int read =inb_p (SMBHSTADD ) &0x01 ; - result =-1 ; + result = -EIO ;/* The quick and receive byte commands are used to probe for chips, so errors are expected, and we don't want to frighten the user. */
@@ -202,12 +202,13 @@ static int vt596_transaction(u8 size)return result; } -/* Return -1 on error, 0 on success */ +/* Return negative errno on error, 0 on success */ static s32 vt596_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data) {int i; +int status;switch (size) {case I2C_SMBUS_QUICK :
@@ -258,8 +259,9 @@ static s32 vt596_access(struct i2c_adaptoutb_p (((addr &0x7f ) <<1 ) | read_write,SMBHSTADD ); -if (vt596_transaction (size))/* Error in transaction */ -return -1 ; + status =vt596_transaction (size); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==VT596_QUICK ))return 0 ;
@@ -287,7 +289,7 @@ static s32 vt596_access(struct i2c_adapt exit_unsupported:dev_warn (&vt596_adapter.dev,"Unsupported command invoked! (0x%02x)\n" , size); -return -1 ; +return -EOPNOTSUPP ; }static u32 vt596_func (struct i2c_adapter *adapter)
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805012046.07885.david-b-yBeKhBN/[email protected]
Hi David,
Quoted 11 lines · David Brownell
Tighten error paths used by various other i2c adapters so they return real fault/errno codes instead of a literal "-1" (which is most often interpreted as "
-EPERM"). Build tested.Signed-off-by David Brownell <[email protected]>---
NOTE there are many other adapter drivers to audit and update; and they're not just within thedrivers/i2ctree. This patch is a PC oriented start on some bottom-up improvement of fault reporting. The i2c-gpio code looks be good too.
Quoted 16 lines
drivers/i2c/algos/i2c-algo-bit.c | 11 +++++--- drivers/i2c/busses/i2c-ali1535.c | 22 +++++++--------- drivers/i2c/busses/i2c-ali1563.c | 4 +-- drivers/i2c/busses/i2c-ali15x3.c | 19 +++++++------- drivers/i2c/busses/i2c-amd756-s4882.c | 4 +-- drivers/i2c/busses/i2c-amd756.c | 18 +++++++------ drivers/i2c/busses/i2c-amd8111.c | 44 +++++++++++++++++++++------------ drivers/i2c/busses/i2c-i801.c | 45 +++++++++++++++++----------------- drivers/i2c/busses/i2c-nforce2.c | 25 +++++++++--------- drivers/i2c/busses/i2c-piix4.c | 20 ++++++++------- drivers/i2c/busses/i2c-sis5595.c | 19 ++++++++------ drivers/i2c/busses/i2c-sis630.c | 43 ++++++++++++++++++-------------- drivers/i2c/busses/i2c-sis96x.c | 20 ++++++++------- drivers/i2c/busses/i2c-stub.c | 4 +-- drivers/i2c/busses/i2c-viapro.c | 20 ++++++++------- 15 files changed, 176 insertions(+), 142 deletions(-)
I am in the process of reviewing and testing this patch. I think it would help me if you could list your error value choices for the common error conditions of I2C and SMBus controllers (bus busy, arbitration lost, transaction timeout, etc.) With such a list I could check the different drivers for consistency, and maybe this could even become documentation for future driver authors.
Thanks,
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 6 lines · Jean Delvare
I am in the process of reviewing and testing this patch. I think it would help me if you could list your error value choices for the common error conditions of I2C and SMBus controllers (bus busy, arbitration lost, transaction timeout, etc.) With such a list I could check the different drivers for consistency, and maybe this could even become documentation for future driver authors.
Yeah, I'll write something up. Agreed that would be handy ... and since not all the fault codes indicate errors (losing arbitration, for example), it's important to agree on codes where we think that drivers should eventually be able to kick in recovery strategies.
- Dave
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
Quoted 6 lines · Jean Delvare
I am in the process of reviewing and testing this patch. I think it would help me if you could list your error value choices for the common error conditions of I2C and SMBus controllers (bus busy, arbitration lost, transaction timeout, etc.) With such a list I could check the different drivers for consistency, and maybe this could even become documentation for future driver authors.
Here's a patch adding such information ... against 2.6.26-rc2 and in synch with both the "-Errno not -1" patches I've sent.
- Dave
=============== CUT HERE
Create Documentation/i2c/fault-codes.txt to help standardize fault/error code usage in the I2C stack. It turns out that returning -1 (-EPERM) for everything was not at all helpful.
--- Documentation/i2c/fault-codes.txt | 118 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+)
Documentation/i2c/fault-codes.txt new file +118 -0
@@ -0,0 +1,118 @@ +This is a summary of the most important conventions for use of fault +codes in the I2C/SMBus stack. + + +A "Fault" is not always an "Error" +---------------------------------- +Not all fault reports imply errors; "page faults" should be a familiar +example. Software often retries idempotent operations after transient +faults. There may be fancier recovery schemes that are appropriate in +some cases, such as re-initializing (and maybe resetting). After such +recovery, triggered by a fault report, there is no error. + +In a similar way, sometimes a "fault" code just reports one defined +result for an operation ... it doesn't indicate that anything is wrong +at all, just that the the outcome wasn't on the "golden path". + +In short, your I2C driver code may need to know these codes in order +to respond correctly. Other code may need to rely on YOUR code reporting +the right fault code, so that it can (in turn) behave correctly. + + +I2C and SMBus fault codes +------------------------- +These are returned as negative numbers from most calls, with zero or +some positive number indicating a non-fault return. The specific +numbers associated with these symbols differ between architectures, +though most Linux systems use <asm-generic/errno*.h> numbering. + +Note that the descriptions here are not exhaustive. There are other +codes that may be returned, and other cases where these codes should +be returned. However, drivers should not return other codes for these +cases (unless the hardware doesn't provide unique fault reports). + +Also, codes returned by adapter probe methods follow rules which are +specific to their host bus (such as PCI, or the platform bus). + + +EAGAIN + Returned by I2C adapters when they lose arbitration in master + transmit mode: some other master was transmitting different + data at the same time. + + Also returned when trying to invoke an I2C operation in an + atomic context, when some task is already using that I2C bus + to execture some other operation. + +EBADMSG + Returned by SMBus logic when an invalid Packet Error Code byte + is received. This code is a CRC covering all bytes in the + transaction, and is sent before the terminating STOP. This + fault is only reported on read transactions; the SMBus slave + may have a way to report PEC mismatches on writes from the + host. Note that even if PECs are in use, you should not rely + on these as the only way to detect incorrect data transfers. + +EBUSY + Returned by SMBus adapters when the bus was busy for longer + than allowed. This usually indicates some device (maybe the + SMBus adapter) needs some fault recovery (such as resetting), + or that the reset was attempted but failed. + +EINVAL + This rather vague error means an invalid parameter has been + detected before any I/O operation was started. Use a more + specific fault code when you can. + + One example would be a driver trying an SMBus Block Write + with block size outside the range of 1-32 bytes. + +EIO + This rather vague error means something went wrong when + performing an I/O operation. Use a more specific fault + code when you can. + +ENODEV + Returned by driver probe() methods, This is a bit more + specific than ENXIO, implying the problem isn't with the + address, but with the device found there. Driver probes + often do more than just verify that something responds to + an address; they may also verify the *correct* responses. + +ENOMEM + Returned by any component that can't allocate memory when + it needs to do so. + +ENXIO + Returned by I2C adapters to indicate that the address phase + of a transfer didn't get an ACK. While it might just mean + an I2C device was temporarily not responding, usually it + means there's nothing listening at that address. + + Returned by driver probe() methods to indicate that they + found no device to bind to. (ENODEV may also be used.) + +EOPNOTSUPP + Returned by an adapter when asked to perform an operation + that it doesn't, or can't, support. For example, if an + adapter doesn't support SMBus block transfers, this would + be returned when it is asked to issue one. Or if an I2C + adapter can't execute all legal I2C messages, it should + return this in some cases. + +EPROTO + Returned when the length of an SMBus Block Read data response + (from the SMBus slave) is outside the range 1-32 bytes. + +ETIMEDOUT + This is returned by drivers when an operation took too much + time, and was aborted before it completed. (However, use + ENXIO for timeouts when sending the first address byte.) + + SMBus adapters may return it when an operation took more + time than allowed by the SMBus specification; for example, + when a slave stretches clocks too far. I2C has no such + timeouts, but it's normal for I2C adapters to impose some + arbitrary limits (much longer than SMBus!) too. + +
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805120948.23842.david-b-yBeKhBN/[email protected]
Hi David,
Quoted 10 lines · David Brownell
Quoted 6 lines · Jean Delvare
I am in the process of reviewing and testing this patch. I think it would help me if you could list your error value choices for the common error conditions of I2C and SMBus controllers (bus busy, arbitration lost, transaction timeout, etc.) With such a list I could check the different drivers for consistency, and maybe this could even become documentation for future driver authors.
Here's a patch adding such information ... against 2.6.26-rc2 and in synch with both the "-Errno not -1" patches I've sent.
Thanks for doing this. This document will be very helpful both for me when reviewing your patches, and for both I2C bus and I2C device driver authors later.
Quoted 11 lines
- Dave
=============== CUT HERE
CreateDocumentation/i2c/fault-codes.txtto help standardize fault/error code usage in the I2C stack. It turns out that returning -1 (-EPERM) for everything was not at all helpful.Signed-off-by David Brownell <[email protected]>--- Documentation/i2c/fault-codes.txt | 118 ++++++++++++++++++++++++++++++++++++++
No file in this directory has a .txt suffix, so I guess we'd just name the file fault-codes for consistency.
Documentation/i2c/fault-codes.txt line 8
Quoted 13 lines
1 file changed, 118 insertions(+)Documentation/i2c/fault-codes.txt new file +8
-0@@ -0,0 +1,118 @@ +This is a summary of the most important conventions for use of fault +codes in the I2C/SMBus stack. + + +A "Fault" is not always an "Error" +---------------------------------- +Not all fault reports imply errors; "page faults" should be a familiar +example. Software often retries idempotent operations after transient
Too many spaces after dot. I'm fine with 2 if you like it, but 3 is to many.
Documentation/i2c/fault-codes.txt line 15
Quoted 7 lines
Documentation/i2c/fault-codes.txt new file +7
-0+faults. There may be fancier recovery schemes that are appropriate in +some cases, such as re-initializing (and maybe resetting). After such +recovery, triggered by a fault report, there is no error. + +In a similar way, sometimes a "fault" code just reports one defined +result for an operation ... it doesn't indicate that anything is wrong +at all, just that the the outcome wasn't on the "golden path".
Doubled "the".
Quoted 20 lines
Documentation/i2c/fault-codes.txt new file +20
-0+ +In short, your I2C driver code may need to know these codes in order +to respond correctly. Other code may need to rely on YOUR code reporting +the right fault code, so that it can (in turn) behave correctly. + + +I2C and SMBus fault codes +------------------------- +These are returned as negative numbers from most calls, with zero or +some positive number indicating a non-fault return. The specific +numbers associated with these symbols differ between architectures, +though most Linux systems use <asm-generic/errno*.h> numbering. + +Note that the descriptions here are not exhaustive. There are other +codes that may be returned, and other cases where these codes should +be returned. However, drivers should not return other codes for these +cases (unless the hardware doesn't provide unique fault reports). + +Also, codes returned by adapter probe methods follow rules which are +specific to their host bus (such as PCI, or the platform bus).
Documentation/i2c/fault-codes.txt line 45
Quoted 10 lines
Documentation/i2c/fault-codes.txt new file +10
-0+ + +EAGAIN + Returned by I2C adapters when they lose arbitration in master + transmit mode: some other master was transmitting different + data at the same time. + + Also returned when trying to invoke an I2C operation in an + atomic context, when some task is already using that I2C bus + to execture some other operation.
excecute?
Documentation/i2c/fault-codes.txt line 54
Quoted 9 lines
Documentation/i2c/fault-codes.txt new file +9
-0+ +EBADMSG + Returned by SMBus logic when an invalid Packet Error Code byte + is received. This code is a CRC covering all bytes in the + transaction, and is sent before the terminating STOP. This + fault is only reported on read transactions; the SMBus slave + may have a way to report PEC mismatches on writes from the + host. Note that even if PECs are in use, you should not rely + on these as the only way to detect incorrect data transfers.
As far as I can see, only the i2c-core is returning this error when SMBus is emulated over I2C, SMBus master drivers do not? If it is a hardware limitation of most SMBus controllers then I wonder if it is worth having a separate error code just for i2c-core.
Quoted 12 lines
Documentation/i2c/fault-codes.txt new file +12
-0+ +EBUSY + Returned by SMBus adapters when the bus was busy for longer + than allowed. This usually indicates some device (maybe the + SMBus adapter) needs some fault recovery (such as resetting), + or that the reset was attempted but failed. + +EINVAL + This rather vague error means an invalid parameter has been + detected before any I/O operation was started. Use a more + specific fault code when you can. +
Documentation/i2c/fault-codes.txt line 76
Quoted 10 lines
Documentation/i2c/fault-codes.txt new file +10
-0+ One example would be a driver trying an SMBus Block Write + with block size outside the range of 1-32 bytes. + +EIO + This rather vague error means something went wrong when + performing an I/O operation. Use a more specific fault + code when you can. + +ENODEV + Returned by driver probe() methods, This is a bit more
I guess you want a dot rather than comma, and one less space.
Documentation/i2c/fault-codes.txt line 80
Quoted 4 lines
Documentation/i2c/fault-codes.txt new file +4
-0+ specific than ENXIO, implying the problem isn't with the + address, but with the device found there. Driver probes + often do more than just verify that something responds to + an address; they may also verify the *correct* responses.
In fact driver probes should never verify that something responds to an address. That's not their job; by the time they are called, either i2c-core has done a probe, or some code guaranteed that there was a device at this address, or (for legacy devices) the user explicitly asked for the device presence check to be skipped.
It may happen that, while they are checking something about the device, they discover that apparently there is no device at all, but this is only a side effect.
Documentation/i2c/fault-codes.txt line 89
Quoted 9 lines
Documentation/i2c/fault-codes.txt new file +9
-0+ +ENOMEM + Returned by any component that can't allocate memory when + it needs to do so. + +ENXIO + Returned by I2C adapters to indicate that the address phase + of a transfer didn't get an ACK. While it might just mean + an I2C device was temporarily not responding, usually it
Doubled space.
Documentation/i2c/fault-codes.txt line 101
Quoted 12 lines
Documentation/i2c/fault-codes.txt new file +12
-0+ means there's nothing listening at that address. + + Returned by driver probe() methods to indicate that they + found no device to bind to. (ENODEV may also be used.) + +EOPNOTSUPP + Returned by an adapter when asked to perform an operation + that it doesn't, or can't, support. For example, if an + adapter doesn't support SMBus block transfers, this would + be returned when it is asked to issue one. Or if an I2C + adapter can't execute all legal I2C messages, it should + return this in some cases.
It might be worth mentioning here that I2C device drivers are supposed to check the adapter functionality before they run any transaction. So, in most cases, I2C bus drivers would be in their own right to return -EINVAL when requested to perform operations they don't support. We use -EOPNOTSUPP only because it's nice to have a dedicated error value for these cases.
The only (rare) case where EOPNOTSUPP is legitimately returned by a bus driver is when the bus driver doesn't fully support a given transaction type, but cannot express this limitation in the functionality flags (for example a bus driver supporting I2C Block transactions but only for ceertain block lengths.)
Documentation/i2c/fault-codes.txt line 105
Quoted 4 lines
Documentation/i2c/fault-codes.txt new file +4
-0+ +EPROTO + Returned when the length of an SMBus Block Read data response + (from the SMBus slave) is outside the range 1-32 bytes.
While this is the only care where we return this error code currently, I suppose that there could be others in the future, for example for an SMBus block read-block write process call transaction. So maybe it would be better to define this error code as being returned when data sent by a slave doesn't comply with the protocol in general, and then quote the SMBus Block Read length byte as the most common example.
Documentation/i2c/fault-codes.txt line 110
Quoted 5 lines
Documentation/i2c/fault-codes.txt new file +5
-0+ +ETIMEDOUT + This is returned by drivers when an operation took too much + time, and was aborted before it completed. (However, use + ENXIO for timeouts when sending the first address byte.)
No. A missing ack on the address byte leads to no timeout. The master controls the clock, so either ack or nack takes exactly one clock cycle. As far as I remember, clock stretching by a slave during the address byte is not even allowed.
So, there is no need to mention ENXIO and the address byte here.
Documentation/i2c/fault-codes.txt line 116
Quoted 6 lines
Documentation/i2c/fault-codes.txt new file +6
-0+ + SMBus adapters may return it when an operation took more + time than allowed by the SMBus specification; for example, + when a slave stretches clocks too far. I2C has no such + timeouts, but it's normal for I2C adapters to impose some + arbitrary limits (much longer than SMBus!) too.
Thanks,
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 7 lines · Jean Delvare
Hi David,
Quoted 4 lines · David Brownell
Quoted 2 lines · Jean Delvare
... list your error value choices for the common
error conditions of I2C and SMBus controllers ...
Quoted 6 lines
Quoted 2 lines
Here's a patch adding such information ... against 2.6.26-rc2 and in synch with both the "-Errno not -1" patches I've sent.
Thanks for doing this. This document will be very helpful both for me when reviewing your patches, and for both I2C bus and I2C device driver authors later.
Exactly. ;)
I addressed your comments; no further responses except as below.
Quoted 11 lines
Documentation/i2c/fault-codes.txt line 54
Quoted 8 lines
Documentation/i2c/fault-codes.txt new file +8
-0+EBADMSG + Returned by SMBus logic when an invalid Packet Error Code byte + is received. This code is a CRC covering all bytes in the + transaction, and is sent before the terminating STOP. This + fault is only reported on read transactions; the SMBus slave + may have a way to report PEC mismatches on writes from the + host. Note that even if PECs are in use, you should not rely + on these as the only way to detect incorrect data transfers.As far as I can see, only the i2c-core is returning this error when SMBus is emulated over I2C, SMBus master drivers do not?
I didn't check hardware specs or driver details for the three adapters currently reporting I2C_FUNC_SMBUS_PEC: amd8111, i801, and nforce2. So I don't know what they report ...
Quoted 3 lines
If it is a
hardware limitation of most SMBus controllers then I wonder if it is worth having a separate error code just for i2c-core.
As a rule, it's important to know that an error is "soft" (like PEC corruption) or not ... soft errors are very amenable to retries.
So even if those SMBus controllers have braindead designs which don't let drivers know if the failure was from PEC, I'd think that it's worth having such a code. After all, it's not like there's anything *preventing* sane nardware. (Right?!?)
Quoted 10 lines
Documentation/i2c/fault-codes.txt line 101
Quoted 7 lines
Documentation/i2c/fault-codes.txt new file +7
-0+EOPNOTSUPP + Returned by an adapter when asked to perform an operation + that it doesn't, or can't, support. For example, if an + adapter doesn't support SMBus block transfers, this would + be returned when it is asked to issue one. Or if an I2C + adapter can't execute all legal I2C messages, it should + return this in some cases.It might be worth mentioning here that I2C device drivers are supposed to check the adapter functionality before they run any transaction.
Done.
Quoted 3 lines
So,
in most cases, I2C bus drivers would be in their own right to return-EINVALwhen requested to perform operations they don't support.
I'll disagree. The request was valid, and the only thing that was inappropriate was sending it to *this* adapter. Whether a request is valid (or not) should be minimally context-sensitive.
It's an error to make a given valid request to certain adapters; sure. But the *reason* is that the adapter doesn't support such calls ... not that the request itself is invalid.
Quoted 2 lines
As far as I remember, clock stretching by a slave during the
address byte is not even allowed.
It's allowed anywhere. Remember that one of the reasons to stretch is to make sure the device has enough time to react ... and also that multi-master configurations will effectively need to arbitrate the clock signal (looks just like clock stretching), not just the data signal.
Quoted 1 line
So, there is no need to mention ENXIO and the address byte here.
Right, I realized that but it was time to send for review rather than make more edits. ;)
Updated patch in a separate message.
- Dave
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
Quoted 7 lines · Jean Delvare
Quoted 3 lines
Here's a patch adding such information ... against 2.6.26-rc2 and in synch with both the "-Errno not -1" patches I've sent.
Thanks for doing this. This document will be very helpful both for me when reviewing your patches, and for both I2C bus and I2C device driver authors later.
Updated version.
======== CUT HERE
Create Documentation/i2c/fault-codes to help standardize fault/error code usage in the I2C stack. It turns out that returning -1 (-EPERM) for everything was not at all helpful.
--- Documentation/i2c/fault-codes | 127 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+)
Documentation/i2c/fault-codes new file +127 -0
@@ -0,0 +1,127 @@ +This is a summary of the most important conventions for use of fault +codes in the I2C/SMBus stack. + + +A "Fault" is not always an "Error" +---------------------------------- +Not all fault reports imply errors; "page faults" should be a familiar +example. Software often retries idempotent operations after transient +faults. There may be fancier recovery schemes that are appropriate in +some cases, such as re-initializing (and maybe resetting). After such +recovery, triggered by a fault report, there is no error. + +In a similar way, sometimes a "fault" code just reports one defined +result for an operation ... it doesn't indicate that anything is wrong +at all, just that the outcome wasn't on the "golden path". + +In short, your I2C driver code may need to know these codes in order +to respond correctly. Other code may need to rely on YOUR code reporting +the right fault code, so that it can (in turn) behave correctly. + + +I2C and SMBus fault codes +------------------------- +These are returned as negative numbers from most calls, with zero or +some positive number indicating a non-fault return. The specific +numbers associated with these symbols differ between architectures, +though most Linux systems use <asm-generic/errno*.h> numbering. + +Note that the descriptions here are not exhaustive. There are other +codes that may be returned, and other cases where these codes should +be returned. However, drivers should not return other codes for these +cases (unless the hardware doesn't provide unique fault reports). + +Also, codes returned by adapter probe methods follow rules which are +specific to their host bus (such as PCI, or the platform bus). + + +EAGAIN + Returned by I2C adapters when they lose arbitration in master + transmit mode: some other master was transmitting different + data at the same time. + + Also returned when trying to invoke an I2C operation in an + atomic context, when some task is already using that I2C bus + to execute some other operation. + +EBADMSG + Returned by SMBus logic when an invalid Packet Error Code byte + is received. This code is a CRC covering all bytes in the + transaction, and is sent before the terminating STOP. This + fault is only reported on read transactions; the SMBus slave + may have a way to report PEC mismatches on writes from the + host. Note that even if PECs are in use, you should not rely + on these as the only way to detect incorrect data transfers. + +EBUSY + Returned by SMBus adapters when the bus was busy for longer + than allowed. This usually indicates some device (maybe the + SMBus adapter) needs some fault recovery (such as resetting), + or that the reset was attempted but failed. + +EINVAL + This rather vague error means an invalid parameter has been + detected before any I/O operation was started. Use a more + specific fault code when you can. + + One example would be a driver trying an SMBus Block Write + with block size outside the range of 1-32 bytes. + +EIO + This rather vague error means something went wrong when + performing an I/O operation. Use a more specific fault + code when you can. + +ENODEV + Returned by driver probe() methods. This is a bit more + specific than ENXIO, implying the problem isn't with the + address, but with the device found there. Driver probes + may verify the device returns *correct* responses, and + return this as appropriate. (The driver core will warn + about probe faults other than ENXIO and ENODEV.) + +ENOMEM + Returned by any component that can't allocate memory when + it needs to do so. + +ENXIO + Returned by I2C adapters to indicate that the address phase + of a transfer didn't get an ACK. While it might just mean + an I2C device was temporarily not responding, usually it + means there's nothing listening at that address. + + Returned by driver probe() methods to indicate that they + found no device to bind to. (ENODEV may also be used.) + +EOPNOTSUPP + Returned by an adapter when asked to perform an operation + that it doesn't, or can't, support. + + For example, this would be returned when an adapter that + doesn't support SMBus block transfers is asked to execute + one. In that case, the driver making that request should + have verified that functionality was supported before it + made that block transfer request. + + Similarly, if an I2C adapter can't execute all legal I2C + messages, it should return this when asked to perform a + transaction it can't. (These limitations can't be seen in + the adapter's functionality mask, since the assumption is + that if an adapter supports I2C it supports all of I2C.) + +EPROTO + Returned when slave does not conform to the relevant I2C + or SMBus (or chip-specific) protocol specifications. One + case is when the length of an SMBus block data response + (from the SMBus slave) is outside the range 1-32 bytes. + +ETIMEDOUT + This is returned by drivers when an operation took too much + time, and was aborted before it completed. + + SMBus adapters may return it when an operation took more + time than allowed by the SMBus specification; for example, + when a slave stretches clocks too far. I2C has no such + timeouts, but it's normal for I2C adapters to impose some + arbitrary limits (much longer than SMBus!) too. +
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805140750.49365.david-b-yBeKhBN/[email protected]
Jean Delvare
AppliedQuoted 16 lines · David Brownell
Quoted 7 lines · Jean Delvare
Quoted 3 lines
Here's a patch adding such information ... against 2.6.26-rc2 and in synch with both the "-Errno not -1" patches I've sent.
Thanks for doing this. This document will be very helpful both for me when reviewing your patches, and for both I2C bus and I2C device driver authors later.
Updated version.
======== CUT HERE
CreateDocumentation/i2c/fault-codesto help standardize fault/error code usage in the I2C stack. It turns out that returning -1 (-EPERM) for everything was not at all helpful.
Quoted 4 lines
Signed-off-by David Brownell <[email protected]>--- Documentation/i2c/fault-codes | 127 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+)
Applied, thanks.
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
Hi David,
Quoted 3 lines · David Brownell
Tighten error paths used by various other i2c adapters so they return real fault/errno codes instead of a literal "-1" (which is most often interpreted as "
-EPERM"). Build tested.
Thanks for doing this, this was very much needed.
Quoted 45 lines
Signed-off-by David Brownell <[email protected]>---
NOTE there are many other adapter drivers to audit and update; and they're not just within thedrivers/i2ctree. This patch is a PC oriented start on some bottom-up improvement of fault reporting. The i2c-gpio code looks be good too.drivers/i2c/algos/i2c-algo-bit.c | 11 +++++--- drivers/i2c/busses/i2c-ali1535.c | 22 +++++++--------- drivers/i2c/busses/i2c-ali1563.c | 4 +-- drivers/i2c/busses/i2c-ali15x3.c | 19 +++++++------- drivers/i2c/busses/i2c-amd756-s4882.c | 4 +-- drivers/i2c/busses/i2c-amd756.c | 18 +++++++------ drivers/i2c/busses/i2c-amd8111.c | 44 +++++++++++++++++++++------------ drivers/i2c/busses/i2c-i801.c | 45 +++++++++++++++++----------------- drivers/i2c/busses/i2c-nforce2.c | 25 +++++++++--------- drivers/i2c/busses/i2c-piix4.c | 20 ++++++++------- drivers/i2c/busses/i2c-sis5595.c | 19 ++++++++------ drivers/i2c/busses/i2c-sis630.c | 43 ++++++++++++++++++-------------- drivers/i2c/busses/i2c-sis96x.c | 20 ++++++++------- drivers/i2c/busses/i2c-stub.c | 4 +-- drivers/i2c/busses/i2c-viapro.c | 20 ++++++++------- 15 files changed, 176 insertions(+), 142 deletions(-)drivers/i2c/algos/i2c-algo-bit.c +2
-3@@ -317,10 +317,10 @@ bailout:* -x transmission error */ static int try_address (struct i2c_adapter *i2c_adap, -unsigned char addr,int retries) +unsigned char addr,unsigned retries) {struct i2c_algo_bit_data *adap = i2c_adap->algo_data; -int i, ret =-1 ; +int i, ret;for (i =0 ; i <= retries; i++) { ret =i2c_outb (i2c_adap, addr);@@ -465,9 +465,12 @@ static int bit_doAddress(struct i2c_adapstruct i2c_algo_bit_data *adap = i2c_adap->algo_data;unsigned char addr; -int ret, retries;
drivers/i2c/algos/i2c-algo-bit.c static int bit_doAddress(struct i2c_adap · line 476
Quoted 10 lines
drivers/i2c/algos/i2c-algo-bit.c +5
-1+int ret; +unsigned retries; - retries = nak_ok ?0 : i2c_adap->retries; + retries = (nak_ok || i2c_adap->retries <0 ) + ?0 + : i2c_adap->retries;if (flags &I2C_M_TEN ) {/* a ten bit address */
I'd rather not bother with the adap->retries stuff which we agreed should be removed anyway. The err = -1 above was there just to shut up the compiler I guess, make it err = 0 and you're done. That's what it should have been anyway (if we never try, we just get no ack.)
Quoted 27 lines
drivers/i2c/busses/i2c-ali1535.c +3
-3@@ -259,7 +259,7 @@ static int ali1535_transaction(struct i2dev_err (&adap->dev,"SMBus reset failed! (0x%02x) - controller or " "device on bus is probably hung\n" , temp); -return -1 ; +return -EBUSY ; } }else {/* check and clear done bit */ @@ -281,12 +281,12 @@ static int ali1535_transaction(struct i2/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&adap->dev,"SMBus Timeout!\n" ); }if (temp &ALI1535_STS_FAIL ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); }
drivers/i2c/busses/i2c-ali1535.c static int ali1535_transaction(struct i2 · line 298
Quoted 5 lines
drivers/i2c/busses/i2c-ali1535.c +1
-1@@ -295,7 +295,7 @@ static int ali1535_transaction(struct i2* do a printk. This means that bus collisions go unreported. */ if (temp &ALI1535_STS_BUSERR ) { - result =-1 ; + result = -EIO ;
Given the comment above I'd make this -ENODEV. 99% of the time, no ack means no device.
Quoted 29 lines
drivers/i2c/busses/i2c-ali1535.c +3
-3dev_dbg (&adap->dev,"Error: no response or bus collision ADD=%02x\n" ,inb_p (SMBHSTADD ));@@ -303,13 +303,13 @@ static int ali1535_transaction(struct i2/* haven't ever seen this */ if (temp &ALI1535_STS_DEV ) { - result =-1 ; + result = -EIO ;dev_err (&adap->dev,"Error: device error\n" ); }/* check to see if the "command complete" indication is set */ if (!(temp &ALI1535_STS_DONE )) { - result =-1 ; + result = -EIO ;dev_err (&adap->dev,"Error: command never completed\n" ); }@@ -332,7 +332,7 @@ static int ali1535_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 ali1535_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data)
drivers/i2c/busses/i2c-ali1535.c static s32 ali1535_access(struct i2c_ada · line 363
Quoted 6 lines
drivers/i2c/busses/i2c-ali1535.c +1
-1@@ -359,7 +359,7 @@ static s32 ali1535_access(struct i2c_adaswitch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); - result =-1 ; + result = -EOPNOTSUPP ; goto EXIT;
Side note for a next patch: there's a bug here, this should be handled by a catch-all at the end on the switch, but I see it is missing.
Quoted 19 lines
drivers/i2c/busses/i2c-ali1535.c +2
-4case I2C_SMBUS_QUICK : outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),@@ -420,11 +420,9 @@ static s32 ali1535_access(struct i2c_adabreak ; } -if (ali1535_transaction (adap)) { -/* Error in transaction */ - result =-1 ; + result =ali1535_transaction (adap); +if (result) goto EXIT; - }if ((read_write ==I2C_SMBUS_WRITE ) || (size ==ALI1535_QUICK )) { result =0 ;
drivers/i2c/busses/i2c-ali1563.c static int ali1563_transaction(struct i2 · line 126
Quoted 6 lines
drivers/i2c/busses/i2c-ali1563.c +1
-1@@ -122,7 +122,7 @@ static int ali1563_transaction(struct i2outb_p (0x0 ,SMB_HST_CNTL2 ); } -return -1 ; +return -EIO ; }
Here too, I think -ENODEV would be more appropriate in the "bus error" (no answer case).
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 174
Quoted 9 lines
drivers/i2c/busses/i2c-ali1563.c +1
-1static int ali1563_block_start (struct i2c_adapter * a)@@ -170,7 +170,7 @@ static int ali1563_block_start(struct i2 data &HST_STS_BUSERR ?"No response or Bus Collision " :"" , data &HST_STS_DEVERR ?"Device Error " :"" , !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); -return -1 ; +return -EIO ; }
And same here. That's a little more work, admittedly.
Quoted 29 lines
drivers/i2c/busses/i2c-ali1563.c +0
-0static int ali1563_block (struct i2c_adapter * a,union i2c_smbus_data * data,u8 rw)drivers/i2c/busses/i2c-ali15x3.c +3
-3@@ -282,7 +282,7 @@ static int ali15x3_transaction(struct i2dev_err (&adap->dev,"SMBus reset failed! (0x%02x) - " "controller or device on bus is probably hung\n" , temp); -return -1 ; +return -EBUSY ; } }else {/* check and clear done bit */ @@ -304,12 +304,12 @@ static int ali15x3_transaction(struct i2/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&adap->dev,"SMBus Timeout!\n" ); }if (temp &ALI15X3_STS_TERM ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); }
drivers/i2c/busses/i2c-ali15x3.c static int ali15x3_transaction(struct i2 · line 323
Quoted 5 lines
drivers/i2c/busses/i2c-ali15x3.c +1
-1@@ -320,7 +320,7 @@ static int ali15x3_transaction(struct i2This means that bus collisions go unreported. */ if (temp &ALI15X3_STS_COLL ) { - result =-1 ; + result = -EIO ;
Here too, -ENODEV.
Quoted 22 lines
drivers/i2c/busses/i2c-ali15x3.c +2
-2dev_dbg (&adap->dev,"Error: no response or bus collision ADD=%02x\n" ,inb_p (SMBHSTADD ));@@ -328,7 +328,7 @@ static int ali15x3_transaction(struct i2/* haven't ever seen this */ if (temp &ALI15X3_STS_DEV ) { - result =-1 ; + result = -EIO ;dev_err (&adap->dev,"Error: device error\n" ); } dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "@@ -338,7 +338,7 @@ static int ali15x3_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 ali15x3_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data)
drivers/i2c/busses/i2c-ali15x3.c static s32 ali15x3_access(struct i2c_ada · line 367
Quoted 5 lines
drivers/i2c/busses/i2c-ali15x3.c +1
-1@@ -364,7 +364,7 @@ static s32 ali15x3_access(struct i2c_adaswitch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); -return -1 ; +return -EOPNOTSUPP ;
Same bug as i2c-ali1535 (not your fault of course.) I guess we should check all drivers...
Quoted 27 lines
drivers/i2c/busses/i2c-ali15x3.c +3
-2case I2C_SMBUS_QUICK :outb_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMBHSTADD );@@ -421,8 +421,9 @@ static s32 ali15x3_access(struct i2c_adaoutb_p (size,SMBHSTCNT );/* output command */ -if (ali15x3_transaction (adap))/* Error in transaction */ -return -1 ; + temp =ali15x3_transaction (adap); +if (temp) +return temp;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==ALI15X3_QUICK ))return 0 ;drivers/i2c/busses/i2c-amd756-s4882.c +1
-1@@ -58,7 +58,7 @@ static s32 amd756_access_virt0(struct i2/* We exclude the multiplexed addresses */ if (addr ==0x4c || (addr &0xfc ) ==0x50 || (addr &0xfc ) ==0x30 || addr ==0x18 ) -return -1 ; +return -EINVAL ;mutex_lock (&amd756_lock);
drivers/i2c/busses/i2c-amd756-s4882.c static inline s32 amd756_access_channel( · line 91
Quoted 7 lines
drivers/i2c/busses/i2c-amd756-s4882.c +1
-1@@ -86,7 +86,7 @@ static inline s32 amd756_access_channel(/* We exclude the non-multiplexed addresses */ if (addr !=0x4c && (addr &0xfc ) !=0x50 && (addr &0xfc ) !=0x30 ) -return -1 ; +return -EINVAL ;mutex_lock (&amd756_lock);
For these two I'd go for -ENODEV as well. It's a little unfair to return -EINVAL, given that we are hiding the devices from the caller on purpose and they couldn't guess.
drivers/i2c/busses/i2c-amd756.c static int amd756_transaction(struct i2c · line 155
Quoted 10 lines
drivers/i2c/busses/i2c-amd756.c +1
-1@@ -151,17 +151,17 @@ static int amd756_transaction(struct i2c }if (temp &GS_PRERR_STS ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"SMBus Protocol error (no response)!\n" );
This one would be -ENODEV.
Quoted 140 lines
drivers/i2c/busses/i2c-amd756.c +9
-7}if (temp &GS_COL_STS ) { - result =-1 ; + result = -EIO ;dev_warn (&adap->dev,"SMBus collision!\n" ); }if (temp &GS_TO_STS ) { - result =-1 ; + result = -ETIMEDOUT ;dev_dbg (&adap->dev,"SMBus protocol timeout!\n" ); }@@ -189,22 +189,23 @@ static int amd756_transaction(struct i2coutw_p (inw (SMB_GLOBAL_ENABLE ) |GE_ABORT ,SMB_GLOBAL_ENABLE );msleep (100 );outw_p (GS_CLEAR_STS ,SMB_GLOBAL_STATUS ); -return -1 ; +return -EIO ; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 amd756_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {int i, len; +int status;/** TODO: Should I supporte the 10-bit transfers? */ switch (size) {case I2C_SMBUS_PROC_CALL :dev_dbg (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" );/* TODO: Well... It is supported, I'm just not sure what to do here... */ -return -1 ; +return -EOPNOTSUPP ;case I2C_SMBUS_QUICK :outw_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMB_HOST_ADDRESS );@@ -256,8 +257,9 @@ static s32 amd756_access(struct i2c_adap/* How about enabling interrupts... */ outw_p (size &GE_CYC_TYPE_MASK ,SMB_GLOBAL_ENABLE ); -if (amd756_transaction (adap))/* Error in transaction */ -return -1 ; + status =amd756_transaction (adap); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==AMD756_QUICK ))return 0 ;drivers/i2c/busses/i2c-amd8111.c +25
-14@@ -77,7 +77,7 @@ static unsigned int amd_ec_wait_write(stif (!timeout) {dev_warn (&smbus->dev->dev,"Timeout while waiting for IBF to clear\n" ); -return -1 ; +return -ETIMEDOUT ; }return 0 ;@@ -93,7 +93,7 @@ static unsigned int amd_ec_wait_read(strif (!timeout) {dev_warn (&smbus->dev->dev,"Timeout while waiting for OBF to set\n" ); -return -1 ; +return -ETIMEDOUT ; }return 0 ;@@ -102,16 +102,21 @@ static unsigned int amd_ec_wait_read(strstatic unsigned int amd_ec_read (struct amd_smbus *smbus,unsigned char address,unsigned char *data) { -if (amd_ec_wait_write (smbus)) -return -1 ; +int status; + + status =amd_ec_wait_write (smbus); +if (status) +return status;outb (AMD_EC_CMD_RD , smbus->base +AMD_EC_CMD ); -if (amd_ec_wait_write (smbus)) -return -1 ; + status =amd_ec_wait_write (smbus); +if (status) +return status;outb (address, smbus->base +AMD_EC_DATA ); -if (amd_ec_wait_read (smbus)) -return -1 ; + status =amd_ec_wait_read (smbus); +if (status) +return status; *data =inb (smbus->base +AMD_EC_DATA );return 0 ;@@ -120,16 +125,21 @@ static unsigned int amd_ec_read(struct astatic unsigned int amd_ec_write (struct amd_smbus *smbus,unsigned char address,unsigned char data) { -if (amd_ec_wait_write (smbus)) -return -1 ; +int status; + + status =amd_ec_wait_write (smbus); +if (status) +return status;outb (AMD_EC_CMD_WR , smbus->base +AMD_EC_CMD ); -if (amd_ec_wait_write (smbus)) -return -1 ; + status =amd_ec_wait_write (smbus); +if (status) +return status;outb (address, smbus->base +AMD_EC_DATA ); -if (amd_ec_wait_write (smbus)) -return -1 ; + status =amd_ec_wait_write (smbus); +if (status) +return status;outb (data, smbus->base +AMD_EC_DATA );return 0 ;@@ -185,6 +195,7 @@ static s32 amd8111_access(struct i2c_adastruct amd_smbus *smbus = adap->algo_data;unsigned char protocol, len, pec, temp[2 ];int i; +int status; protocol = (read_write ==I2C_SMBUS_READ ) ?AMD_SMB_PRTCL_READ :AMD_SMB_PRTCL_WRITE ;@@ -267,12 +278,13 @@ static s32 amd8111_access(struct i2c_adadefault :
drivers/i2c/busses/i2c-amd8111.c static s32 amd8111_access(struct i2c_ada · line 288
Quoted 10 lines
drivers/i2c/busses/i2c-amd8111.c +2
-1dev_warn (&adap->dev,"Unsupported transaction %d\n" , size); -return -1 ; +return -EOPNOTSUPP ; }amd_ec_write (smbus,AMD_SMB_ADDR , addr <<1 );amd_ec_write (smbus,AMD_SMB_PRTCL , protocol); +/* FIXME this discards status from ec_read() ... */ amd_ec_read (smbus,AMD_SMB_STS , temp +0 );
Same is true of almost all amd_ec_write and amd_ec_read calls, so I don't get the point of adding a comment for this one occurrence in particular.
Quoted 42 lines
drivers/i2c/busses/i2c-amd8111.c +1
-1if (~temp[0 ] &AMD_SMB_STS_DONE ) {@@ -286,7 +298,7 @@ static s32 amd8111_access(struct i2c_ada }if ((~temp[0 ] &AMD_SMB_STS_DONE ) || (temp[0 ] &AMD_SMB_STS_STATUS )) -return -1 ; +return -EIO ;if (read_write ==I2C_SMBUS_WRITE )return 0 ;drivers/i2c/busses/i2c-i801.c +3
-4@@ -151,7 +151,7 @@ static int i801_transaction(int xact)outb_p (temp,SMBHSTSTS );if ((temp = (0x1f &inb_p (SMBHSTSTS ))) !=0x00 ) {dev_dbg (&I801_dev->dev,"Failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&I801_dev->dev,"Successful!\n" ); }@@ -170,7 +170,7 @@ static int i801_transaction(int xact)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_dbg (&I801_dev->dev,"SMBus Timeout!\n" ); - result =-1 ; + result = -ETIMEDOUT ;/* try to stop the current command */ dev_dbg (&I801_dev->dev,"Terminating the current operation\n" );outb_p (inb_p (SMBHSTCNT ) |SMBHSTCNT_KILL ,SMBHSTCNT );@@ -179,19 +179,19 @@ static int i801_transaction(int xact) }if (temp &SMBHSTSTS_FAILED ) { - result =-1 ; + result = -EIO ;dev_dbg (&I801_dev->dev,"Error: Failed bus transaction\n" ); }if (temp &SMBHSTSTS_BUS_ERR ) { - result =-1 ;
drivers/i2c/busses/i2c-i801.c static int i801_transaction(int xact) · line 195
Quoted 10 lines
drivers/i2c/busses/i2c-i801.c +2
-1+ result = -EIO ;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 */ }if (temp &SMBHSTSTS_DEV_ERR ) { - result =-1 ; + result = -EIO ;dev_dbg (&I801_dev->dev,"Error: no response!\n" );
-ENODEV
Quoted 11 lines
drivers/i2c/busses/i2c-i801.c +1
-0}@@ -231,6 +231,7 @@ static int i801_block_transaction_by_blo char read_write, int hwpec) { int i, len; +int status;inb_p (SMBHSTCNT );/* reset the data buffer index */
drivers/i2c/busses/i2c-i801.c static int i801_block_transaction_by_blo · line 247
Quoted 8 lines
drivers/i2c/busses/i2c-i801.c +2
-3@@ -242,14 +243,15 @@ static int i801_block_transaction_by_blooutb_p (data->block[i+1 ],SMBBLKDAT ); } -if (i801_transaction (I801_BLOCK_DATA |ENABLE_INT9 | -I801_PEC_EN * hwpec)) -return -1 ; + status =i801_transaction (I801_BLOCK_DATA |ENABLE_INT9 | +I801_PEC_EN * hwpec);
Please preserve the alignment on opening parenthesis.
drivers/i2c/busses/i2c-i801.c static int i801_block_transaction_by_blo · line 254
Quoted 8 lines
drivers/i2c/busses/i2c-i801.c +3
-1+if (status) +return status;if (read_write ==I2C_SMBUS_READ ) { len =inb_p (SMBHSTDAT0 );if (len <1 || len >I2C_SMBUS_BLOCK_MAX ) -return -1 ; +return -EILSEQ ;
Huh, definitely not. This error code has to so with multi-byte character encoding, that's inappropriate here. I'd return -EINVAL, or -EREMOTEIO if you think EINVAL is unfair for the caller. But most likely, if the returned length is not within the SMBus specifications, it means that the caller ran an SMBus block transaction at the wrong offset or on a device that doesn't support it, so -EINVAL seems reasonable to me.
Quoted 29 lines
drivers/i2c/busses/i2c-i801.c +4
-4data->block[0 ] = len;for (i =0 ; i < len; i++)@@ -314,11 +316,11 @@ static int i801_block_transaction_byte_bif (((temp =inb_p (SMBHSTSTS )) & errmask) !=0x00 ) {dev_err (&I801_dev->dev,"Reset failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }if (i !=1 )/* if die in middle of block transaction, fail */ -return -1 ; +return -EIO ; }if (i ==1 )@@ -342,19 +344,19 @@ static int i801_block_transaction_byte_bmsleep (1 );outb_p (inb_p (SMBHSTCNT ) & (~SMBHSTCNT_KILL ),SMBHSTCNT ); - result =-1 ; + result = -ETIMEDOUT ;dev_dbg (&I801_dev->dev,"SMBus Timeout!\n" ); }if (temp &SMBHSTSTS_FAILED ) { - result =-1 ; + result = -EIO ;
drivers/i2c/busses/i2c-i801.c static int i801_block_transaction_byte_b · line 360
Quoted 10 lines
drivers/i2c/busses/i2c-i801.c +2
-2dev_dbg (&I801_dev->dev,"Error: Failed bus transaction\n" ); }else if (temp &SMBHSTSTS_BUS_ERR ) { - result =-1 ; + result = -EIO ;dev_err (&I801_dev->dev,"Bus collision!\n" ); }else if (temp &SMBHSTSTS_DEV_ERR ) { - result =-1 ; + result = -EIO ;dev_dbg (&I801_dev->dev,"Error: no response!\n" );
-ENODEV
drivers/i2c/busses/i2c-i801.c static int i801_block_transaction_byte_b · line 367
Quoted 8 lines
drivers/i2c/busses/i2c-i801.c +1
-1}@@ -362,7 +364,7 @@ static int i801_block_transaction_byte_b && command != I2C_SMBUS_I2C_BLOCK_DATA) { len =inb_p (SMBHSTDAT0 );if (len <1 || len >I2C_SMBUS_BLOCK_MAX ) -return -1 ; +return -EILSEQ ;
Same as above.
drivers/i2c/busses/i2c-i801.c static int i801_block_transaction_byte_b · line 390
Quoted 11 lines
drivers/i2c/busses/i2c-i801.c +0
-1data->block[0 ] = len; }@@ -383,7 +385,6 @@ static int i801_block_transaction_byte_b"ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n" , i,inb_p (SMBHSTCNT ),inb_p (SMBHSTCMD ),inb_p (SMBHSTADD ), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT)); -if (result <0 )return result; }
Pointless, please revert.
Quoted 77 lines
drivers/i2c/busses/i2c-i801.c +5
-5@@ -394,7 +395,7 @@ static int i801_set_block_buffer_mode(vo {outb_p (inb_p (SMBAUXCTL ) |SMBAUXCTL_E32B ,SMBAUXCTL );if ((inb_p (SMBAUXCTL ) &SMBAUXCTL_E32B ) ==0 ) -return -1 ; +return -EIO ;return 0 ; }@@ -414,7 +415,7 @@ static int i801_block_transaction(union }else if (!(i801_features &FEATURE_I2C_BLOCK_READ )) {dev_err (&I801_dev->dev,"I2C block read is unsupported!\n" ); -return -1 ; +return -EOPNOTSUPP ; } }@@ -449,7 +450,7 @@ static int i801_block_transaction(unionreturn result; } -/* Return -1 on error. */ +/* Return negative errno 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)@@ -514,7 +515,7 @@ static s32 i801_access(struct i2c_adaptecase I2C_SMBUS_PROC_CALL :default :dev_err (&I801_dev->dev,"Unsupported transaction %d\n" , size); -return -1 ; +return -EOPNOTSUPP ; }if (hwpec)/* enable/disable hardware PEC */ @@ -537,7 +538,7 @@ static s32 i801_access(struct i2c_adapteif (block)return ret;if (ret) -return -1 ; +return ret;if ((read_write ==I2C_SMBUS_WRITE ) || (xact ==I801_QUICK ))return 0 ;drivers/i2c/busses/i2c-nforce2.c +4
-4@@ -145,16 +145,16 @@ static int nforce2_check_status(struct idev_dbg (&adap->dev,"SMBus Timeout!\n" );if (smbus->can_abort)nforce2_abort (adap); -return -1 ; +return -ETIMEDOUT ; }if (!(temp &NVIDIA_SMB_STS_DONE ) || (temp &NVIDIA_SMB_STS_STATUS )) {dev_dbg (&adap->dev,"Transaction failed (0x%02x)!\n" , temp); -return -1 ; +return -EIO ; }return 0 ; } -/* Return -1 on error */ +/* Return negative errno on error */ static s32 nforce2_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data)@@ -162,7 +162,7 @@ static s32 nforce2_access(struct i2c_adastruct nforce2_smbus *smbus = adap->algo_data;unsigned char protocol, pec;u8 len; -int i; +int i, status; protocol = (read_write ==I2C_SMBUS_READ ) ?NVIDIA_SMB_PRTCL_READ :NVIDIA_SMB_PRTCL_WRITE ;
drivers/i2c/busses/i2c-nforce2.c static s32 nforce2_access(struct i2c_ada · line 209
Quoted 5 lines
drivers/i2c/busses/i2c-nforce2.c +1
-1@@ -206,7 +206,7 @@ static s32 nforce2_access(struct i2c_ada"Transaction failed " "(requested block size: %d)\n" , len); -return -1 ; +return -E2BIG ;
-E2BIG means argument list too long, it hardly applied here. Again, -EINVAL seems appropriate to me.
Quoted 23 lines
drivers/i2c/busses/i2c-nforce2.c +4
-3}outb_p (len,NVIDIA_SMB_BCNT );for (i =0 ; i <I2C_SMBUS_BLOCK_MAX ; i++)@@ -218,14 +218,15 @@ static s32 nforce2_access(struct i2c_adadefault :dev_err (&adap->dev,"Unsupported transaction %d\n" , size); -return -1 ; +return -EOPNOTSUPP ; }outb_p ((addr &0x7f ) <<1 ,NVIDIA_SMB_ADDR );outb_p (protocol,NVIDIA_SMB_PRTCL ); -if (nforce2_check_status (adap)) -return -1 ; + status =nforce2_check_status (adap); +if (status) +return status;if (read_write ==I2C_SMBUS_WRITE )return 0 ;
drivers/i2c/busses/i2c-nforce2.c static s32 nforce2_access(struct i2c_ada · line 252
Quoted 6 lines
drivers/i2c/busses/i2c-nforce2.c +1
-1@@ -247,7 +248,7 @@ static s32 nforce2_access(struct i2c_adadev_err (&adap->dev,"Transaction failed " "(received block size: 0x%02x)\n" , len); -return -1 ; +return -EILSEQ ; }
See above.
Quoted 56 lines
drivers/i2c/busses/i2c-nforce2.c +3
-3for (i =0 ; i < len; i++) data->block[i+1 ] =inb_p (NVIDIA_SMB_DATA + i);@@ -308,7 +309,7 @@ static int __devinit nforce2_probe_smb ( != PCIBIOS_SUCCESSFUL) {dev_err (&dev->dev,"Error reading PCI config for %s\n" , name); -return -1 ; +return -EIO ; } smbus->base = iobase &PCI_BASE_ADDRESS_IO_MASK ;@@ -318,7 +319,7 @@ static int __devinit nforce2_probe_smb (if (!request_region (smbus->base, smbus->size, nforce2_driver.name)) {dev_err (&smbus->adapter.dev,"Error requesting region %02x .. %02X for %s\n" , smbus->base, smbus->base+smbus->size-1 , name); -return -1 ; +return -EBUSY ; } smbus->adapter.owner =THIS_MODULE ; smbus->adapter.id =I2C_HW_SMBUS_NFORCE2 ;@@ -333,7 +334,7 @@ static int __devinit nforce2_probe_smb (if (error) {dev_err (&smbus->adapter.dev,"Failed to register adapter.\n" );release_region (smbus->base, smbus->size); -return -1 ; +return error; }dev_info (&smbus->adapter.dev,"nForce2 SMBus adapter at %#x\n" , smbus->base);return 0 ;drivers/i2c/busses/i2c-piix4.c +3
-4@@ -220,7 +220,7 @@ static int piix4_transaction(void)outb_p (temp,SMBHSTSTS );if ((temp =inb_p (SMBHSTSTS )) !=0x00 ) {dev_err (&piix4_adapter.dev,"Failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&piix4_adapter.dev,"Successful!\n" ); }@@ -238,23 +238,23 @@ static int piix4_transaction(void)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_err (&piix4_adapter.dev,"SMBus Timeout!\n" ); - result =-1 ; + result = -ETIMEDOUT ; }if (temp &0x10 ) { - result =-1 ; + result = -EIO ;dev_err (&piix4_adapter.dev,"Error: Failed bus transaction\n" ); }if (temp &0x08 ) { - result =-1 ;
drivers/i2c/busses/i2c-piix4.c static int piix4_transaction(void) · line 258
Quoted 10 lines
drivers/i2c/busses/i2c-piix4.c +2
-1+ result = -EIO ;dev_dbg (&piix4_adapter.dev,"Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n" );/* Clock stops and slave is stuck in mid-transmission */ }if (temp &0x04 ) { - result =-1 ; + result = -EIO ;dev_dbg (&piix4_adapter.dev,"Error: no response!\n" );
-ENODEV
Quoted 48 lines
drivers/i2c/busses/i2c-piix4.c +6
-4}@@ -272,17 +272,18 @@ static int piix4_transaction(void)return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 piix4_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {int i, len; +int status;switch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); -return -1 ; +return -EOPNOTSUPP ;case I2C_SMBUS_QUICK :outb_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMBHSTADD );@@ -334,8 +335,9 @@ static s32 piix4_access(struct i2c_adaptoutb_p ((size &0x1C ) + (ENABLE_INT9 &1 ),SMBHSTCNT ); -if (piix4_transaction ())/* Error in transaction */ -return -1 ; + status =piix4_transaction (); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==PIIX4_QUICK ))return 0 ;drivers/i2c/busses/i2c-sis5595.c +1
-1@@ -236,7 +236,7 @@ static int sis5595_transaction(struct i2sis5595_write (SMB_STS_HI , temp >>8 );if ((temp =sis5595_read (SMB_STS_LO ) + (sis5595_read (SMB_STS_HI ) <<8 )) !=0x00 ) {dev_dbg (&adap->dev,"Failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&adap->dev,"Successful!\n" ); }@@ -254,19 +254,19 @@ static int sis5595_transaction(struct i2/* If the SMBus is still busy, we give up */
drivers/i2c/busses/i2c-sis5595.c static int sis5595_transaction(struct i2 · line 262
Quoted 10 lines
drivers/i2c/busses/i2c-sis5595.c +2
-2if (timeout >=MAX_TIMEOUT ) {dev_dbg (&adap->dev,"SMBus Timeout!\n" ); - result =-1 ; + result = -ETIMEDOUT ; }if (temp &0x10 ) {dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); - result =-1 ; + result = -EIO ;
-ENODEV
Quoted 58 lines
drivers/i2c/busses/i2c-sis5595.c +8
-5}if (temp &0x20 ) {dev_err (&adap->dev,"Bus collision! SMBus may be locked until " "next hard reset (or not...)\n" );/* Clock stops and slave is stuck in mid-transmission */ - result =-1 ; + result = -EIO ; } temp =sis5595_read (SMB_STS_LO ) + (sis5595_read (SMB_STS_HI ) <<8 );@@ -282,11 +282,13 @@ static int sis5595_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis5595_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data) { +int status; +switch (size) {case I2C_SMBUS_QUICK :sis5595_write (SMB_ADDR , ((addr &0x7f ) <<1 ) | (read_write &0x01 ));@@ -318,13 +320,14 @@ static s32 sis5595_access(struct i2c_adabreak ;default :dev_warn (&adap->dev,"Unsupported transaction %d\n" , size); -return -1 ; +return -EOPNOTSUPP ; }sis5595_write (SMB_CTL_LO , ((size &0x0E ))); -if (sis5595_transaction (adap)) -return -1 ; + status =sis5595_transaction (adap); +if (status) +return status;if ((size !=SIS5595_PROC_CALL ) && ((read_write ==I2C_SMBUS_WRITE ) || (size ==SIS5595_QUICK )))drivers/i2c/busses/i2c-sis630.c +1
-1@@ -134,7 +134,7 @@ static int sis630_transaction_start(struif ((temp =sis630_read (SMB_CNT ) &0x03 ) !=0x00 ) {dev_dbg (&adap->dev,"Failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&adap->dev,"Successful!\n" ); }@@ -177,17 +177,17 @@ static int sis630_transaction_wait(struc/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {
drivers/i2c/busses/i2c-sis630.c static int sis630_transaction_wait(struc · line 186
Quoted 10 lines
drivers/i2c/busses/i2c-sis630.c +2
-2dev_dbg (&adap->dev,"SMBus Timeout!\n" ); - result =-1 ; + result = -ETIMEDOUT ; }if (temp &0x02 ) {dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); - result =-1 ; + result = -EIO ; }
-ENODEV
Quoted 70 lines
drivers/i2c/busses/i2c-sis630.c +17
-11if (temp &0x04 ) {dev_err (&adap->dev,"Bus collision!\n" ); - result =-1 ; + result = -EIO ;/* TBD: Datasheet say: the software should clear this bit and restart SMBUS operation. @@ -250,8 +250,10 @@ static int sis630_block_data(struct i2c_if (i==8 || (len<8 && i==len)) {dev_dbg (&adap->dev,"start trans len=%d i=%d\n" ,len ,i);/* first transaction */ -if (sis630_transaction_start (adap,SIS630_BLOCK_DATA , &oldclock)) -return -1 ; + rc =sis630_transaction_start (adap, +SIS630_BLOCK_DATA , &oldclock); +if (rc) +return rc; }else if ((i-1 )%8 ==7 || i==len) {dev_dbg (&adap->dev,"trans_wait len=%d i=%d\n" ,len,i);@@ -264,9 +266,10 @@ static int sis630_block_data(struct i2c_*/ sis630_write (SMB_STS ,0x10 ); } -if (sis630_transaction_wait (adap,SIS630_BLOCK_DATA )) { + rc =sis630_transaction_wait (adap, +SIS630_BLOCK_DATA ); +if (rc) {dev_dbg (&adap->dev,"trans_wait failed\n" ); - rc =-1 ;break ; } }@@ -275,13 +278,14 @@ static int sis630_block_data(struct i2c_else {/* read request */ data->block[0 ] = len =0 ; -if (sis630_transaction_start (adap,SIS630_BLOCK_DATA , &oldclock)) { -return -1 ; - } + rc =sis630_transaction_start (adap, +SIS630_BLOCK_DATA , &oldclock); +if (rc) +return rc; do { - if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) { + rc = sis630_transaction_wait(adap, SIS630_BLOCK_DATA); + if (rc) { dev_dbg(&adap->dev, "trans_wait failed\n"); - rc = -1; break; } /* if this first transaction then read byte count */@@ -311,11 +315,13 @@ static int sis630_block_data(struct i2c_return rc; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis630_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data) { +int status; +switch (size) {case I2C_SMBUS_QUICK :sis630_write (SMB_ADDR , ((addr &0x7f ) <<1 ) | (read_write &0x01 ));
drivers/i2c/busses/i2c-sis630.c static s32 sis630_access(struct i2c_adap · line 361
Quoted 6 lines
drivers/i2c/busses/i2c-sis630.c +1
-1@@ -351,12 +357,13 @@ static s32 sis630_access(struct i2c_adapreturn sis630_block_data (adap, data, read_write);default :printk ("Unsupported I2C size\n" ); -return -1 ; +return -EMSGSIZE ;break ;
Don't get fooled by the name of the variable and the log message... "size" is an SMBus transaction type, it doesn't have much to do with a size. Use -EOPNOTSUPP as for the other drivers.
Quoted 41 lines
drivers/i2c/busses/i2c-sis630.c +4
-3} -if (sis630_transaction (adap, size)) -return -1 ; + status =sis630_transaction (adap, size); +if (status) +return status;if ((size !=SIS630_PCALL ) && ((read_write ==I2C_SMBUS_WRITE ) || (size ==SIS630_QUICK ))) {@@ -373,7 +380,7 @@ static s32 sis630_access(struct i2c_adap data->word =sis630_read (SMB_BYTE ) + (sis630_read (SMB_BYTE +1 ) <<8 );break ;default : -return -1 ; +return -EOPNOTSUPP ;break ; }drivers/i2c/busses/i2c-sis96x.c +2
-2@@ -111,7 +111,7 @@ static int sis96x_transaction(int size)/* check it again */ if (((temp =sis96x_read (SMB_CNT )) &0x03 ) !=0x00 ) {dev_dbg (&sis96x_adapter.dev,"Failed (0x%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&sis96x_adapter.dev,"Successful\n" ); }@@ -136,19 +136,19 @@ static int sis96x_transaction(int size)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_dbg (&sis96x_adapter.dev,"SMBus Timeout! (0x%02x)\n" , temp); - result =-1 ; + result = -ETIMEDOUT ; }/* device error - probably missing ACK */ if (temp &0x02 ) {dev_dbg (&sis96x_adapter.dev,"Failed bus transaction!\n" );
drivers/i2c/busses/i2c-sis96x.c static int sis96x_transaction(int size) · line 152
Quoted 10 lines
drivers/i2c/busses/i2c-sis96x.c +2
-2- result =-1 ; + result = -EIO ; }/* bus collision */ if (temp &0x04 ) {dev_dbg (&sis96x_adapter.dev,"Bus collision!\n" ); - result =-1 ; + result = -EIO ; }
-ENODEV
Quoted 18 lines
drivers/i2c/busses/i2c-sis96x.c +2
-1/* Finish up by resetting the bus */ @@ -161,11 +161,12 @@ static int sis96x_transaction(int size)return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis96x_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) { +int status;switch (size) {case I2C_SMBUS_QUICK :@@ -203,17 +204,18 @@ static s32 sis96x_access(struct i2c_adapcase I2C_SMBUS_BLOCK_DATA :
drivers/i2c/busses/i2c-sis96x.c static s32 sis96x_access(struct i2c_adap · line 212
Quoted 10 lines
drivers/i2c/busses/i2c-sis96x.c +2
-2/* TO DO: */ dev_info (&adap->dev,"SMBus block not implemented!\n" ); -return -1 ; +return -EOPNOTSUPP ;break ;default :dev_info (&adap->dev,"Unsupported I2C size\n" ); -return -1 ; +return -EMSGSIZE ;
-EOPNOTSUPP
Quoted 58 lines
drivers/i2c/busses/i2c-sis96x.c +3
-2break ; } -if (sis96x_transaction (size)) -return -1 ; + status =sis96x_transaction (size); +if (status) +return status;if ((size != SIS96x_PROC_CALL) && ((read_write ==I2C_SMBUS_WRITE ) || (size == SIS96x_QUICK)))drivers/i2c/busses/i2c-stub.c +2
-2@@ -43,7 +43,7 @@ struct stub_chip {static struct stub_chip *stub_chips; -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 stub_xfer (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {@@ -120,7 +120,7 @@ static s32 stub_xfer(struct i2c_adapterdefault :dev_dbg (&adap->dev,"Unsupported I2C/SMBus command\n" ); - ret =-1 ; + ret = -EOPNOTSUPP ;break ; }/* switch (size) */ drivers/i2c/busses/i2c-viapro.c +3
-3@@ -152,7 +152,7 @@ static int vt596_transaction(u8 size)if ((temp =inb_p (SMBHSTSTS )) &0x1F ) {dev_err (&vt596_adapter.dev,"SMBus reset failed! " "(0x%02x)\n" , temp); -return -1 ; +return -EBUSY ; } }@@ -167,24 +167,24 @@ static int vt596_transaction(u8 size)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&vt596_adapter.dev,"SMBus timeout!\n" ); }if (temp &0x10 ) { - result =-1 ; + result = -EIO ;dev_err (&vt596_adapter.dev,"Transaction failed (0x%02x)\n" , size); }
drivers/i2c/busses/i2c-viapro.c static int vt596_transaction(u8 size) · line 187
Quoted 10 lines
drivers/i2c/busses/i2c-viapro.c +2
-2if (temp &0x08 ) { - result =-1 ; + result = -EIO ;dev_err (&vt596_adapter.dev,"SMBus collision!\n" ); }if (temp &0x04 ) {int read =inb_p (SMBHSTADD ) &0x01 ; - result =-1 ; + result = -EIO ;
-ENODEV
Quoted 31 lines
drivers/i2c/busses/i2c-viapro.c +5
-3/* The quick and receive byte commands are used to probe for chips, so errors are expected, and we don't want to frighten the user. */ @@ -202,12 +202,13 @@ static int vt596_transaction(u8 size)return result; } -/* Return -1 on error, 0 on success */ +/* Return negative errno on error, 0 on success */ static s32 vt596_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data) {int i; +int status;switch (size) {case I2C_SMBUS_QUICK :@@ -258,8 +259,9 @@ static s32 vt596_access(struct i2c_adaptoutb_p (((addr &0x7f ) <<1 ) | read_write,SMBHSTADD ); -if (vt596_transaction (size))/* Error in transaction */ -return -1 ; + status =vt596_transaction (size); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==VT596_QUICK ))return 0 ;
drivers/i2c/busses/i2c-viapro.c static s32 vt596_access(struct i2c_adapt · line 295
Quoted 8 lines
drivers/i2c/busses/i2c-viapro.c +1
-1@@ -287,7 +289,7 @@ static s32 vt596_access(struct i2c_adapt exit_unsupported:dev_warn (&vt596_adapter.dev,"Unsupported command invoked! (0x%02x)\n" , size); -return -1 ; +return -EOPNOTSUPP ; }static u32 vt596_func (struct i2c_adapter *adapter)
Please send an updated patch and I'll push it to -next and -mm so that it gets some testing.
Thanks,
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 2 lines · Jean Delvare
Quoted 2 lines
drivers/i2c/.............................15 files changed, 176 insertions(+), 142 deletions(-)
So I'll probably respond to your comments in smaller chunks. ;)
Arguably this should become a bunch of smaller patches, but that would of course make more confusion during initial review for this type change ... harder to notice the patterns.
Quoted 16 lines
Quoted 16 lines
drivers/i2c/algos/i2c-algo-bit.c +5
-2@@ -465,9 +465,12 @@ static int bit_doAddress(struct i2c_adapstruct i2c_algo_bit_data *adap = i2c_adap->algo_data;unsigned char addr; -int ret, retries; +int ret; +unsigned retries; - retries = nak_ok ?0 : i2c_adap->retries; + retries = (nak_ok || i2c_adap->retries <0 ) + ?0 + : i2c_adap->retries;
Quoted 5 lines
drivers/i2c/algos/i2c-algo-bit.c static int bit_doAddress(struct i2c_adap · line 476
Quoted 2 lines
drivers/i2c/algos/i2c-algo-bit.c +0
-0if (flags &I2C_M_TEN ) {/* a ten bit address */ I'd rather not bother with the
adap->retriesstuff which we agreed should be removed anyway.
Until it's gone, I just wanted to be sane with it. Or should we just rip it out of this driver? Negative retries is a very nonsensical notion, and that's the only way I recall algo-bit seemed to have obvious (albeit potential) fault code goofiness.
(Other than returning an odd code for devices that don't ACK their address; see below.)
Quoted 4 lines
Quoted 4 lines
drivers/i2c/busses/i2c-ali1535.c +0
-0@@ -295,7 +295,7 @@ static int ali1535_transaction(struct i2
Quoted 8 lines
drivers/i2c/busses/i2c-ali1535.c static int ali1535_transaction(struct i2 · line 298
Quoted 5 lines
drivers/i2c/busses/i2c-ali1535.c +1
-1* do a printk. This means that bus collisions go unreported. */ if (temp &ALI1535_STS_BUSERR ) { - result =-1 ; + result = -EIO ;Given the comment above I'd make this
-ENODEV. 99% of the time, no ack means no device.
Either ENODEV or ENXIO for "it didn't ACK the address". Any other code will make the driver core emit diagnostics when the probe() fails ... diagnostics we want to avoid, when probe() code does the Right Thing and just returns such fault codes.
That's probably an issue with most of these updates.
Quoted 11 lines
...drivers/i2c/busses/i2c-ali1535.c static s32 ali1535_access(struct i2c_ada · line 363
Quoted 7 lines
drivers/i2c/busses/i2c-ali1535.c +1
-1@@ -359,7 +359,7 @@ static s32 ali1535_access(struct i2c_adaswitch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); - result =-1 ; + result = -EOPNOTSUPP ; goto EXIT;Side note for a next patch: there's a bug here, this should be handled by a catch-all at the end on the switch, but I see it is missing.
Right, several drivers copied the same goofy template and its bugs. (So assume I agree on repeatis of those issues, in the interest of brevity.)
Quoted 18 lines
Quoted 18 lines
drivers/i2c/busses/i2c-amd756-s4882.c +2
-2@@ -58,7 +58,7 @@ static s32 amd756_access_virt0(struct i2/* We exclude the multiplexed addresses */ if (addr ==0x4c || (addr &0xfc ) ==0x50 || (addr &0xfc ) ==0x30 || addr ==0x18 ) -return -1 ; +return -EINVAL ;mutex_lock (&amd756_lock);@@ -86,7 +86,7 @@ static inline s32 amd756_access_channel(/* We exclude the non-multiplexed addresses */ if (addr !=0x4c && (addr &0xfc ) !=0x50 && (addr &0xfc ) !=0x30 ) -return -1 ; +return -EINVAL ;
Quoted 5 lines
drivers/i2c/busses/i2c-amd756-s4882.c static inline s32 amd756_access_channel( · line 91
Quoted 1 line
drivers/i2c/busses/i2c-amd756-s4882.c +0
-0mutex_lock (&amd756_lock);For these two I'd go for
-ENODEVas well. It's a little unfair to return-EINVAL, given that we are hiding the devices from the caller on purpose and they couldn't guess.
That might be a case where -ENXIO could provide a useful distinction. "No such device *OR ADDRESS*" vs "No such device". ;)
Quoted 11 lines
drivers/i2c/busses/i2c-amd756.c static int amd756_transaction(struct i2c · line 155
Quoted 9 lines
drivers/i2c/busses/i2c-amd756.c +1
-1@@ -151,17 +151,17 @@ static int amd756_transaction(struct i2c }if (temp &GS_PRERR_STS ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"SMBus Protocol error (no response)!\n" );This one would be
-ENODEV.
How are you knowing all these things? I wouldn't interpret "protocol error" as "no device". And while I do happen to have amd756 docs around (board broken though, sigh) I didn't dig that info out ... I'd be less concerned with reporting needlessly generic (EIO) errors than with wrongly reporting ones that are too specific (ENODEV).
That's kind of a general issue with this patch. I think my first idea was to stop reporting "-EPERM" for everything and provide plausible codes, but allow updates later. I can't imagine every fault report, the first time around, will be the best one we could be reporting.
Quoted 3 lines
drivers/i2c/busses/i2c-i801.c
Quoted 3 lines
drivers/i2c/busses/i2c-i801.c +0
-0
Though didn't I see a patch removing this driver?
Quoted 17 lines
Quoted 17 lines
drivers/i2c/busses/i2c-i801.c +2
-2@@ -179,19 +179,19 @@ static int i801_transaction(int xact) }if (temp &SMBHSTSTS_FAILED ) { - result =-1 ; + result = -EIO ;dev_dbg (&I801_dev->dev,"Error: Failed bus transaction\n" ); }if (temp &SMBHSTSTS_BUS_ERR ) { - result =-1 ; + result = -EIO ;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 */ }
Quoted 6 lines
drivers/i2c/busses/i2c-i801.c static int i801_transaction(int xact) · line 195
Quoted 4 lines
drivers/i2c/busses/i2c-i801.c +1
-1if (temp &SMBHSTSTS_DEV_ERR ) { - result =-1 ; + result = -EIO ;dev_dbg (&I801_dev->dev,"Error: no response!\n" );
-ENODEV
Is that *really* a "no response to address" error?
But there's another issue with that type of code. This particular one looks maybe sane ... in the sense that it seems to replace generic fault codes with more specific ones (maybe), but I don't think all the I2C adapters were doing that. Some of them looked like they were testing the specific faults first, then clobbering them with vague generic idicators...
Quoted 11 lines
drivers/i2c/busses/i2c-i801.c static int i801_block_transaction_by_blo · line 254
Quoted 8 lines
drivers/i2c/busses/i2c-i801.c +3
-1+if (status) +return status;if (read_write ==I2C_SMBUS_READ ) { len =inb_p (SMBHSTDAT0 );if (len <1 || len >I2C_SMBUS_BLOCK_MAX ) -return -1 ; +return -EILSEQ ;Huh, definitely not. This error code has to so with multi-byte character encoding, that's inappropriate here.
No; most of the errno values get recycled. "Illegal Byte Sequence" is exactly what we got there, in fact! I know that USB has used EILSEQ for some years (indicating a lowlevel bit protocol failure), and MMC is using it too.
So if you want to say "not", it should be for some better reason than that...
Quoted 2 lines
I'd return
-EINVAL, or-EREMOTEIOif you think EINVAL is unfair for the caller.
It's not an I/O error; the I/O actually worked, it's the bytes that were wrong. It's not an "argument" provided by the caller. So neither of those codes seems appropriate.
Quoted 5 lines
But most
likely, if the returned length is not within the SMBus specifications, it means that the caller ran an SMBus block transaction at the wrong offset or on a device that doesn't support it, so-EINVALseems reasonable to me.
That's only a guess though. All we *know* is that we saw an illegal byte sequence...
... enough for now.
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805110117.23023.david-b-yBeKhBN/[email protected]
Hi David,
Before I forget: I just noticed that your patch adds the following warning:
CC [M] drivers/i2c/busses/i2c-amd8111.odrivers/i2c/busses/i2c-amd8111.c: In function ‘amd8111_access’:drivers/i2c/busses/i2c-amd8111.c:198: warning: unused variable ‘status’
Please fix.
Quoted 9 lines · David Brownell
Quoted 2 lines · Jean Delvare
Quoted 2 lines
drivers/i2c/.............................15 files changed, 176 insertions(+), 142 deletions(-)So I'll probably respond to your comments in smaller chunks. ;)
Arguably this should become a bunch of smaller patches, but that would of course make more confusion during initial review for this type change ... harder to notice the patterns.
I am totally fine with all the drivers being fixed in the same patch, no problem with this.
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
drivers/i2c/algos/i2c-algo-bit.c +5
-2@@ -465,9 +465,12 @@ static int bit_doAddress(struct i2c_adapstruct i2c_algo_bit_data *adap = i2c_adap->algo_data;unsigned char addr; -int ret, retries; +int ret; +unsigned retries; - retries = nak_ok ?0 : i2c_adap->retries; + retries = (nak_ok || i2c_adap->retries <0 ) + ?0 + : i2c_adap->retries;
Quoted 7 lines
Quoted 5 lines
drivers/i2c/algos/i2c-algo-bit.c static int bit_doAddress(struct i2c_adap · line 476
Quoted 2 lines
drivers/i2c/algos/i2c-algo-bit.c +0
-0if (flags &I2C_M_TEN ) {/* a ten bit address */ I'd rather not bother with the
adap->retriesstuff which we agreed should be removed anyway.Until it's gone, I just wanted to be sane with it.
To make it sane, just change "ret = -1" to "ret = 0" in try_address(). It does the "right thing" if the i2c adapter provided a negative number of retries (which nobody does anyway.) That's the minimal fix and the only one I am willing to take.
Quoted 3 lines
Or should we just rip it out of this driver? Negative retries is a very nonsensical notion, and that's the only way I recall algo-bit seemed to have obvious (albeit potential) fault code goofiness.
Not in the middle of your -1 -> -errno patches, no. But once we're done with them and the dust has settled down, yes, chip drivers will hopefully have a reliable way to know when then want to retry a failed read, and we can get rid of this automatic retry mechanism at the adapter level.
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
drivers/i2c/busses/i2c-ali1535.c +0
-0@@ -295,7 +295,7 @@ static int ali1535_transaction(struct i2Quoted 8 lines
drivers/i2c/busses/i2c-ali1535.c static int ali1535_transaction(struct i2 · line 298
Quoted 5 lines
drivers/i2c/busses/i2c-ali1535.c +1
-1* do a printk. This means that bus collisions go unreported. */ if (temp &ALI1535_STS_BUSERR ) { - result =-1 ; + result = -EIO ;Given the comment above I'd make this
-ENODEV. 99% of the time, no ack means no device.
Quoted 6 lines
Either ENODEV or ENXIO for "it didn't ACK the address". Any other code will make the driver core emit diagnostics when the
probe()fails ... diagnostics we want to avoid, whenprobe()code does the Right Thing and just returns such fault codes.That's probably an issue with most of these updates.
My point exactly. I am fine with both -ENXIO and -ENODEV, pick the one you like, then make sure all drivers are using it consistently.
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
drivers/i2c/busses/i2c-amd756-s4882.c +2
-2@@ -58,7 +58,7 @@ static s32 amd756_access_virt0(struct i2/* We exclude the multiplexed addresses */ if (addr ==0x4c || (addr &0xfc ) ==0x50 || (addr &0xfc ) ==0x30 || addr ==0x18 ) -return -1 ; +return -EINVAL ;mutex_lock (&amd756_lock);@@ -86,7 +86,7 @@ static inline s32 amd756_access_channel(/* We exclude the non-multiplexed addresses */ if (addr !=0x4c && (addr &0xfc ) !=0x50 && (addr &0xfc ) !=0x30 ) -return -1 ; +return -EINVAL ;
Quoted 8 lines
Quoted 5 lines
drivers/i2c/busses/i2c-amd756-s4882.c static inline s32 amd756_access_channel( · line 91
Quoted 1 line
drivers/i2c/busses/i2c-amd756-s4882.c +0
-0mutex_lock (&amd756_lock);For these two I'd go for
-ENODEVas well. It's a little unfair to return-EINVAL, given that we are hiding the devices from the caller on purpose and they couldn't guess.That might be a case where
-ENXIOcould provide a useful distinction. "No such device *OR ADDRESS*" vs "No such device". ;)
What matters here is to return the same code that other bus drivers return when they don't get a ack on a given transaction. The caller shouldn't be able to differentiate between both cases, multiplexing should be completely transparent to the chip drivers.
Quoted 19 lines
Quoted 11 lines
drivers/i2c/busses/i2c-amd756.c static int amd756_transaction(struct i2c · line 155
Quoted 9 lines
drivers/i2c/busses/i2c-amd756.c +1
-1@@ -151,17 +151,17 @@ static int amd756_transaction(struct i2c }if (temp &GS_PRERR_STS ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"SMBus Protocol error (no response)!\n" );This one would be
-ENODEV.How are you knowing all these things? I wouldn't interpret "protocol error" as "no device". And while I do happen to have amd756 docs around (board broken though, sigh) I didn't dig that info out ... I'd be less concerned with reporting needlessly generic (EIO) errors than with wrongly reporting ones that are too specific (ENODEV).
Quoted 5 lines
That's kind of a general issue with this patch. I think my first idea was to stop reporting "
-EPERM" for everything and provide plausible codes, but allow updates later. I can't imagine every fault report, the first time around, will be the best one we could be reporting.
I agree that it's not easy for you (or anyone else, including me) to figure out the right error code all the time, and I am fine with using -EIO as the default error value when there's no other obvious value to return.
As for "how do I know": check whether the code is using dev_err() or dev_dbg(). Each time a driver uses dev_dbg(), chances are good that the error in question isn't really an error, and we've turned the error message into a debug message to avoid log fills and user complaints. So basically, when I see a dev_dbg() in these SMBus "access" functions, I can be almost sure that the error in question is what that controller returns when a transaction isn't acked. But that's only a heuristic - I could be wrong, too.
A variant of this is when a driver uses dev_err() but hides the error message on SMBus quick command and sometimes on SMBus receive byte as well. These are the transactions used by i2cdetect and sensors-detect to probe for I2C devices. When you see this you can be certain that it's the error that is returned on no-ack.
Quoted 4 lines
Quoted 2 lines
drivers/i2c/busses/i2c-i801.c
Quoted 2 lines
drivers/i2c/busses/i2c-i801.c +0
-0Though didn't I see a patch removing this driver?
Hell no. You saw i2c-i810 go away, not i2c-i801. i2c-i801 drives the Intel mainboards' SMBus, i2c-i810 was a bit-banging driver for the integrated Intel video chips' DDC and I2C buses. i2c-i801 is there to stay.
Quoted 8 lines
Quoted 6 lines
drivers/i2c/busses/i2c-i801.c static int i801_transaction(int xact) · line 195
Quoted 4 lines
drivers/i2c/busses/i2c-i801.c +1
-1if (temp &SMBHSTSTS_DEV_ERR ) { - result =-1 ; + result = -EIO ;dev_dbg (&I801_dev->dev,"Error: no response!\n" );
-ENODEVIs that *really* a "no response to address" error?
It uses dev_dbg() ;)
Quoted 7 lines
But there's another issue with that type of code. This particular one looks maybe sane ... in the sense that it seems to replace generic fault codes with more specific ones (maybe), but I don't think all the I2C adapters were doing that. Some of them looked like they were testing the specific faults first, then clobbering them with vague generic idicators...
You're right, I have noticed this too... most of these drivers check for many error conditions and overwrite the error value each time, so the last error checked wins. We might have to reorder the checks so that the best error code is kept, but honestly I'm not sure I would be able to tell right away what the best order would be each time. So I am fine leaving things as they are for now and fixing them later if they really need to be.
Quoted 12 lines
Quoted 11 lines
drivers/i2c/busses/i2c-i801.c static int i801_block_transaction_by_blo · line 254
Quoted 8 lines
drivers/i2c/busses/i2c-i801.c +3
-1+if (status) +return status;if (read_write ==I2C_SMBUS_READ ) { len =inb_p (SMBHSTDAT0 );if (len <1 || len >I2C_SMBUS_BLOCK_MAX ) -return -1 ; +return -EILSEQ ;Huh, definitely not. This error code has to so with multi-byte character encoding, that's inappropriate here.
Quoted 7 lines
No; most of the errno values get recycled. "Illegal Byte Sequence" is exactly what we got there, in fact! I know that USB has used EILSEQ for some years (indicating a lowlevel bit protocol failure), and MMC is using it too.
So if you want to say "not", it should be for some better reason than that...
When calling strerror on EILSEQ, you get: "Invalid or incomplete multibyte or wide character". This has nothing to do with the error in question, and that's what I am worried about. I don't know whether it makes sense or not in the USB and MMC code, but in the I2C/SMBus context, I'm sure it does not.
Quoted 4 lines
Quoted 2 lines
I'd return
-EINVAL, or-EREMOTEIOif you think EINVAL is unfair for the caller.It's not an I/O error; the I/O actually worked, it's the bytes
True...
Quoted 2 lines
that were wrong. It's not an "argument" provided by the caller. So neither of those codes seems appropriate.
The returned value depends on an argument provided by the caller, though.
Quoted 8 lines
Quoted 5 lines
But most
likely, if the returned length is not within the SMBus specifications, it means that the caller ran an SMBus block transaction at the wrong offset or on a device that doesn't support it, so-EINVALseems reasonable to me.That's only a guess though. All we *know* is that we saw an illegal byte sequence...
That's not an illegal "sequence", sorry. The length byte by itself is either valid or not valid. What we saw is an illegal byte value.
Yes, -EINVAL is a guess, but according to my experience, this guess will always be correct. Leaving actual I/O errors aside, there are only two ways that the SMBus block length byte we receive from an SMBus chip can be incorrect: either the chip in question is returning invalid data to a proper request, or the request was incorrect. The former would mean that the chip is basically unusable, so it's very unlikely to happen. As a matter of fact, I've never seen it (not that I have seen that many chips using SMBus block reads, though.) That's why I say that the latter will always be true in practice, and -EINVAL makes sense then even if it's not perfect.
If you are still worried that -EINVAL has a small chance of not being correct, I'd rather go for -EMSGSIZE (Message too long), although the error message would be confusing in the 0 case. Even -EOVERFLOW (Value too large for defined data type) would be more appropriate than -EILSEQ, I think.
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 8 lines · you
Quoted 8 lines
Quoted 2 lines
Given the comment above I'd make this
-ENODEV. 99% of the time, no ack means no device.Either ENODEV or ENXIO for "it didn't ACK the address". Any other code will make the driver core emit diagnostics when the
probe()fails ... diagnostics we want to avoid, whenprobe()code does the Right Thing and just returns such fault codes.
Quoted 4 lines
Quoted 1 line
That's probably an issue with most of these updates.
My point exactly. I am fine with both
-ENXIOand-ENODEV, pick the one you like, then make sure all drivers are using it consistently.
I'll go with ENXIO "no such device or address" as being a bit more appropriate for addressing issues. Driver probe() code can return ENODEV in the case where there is a device there ... but the wrong one for that driver.
Quoted 8 lines
As for "how do I know": check whether the code is using
dev_err()ordev_dbg(). Each time a driver usesdev_dbg(), chances are good that the error in question isn't really an error, and we've turned the error message into a debug message to avoid log fills and user complaints. So basically, when I see adev_dbg()in these SMBus "access" functions, I can be almost sure that the error in question is what that controller returns when a transaction isn't acked. But that's only a heuristic - I could be wrong, too.
Makes sense to me.
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
drivers/i2c/busses/i2c-i801.c
Quoted 2 lines
drivers/i2c/busses/i2c-i801.c +0
-0Though didn't I see a patch removing this driver?
Hell no. You saw i2c-i810 go away, not i2c-i801.
10, 01 ... it's just an off-by-one error (in binary). ;)
Quoted 11 lines
Quoted 11 lines
Quoted 5 lines
drivers/i2c/busses/i2c-i801.c
Quoted 2 lines
drivers/i2c/busses/i2c-i801.c +1
-1-return -1 ; +return -EILSEQ ;Huh, definitely not. This error code has to so with multi-byte character encoding, that's inappropriate here.
No; most of the errno values get recycled. "Illegal Byte Sequence" is exactly what we got there, in fact! I know that USB has used EILSEQ for some years (indicating a lowlevel bit protocol failure), and MMC is using it too.
Quoted 5 lines
Quoted 2 lines
So if you want to say "not", it should be for some better reason than that...
When calling strerror on EILSEQ, you get: "Invalid or incomplete multibyte or wide character".
While "man 1 errno" says "Illegal byte sequence" ...
In any case: as a rule, strerror() is not expected to give good diagnostics. Those "standard strings" are generated without any context whatever, and so their messages have mostly been useful for distinguishing faults rather than diagnosing them.
You may recall the case of "ENOTTY" --> "Not a TTY", for example. That's also a good example of how code semantics evolve over time. (Sure it's not a TTY ... that code means *other* things too.)
Quoted 4 lines
This has nothing to do with the error in
question, and that's what I am worried about. I don't know whether it makes sense or not in the USB and MMC code, but in the I2C/SMBus context, I'm sure it does not.
It most certainly *is* an illegal byte sequence though...
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines
I'd return
-EINVAL, or-EREMOTEIOif you think EINVAL is unfair for the caller.It's not an I/O error; the I/O actually worked, it's the bytes
Quoted 7 lines
True...
Quoted 2 lines
that were wrong. It's not an "argument" provided by the caller. So neither of those codes seems appropriate.
The returned value depends on an argument provided by the caller, though.
Among an arbitrary number of other things. It could also be just bad device firmware ... I have in fact seen such cases:
perfectly valid SMBus requests generating bogus responses.
(This happened to be on shipping hardware, but of course it's also easy to imagine that in developer setups too...)
Rule of thumb: make the fault report reflect observation, not guesses about what caused the behavior. It's harder to get it wrong that way.
Quoted 11 lines
Quoted 8 lines
Quoted 5 lines
But most
likely, if the returned length is not within the SMBus specifications, it means that the caller ran an SMBus block transaction at the wrong offset or on a device that doesn't support it, so-EINVALseems reasonable to me.That's only a guess though. All we *know* is that we saw an illegal byte sequence...
That's not an illegal "sequence", sorry. The length byte by itself is either valid or not valid. What we saw is an illegal byte value.
It's part of a sequence. The length byte will usually be the fourth byte of the sequence:
S addr/w [A] command [A] S addr/r [A] [length] A ... P
That value is perfectly legal ... it's just that in that location within *THIS* byte sequence, it's trouble. Mostly because that byte is being interpreted; in other contexts, that sequence is fine.
Quoted 3 lines
If you are still worried that
-EINVALhas a small chance of not being correct, I'd rather go for-EMSGSIZE(Message too long), although the error message would be confusing in the 0 case.
Right...
Quoted 1 line
Even
-EOVERFLOW(Value too large for defined data type)
... also confusing in the 0 case, and also wrong for PMBus (where values 1..255 are all valid so it can't be "too large").
Quoted 1 line
would be more appropriate than
-EILSEQ, I think.
How about "-EPROTO" for protocol error, then, if you're so strongly opposed to "illegal byte sequence"? The reason I avoided EPROTO in that case is that it's so generic; while we could use EILSEQ to indicate this specific case.
- Dave
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805110923.44693.david-b-yBeKhBN/[email protected]
Quoted 8 lines · David Brownell
Quoted 2 lines · you
My point exactly. I am fine with both
-ENXIOand-ENODEV, pick the one you like, then make sure all drivers are using it consistently.I'll go with ENXIO "no such device or address" as being a bit more appropriate for addressing issues. Driver
probe()code can return ENODEV in the case where there is a device there ... but the wrong one for that driver.
OK, fine with me.
Quoted 5 lines
Quoted 3 lines
(...)
When calling strerror on EILSEQ, you get: "Invalid or incomplete multibyte or wide character".While "man 1 errno" says "Illegal byte sequence" ...
Yes, it's unfortunately inconsistent. Ideally man 1 errno would be generated automatically by calling strerror on all error codes.
Quoted 8 lines
Quoted 3 lines
(...)
The returned value depends on an argument provided by the caller, though.Among an arbitrary number of other things. It could also be just bad device firmware ... I have in fact seen such cases:
perfectly valid SMBus requests generating bogus responses.
Quoted 6 lines
(This happened to be on shipping hardware, but of course it's also easy to imagine that in developer setups too...)
Rule of thumb: make the fault report reflect observation, not guesses about what caused the behavior. It's harder to get it wrong that way.
I have to agree...
Quoted 4 lines
Quoted 3 lines
(...)
That's not an illegal "sequence", sorry. The length byte by itself is either valid or not valid. What we saw is an illegal byte value.
Quoted 8 lines
It's part of a sequence. The length byte will usually be the fourth byte of the sequence:
S addr/w [A] command [A] S addr/r [A] [length] A ... P
That value is perfectly legal ... it's just that in that location within *THIS* byte sequence, it's trouble. Mostly because that byte is being interpreted; in other contexts, that sequence is fine.
Going down that route, everything is part of a sequence, so we would have to stop using -EINVAL and use -EILSEQ everywhere. Numbers by themselves are never invalid, what makes them invalid is the context in which they are encountered, and for a computer, a given context has to come from a sequence of some kind.
So I'm not buying this, sorry. Especially when the first 3 bytes are emitted by the master and the 4th one comes from the slave, calling them a sequence as a whole is almost dishonest ;)
Quoted 11 lines
Quoted 3 lines
If you are still worried that
-EINVALhas a small chance of not being correct, I'd rather go for-EMSGSIZE(Message too long), although the error message would be confusing in the 0 case.Right...
Quoted 1 line
Even
-EOVERFLOW(Value too large for defined data type)... also confusing in the 0 case, and also wrong for PMBus (where values 1..255 are all valid so it can't be "too large").
Quoted 6 lines
Quoted 1 line
would be more appropriate than
-EILSEQ, I think.How about "
-EPROTO" for protocol error, then, if you're so strongly opposed to "illegal byte sequence"? The reason I avoided EPROTO in that case is that it's so generic; while we could use EILSEQ to indicate this specific case.
-EPROTO sounds good to me. We're not using it anywhere in the i2c subsystem so there's no need to worry about it being "too generic".
Thanks,
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 10 lines · Jean Delvare
Quoted 7 lines
Quoted 2 lines
would be more appropriate than
-EILSEQ, I think.How about "
-EPROTO" for protocol error, then, if you're so strongly opposed to "illegal byte sequence"? The reason I avoided EPROTO in that case is that it's so generic; while we could use EILSEQ to indicate this specific case.
-EPROTOsounds good to me. We're not using it anywhere in the i2c subsystem so there's no need to worry about it being "too generic".
I'd be happier with EILSEQ, matching related use elsewhere in Linux, but it's now been switched to EPROTO.
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
Quoted 11 lines · you
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 174
Quoted 9 lines
static intali1563_block_start(struct i2c_adapter * a)drivers/i2c/busses/i2c-ali1563.c +1
-1@@ -170,7 +170,7 @@ static int ali1563_block_start(struct i2 data & HST_STS_BUSERR ? "No response or Bus Collision " : "", data & HST_STS_DEVERR ? "Device Error " : "", !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); - return -1; + return -EIO; }And same here. That's a little more work, admittedly.
Returning ENXIO for BUSERR/no-response doesn't follow your heuristic of trusting the logspam-eliminators ... plus, it's not clear that's not a different failure mode on that path.
NVidia seems to not have ALI 1563 specs on line (sigh) so for now I'll just stick to your heuristic.
I did make the "timeout" fault unique there, since that fault was clearly distinguishable.
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805111013.25440.david-b-yBeKhBN/[email protected]
Quoted 13 lines · David Brownell
Quoted 11 lines · you
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 174
Quoted 9 lines
static intali1563_block_start(struct i2c_adapter * a)drivers/i2c/busses/i2c-ali1563.c +1
-1@@ -170,7 +170,7 @@ static int ali1563_block_start(struct i2 data & HST_STS_BUSERR ? "No response or Bus Collision " : "", data & HST_STS_DEVERR ? "Device Error " : "", !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); - return -1; + return -EIO; }And same here. That's a little more work, admittedly.
Quoted 3 lines
Returning ENXIO for BUSERR/no-response doesn't follow your heuristic of trusting the logspam-eliminators ... plus, it's not clear that's not a different failure mode on that path.
Elsewhere in this driver there is:
/* device error - no response, ignore the autodetection case */
if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) {
dev_err(&a->dev, "Device error!\n");
}which makes it clear to me that HST_STS_DEVERR is what you get when no device acks a transaction. So returning -ENODEV would make sense.
Quoted 2 lines
NVidia seems to not have ALI 1563 specs on line (sigh) so for now I'll just stick to your heuristic.
Not sure why nVidia would host ALi datasheets in the first place? Let alone the fact that nVidia is notoriously known to _not_ publish datasheets anyway :(
Quoted 2 lines
I did make the "timeout" fault unique there, since that fault was clearly distinguishable.
Agreed.
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 20 lines · Jean Delvare
Quoted 13 lines · David Brownell
Quoted 11 lines · you
Review static int ali1563_block_start(struct i2 · line 174
Quoted 9 lines
static intali1563_block_start(struct i2c_adapter * a)(quoted diff) +1
-1@@ -170,7 +170,7 @@ static int ali1563_block_start(struct i2 data & HST_STS_BUSERR ? "No response or Bus Collision " : "", data & HST_STS_DEVERR ? "Device Error " : "", !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); - return -1; + return -EIO; }And same here. That's a little more work, admittedly.
Quoted 3 lines
Returning ENXIO for BUSERR/no-response doesn't follow your heuristic of trusting the logspam-eliminators ... plus, it's not clear that's not a different failure mode on that path.
Elsewhere in this driver there is:
Quoted 7 lines
/* device error - no response, ignore the autodetection case */ if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { dev_err(&a->dev, "Device error!\n"); }which makes it clear to me that
HST_STS_DEVERRis what you get when no device acks a transaction. So returning-ENODEVwould make sense.
In that case, yes. That one is fixed. (DEVERR and QUICK report as ENXIO.)
But it looks like a case of bundling faults into one bit, ergo my comment. ONLY that case with QUICK is special cased per your heuristic. That other case isn't special cased... it could well be exposing some *other* and more significant error.
Quoted 6 lines
Quoted 2 lines
NVidia seems to not have ALI 1563 specs on line (sigh) so for now I'll just stick to your heuristic.
Not sure why nVidia would host ALi datasheets in the first place? Let alone the fact that nVidia is notoriously known to _not_ publish datasheets anyway :(
ALI renamed itself to ULI, and NVidia bought ULI.
Quoted 5 lines
Quoted 2 lines
I did make the "timeout" fault unique there, since that fault was clearly distinguishable.
Agreed.
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805120925.33533.david-b-yBeKhBN/[email protected]
Quoted 11 lines · David Brownell
Quoted 9 lines · Jean Delvare
Elsewhere in this driver there is:
/* device error - no response, ignore the autodetection case */ if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { dev_err(&a->dev, "Device error!\n"); }which makes it clear to me that
HST_STS_DEVERRis what you get when no device acks a transaction. So returning-ENODEVwould make sense.
Quoted 7 lines
In that case, yes. That one is fixed. (DEVERR and QUICK report as ENXIO.)
But it looks like a case of bundling faults into one bit, ergo my comment. ONLY that case with QUICK is special cased per your heuristic. That other case isn't special cased... it could well be exposing some *other* and more significant error.
Just to make sure it's clear: the Quick command case isn't special as far as the returned error value is concerned. If nobody acks a Quick command, that's still -ENXIO.
What is special about the Quick command is that we don't want to log the error in this case, because it's used for detection purposes so it happens frequently and it isn't something the user should worry about.
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 6 lines · Jean Delvare
Quoted 5 lines
But it looks like a case of bundling faults into one bit, ergo my comment. ONLY that case with QUICK is special cased per your heuristic. That other case isn't special cased... it could well be exposing some *other* and more significant error.
Quoted 7 lines
Just to make sure it's clear: the Quick command case isn't special as far as the returned error value is concerned. If nobody acks a Quick command, that's still
-ENXIO.What is special about the Quick command is that we don't want to log the error in this case, because it's used for detection purposes so it happens frequently and it isn't something the user should worry about.
Close...
The desired out come is that whenever the first address doesn't get ACKed, we report ENXIO. Arguably the same should be true of the address byte after all repeated START bits too ... but then we run into other error reporting problems.
Logging is orthogonal. We don't want to log probing errors, as a rule, and Quick is (for our purposes) basically about probing.
Then there's also the "what does this hardware bit mean" issue. In this case, absent hardware docs, we're guessing in all cases except for the QUICK case. With only a few bits to report all faults, it's clear there's some degree of fault bundling. Ergo my caution: I didn't restructure all fault paths in that driver to treat that one bit as if it only means "no address ACK", only the one where it's clear that was how the driver interpreted it.
- Dave
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
Quoted 6 lines · Jean Delvare
Quoted 5 lines
amd_ec_write(smbus,
AMD_SMB_ADDR, addr << 1);amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
+ /* FIXME this discards status fromec_read()... */amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
Quoted 6 lines
Same is true of almost all
amd_ec_writeandamd_ec_readcalls, so I don't get the point of adding a comment for this one occurrence in particular.Quoted 2 lines
if (~temp[0] &AMD_SMB_STS_DONE) {
I updated that comment. The issue is that temp[0] will have random stack garbage at that point, so the rest of that routine is at best dicey.
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
Quoted 2 lines · Jean Delvare
Please send an updated patch and I'll push it to -next and -mm so that it gets some testing.
Appended ... agaist 2.6.26-rc2.
========= CUT HERE
Tighten error paths used by various i2c adapters (mostly x86) so they return real fault/errno codes instead of a "-1" (which is most often interpreted as "-EPERM"). Build tested, with eyeball review.
One minor initial goal is to have adapters consistently return the code "-ENXIO" when addressing a device doesn't get an ACK response, at least in the probe paths where they are already good at stifling related logspam.
---
UPDATED per feedback
NOTE there are many other adapter drivers to audit and update; and they're not just within the drivers/i2c tree. This patch is a PC oriented start on some bottom-up improvement of fault reporting. The i2c-gpio code looks be good too.
drivers/i2c/algos/i2c-algo-bit.c | 4 +- drivers/i2c/busses/i2c-ali1535.c | 22 +++++++-------- drivers/i2c/busses/i2c-ali1563.c | 16 ++++++++--- drivers/i2c/busses/i2c-ali15x3.c | 19 +++++++------ drivers/i2c/busses/i2c-amd756-s4882.c | 4 +- drivers/i2c/busses/i2c-amd756.c | 18 +++++++------ drivers/i2c/busses/i2c-amd8111.c | 47 ++++++++++++++++++++++------------ drivers/i2c/busses/i2c-i801.c | 44 ++++++++++++++++--------------- drivers/i2c/busses/i2c-nforce2.c | 25 +++++++++--------- drivers/i2c/busses/i2c-piix4.c | 20 +++++++------- drivers/i2c/busses/i2c-sis5595.c | 19 +++++++------ drivers/i2c/busses/i2c-sis630.c | 47 ++++++++++++++++++---------------- drivers/i2c/busses/i2c-sis96x.c | 23 ++++++++-------- drivers/i2c/busses/i2c-stub.c | 4 +- drivers/i2c/busses/i2c-viapro.c | 22 +++++++++------ 15 files changed, 188 insertions(+), 146 deletions(-)
drivers/i2c/algos/i2c-algo-bit.c +2 -2
@@ -320,7 +320,7 @@ static int try_address(struct i2c_adapte unsigned char addr, int retries) {struct i2c_algo_bit_data *adap = i2c_adap->algo_data; -int i, ret =-1 ; +int i, ret =0 ;for (i =0 ; i <= retries; i++) { ret =i2c_outb (i2c_adap, addr);
@@ -508,7 +508,7 @@ static int bit_doAddress(struct i2c_adap addr ^=1 ; ret =try_address (i2c_adap, addr, retries);if ((ret !=1 ) && !nak_ok) -return -EREMOTEIO ; +return -ENXIO ; }return 0 ;
drivers/i2c/busses/i2c-ali1535.c +10 -12
@@ -259,7 +259,7 @@ static int ali1535_transaction(struct i2dev_err (&adap->dev,"SMBus reset failed! (0x%02x) - controller or " "device on bus is probably hung\n" , temp); -return -1 ; +return -EBUSY ; } }else {/* check and clear done bit */
@@ -281,12 +281,12 @@ static int ali1535_transaction(struct i2/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&adap->dev,"SMBus Timeout!\n" ); }if (temp &ALI1535_STS_FAIL ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); }
@@ -295,7 +295,7 @@ static int ali1535_transaction(struct i2* do a printk. This means that bus collisions go unreported. */ if (temp &ALI1535_STS_BUSERR ) { - result =-1 ; + result = -ENXIO ;dev_dbg (&adap->dev,"Error: no response or bus collision ADD=%02x\n" ,inb_p (SMBHSTADD ));
@@ -303,13 +303,13 @@ static int ali1535_transaction(struct i2/* haven't ever seen this */ if (temp &ALI1535_STS_DEV ) { - result =-1 ; + result = -EIO ;dev_err (&adap->dev,"Error: device error\n" ); }/* check to see if the "command complete" indication is set */ if (!(temp &ALI1535_STS_DONE )) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&adap->dev,"Error: command never completed\n" ); }
@@ -332,7 +332,7 @@ static int ali1535_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 ali1535_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data)
@@ -359,7 +359,7 @@ static s32 ali1535_access(struct i2c_adaswitch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); - result =-1 ; + result = -EOPNOTSUPP ; goto EXIT;case I2C_SMBUS_QUICK : outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
@@ -420,11 +420,9 @@ static s32 ali1535_access(struct i2c_adabreak ; } -if (ali1535_transaction (adap)) { -/* Error in transaction */ - result =-1 ; + result =ali1535_transaction (adap); +if (result) goto EXIT; - }if ((read_write ==I2C_SMBUS_WRITE ) || (size ==ALI1535_QUICK )) { result =0 ;
drivers/i2c/busses/i2c-ali1563.c +12 -4
@@ -106,8 +106,11 @@ static int ali1563_transaction(struct i2 }/* device error - no response, ignore the autodetection case */ -if ((data &HST_STS_DEVERR ) && (size !=HST_CNTL2_QUICK )) { -dev_err (&a->dev,"Device error!\n" ); +if (data &HST_STS_DEVERR ) { +if (size !=HST_CNTL2_QUICK ) +dev_err (&a->dev,"Device error!\n" ); +else +return -ENXIO ; }/* bus collision */
@@ -122,13 +125,14 @@ static int ali1563_transaction(struct i2outb_p (0x0 ,SMB_HST_CNTL2 ); } -return -1 ; +return -EIO ; }static int ali1563_block_start (struct i2c_adapter * a) {u32 data;int timeout; +int status = -EIO ; dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, " "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
@@ -164,13 +168,17 @@ static int ali1563_block_start(struct i2if (timeout && !(data &HST_STS_BAD ))return 0 ; + +if (timeout ==0 && !(data &HST_STS_DONE )) + status = -ETIMEDOUT ; +dev_err (&a->dev,"SMBus Error: %s%s%s%s%s\n" , timeout ?"Timeout " :"" , data &HST_STS_FAIL ?"Transaction Failed " :"" , data &HST_STS_BUSERR ?"No response or Bus Collision " :"" , data &HST_STS_DEVERR ?"Device Error " :"" , !(data &HST_STS_DONE ) ?"Transaction Never Finished " :"" ); -return -1 ; +return status; }static int ali1563_block (struct i2c_adapter * a,union i2c_smbus_data * data,u8 rw)
drivers/i2c/busses/i2c-ali15x3.c +10 -9
@@ -282,7 +282,7 @@ static int ali15x3_transaction(struct i2dev_err (&adap->dev,"SMBus reset failed! (0x%02x) - " "controller or device on bus is probably hung\n" , temp); -return -1 ; +return -EBUSY ; } }else {/* check and clear done bit */
@@ -304,12 +304,12 @@ static int ali15x3_transaction(struct i2/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&adap->dev,"SMBus Timeout!\n" ); }if (temp &ALI15X3_STS_TERM ) { - result =-1 ; + result = -EIO ;dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); }
@@ -320,7 +320,7 @@ static int ali15x3_transaction(struct i2This means that bus collisions go unreported. */ if (temp &ALI15X3_STS_COLL ) { - result =-1 ; + result = -ENXIO ;dev_dbg (&adap->dev,"Error: no response or bus collision ADD=%02x\n" ,inb_p (SMBHSTADD ));
@@ -328,7 +328,7 @@ static int ali15x3_transaction(struct i2/* haven't ever seen this */ if (temp &ALI15X3_STS_DEV ) { - result =-1 ; + result = -EIO ;dev_err (&adap->dev,"Error: device error\n" ); } dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "
@@ -338,7 +338,7 @@ static int ali15x3_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 ali15x3_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data)
@@ -364,7 +364,7 @@ static s32 ali15x3_access(struct i2c_adaswitch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); -return -1 ; +return -EOPNOTSUPP ;case I2C_SMBUS_QUICK :outb_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMBHSTADD );
@@ -421,8 +421,9 @@ static s32 ali15x3_access(struct i2c_adaoutb_p (size,SMBHSTCNT );/* output command */ -if (ali15x3_transaction (adap))/* Error in transaction */ -return -1 ; + temp =ali15x3_transaction (adap); +if (temp) +return temp;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==ALI15X3_QUICK ))return 0 ;
drivers/i2c/busses/i2c-amd756-s4882.c +2 -2
@@ -58,7 +58,7 @@ static s32 amd756_access_virt0(struct i2/* We exclude the multiplexed addresses */ if (addr ==0x4c || (addr &0xfc ) ==0x50 || (addr &0xfc ) ==0x30 || addr ==0x18 ) -return -1 ; +return -ENXIO ;mutex_lock (&amd756_lock);
@@ -86,7 +86,7 @@ static inline s32 amd756_access_channel(/* We exclude the non-multiplexed addresses */ if (addr !=0x4c && (addr &0xfc ) !=0x50 && (addr &0xfc ) !=0x30 ) -return -1 ; +return -ENXIO ;mutex_lock (&amd756_lock);
drivers/i2c/busses/i2c-amd756.c +10 -8
@@ -151,17 +151,17 @@ static int amd756_transaction(struct i2c }if (temp &GS_PRERR_STS ) { - result =-1 ; + result = -ENXIO ;dev_dbg (&adap->dev,"SMBus Protocol error (no response)!\n" ); }if (temp &GS_COL_STS ) { - result =-1 ; + result = -EIO ;dev_warn (&adap->dev,"SMBus collision!\n" ); }if (temp &GS_TO_STS ) { - result =-1 ; + result = -ETIMEDOUT ;dev_dbg (&adap->dev,"SMBus protocol timeout!\n" ); }
@@ -189,22 +189,23 @@ static int amd756_transaction(struct i2coutw_p (inw (SMB_GLOBAL_ENABLE ) |GE_ABORT ,SMB_GLOBAL_ENABLE );msleep (100 );outw_p (GS_CLEAR_STS ,SMB_GLOBAL_STATUS ); -return -1 ; +return -EIO ; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 amd756_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {int i, len; +int status;/** TODO: Should I supporte the 10-bit transfers? */ switch (size) {case I2C_SMBUS_PROC_CALL :dev_dbg (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" );/* TODO: Well... It is supported, I'm just not sure what to do here... */ -return -1 ; +return -EOPNOTSUPP ;case I2C_SMBUS_QUICK :outw_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMB_HOST_ADDRESS );
@@ -256,8 +257,9 @@ static s32 amd756_access(struct i2c_adap/* How about enabling interrupts... */ outw_p (size &GE_CYC_TYPE_MASK ,SMB_GLOBAL_ENABLE ); -if (amd756_transaction (adap))/* Error in transaction */ -return -1 ; + status =amd756_transaction (adap); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==AMD756_QUICK ))return 0 ;
drivers/i2c/busses/i2c-amd8111.c +31 -16
96 lines not on this page · raw message
drivers/i2c/busses/i2c-i801.c +23 -21
148 lines not on this page · raw message
drivers/i2c/busses/i2c-nforce2.c +13 -12
@@ -145,16 +145,16 @@ static int nforce2_check_status(struct idev_dbg (&adap->dev,"SMBus Timeout!\n" );if (smbus->can_abort)nforce2_abort (adap); -return -1 ; +return -ETIMEDOUT ; }if (!(temp &NVIDIA_SMB_STS_DONE ) || (temp &NVIDIA_SMB_STS_STATUS )) {dev_dbg (&adap->dev,"Transaction failed (0x%02x)!\n" , temp); -return -1 ; +return -EIO ; }return 0 ; } -/* Return -1 on error */ +/* Return negative errno on error */ static s32 nforce2_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data)
@@ -162,7 +162,7 @@ static s32 nforce2_access(struct i2c_adastruct nforce2_smbus *smbus = adap->algo_data;unsigned char protocol, pec;u8 len; -int i; +int i, status; protocol = (read_write ==I2C_SMBUS_READ ) ?NVIDIA_SMB_PRTCL_READ :NVIDIA_SMB_PRTCL_WRITE ;
@@ -206,7 +206,7 @@ static s32 nforce2_access(struct i2c_ada"Transaction failed " "(requested block size: %d)\n" , len); -return -1 ; +return -EINVAL ; }outb_p (len,NVIDIA_SMB_BCNT );for (i =0 ; i <I2C_SMBUS_BLOCK_MAX ; i++)
@@ -218,14 +218,15 @@ static s32 nforce2_access(struct i2c_adadefault :dev_err (&adap->dev,"Unsupported transaction %d\n" , size); -return -1 ; +return -EOPNOTSUPP ; }outb_p ((addr &0x7f ) <<1 ,NVIDIA_SMB_ADDR );outb_p (protocol,NVIDIA_SMB_PRTCL ); -if (nforce2_check_status (adap)) -return -1 ; + status =nforce2_check_status (adap); +if (status) +return status;if (read_write ==I2C_SMBUS_WRITE )return 0 ;
@@ -247,7 +248,7 @@ static s32 nforce2_access(struct i2c_adadev_err (&adap->dev,"Transaction failed " "(received block size: 0x%02x)\n" , len); -return -1 ; +return -EPROTO ; }for (i =0 ; i < len; i++) data->block[i+1 ] =inb_p (NVIDIA_SMB_DATA + i);
@@ -308,7 +309,7 @@ static int __devinit nforce2_probe_smb ( != PCIBIOS_SUCCESSFUL) {dev_err (&dev->dev,"Error reading PCI config for %s\n" , name); -return -1 ; +return -EIO ; } smbus->base = iobase &PCI_BASE_ADDRESS_IO_MASK ;
@@ -318,7 +319,7 @@ static int __devinit nforce2_probe_smb (if (!request_region (smbus->base, smbus->size, nforce2_driver.name)) {dev_err (&smbus->adapter.dev,"Error requesting region %02x .. %02X for %s\n" , smbus->base, smbus->base+smbus->size-1 , name); -return -1 ; +return -EBUSY ; } smbus->adapter.owner =THIS_MODULE ; smbus->adapter.id =I2C_HW_SMBUS_NFORCE2 ;
@@ -333,7 +334,7 @@ static int __devinit nforce2_probe_smb (if (error) {dev_err (&smbus->adapter.dev,"Failed to register adapter.\n" );release_region (smbus->base, smbus->size); -return -1 ; +return error; }dev_info (&smbus->adapter.dev,"nForce2 SMBus adapter at %#x\n" , smbus->base);return 0 ;
drivers/i2c/busses/i2c-piix4.c +11 -9
@@ -253,7 +253,7 @@ static int piix4_transaction(void)outb_p (temp,SMBHSTSTS );if ((temp =inb_p (SMBHSTSTS )) !=0x00 ) {dev_err (&piix4_adapter.dev,"Failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&piix4_adapter.dev,"Successful!\n" ); }
@@ -275,23 +275,23 @@ static int piix4_transaction(void)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_err (&piix4_adapter.dev,"SMBus Timeout!\n" ); - result =-1 ; + result = -ETIMEDOUT ; }if (temp &0x10 ) { - result =-1 ; + result = -EIO ;dev_err (&piix4_adapter.dev,"Error: Failed bus transaction\n" ); }if (temp &0x08 ) { - result =-1 ; + result = -EIO ;dev_dbg (&piix4_adapter.dev,"Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n" );/* Clock stops and slave is stuck in mid-transmission */ }if (temp &0x04 ) { - result =-1 ; + result = -ENXIO ;dev_dbg (&piix4_adapter.dev,"Error: no response!\n" ); }
@@ -309,17 +309,18 @@ static int piix4_transaction(void)return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 piix4_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {int i, len; +int status;switch (size) {case I2C_SMBUS_PROC_CALL :dev_err (&adap->dev,"I2C_SMBUS_PROC_CALL not supported!\n" ); -return -1 ; +return -EOPNOTSUPP ;case I2C_SMBUS_QUICK :outb_p (((addr &0x7f ) <<1 ) | (read_write &0x01 ),SMBHSTADD );
@@ -371,8 +372,9 @@ static s32 piix4_access(struct i2c_adaptoutb_p ((size &0x1C ) + (ENABLE_INT9 &1 ),SMBHSTCNT ); -if (piix4_transaction ())/* Error in transaction */ -return -1 ; + status =piix4_transaction (); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==PIIX4_QUICK ))return 0 ;
drivers/i2c/busses/i2c-sis5595.c +11 -8
@@ -236,7 +236,7 @@ static int sis5595_transaction(struct i2sis5595_write (SMB_STS_HI , temp >>8 );if ((temp =sis5595_read (SMB_STS_LO ) + (sis5595_read (SMB_STS_HI ) <<8 )) !=0x00 ) {dev_dbg (&adap->dev,"Failed! (%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&adap->dev,"Successful!\n" ); }
@@ -254,19 +254,19 @@ static int sis5595_transaction(struct i2/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_dbg (&adap->dev,"SMBus Timeout!\n" ); - result =-1 ; + result = -ETIMEDOUT ; }if (temp &0x10 ) {dev_dbg (&adap->dev,"Error: Failed bus transaction\n" ); - result =-1 ; + result = -ENXIO ; }if (temp &0x20 ) {dev_err (&adap->dev,"Bus collision! SMBus may be locked until " "next hard reset (or not...)\n" );/* Clock stops and slave is stuck in mid-transmission */ - result =-1 ; + result = -EIO ; } temp =sis5595_read (SMB_STS_LO ) + (sis5595_read (SMB_STS_HI ) <<8 );
@@ -282,11 +282,13 @@ static int sis5595_transaction(struct i2return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis5595_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data) { +int status; +switch (size) {case I2C_SMBUS_QUICK :sis5595_write (SMB_ADDR , ((addr &0x7f ) <<1 ) | (read_write &0x01 ));
@@ -318,13 +320,14 @@ static s32 sis5595_access(struct i2c_adabreak ;default :dev_warn (&adap->dev,"Unsupported transaction %d\n" , size); -return -1 ; +return -EOPNOTSUPP ; }sis5595_write (SMB_CTL_LO , ((size &0x0E ))); -if (sis5595_transaction (adap)) -return -1 ; + status =sis5595_transaction (adap); +if (status) +return status;if ((size !=SIS5595_PROC_CALL ) && ((read_write ==I2C_SMBUS_WRITE ) || (size ==SIS5595_QUICK )))
drivers/i2c/busses/i2c-sis630.c +26 -21
112 lines not on this page · raw message
drivers/i2c/busses/i2c-sis96x.c +12 -11
@@ -111,7 +111,7 @@ static int sis96x_transaction(int size)/* check it again */ if (((temp =sis96x_read (SMB_CNT )) &0x03 ) !=0x00 ) {dev_dbg (&sis96x_adapter.dev,"Failed (0x%02x)\n" , temp); -return -1 ; +return -EBUSY ; }else {dev_dbg (&sis96x_adapter.dev,"Successful\n" ); }
@@ -136,19 +136,19 @@ static int sis96x_transaction(int size)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) {dev_dbg (&sis96x_adapter.dev,"SMBus Timeout! (0x%02x)\n" , temp); - result =-1 ; + result = -ETIMEDOUT ; }/* device error - probably missing ACK */ if (temp &0x02 ) {dev_dbg (&sis96x_adapter.dev,"Failed bus transaction!\n" ); - result =-1 ; + result = -ENXIO ; }/* bus collision */ if (temp &0x04 ) {dev_dbg (&sis96x_adapter.dev,"Bus collision!\n" ); - result =-1 ; + result = -EIO ; }/* Finish up by resetting the bus */
@@ -161,11 +161,12 @@ static int sis96x_transaction(int size)return result; } -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 sis96x_access (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) { +int status;switch (size) {case I2C_SMBUS_QUICK :
@@ -203,17 +204,17 @@ static s32 sis96x_access(struct i2c_adapcase I2C_SMBUS_BLOCK_DATA :/* TO DO: */ dev_info (&adap->dev,"SMBus block not implemented!\n" ); -return -1 ; +return -EOPNOTSUPP ;break ;default : -dev_info (&adap->dev,"Unsupported I2C size\n" ); -return -1 ; -break ; +dev_info (&adap->dev,"Unsupported SMBus operation\n" ); +return -EOPNOTSUPP ; } -if (sis96x_transaction (size)) -return -1 ; + status =sis96x_transaction (size); +if (status) +return status;if ((size != SIS96x_PROC_CALL) && ((read_write ==I2C_SMBUS_WRITE ) || (size == SIS96x_QUICK)))
drivers/i2c/busses/i2c-stub.c +2 -2
@@ -43,7 +43,7 @@ struct stub_chip {static struct stub_chip *stub_chips; -/* Return -1 on error. */ +/* Return negative errno on error. */ static s32 stub_xfer (struct i2c_adapter * adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data * data) {
@@ -120,7 +120,7 @@ static s32 stub_xfer(struct i2c_adapterdefault :dev_dbg (&adap->dev,"Unsupported I2C/SMBus command\n" ); - ret =-1 ; + ret = -EOPNOTSUPP ;break ; }/* switch (size) */
drivers/i2c/busses/i2c-viapro.c +13 -9
@@ -152,7 +152,7 @@ static int vt596_transaction(u8 size)if ((temp =inb_p (SMBHSTSTS )) &0x1F ) {dev_err (&vt596_adapter.dev,"SMBus reset failed! " "(0x%02x)\n" , temp); -return -1 ; +return -EBUSY ; } }
@@ -167,30 +167,32 @@ static int vt596_transaction(u8 size)/* If the SMBus is still busy, we give up */ if (timeout >=MAX_TIMEOUT ) { - result =-1 ; + result = -ETIMEDOUT ;dev_err (&vt596_adapter.dev,"SMBus timeout!\n" ); }if (temp &0x10 ) { - result =-1 ; + result = -EIO ;dev_err (&vt596_adapter.dev,"Transaction failed (0x%02x)\n" , size); }if (temp &0x08 ) { - result =-1 ; + result = -EIO ;dev_err (&vt596_adapter.dev,"SMBus collision!\n" ); }if (temp &0x04 ) {int read =inb_p (SMBHSTADD ) &0x01 ; - result =-1 ; + result = -EIO ;/* The quick and receive byte commands are used to probe for chips, so errors are expected, and we don't want to frighten the user. */ if (!((size ==VT596_QUICK && !read) || (size ==VT596_BYTE && read)))dev_err (&vt596_adapter.dev,"Transaction error!\n" ); +else + result = -ENXIO ; }/* Resetting status register */
@@ -202,12 +204,13 @@ static int vt596_transaction(u8 size)return result; } -/* Return -1 on error, 0 on success */ +/* Return negative errno on error, 0 on success */ static s32 vt596_access (struct i2c_adapter *adap,u16 addr,unsigned short flags,char read_write,u8 command,int size,union i2c_smbus_data *data) {int i; +int status;switch (size) {case I2C_SMBUS_QUICK :
@@ -258,8 +261,9 @@ static s32 vt596_access(struct i2c_adaptoutb_p (((addr &0x7f ) <<1 ) | read_write,SMBHSTADD ); -if (vt596_transaction (size))/* Error in transaction */ -return -1 ; + status =vt596_transaction (size); +if (status) +return status;if ((read_write ==I2C_SMBUS_WRITE ) || (size ==VT596_QUICK ))return 0 ;
@@ -287,7 +291,7 @@ static s32 vt596_access(struct i2c_adapt exit_unsupported:dev_warn (&vt596_adapter.dev,"Unsupported command invoked! (0x%02x)\n" , size); -return -1 ; +return -EOPNOTSUPP ; }static u32 vt596_func (struct i2c_adapter *adapter)
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805120943.04899.david-b-yBeKhBN/[email protected]
Hi David,
Quoted 4 lines · David Brownell
drivers/i2c/busses/i2c-ali1563.c +0
-0@@ -106,8 +106,11 @@ static int ali1563_transaction(struct i2 }
drivers/i2c/busses/i2c-ali1563.c static int ali1563_transaction(struct i2 · line 114
Quoted 10 lines
drivers/i2c/busses/i2c-ali1563.c +5
-2/* device error - no response, ignore the autodetection case */ -if ((data &HST_STS_DEVERR ) && (size !=HST_CNTL2_QUICK )) { -dev_err (&a->dev,"Device error!\n" ); +if (data &HST_STS_DEVERR ) { +if (size !=HST_CNTL2_QUICK ) +dev_err (&a->dev,"Device error!\n" ); +else +return -ENXIO ; }
This one doesn't look right. You should return -ENXIO in all cases (but only print the error message on size != HST_CNTL2_QUICK.) The right way to do this, I think, would be to move this specific check at the end of the function, so that the other error checks are still done in all cases.
Quoted 19 lines
drivers/i2c/busses/i2c-ali1563.c +2
-1/* bus collision */ @@ -122,13 +125,14 @@ static int ali1563_transaction(struct i2outb_p (0x0 ,SMB_HST_CNTL2 ); } -return -1 ; +return -EIO ; }static int ali1563_block_start (struct i2c_adapter * a) {u32 data;int timeout; +int status = -EIO ; dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, " "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 173
Quoted 6 lines
drivers/i2c/busses/i2c-ali1563.c +3
-0@@ -164,13 +168,17 @@ static int ali1563_block_start(struct i2if (timeout && !(data &HST_STS_BAD ))return 0 ; + +if (timeout ==0 && !(data &HST_STS_DONE )) + status = -ETIMEDOUT ;
That's pretty strange to check for both timeout == 0 and !(data & HST_STS_DONE), given that the former implies the latter if I read the code correctly. The same strangeness is present in the code below, if we print "Timeout" then we will also print "Transaction Never Finished".
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 176
Quoted 3 lines
drivers/i2c/busses/i2c-ali1563.c +1
-0+ dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", timeout ? "Timeout " : "",
BTW, isn't there a bug here? I think the test should be timeout == 0.
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 182
Quoted 7 lines
drivers/i2c/busses/i2c-ali1563.c +1
-1data &HST_STS_FAIL ?"Transaction Failed " :"" , data &HST_STS_BUSERR ?"No response or Bus Collision " :"" , data &HST_STS_DEVERR ?"Device Error " :"" , !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); -return -1 ; +return status; }
I thought we had agreed that we would return -ENXIO for HST_STS_DEVERR, as we already do in ali1563_transaction()?
Quoted 7 lines
drivers/i2c/busses/i2c-viapro.c +0
-1@@ -152,7 +152,7 @@ static int vt596_transaction(u8 size)if (temp &0x04 ) {int read =inb_p (SMBHSTADD ) &0x01 ; - result =-1 ;
drivers/i2c/busses/i2c-viapro.c static int vt596_transaction(u8 size) · line 196
Quoted 10 lines
drivers/i2c/busses/i2c-viapro.c +3
-0+ result = -EIO ;/* The quick and receive byte commands are used to probe for chips, so errors are expected, and we don't want to frighten the user. */ if (!((size ==VT596_QUICK && !read) || (size ==VT596_BYTE && read)))dev_err (&vt596_adapter.dev,"Transaction error!\n" ); +else + result = -ENXIO ; }
This is not correct, the result is always -ENXIO, whether you display an error message or not.
All the rest looks fine now. BTW, I can test i2c-piix4, i2c-i801, i2c-viapro and i2c-nforce2 here, and will do soon.
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 12 lines · Jean Delvare
Hi David,
drivers/i2c/busses/i2c-ali1563.c
Quoted 3 lines · David Brownell
drivers/i2c/busses/i2c-ali1563.c +0
-0This one doesn't look right. You should return
-ENXIOin all cases (but only print the error message on size !=HST_CNTL2_QUICK.) The right way to do this, I think, would be to move this specific check at the end of the function, so that the other error checks are still done in all cases.
OK, done ...
Quoted 12 lines
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 173
Quoted 7 lines
drivers/i2c/busses/i2c-ali1563.c +3
-0@@ -164,13 +168,17 @@ static int ali1563_block_start(struct i2if (timeout && !(data &HST_STS_BAD ))return 0 ; + +if (timeout ==0 && !(data &HST_STS_DONE )) + status = -ETIMEDOUT ;That's pretty strange to check for both timeout == 0 and !(data &
HST_STS_DONE), given that the former implies the latter if I read the code correctly. The same strangeness is present in the code below, if we print "Timeout" then we will also print "Transaction Never Finished".
Without chip docs, and knowing that it overloads lots of fault cases into not enough bits, I wouldn't rely on such conclusions. Instead, I just tried to make sure the ETIMEDOUT means exactly what is promised in the faultcode writeup.
Quoted 5 lines
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 176
Quoted 3 lines
drivers/i2c/busses/i2c-ali1563.c +1
-0+ dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", timeout ? "Timeout " : "",BTW, isn't there a bug here? I think the test should be timeout == 0.
Right, fixed.
Quoted 10 lines
drivers/i2c/busses/i2c-ali1563.c static int ali1563_block_start(struct i2 · line 182
Quoted 7 lines
drivers/i2c/busses/i2c-ali1563.c +1
-1data &HST_STS_FAIL ?"Transaction Failed " :"" , data &HST_STS_BUSERR ?"No response or Bus Collision " :"" , data &HST_STS_DEVERR ?"Device Error " :"" , !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); -return -1 ; +return status; }I thought we had agreed that we would return
-ENXIOforHST_STS_DEVERR, as we already do inali1563_transaction()?
I thought we'd agreed to not play guessing games about the behavior of chips we don't have docs for ... ;)
Quoted 12 lines
Quoted 12 lines
drivers/i2c/busses/i2c-viapro.c +1
-1@@ -152,7 +152,7 @@ static int vt596_transaction(u8 size)if (temp &0x04 ) {int read =inb_p (SMBHSTADD ) &0x01 ; - result =-1 ; + result = -EIO ;/* The quick and receive byte commands are used to probe for chips, so errors are expected, and we don't want to frighten the user. */ if (!((size == VT596_QUICK && !read) ||
Quoted 8 lines
drivers/i2c/busses/i2c-viapro.c
Quoted 5 lines
drivers/i2c/busses/i2c-viapro.c +2
-0(size == VT596_BYTE && read)))dev_err (&vt596_adapter.dev,"Transaction error!\n" ); + else + result = -ENXIO ; }This is not correct, the result is always
-ENXIO, whether you display an error message or not.
Fixed.
Quoted 2 lines
All the rest looks fine now. BTW, I can test i2c-piix4, i2c-i801, i2c-viapro and i2c-nforce2 here, and will do soon.
Appended is a small fixup patch addressing the issues above ...
- Dave
drivers/i2c/busses/i2c-ali1563.c +8 -9
@@ -105,14 +105,6 @@ static int ali1563_transaction(struct i2 data =inb_p (SMB_HST_STS ); } -/* device error - no response, ignore the autodetection case */ -if (data &HST_STS_DEVERR ) { -if (size !=HST_CNTL2_QUICK ) -dev_err (&a->dev,"Device error!\n" ); -else -return -ENXIO ; - } -/* bus collision */ if (data &HST_STS_BUSERR ) {dev_err (&a->dev,"Bus collision!\n" );
@@ -125,6 +117,13 @@ static int ali1563_transaction(struct i2outb_p (0x0 ,SMB_HST_CNTL2 ); } +/* device error - no response, ignore the autodetection case */ +if (data &HST_STS_DEVERR ) { +if (size !=HST_CNTL2_QUICK ) +dev_err (&a->dev,"Device error!\n" ); +return -ENXIO ; + } +return -EIO ; }
@@ -173,7 +172,7 @@ static int ali1563_block_start(struct i2 status = -ETIMEDOUT ; dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", - timeout ? "Timeout " : "", + timeout ? "" : "Timeout ", data & HST_STS_FAIL ? "Transaction Failed " : "", data & HST_STS_BUSERR ? "No response or Bus Collision " : "", data & HST_STS_DEVERR ? "Device Error " : "",
drivers/i2c/busses/i2c-viapro.c +2 -3
@@ -184,15 +184,14 @@ static int vt596_transaction(u8 size)if (temp &0x04 ) {int read =inb_p (SMBHSTADD ) &0x01 ; - result = -EIO ; +/* The quick and receive byte commands are used to probe for chips, so errors are expected, and we don't want to frighten the user. */ if (!((size ==VT596_QUICK && !read) || (size ==VT596_BYTE && read)))dev_err (&vt596_adapter.dev,"Transaction error!\n" ); -else - result = -ENXIO ; + result = -ENXIO ; }/* Resetting status register */
_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c
A message that is not in the archive (sent off-list or not yet received): 200805171754.15976.david-b-yBeKhBN/[email protected]
Hi David,
Quoted 16 lines · David Brownell
Quoted 4 lines · Jean Delvare
Hi David,
Quoted 2 lines · David Brownell
(quoted diff) +0
-0@@ -164,13 +168,17 @@ static int ali1563_block_start(struct i2Quoted 10 lines
Review static int ali1563_block_start(struct i2 · line 173
Quoted 5 lines
(quoted diff) +3
-0if (timeout && !(data & HST_STS_BAD)) return 0; + + if (timeout == 0 && !(data & HST_STS_DONE)) + status = -ETIMEDOUT;That's pretty strange to check for both timeout == 0 and !(data &
HST_STS_DONE), given that the former implies the latter if I read the code correctly. The same strangeness is present in the code below, if we print "Timeout" then we will also print "Transaction Never Finished".
Quoted 4 lines
Without chip docs, and knowing that it overloads lots of fault cases into not enough bits, I wouldn't rely on such conclusions. Instead, I just tried to make sure the ETIMEDOUT means exactly what is promised in the faultcode writeup.
This doesn't have anything to do with the hardware. The poll loop is:
timeout = ALI1563_MAX_TIMEOUT; do msleep(1); while (!((data = inb_p(SMB_HST_STS)) & HST_STS_DONE) && --timeout);
Regardless of what the hardware does, it is simply impossible to have timeout == 0 if you don't have !(data & HST_STS_DONE), because you wouldn't decrease timeout if (data & HST_STS_DONE). This, testing for just timeout == 0 after this loop is equivalent to testing for timeout == 0 && !(data & HST_STS_DONE). As a matter of fact, the driver only tests for timeout == 0 in ali1563_transaction() (although it doesn't return -ETIMEDOUT there, we probably should fix that.)
Quoted 11 lines
Quoted 10 lines
Review static int ali1563_block_start(struct i2 · line 179
Quoted 7 lines
(quoted diff) +1
-1data & HST_STS_FAIL ? "Transaction Failed " : "", data & HST_STS_BUSERR ? "No response or Bus Collision " : "", data & HST_STS_DEVERR ? "Device Error " : "", !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); - return -1; + return status; }I thought we had agreed that we would return
-ENXIOforHST_STS_DEVERR, as we already do inali1563_transaction()?
Quoted 2 lines
I thought we'd agreed to not play guessing games about the behavior of chips we don't have docs for ... ;)
The problem is that in ali1563_transaction() we map (data & HST_STS_DEVERR) to -ENXIO, so not doing the same in ali1563_block_start() is somewhat inconsistent.
Quoted 55 lines
Appended is a small fixup patch addressing the issues above ...
- Dave
drivers/i2c/busses/i2c-ali1563.c +8
-9@@ -105,14 +105,6 @@ static int ali1563_transaction(struct i2 data =inb_p (SMB_HST_STS ); } -/* device error - no response, ignore the autodetection case */ -if (data &HST_STS_DEVERR ) { -if (size !=HST_CNTL2_QUICK ) -dev_err (&a->dev,"Device error!\n" ); -else -return -ENXIO ; - } -/* bus collision */ if (data &HST_STS_BUSERR ) {dev_err (&a->dev,"Bus collision!\n" );@@ -125,6 +117,13 @@ static int ali1563_transaction(struct i2outb_p (0x0 ,SMB_HST_CNTL2 ); } +/* device error - no response, ignore the autodetection case */ +if (data &HST_STS_DEVERR ) { +if (size !=HST_CNTL2_QUICK ) +dev_err (&a->dev,"Device error!\n" ); +return -ENXIO ; + } +return -EIO ; }@@ -173,7 +172,7 @@ static int ali1563_block_start(struct i2 status = -ETIMEDOUT ; dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", - timeout ? "Timeout " : "", + timeout ? "" : "Timeout ", data & HST_STS_FAIL ? "Transaction Failed " : "", data & HST_STS_BUSERR ? "No response or Bus Collision " : "", data & HST_STS_DEVERR ? "Device Error " : "",drivers/i2c/busses/i2c-viapro.c +1
-1@@ -184,15 +184,14 @@ static int vt596_transaction(u8 size)if (temp &0x04 ) {int read =inb_p (SMBHSTADD ) &0x01 ; - result = -EIO ; +/* The quick and receive byte commands are used to probe for chips, so errors are expected, and we don't want
drivers/i2c/busses/i2c-viapro.c static int vt596_transaction(u8 size) · line 197
Quoted 10 lines
drivers/i2c/busses/i2c-viapro.c +1
-2to frighten the user. */ if (!((size ==VT596_QUICK && !read) || (size ==VT596_BYTE && read)))dev_err (&vt596_adapter.dev,"Transaction error!\n" ); -else - result = -ENXIO ; + result = -ENXIO ; }/* Resetting status register */
OK, I've merged that. I'll add a couple minor fixes as discussed above, and then your patch is ready for linux-next. Thanks!
Signature · 6 lines
Jean Delvare _______________________________________________ i2c mailing list [email protected] http://lists.lm-sensors.org/mailman/listinfo/i2c