/* Return -1 on error, 0 on success */ static int vt596_transaction(u8 size) { int temp; int result = 0; int timeout = 0; vt596_dump_regs("Transaction (pre)", size); /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " "Resetting...\n", temp); outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_err(&vt596_adapter.dev, "SMBus reset failed! " "(0x%02x)\n", temp); return -EBUSY; } } /* Start the transaction by setting bit 6 */ outb_p(0x40 | size, SMBHSTCNT); /* We will always wait for a fraction of a second */ do { msleep(1); temp = inb_p(SMBHSTSTS); } while ((temp & 0x01) && (++timeout < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout == MAX_TIMEOUT) { result = -ETIMEDOUT; dev_err(&vt596_adapter.dev, "SMBus timeout!\n"); } if (temp & 0x10) { result = -EIO; dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", size); } if (temp & 0x08) { result = -EIO; dev_err(&vt596_adapter.dev, "SMBus collision!\n"); } if (temp & 0x04) { result = -ENXIO; dev_dbg(&vt596_adapter.dev, "No response\n"); } /* Resetting status register */ if (temp & 0x1F) outb_p(temp, SMBHSTSTS); vt596_dump_regs("Transaction (post)", size); return result; }
static int vt596_transaction(u8 size) { int temp; int result = 0; int timeout = 0; vt596_dump_regs("Transaction (pre)", size); if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " "Resetting...\n", temp); outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_err(&vt596_adapter.dev, "SMBus reset failed! " "(0x%02x)\n", temp); return -EBUSY; } } outb_p(0x40 | size, SMBHSTCNT); do { msleep(1); temp = inb_p(SMBHSTSTS); } while ((temp & 0x01) && (++timeout < MAX_TIMEOUT)); if (timeout == MAX_TIMEOUT) { result = -ETIMEDOUT; dev_err(&vt596_adapter.dev, "SMBus timeout!\n"); } if (temp & 0x10) { result = -EIO; dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", size); } if (temp & 0x08) { result = -EIO; dev_err(&vt596_adapter.dev, "SMBus collision!\n"); } if (temp & 0x04) { result = -ENXIO; dev_dbg(&vt596_adapter.dev, "No response\n"); } if (temp & 0x1F) outb_p(temp, SMBHSTSTS); vt596_dump_regs("Transaction (post)", size); return result; }
/* Return -1 on error, 0 on success */ static int vt596_transaction(u8 size) { int temp; int result = 0; int timeout = 0; vt596_dump_regs("Transaction (pre)", size); /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " "Resetting...\n", temp); outb_p(temp, SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { dev_err(&vt596_adapter.dev, "SMBus reset failed! " "(0x%02x)\n", temp); return -EBUSY; } } /* Start the transaction by setting bit 6 */ outb_p(0x40 | size, SMBHSTCNT); /* We will always wait for a fraction of a second */ do { msleep(1); temp = inb_p(SMBHSTSTS); } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { result = -ETIMEDOUT; dev_err(&vt596_adapter.dev, "SMBus timeout!\n"); } if (temp & 0x10) { result = -EIO; dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", size); } if (temp & 0x08) { result = -EIO; dev_err(&vt596_adapter.dev, "SMBus collision!\n"); } if (temp & 0x04) { int read = inb_p(SMBHSTADD) & 0x01; result = -ENXIO; /* 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"); } /* Resetting status register */ if (temp & 0x1F) outb_p(temp, SMBHSTSTS); vt596_dump_regs("Transaction (post)", size); return result; }