]>
Commit | Line | Data |
---|---|---|
9ae184f0 GKH |
1 | From 25f2bd7f5add608c1d1405938f39c96927b275ca Mon Sep 17 00:00:00 2001 |
2 | From: Henrik Rydberg <rydberg@euromail.se> | |
3 | Date: Wed, 2 Oct 2013 19:15:03 +0200 | |
4 | Subject: hwmon: (applesmc) Always read until end of data | |
5 | ||
6 | From: Henrik Rydberg <rydberg@euromail.se> | |
7 | ||
8 | commit 25f2bd7f5add608c1d1405938f39c96927b275ca upstream. | |
9 | ||
10 | The crash reported and investigated in commit 5f4513 turned out to be | |
11 | caused by a change to the read interface on newer (2012) SMCs. | |
12 | ||
13 | Tests by Chris show that simply reading the data valid line is enough | |
14 | for the problem to go away. Additional tests show that the newer SMCs | |
15 | no longer wait for the number of requested bytes, but start sending | |
16 | data right away. Apparently the number of bytes to read is no longer | |
17 | specified as before, but instead found out by reading until end of | |
18 | data. Failure to read until end of data confuses the state machine, | |
19 | which eventually causes the crash. | |
20 | ||
21 | As a remedy, assuming bit0 is the read valid line, make sure there is | |
22 | nothing more to read before leaving the read function. | |
23 | ||
24 | Tested to resolve the original problem, and runtested on MBA3,1, | |
25 | MBP4,1, MBP8,2, MBP10,1, MBP10,2. The patch seems to have no effect on | |
26 | machines before 2012. | |
27 | ||
28 | Tested-by: Chris Murphy <chris@cmurf.com> | |
29 | Signed-off-by: Henrik Rydberg <rydberg@euromail.se> | |
30 | Signed-off-by: Guenter Roeck <linux@roeck-us.net> | |
31 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
32 | ||
33 | --- | |
34 | drivers/hwmon/applesmc.c | 13 +++++++++++++ | |
35 | 1 file changed, 13 insertions(+) | |
36 | ||
37 | --- a/drivers/hwmon/applesmc.c | |
38 | +++ b/drivers/hwmon/applesmc.c | |
39 | @@ -230,6 +230,7 @@ static int send_argument(const char *key | |
40 | ||
41 | static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) | |
42 | { | |
43 | + u8 status, data = 0; | |
44 | int i; | |
45 | ||
46 | if (send_command(cmd) || send_argument(key)) { | |
47 | @@ -237,6 +238,7 @@ static int read_smc(u8 cmd, const char * | |
48 | return -EIO; | |
49 | } | |
50 | ||
51 | + /* This has no effect on newer (2012) SMCs */ | |
52 | if (send_byte(len, APPLESMC_DATA_PORT)) { | |
53 | pr_warn("%.4s: read len fail\n", key); | |
54 | return -EIO; | |
55 | @@ -250,6 +252,17 @@ static int read_smc(u8 cmd, const char * | |
56 | buffer[i] = inb(APPLESMC_DATA_PORT); | |
57 | } | |
58 | ||
59 | + /* Read the data port until bit0 is cleared */ | |
60 | + for (i = 0; i < 16; i++) { | |
61 | + udelay(APPLESMC_MIN_WAIT); | |
62 | + status = inb(APPLESMC_CMD_PORT); | |
63 | + if (!(status & 0x01)) | |
64 | + break; | |
65 | + data = inb(APPLESMC_DATA_PORT); | |
66 | + } | |
67 | + if (i) | |
68 | + pr_warn("flushed %d bytes, last value is: %d\n", i, data); | |
69 | + | |
70 | return 0; | |
71 | } | |
72 |