From nobody Thu May 4 00:27:04 2023 X-Original-To: freebsd-acpi@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QBZQM1hzgz49RLW for ; Thu, 4 May 2023 00:27:23 +0000 (UTC) (envelope-from dmitry.medvedev@gmail.com) Received: from mail-pf1-x431.google.com (mail-pf1-x431.google.com [IPv6:2607:f8b0:4864:20::431]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QBZQL1hWDz4GSm for ; Thu, 4 May 2023 00:27:22 +0000 (UTC) (envelope-from dmitry.medvedev@gmail.com) Authentication-Results: mx1.freebsd.org; none Received: by mail-pf1-x431.google.com with SMTP id d2e1a72fcca58-64115e652eeso8928037b3a.0 for ; Wed, 03 May 2023 17:27:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683160041; x=1685752041; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=a8iGHQptZZ9N4LK+EigAlcE61ijxYIx4seCSJYB3Th0=; b=PzXz3Kbdfq3CfVYbyOXOmdxg58/ogJwR88BAEfkRSMiugDbgQJFRzS6D3f8bUHu6iI OJrmcJYs+vtHta/gCOLpaoFOWz9YZ3MDWKOu/LMdcm4YVna8XGJGiuWqHGVTjTEKk6Oa +qB4mxjl0quU/MLL/xZ49srKfxLYebQ1Scno/7rHEfNGqu4Tl8JMHiy7zo/OcLeCR5qM ZnfbRWdsEshqKZ35J4u+Z3h9IMR+MDc3Fw0BFIgWTAmxFrkMtahsdltwJNH5QgQ8qTkp DDfb+mVZ8W2ke5TklTCvn6MN19dZMBlfw8K/XwoZBLdQRo50BQuwca2BbDpehhXWVr7j V3Bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683160041; x=1685752041; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=a8iGHQptZZ9N4LK+EigAlcE61ijxYIx4seCSJYB3Th0=; b=Dnvp2JeIsRIzCREFVsPeWQyz9xcMKUzR4EX7sqflGWrcSz0Ua3mATmcW6+R2E/XVJ6 dgZiMcgu+W3jW9Bdb5f2lHnSvXDGZiqqwAENn/XnTfXdUjY8ZbgSZDEPt4iCaw9LFGcx XzhDOijU2X32wdMKnIQfBVi7VF2gNZg6uC1O36UUvoYUq/5b/WsZyUY8lqYok669juws mURqu1BZoCGgWLUFLslCGy0R5vD4SvCvupO34OS7mCAVosuBZTn0pPhujC6UExRRd6cK iUzDEkKDbU3TCwDxWXTiJ8xSavR5CeHM5CIbIpSoFtMzAz45LTClh+5EyFI2T5SoEAP9 Wu5g== X-Gm-Message-State: AC+VfDzJtyR+V1U9vm6RbGRsOBW4w8itvRoYUexKvjD9q6WO5LW9qiNo KcbOpThFykcZM+TN3TrEmtvrNb6ar6e0AwisdeM= X-Google-Smtp-Source: ACHHUZ6ymCIelis7KbFylGybG7TqKPmQ8+z1jTJUkkkY+wcMn4FLDa581n3RSyMucO2iR+fmt1Cm3nqX56N44BKg+io= X-Received: by 2002:a17:90a:3807:b0:246:9c75:351a with SMTP id w7-20020a17090a380700b002469c75351amr156694pjb.12.1683160040547; Wed, 03 May 2023 17:27:20 -0700 (PDT) List-Id: ACPI and power management development List-Archive: https://lists.freebsd.org/archives/freebsd-acpi List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-acpi@freebsd.org MIME-Version: 1.0 References: In-Reply-To: From: "Dmitry N. Medvedev" Date: Thu, 4 May 2023 02:27:04 +0200 Message-ID: Subject: Re: Re: managing a fan speed via memory address To: Georg Lindenberg Cc: freebsd-acpi@freebsd.org Content-Type: multipart/alternative; boundary="000000000000512a4e05fad33cb5" X-Rspamd-Queue-Id: 4QBZQL1hWDz4GSm X-Spamd-Bar: ---- X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[]; ASN(0.00)[asn:15169, ipnet:2607:f8b0::/32, country:US]; TAGGED_FROM(0.00)[] X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-ThisMailContainsUnwantedMimeParts: N --000000000000512a4e05fad33cb5 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable oh!.. will do! much appreciated, Georg! On Wed, May 3, 2023 at 8:02=E2=80=AFPM Georg Lindenberg wrote: > > Hello, > > ACPI can control fans, but it is up to the hardware manufacturer (OEM) to > implement it. > > _______________________________ > Step 1. Check for ACPI fan control > > The OEM needs to add a device with id "PNP0C0B" to the acpi namespace. > In FreeBSD, you can test this with the command: acpidump -d -t | grep > PNP0C0B > > On Windows, you can download acpi tools at > https://acpica.org/downloads/binary-tools > Then use the command: acpidump.exe | findstr PNP0C0B > > Some fans use IDs which are not documented in the ACPI specification: > "PNP0C0B", /* Generic Fan */ \ > "INT3404", /* Fan */ \ > "INTC1044", /* Fan for Tiger Lake generation */ > "INTC1048", /* Fan for Alder Lake generation */ > "INTC1063", /* Fan for Meteor Lake generation */ > "INTC10A2", /* Fan for Raptor Lake generation */ > > You might want to search for these strings as well. > > __________________________ > Step 2. Check for version of ACPI > > Fan version is either 1.0 or 4.0. > > a) Acpi version 1.0 > > If you suceed with step 1., then you can communicate with the fan. You ca= n > turn it on and off > by putting it in power state D0 or D3. > In C, you would probably use acpi_set_powerstate(dev, ACPI_STATE_D3), > or maybe use acpi power methods, like _ON, _OFF, _PR3, _PR0 (haven't > tested it). > > Or maybe an alternative: There is a suggestion on FreeBSD acpi wiki: > device_power -- Add a "power" argument to devctl(8) that allows a device > to be set into various low power or off states. > Noone has implemented that yet ("not done"). :) > > b) ACPI version 4.0 > > To check, whether your fan supports fan levels, you can do this: > > OEM _must_ provide four predefined acpi methods. They are described in > detail in the acpi > specification. They are called: _FIF, _FPS, _FSL, _FST > So just use: > acpidump -d -t | grep _FPS > and so on. If all four are present, you can use fan levels! :-) > > In your source code, it could look like this: > > ACPI_HANDLE handle; > ACPI_HANDLE tmp; > > /* fans are either acpi 1.0 or 4.0 compatible, so check now. */ > if (ACPI_SUCCESS(acpi_get_handle(handle, "_FIF", &tmp)) && > ACPI_SUCCESS(acpi_get_handle(handle, "_FPS", &tmp)) && > ACPI_SUCCESS(acpi_get_handle(handle, "_FSL", &tmp)) && > ACPI_SUCCESS(acpi_get_handle(handle, "_FST", &tmp))) > acpi_fan_initiate_acpi4(dev); > > else /* nothing to do in acpi version 1, really */ > acpi_fan_softc.version =3D 1; > > 3. How to set fan levels > > As a driver author, you'd need to decide how you'd want to implement the > fan level. It can be done > via /dev/acpi (and also add code to acpiconf (8)). Or it can be done via > systctls. > > So in your code, you could add a proc sysctl. There are multiple ways to > implement sysctls, > one way could be this: > > sysctl_ctx_init(&clist); /* sysctl context */ > > struct sysctl_oid *fan_oid =3D device_get_sysctl_tree(dev); > SYSCTL_ADD_PROC(&clist, SYSCTL_CHILDREN(fan_oid), OID_AUTO, > "Fan level", CTLTYPE_INT | CTLFLAG_RW, 0, 0, > acpi_fan_level_sysctl, "I" ,"Fan level"); > > Or whatever code you like. > > Then you need a sysctl handler: > > static int > acpi_fan_level_sysctl(SYSCTL_HANDLER_ARGS) { > > ... > } > > In the handler function you could "handle" the fan level, and probably ca= ll > acpi_evaluate_object() on the _FIF, _FPS, _FSL, and _FST methods. > > Unfortunately, my laptops don't support fans at all. So I can't really > write a fan driver. > I think it is a good beginners task. > > Basically, if your fan has three or four pins, it might support fan > levels. The first two pins are > used for electricity. The third pin is used to upscale or downscale the > power (voltage?), > thus increasing or decreasing the fan speed. There is no magic to this. > > 4. Sceleton acpi driver > > If you need a sceleton acpi driver, that shouldn't be a problem. > FreeBSD puts all acpi drivers (modules) into the acpi subsystem > (sys/dev/acpica), instead > of giving them a separate makefile in sys/modules. > > This was my first attempt, without ever testing anything (bugs to be > expected): :-) > > #include "opt_acpi.h" > #include > #include > #include > > /* for testing, aka printf */ > #include > #include > > #include > #include > #include > > /* Hooks for the ACPI CA debugging infrastructure */ > #define _COMPONENT ACPI_FAN > ACPI_MODULE_NAME("FAN") > > /* driver software context */ > struct acpi_fan_softc { > device_t dev; > int version; /* either ACPI 1.0 or 4.0 */ > }; > > static device_method_t acpi_fan_methods[] =3D { > /* Device interface */ > DEVMETHOD(device_probe, acpi_fan_probe), > DEVMETHOD(device_attach, acpi_fan_attach), > DEVMETHOD(device_detach, acpi_fan_detach), > DEVMETHOD_END > }; > > static int > acpi_fan_probe(device_t dev) > { > static char *fan_ids[] =3D { \ > "PNP0C0B", /* Generic Fan */ \ > "INT3404", /* Fan */ \ > "INTC1044", /* Fan for Tiger Lake generation */ \ > "INTC1048", /* Fan for Alder Lake generation */ \ > "INTC1063", /* Fan for Meteor Lake generation */ \ > "INTC10A2", /* Fan for Raptor Lake generation */ \ > NULL }; > int rv; > > if (acpi_disabled("fan")) > return (ENXIO); > rv =3D ACPI_ID_PROBE(device_get_parent(dev), dev, fan_ids, NULL); > if (rv <=3D 0) > device_set_desc(dev, "ACPI FAN"); > return (rv); > } > > static int > acpi_fan_attach(device_t dev) > { > int error; > ACPI_HANDLE handle; > ACPI_HANDLE tmp; > struct acpi_fan_softc *sc; > > sc =3D device_get_softc(dev); > handle =3D acpi_get_handle(dev); > > /* fans are either acpi 1.0 or 4.0 compatible, so check now. */ > if (ACPI_SUCCESS(acpi_get_handle(handle, "_FIF", &tmp)) && > ACPI_SUCCESS(acpi_get_handle(handle, "_FPS", &tmp)) && > ACPI_SUCCESS(acpi_get_handle(handle, "_FSL", &tmp)) && > ACPI_SUCCESS(acpi_get_handle(handle, "_FST", &tmp))) > acpi_fan_softc.version =3D 4; > > else /* nothing to do in acpi version 1, really */ > acpi_fan_softc.version =3D 1; > > return 0; > } > > static int > acpi_fan_detach(device_t dev) { > sysctl_ctx_free(&clist); > return 0; > } > > > static driver_t acpi_fan_driver =3D { > "fan", > acpi_fan_methods, > sizeof(struct acpi_fan_softc), > }; > DRIVER_MODULE(acpi_fan, acpi, acpi_fan_driver, 0, 0); > MODULE_DEPEND(acpi_fan, acpi, 1, 1, 1); > > _____________________ > 5. How linux does it > > You can check linux fan driver on github: > https://github.com/torvalds/linux/tree/master/drivers/acpi > > They separate the driver into three files. > fan.h > fan_attr.c > fan_core.c > > It's ok to learn from linux. :-) > > > Sorry for long message. > Georg. > *Gesendet:* Mittwoch, 03. Mai 2023 um 02:26 Uhr > *Von:* "Dmitry N. Medvedev" > *An:* "Adrian Chadd" > *Cc:* freebsd-acpi@freebsd.org > *Betreff:* Re: managing a fan speed via memory address > good morning Adrian, > > 1. I am just learning :) Not 100% sure ACPI has anything to do with fan > control ( still it looks that it actually does ) > -- found the Advanced Configuration and Power Interface Specification PDF= . > Will spend some time grasping the ideas > 2. to quickly write any driver I will have to first find out how to do it > :) any guidance ( preferable in textual form will be greatly appreciated = ) > will learn it :) > 3. there isn't a single thermal sensor, but the SAS disks report their > temperatures > ( via dmidecode if I am not mistaken, or some other program -- I will be > more sure tomorrow morning ). > so, theoretically I could be able to read their temperature and decide if > I would like to send more power to the fan. > > On Wed, May 3, 2023 at 2:14=E2=80=AFAM Adrian Chadd = wrote: > >> Is it not an ACPI driver? If not, you could write a quick fan driver! >> >> Is there a thermal sensor(s) you could read to see how warm they get? >> >> >> >> -adrian >> >> >> On Tue, 2 May 2023 at 17:06, Dmitry N. Medvedev < >> dmitry.medvedev@gmail.com> wrote: >> >>> good morning, >>> >>> Recently I have learned about the dmidecode program and found the >>> address of the FRNTFAN port in my HP Z420 machine: 0x0037. >>> Since I am a complete newbie, I would like to learn if there is a way t= o >>> read and change the value at this address. >>> I need a bit of guidance. >>> >>> *The context*: I have added 8 SAS disks to the machine, put noctua fan >>> in front of them and connected the fan to the FRNTFAN port on the >>> motherboard. >>> It looks like the fan works, but I am sure the disks would benefit if >>> the fan produced more pressure. Which I fantasize I could do via changi= ng >>> the value at the said address. >>> Not sure, of course. >>> >>> best regards, >>> Dmitry N. Medvedev >>> >> --000000000000512a4e05fad33cb5 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
oh!.. will do! much appreciated, Georg!

On Wed, May 3, 2023= at 8:02=E2=80=AFPM Georg Lindenberg <georg.lindenberg@web.de> wrote:
=C2=A0
Hello,
=C2=A0
ACPI can control fans, but it is up to the hardware manufacturer (OEM)= to implement it.
=C2=A0
_______________________________
Step 1. Check for ACPI fan control
=C2=A0
The OEM needs to add a device with id "PNP0C0B" to the acpi = namespace.
In FreeBSD, you can test this with the command: acpidump -d -t | grep = PNP0C0B
=C2=A0
On Windows, you can download acpi tools at https://acpica.org/downloads/b= inary-tools
Then use the command: acpidump.exe | findstr PNP0C0B
=C2=A0
Some fans use IDs which are not documented in the ACPI specification:<= /div>
=C2=A0=C2=A0=C2=A0 "PNP0C0B", =C2=A0=C2=A0 =C2=A0=C2=A0=C2= =A0 =C2=A0/* Generic Fan */ \
=C2=A0=C2=A0 =C2=A0"INT3404", =C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 /* = Fan */ \
=C2=A0=C2=A0 =C2=A0"INTC1044", =C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 /*= Fan for Tiger Lake generation */
=C2=A0=C2=A0 =C2=A0"INTC1048", =C2=A0=C2=A0=C2=A0 /* Fan for Alde= r Lake generation */
=C2=A0=C2=A0 =C2=A0"INTC1063", =C2=A0=C2=A0 /* Fan for Meteor Lak= e generation */
=C2=A0=C2=A0 =C2=A0"INTC10A2", =C2=A0=C2=A0 /* Fan for Raptor Lak= e generation */
=C2=A0
You might want to search for these strings as well.
=C2=A0
__________________________
Step 2. Check for version of ACPI
=C2=A0
Fan version is either 1.0 or 4.0.
=C2=A0
a) Acpi version 1.0
=C2=A0
If you suceed with step 1., then you can communicate with the fan. You= can turn it on and off
by putting it in power state D0 or D3.
In C, you would probably use acpi_set_powerstate(dev, ACPI_STATE_D3),<= /div>
or maybe use acpi power methods, like _ON, _OFF, _PR3, _PR0 (haven'= ;t tested it).
=C2=A0
Or maybe an alternative: There is a suggestion on FreeBSD acpi wiki:
device_power -- Add a "power" argument to devctl(8) that all= ows a device to be set into various low power or off states.
Noone has implemented that yet ("not done"). :)
=C2=A0
b) ACPI version 4.0
=C2=A0
To check, whether your fan supports fan levels, you can do this:
=C2=A0
OEM _must_ provide four predefined acpi methods. They are described in= detail in the acpi
specification. They are called: _FIF, _FPS, _FSL, _FST
So just use:
acpidump -d -t | grep _FPS
and so on. If all four are present, you can use fan levels! :-)
=C2=A0
In your source code, it could look like this:
=C2=A0
=C2=A0=C2=A0=C2=A0 ACPI_HANDLE=C2=A0=C2=A0 =C2=A0handle;
=C2=A0=C2=A0 =C2=A0ACPI_HANDLE tmp;
=C2=A0
=C2=A0=C2=A0=C2=A0 /* fans are either acpi 1.0 or 4.0 compatible, so c= heck now. */
=C2=A0=C2=A0=C2=A0 =C2=A0if (ACPI_SUCCESS(acpi_get_handle(handle, "_FI= F", &tmp)) &&
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, "_FPS", &= amp;tmp)) &&
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, "_FSL", &= amp;tmp)) &&
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, "_FST", &= amp;tmp))) =C2=A0=C2=A0
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0acpi_fan_initiate_acpi4(dev);
=C2=A0
=C2=A0=C2=A0=C2=A0 else=C2=A0=C2=A0 =C2=A0/* nothing to do in acpi ver= sion 1, really */
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0acpi_fan_softc.version =3D 1;
=C2=A0
3. How to set fan levels
=C2=A0
As a driver author, you'd need to decide how you'd want to imp= lement the fan level. It can be done
via /dev/acpi (and also add code to acpiconf (8)). Or it can be done v= ia systctls.
=C2=A0
So in your code, you could add a proc sysctl. There are multiple ways = to implement sysctls,
one way could be this:
=C2=A0
=C2=A0=C2=A0=C2=A0 sysctl_ctx_init(&clist);=C2=A0=C2=A0 =C2=A0=C2= =A0=C2=A0 =C2=A0/* sysctl context */

=C2=A0=C2=A0 =C2=A0struct sysctl_oid *fan_oid =3D device_get_sysctl_tree(de= v);
=C2=A0=C2=A0 =C2=A0SYSCTL_ADD_PROC(&clist, SYSCTL_CHILDREN(fan_oid), OI= D_AUTO,
=C2=A0=C2=A0 =C2=A0"Fan level", CTLTYPE_INT | CTLFLAG_RW, 0, 0, =C2=A0=C2=A0 =C2=A0acpi_fan_level_sysctl, "I" ,"Fan level&qu= ot;);
=C2=A0
Or whatever code you like.
=C2=A0
Then you need a sysctl handler:
=C2=A0
static int
acpi_fan_level_sysctl(SYSCTL_HANDLER_ARGS) {
=C2=A0
...
}
=C2=A0
In the handler function you could "handle" the fan level, an= d probably call
acpi_evaluate_object() on the _FIF, _FPS, _FSL, and _FST methods.
=C2=A0
Unfortunately, my laptops don't support fans at all. So I can'= t really write a fan driver.
I think it is a good beginners task.
=C2=A0
Basically, if your fan has three or four pins, it might support fan le= vels. The first two pins are
used for electricity. The third pin is used to upscale or downscale th= e power (voltage?),
thus increasing or decreasing the fan speed. There is no magic to this= .
=C2=A0
4. Sceleton acpi driver
=C2=A0
If you need a sceleton acpi driver, that shouldn't be a problem.
FreeBSD puts all acpi drivers (modules) into the acpi subsystem (sys/d= ev/acpica), instead
of giving them a separate makefile in sys/modules.
=C2=A0
This was my first attempt, without ever testing anything (bugs to be e= xpected): :-)
=C2=A0
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
=C2=A0
/* for testing, aka printf */
#include <sys/types.h>
#include <sys/systm.h>
=C2=A0
#include <contrib/dev/acpica/include/acpi.h>
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
=C2=A0
/* Hooks for the ACPI CA debugging infrastructure */
#define=C2=A0=C2=A0 =C2=A0_COMPONENT=C2=A0=C2=A0 =C2=A0ACPI_FAN
ACPI_MODULE_NAME("FAN")
=C2=A0
/* driver software context */
struct acpi_fan_softc {
=C2=A0=C2=A0 =C2=A0device_t=C2=A0=C2=A0 =C2=A0dev;
=C2=A0=C2=A0 =C2=A0int=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 = =C2=A0version;=C2=A0=C2=A0 =C2=A0/* either ACPI 1.0 or 4.0 */
};
=C2=A0
static device_method_t acpi_fan_methods[] =3D {
=C2=A0=C2=A0=C2=A0 /* Device interface */
=C2=A0=C2=A0=C2=A0 DEVMETHOD(device_probe,=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 = =C2=A0acpi_fan_probe),
=C2=A0=C2=A0=C2=A0 DEVMETHOD(device_attach,=C2=A0=C2=A0 =C2=A0acpi_fan_atta= ch),
=C2=A0=C2=A0=C2=A0 DEVMETHOD(device_detach,=C2=A0=C2=A0 =C2=A0acpi_fan_deta= ch),
=C2=A0=C2=A0=C2=A0 DEVMETHOD_END
};
=C2=A0
static int
acpi_fan_probe(device_t dev)
{
=C2=A0=C2=A0=C2=A0 static char *fan_ids[] =3D { \
=C2=A0=C2=A0 =C2=A0"PNP0C0B", =C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0/* Generic Fan */ \
=C2=A0=C2=A0 =C2=A0"INT3404",=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0/* Fan */ \
=C2=A0=C2=A0 =C2=A0"INTC1044",=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0/* Fan for Tiger Lake generation */ \
=C2=A0=C2=A0 =C2=A0"INTC1048", =C2=A0=C2=A0 =C2=A0/* Fan for Alde= r Lake generation */ \
=C2=A0=C2=A0 =C2=A0"INTC1063", =C2=A0=C2=A0 =C2=A0/* Fan for Mete= or Lake generation */ \
=C2=A0=C2=A0 =C2=A0"INTC10A2", =C2=A0=C2=A0 =C2=A0/* Fan for Rapt= or Lake generation */ \
=C2=A0=C2=A0 =C2=A0NULL };
=C2=A0=C2=A0=C2=A0 int rv;
=C2=A0=C2=A0 =C2=A0
=C2=A0=C2=A0=C2=A0 if (acpi_disabled("fan"))
=C2=A0=C2=A0 =C2=A0return (ENXIO);
=C2=A0=C2=A0=C2=A0 rv =3D ACPI_ID_PROBE(device_get_parent(dev), dev, fan_id= s, NULL);
=C2=A0=C2=A0=C2=A0 if (rv <=3D 0)
=C2=A0=C2=A0 =C2=A0device_set_desc(dev, "ACPI FAN");
=C2=A0=C2=A0=C2=A0 return (rv);
}
=C2=A0
static int
acpi_fan_attach(device_t dev)
{
=C2=A0=C2=A0 =C2=A0int=C2=A0=C2=A0 =C2=A0error;
=C2=A0=C2=A0 =C2=A0ACPI_HANDLE=C2=A0=C2=A0 =C2=A0handle;
=C2=A0=C2=A0 =C2=A0ACPI_HANDLE tmp;
=C2=A0=C2=A0 =C2=A0struct acpi_fan_softc *sc;
=C2=A0=C2=A0 =C2=A0
=C2=A0=C2=A0=C2=A0 sc =3D device_get_softc(dev);
=C2=A0=C2=A0=C2=A0 handle =3D acpi_get_handle(dev);
=C2=A0
=C2=A0=C2=A0 =C2=A0/* fans are either acpi 1.0 or 4.0 compatible, so c= heck now. */
=C2=A0=C2=A0 =C2=A0if (ACPI_SUCCESS(acpi_get_handle(handle, "_FIF"= ;, &tmp)) &&
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, "_FPS", &= amp;tmp)) &&
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, "_FSL", &= amp;tmp)) &&
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, "_FST", &= amp;tmp)))=C2=A0=C2=A0 =C2=A0
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 acpi_fan_softc.version =3D 4;
=C2=A0=C2=A0 =C2=A0
=C2=A0=C2=A0 =C2=A0else=C2=A0=C2=A0 =C2=A0/* nothing to do in acpi version = 1, really */
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0acpi_fan_softc.version =3D 1;
=C2=A0
=C2=A0 return 0;
}
=C2=A0
static int
acpi_fan_detach(device_t dev) {
=C2=A0=C2=A0 =C2=A0sysctl_ctx_free(&clist);
=C2=A0=C2=A0 =C2=A0return 0;
}
=C2=A0

static driver_t acpi_fan_driver =3D {
=C2=A0=C2=A0=C2=A0 "fan",
=C2=A0=C2=A0=C2=A0 acpi_fan_methods,
=C2=A0=C2=A0=C2=A0 sizeof(struct acpi_fan_softc),
};
DRIVER_MODULE(acpi_fan, acpi, acpi_fan_driver, 0, 0);
MODULE_DEPEND(acpi_fan, acpi, 1, 1, 1);
=C2=A0
_____________________
5. How linux does it
=C2=A0
You can check linux fan driver on github:
=C2=A0
They separate the driver into three files.
fan.h
fan_attr.c
fan_core.c
=C2=A0
It's ok to learn from linux. :-)
=C2=A0
=C2=A0
Sorry for long message.
Georg.
Gesendet:=C2=A0Mittwoch, 03. Mai = 2023 um 02:26 Uhr
Von:=C2=A0"Dmitry N. Medvedev" <dmitry.medvedev@gmail.com> An:=C2=A0"Adrian Chadd" <adrian@freebsd.org>
Cc:=C2=A0freebsd-acpi@freebsd.org
Betreff:=C2=A0Re: managing a fan speed via memory address
good morning Adrian,
=C2=A0
1. I am just learning :) Not 100% sure ACPI has anything to do with fa= n control ( still it looks that it actually does )
-- found the Advanced Configuration and Power Interface Specification = PDF. Will spend some time grasping the ideas
2. to quickly write any driver=C2=A0I will have to first find out how = to do it :) any=C2=A0guidance ( preferable in textual form will be greatly = appreciated ) will learn it :)
3. there isn't a single thermal sensor, but the SAS disks report t= heir temperatures
( via dmidecode if I am not mistaken, or some other program -- I will = be more sure tomorrow morning ).
so, theoretically I could be able to read their temperature and decide= if I would like to send more power to the fan.
=C2=A0
On Wed, May 3, 2023 at 2:14=E2=80=AFAM Adrian Cha= dd <adrian@freeb= sd.org> wrote:
Is it not an ACPI driver? If not, you could write a quick fan driver!
=C2=A0
Is there a thermal sensor(s) you could read to see how warm they get?<= /div>
=C2=A0
=C2=A0
=C2=A0
-adrian
=C2=A0
=C2=A0
On Tue, 2 May 2023 at 17:06, Dmitry N. Medvedev &= lt;dmitry.me= dvedev@gmail.com> wrote:
good morning,
=C2=A0
Recently I have learned about the dmidecode program and found the addr= ess of the FRNTFAN port in my HP Z420 machine: 0x0037.
Since I am a complete newbie, I would like to learn if there is a way = to read and change the value at this address.
I need a bit of guidance.
=C2=A0
The context: I have added 8 SAS disks to the machine, put noctu= a fan in front of them and connected the fan to the FRNTFAN=C2=A0port on th= e motherboard.
It looks like the fan works, but I am sure the disks would benefit if = the fan produced more pressure. Which I fantasize I could do via changing t= he value at the said address.
Not sure, of course.
=C2=A0
best regards,
Dmitry N. Medvedev
--000000000000512a4e05fad33cb5--