From cc397fc8ec15c200c46798a083861996e34faf96 Mon Sep 17 00:00:00 2001 From: nwhitehorn Date: Sun, 5 May 2013 22:42:10 +0000 Subject: [PATCH] Only check fan type once. Not only is continuously rechecking pointless, a single random failure can reprogram what control mechanism we try to use. MFC after: 2 weeks --- sys/powerpc/powermac/smu.c | 51 ++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/sys/powerpc/powermac/smu.c b/sys/powerpc/powermac/smu.c index 72c5dc7c6eb0..5c622e3cbea6 100644 --- a/sys/powerpc/powermac/smu.c +++ b/sys/powerpc/powermac/smu.c @@ -78,8 +78,8 @@ struct smu_fan { SMU_FAN_RPM, SMU_FAN_PWM } type; - int old_style; int setpoint; + int old_style; int rpm; }; @@ -123,6 +123,7 @@ struct smu_softc { struct smu_fan *sc_fans; int sc_nfans; + int old_style_fans; struct smu_sensor *sc_sensors; int sc_nsensors; @@ -653,6 +654,37 @@ doorbell_attach(device_t dev) * Sensor and fan management */ +static int +smu_fan_check_old_style(struct smu_fan *fan) +{ + device_t smu = fan->dev; + struct smu_softc *sc = device_get_softc(smu); + struct smu_cmd cmd; + int error; + + if (sc->old_style_fans != -1) + return (sc->old_style_fans); + + /* + * Apple has two fan control mechanisms. We can't distinguish + * them except by seeing if the new one fails. If the new one + * fails, use the old one. + */ + + cmd.cmd = SMU_FAN; + cmd.len = 2; + cmd.data[0] = 0x31; + cmd.data[1] = fan->reg; + + do { + error = smu_run_cmd(smu, &cmd, 1); + } while (error == EWOULDBLOCK); + + sc->old_style_fans = (error != 0); + + return (sc->old_style_fans); +} + static int smu_fan_set_rpm(struct smu_fan *fan, int rpm) { @@ -667,12 +699,8 @@ smu_fan_set_rpm(struct smu_fan *fan, int rpm) rpm = max(fan->fan.min_rpm, rpm); rpm = min(fan->fan.max_rpm, rpm); - /* - * Apple has two fan control mechanisms. We can't distinguish - * them except by seeing if the new one fails. If the new one - * fails, use the old one. - */ - + smu_fan_check_old_style(fan); + if (!fan->old_style) { cmd.len = 4; cmd.data[0] = 0x30; @@ -683,9 +711,7 @@ smu_fan_set_rpm(struct smu_fan *fan, int rpm) error = smu_run_cmd(smu, &cmd, 1); if (error && error != EWOULDBLOCK) fan->old_style = 1; - } - - if (fan->old_style) { + } else { cmd.len = 14; cmd.data[0] = 0x00; /* RPM fan. */ cmd.data[1] = 1 << fan->reg; @@ -707,6 +733,8 @@ smu_fan_read_rpm(struct smu_fan *fan) struct smu_cmd cmd; int rpm, error; + smu_fan_check_old_style(fan); + if (!fan->old_style) { cmd.cmd = SMU_FAN; cmd.len = 2; @@ -944,9 +972,10 @@ smu_count_fans(device_t dev) child = OF_peer(child)) { nfans++; /* When allocated, fill the fan properties. */ - if (sc->sc_fans != NULL) + if (sc->sc_fans != NULL) { smu_fill_fan_prop(dev, child, nfans - 1); + } } } if (nfans == 0) {