diff options
author | David Brownell <david-b@pacbell.net> | 2008-07-14 16:38:25 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-14 16:38:25 -0400 |
commit | 97140342e69d479a3ad82bfd4c154c0b08fe3eea (patch) | |
tree | 2ee2ad225c7e4850a30bc57c4bf07251c1da1085 /drivers/i2c/busses/i2c-sis630.c | |
parent | 6ea438ec8da4ec56bf415f5ea360e6b0cb59c6c3 (diff) |
i2c: Bus drivers return -Errno not -1
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.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/busses/i2c-sis630.c')
-rw-r--r-- | drivers/i2c/busses/i2c-sis630.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 3765dd7f450f..c4cc5eddf50d 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c | |||
@@ -134,7 +134,7 @@ static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldc | |||
134 | 134 | ||
135 | if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { | 135 | if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { |
136 | dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); | 136 | dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); |
137 | return -1; | 137 | return -EBUSY; |
138 | } else { | 138 | } else { |
139 | dev_dbg(&adap->dev, "Successful!\n"); | 139 | dev_dbg(&adap->dev, "Successful!\n"); |
140 | } | 140 | } |
@@ -177,17 +177,17 @@ static int sis630_transaction_wait(struct i2c_adapter *adap, int size) | |||
177 | /* If the SMBus is still busy, we give up */ | 177 | /* If the SMBus is still busy, we give up */ |
178 | if (timeout >= MAX_TIMEOUT) { | 178 | if (timeout >= MAX_TIMEOUT) { |
179 | dev_dbg(&adap->dev, "SMBus Timeout!\n"); | 179 | dev_dbg(&adap->dev, "SMBus Timeout!\n"); |
180 | result = -1; | 180 | result = -ETIMEDOUT; |
181 | } | 181 | } |
182 | 182 | ||
183 | if (temp & 0x02) { | 183 | if (temp & 0x02) { |
184 | dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); | 184 | dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); |
185 | result = -1; | 185 | result = -ENXIO; |
186 | } | 186 | } |
187 | 187 | ||
188 | if (temp & 0x04) { | 188 | if (temp & 0x04) { |
189 | dev_err(&adap->dev, "Bus collision!\n"); | 189 | dev_err(&adap->dev, "Bus collision!\n"); |
190 | result = -1; | 190 | result = -EIO; |
191 | /* | 191 | /* |
192 | TBD: Datasheet say: | 192 | TBD: Datasheet say: |
193 | the software should clear this bit and restart SMBUS operation. | 193 | the software should clear this bit and restart SMBUS operation. |
@@ -250,8 +250,10 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat | |||
250 | if (i==8 || (len<8 && i==len)) { | 250 | if (i==8 || (len<8 && i==len)) { |
251 | dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i); | 251 | dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i); |
252 | /* first transaction */ | 252 | /* first transaction */ |
253 | if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) | 253 | rc = sis630_transaction_start(adap, |
254 | return -1; | 254 | SIS630_BLOCK_DATA, &oldclock); |
255 | if (rc) | ||
256 | return rc; | ||
255 | } | 257 | } |
256 | else if ((i-1)%8 == 7 || i==len) { | 258 | else if ((i-1)%8 == 7 || i==len) { |
257 | dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i); | 259 | dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i); |
@@ -264,9 +266,10 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat | |||
264 | */ | 266 | */ |
265 | sis630_write(SMB_STS,0x10); | 267 | sis630_write(SMB_STS,0x10); |
266 | } | 268 | } |
267 | if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) { | 269 | rc = sis630_transaction_wait(adap, |
270 | SIS630_BLOCK_DATA); | ||
271 | if (rc) { | ||
268 | dev_dbg(&adap->dev, "trans_wait failed\n"); | 272 | dev_dbg(&adap->dev, "trans_wait failed\n"); |
269 | rc = -1; | ||
270 | break; | 273 | break; |
271 | } | 274 | } |
272 | } | 275 | } |
@@ -275,13 +278,14 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat | |||
275 | else { | 278 | else { |
276 | /* read request */ | 279 | /* read request */ |
277 | data->block[0] = len = 0; | 280 | data->block[0] = len = 0; |
278 | if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) { | 281 | rc = sis630_transaction_start(adap, |
279 | return -1; | 282 | SIS630_BLOCK_DATA, &oldclock); |
280 | } | 283 | if (rc) |
284 | return rc; | ||
281 | do { | 285 | do { |
282 | if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) { | 286 | rc = sis630_transaction_wait(adap, SIS630_BLOCK_DATA); |
287 | if (rc) { | ||
283 | dev_dbg(&adap->dev, "trans_wait failed\n"); | 288 | dev_dbg(&adap->dev, "trans_wait failed\n"); |
284 | rc = -1; | ||
285 | break; | 289 | break; |
286 | } | 290 | } |
287 | /* if this first transaction then read byte count */ | 291 | /* if this first transaction then read byte count */ |
@@ -311,11 +315,13 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat | |||
311 | return rc; | 315 | return rc; |
312 | } | 316 | } |
313 | 317 | ||
314 | /* Return -1 on error. */ | 318 | /* Return negative errno on error. */ |
315 | static s32 sis630_access(struct i2c_adapter *adap, u16 addr, | 319 | static s32 sis630_access(struct i2c_adapter *adap, u16 addr, |
316 | unsigned short flags, char read_write, | 320 | unsigned short flags, char read_write, |
317 | u8 command, int size, union i2c_smbus_data *data) | 321 | u8 command, int size, union i2c_smbus_data *data) |
318 | { | 322 | { |
323 | int status; | ||
324 | |||
319 | switch (size) { | 325 | switch (size) { |
320 | case I2C_SMBUS_QUICK: | 326 | case I2C_SMBUS_QUICK: |
321 | sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); | 327 | sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); |
@@ -350,13 +356,13 @@ static s32 sis630_access(struct i2c_adapter *adap, u16 addr, | |||
350 | size = SIS630_BLOCK_DATA; | 356 | size = SIS630_BLOCK_DATA; |
351 | return sis630_block_data(adap, data, read_write); | 357 | return sis630_block_data(adap, data, read_write); |
352 | default: | 358 | default: |
353 | printk("Unsupported I2C size\n"); | 359 | printk("Unsupported SMBus operation\n"); |
354 | return -1; | 360 | return -EOPNOTSUPP; |
355 | break; | ||
356 | } | 361 | } |
357 | 362 | ||
358 | if (sis630_transaction(adap, size)) | 363 | status = sis630_transaction(adap, size); |
359 | return -1; | 364 | if (status) |
365 | return status; | ||
360 | 366 | ||
361 | if ((size != SIS630_PCALL) && | 367 | if ((size != SIS630_PCALL) && |
362 | ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) { | 368 | ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) { |
@@ -373,8 +379,7 @@ static s32 sis630_access(struct i2c_adapter *adap, u16 addr, | |||
373 | data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8); | 379 | data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8); |
374 | break; | 380 | break; |
375 | default: | 381 | default: |
376 | return -1; | 382 | return -EOPNOTSUPP; |
377 | break; | ||
378 | } | 383 | } |
379 | 384 | ||
380 | return 0; | 385 | return 0; |