diff --git a/src/southbridge/intel/common/smbus.c b/src/southbridge/intel/common/smbus.c index 43d7d1901f..90ef03ee12 100644 --- a/src/southbridge/intel/common/smbus.c +++ b/src/southbridge/intel/common/smbus.c @@ -337,7 +337,7 @@ int do_smbus_block_write(unsigned int smbus_base, u8 device, u8 cmd, /* Only since ICH5 */ int do_i2c_block_read(unsigned int smbus_base, u8 device, - unsigned int offset, u32 bytes, u8 *buf) + unsigned int offset, const unsigned int bytes, u8 *buf) { u8 status; int bytes_read = 0; @@ -379,18 +379,25 @@ int do_i2c_block_read(unsigned int smbus_base, u8 device, return SMBUS_ERROR; if (status & SMBHSTSTS_BYTE_DONE) { - *buf = inb(smbus_base + SMBBLKDAT); - buf++; - bytes_read++; - if (--bytes == 1) { + + if (bytes_read < bytes) { + *buf++ = inb(smbus_base + SMBBLKDAT); + bytes_read++; + } + + if (bytes_read + 1 >= bytes) { /* indicate that next byte is the last one */ outb(inb(smbus_base + SMBHSTCTL) | SMBHSTCNT_LAST_BYTE, smbus_base + SMBHSTCTL); } + outb(status, smbus_base + SMBHSTSTAT); } } while ((status & SMBHSTSTS_HOST_BUSY) && loops); + if (bytes_read < bytes) + return SMBUS_ERROR; + return bytes_read; } diff --git a/src/southbridge/intel/common/smbus.h b/src/southbridge/intel/common/smbus.h index 3016a1726f..be1aa76c21 100644 --- a/src/southbridge/intel/common/smbus.h +++ b/src/southbridge/intel/common/smbus.h @@ -42,5 +42,5 @@ int do_smbus_block_write(unsigned int smbus_base, u8 device, u8 cmd, unsigned int bytes, const u8 *buf); /* Only since ICH5 */ int do_i2c_block_read(unsigned int smbus_base, u8 device, - unsigned int offset, u32 bytes, u8 *buf); + unsigned int offset, unsigned int bytes, u8 *buf); #endif