Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 5 May 2013 22:42:11 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r250290 - head/sys/powerpc/powermac
Message-ID:  <201305052242.r45MgBJA086007@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Sun May  5 22:42:10 2013
New Revision: 250290
URL: http://svnweb.freebsd.org/changeset/base/250290

Log:
  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

Modified:
  head/sys/powerpc/powermac/smu.c

Modified: head/sys/powerpc/powermac/smu.c
==============================================================================
--- head/sys/powerpc/powermac/smu.c	Sun May  5 20:59:22 2013	(r250289)
+++ head/sys/powerpc/powermac/smu.c	Sun May  5 22:42:10 2013	(r250290)
@@ -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;
 
@@ -654,6 +655,37 @@ doorbell_attach(device_t dev)
  */
 
 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)
 {
 	device_t smu = fan->dev;
@@ -667,12 +699,8 @@ smu_fan_set_rpm(struct smu_fan *fan, int
 	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
 		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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305052242.r45MgBJA086007>