diff options
Diffstat (limited to 'sys-kernel/mactel-linux-sources/files/2.6.24-mactel-patches-r151/applesmc-retry-when-accessing-keys.patch')
-rw-r--r-- | sys-kernel/mactel-linux-sources/files/2.6.24-mactel-patches-r151/applesmc-retry-when-accessing-keys.patch | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/sys-kernel/mactel-linux-sources/files/2.6.24-mactel-patches-r151/applesmc-retry-when-accessing-keys.patch b/sys-kernel/mactel-linux-sources/files/2.6.24-mactel-patches-r151/applesmc-retry-when-accessing-keys.patch new file mode 100644 index 0000000..a12be92 --- /dev/null +++ b/sys-kernel/mactel-linux-sources/files/2.6.24-mactel-patches-r151/applesmc-retry-when-accessing-keys.patch @@ -0,0 +1,115 @@ +Retry up to 200 ms when reading or writing keys. + +From: Nicolas Boichat <nicolas@boichat.ch> + + +--- + + drivers/hwmon/applesmc.c | 69 +++++++++++++++++++++++++++++++--------------- + 1 files changed, 47 insertions(+), 22 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index c0dd9b1..3b09cdb 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -112,6 +112,9 @@ static const char* fan_speed_keys[] = { + #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ + #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */ + ++#define ACCESS_TIMEOUT_MSECS 500 /* wait up to 500ms when accessing a key */ ++#define ACCESS_WAIT_MSECS 5 /* ... in 5ms increments */ ++ + #define APPLESMC_POLL_INTERVAL 50 /* msecs */ + #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */ + #define APPLESMC_INPUT_FLAT 4 +@@ -186,12 +189,13 @@ static int __wait_status(u8 val) + + /* + * applesmc_read_key - reads len bytes from a given key, and put them in buffer. ++ * Tries up to ACCESS_WAIT_MSECS to read the value. + * Returns zero on success or a negative error on failure. Callers must + * hold applesmc_lock. + */ + static int applesmc_read_key(const char* key, u8* buffer, u8 len) + { +- int i; ++ int i, total, ret; + + if (len > APPLESMC_MAX_DATA_LENGTH) { + printk(KERN_ERR "applesmc_read_key: cannot read more than " +@@ -199,33 +203,54 @@ static int applesmc_read_key(const char* key, u8* buffer, u8 len) + return -EINVAL; + } + +- outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT); +- if (__wait_status(0x0c)) +- return -EIO; ++ for (total = ACCESS_TIMEOUT_MSECS; total > 0; ++ total -= ACCESS_WAIT_MSECS) { ++ ret = 0; ++ outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT); ++ if (__wait_status(0x0c)) { ++ ret = -EIO; ++ goto wait_fail; ++ } + +- for (i = 0; i < 4; i++) { +- outb(key[i], APPLESMC_DATA_PORT); +- if (__wait_status(0x04)) +- return -EIO; +- } +- if (debug) +- printk(KERN_DEBUG "<%s", key); ++ for (i = 0; i < 4; i++) { ++ outb(key[i], APPLESMC_DATA_PORT); ++ if (__wait_status(0x04)) { ++ ret = -EIO; ++ goto wait_fail; ++ } ++ } ++ if (debug) ++ printk(KERN_DEBUG "<%s", key); + +- outb(len, APPLESMC_DATA_PORT); +- if (debug) +- printk(KERN_DEBUG ">%x", len); ++ outb(len, APPLESMC_DATA_PORT); ++ if (debug) ++ printk(KERN_DEBUG ">%x", len); + +- for (i = 0; i < len; i++) { +- if (__wait_status(0x05)) +- return -EIO; +- buffer[i] = inb(APPLESMC_DATA_PORT); ++ for (i = 0; i < len; i++) { ++ if (__wait_status(0x05)) { ++ ret = -EIO; ++ goto wait_fail; ++ } ++ buffer[i] = inb(APPLESMC_DATA_PORT); ++ if (debug) ++ printk(KERN_DEBUG "<%x", buffer[i]); ++ } + if (debug) +- printk(KERN_DEBUG "<%x", buffer[i]); ++ printk(KERN_DEBUG "\n"); ++ ++ break; ++ ++wait_fail: ++ msleep(ACCESS_WAIT_MSECS); ++ continue; + } +- if (debug) +- printk(KERN_DEBUG "\n"); + +- return 0; ++ if (total != ACCESS_TIMEOUT_MSECS) { ++ printk(KERN_DEBUG "Read: Waited %d ms for the value\n", ++ ACCESS_TIMEOUT_MSECS-total); ++ } ++ ++ return ret; + } + + /* |