+ u8 buf_temp[32];
+ int count;
+ int i;
+
+ debug("%s (%d): dev=0x%x offs=0x%x len=0x%x\n",
+ __func__, __LINE__, dev, offset, len);
+ if (smbus_wait_until_ready(base) < 0)
+ return -ETIMEDOUT;
+
+ /* Setup transaction */
+
+ /* Reset the data buffer index */
+ inb(base + SMBHSTCTL);
+
+ /* Set the device I'm talking too */
+ outb(((dev & 0x7f) << 1) | 1, base + SMBXMITADD);
+ /* Set the command/address... */
+ outb(offset & 0xff, base + SMBHSTCMD);
+ /* Set up for a block read */
+ outb((inb(base + SMBHSTCTL) & (~(0x7) << 2)) | (0x5 << 2),
+ (base + SMBHSTCTL));
+ /* Clear any lingering errors, so the transaction will run */
+ outb(inb(base + SMBHSTSTAT), base + SMBHSTSTAT);
+
+ /* Start the command */
+ outb((inb(base + SMBHSTCTL) | SMBHSTCNT_START), base + SMBHSTCTL);
+
+ /* Poll for transaction completion */
+ if (smbus_wait_until_done(base) < 0) {
+ printf("SMBUS read transaction timeout (dev=0x%x)\n", dev);
+ return -ETIMEDOUT;
+ }
+
+ count = inb(base + SMBHSTDAT0);
+ debug("%s (%d): count=%d (len=%d)\n", __func__, __LINE__, count, len);
+ if (count == 0) {
+ debug("ERROR: len=0 on read\n");
+ return -EIO;
+ }
+
+ if (count < len) {
+ debug("ERROR: too few bytes read\n");
+ return -EIO;
+ }
+
+ if (count > 32) {
+ debug("ERROR: count=%d too high\n", count);
+ return -EIO;
+ }
+
+ /* Read all available bytes from buffer */
+ for (i = 0; i < count; i++)
+ buf_temp[i] = inb(base + SMBBLKDAT);
+
+ memcpy(buffer, buf_temp, len);
+
+ /* Return results of transaction */
+ if (!(inb(base + SMBHSTSTAT) & SMBHSTSTS_INTR))
+ return -EIO;
+