Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 May 2023 02:27:04 +0200
From:      "Dmitry N. Medvedev" <dmitry.medvedev@gmail.com>
To:        Georg Lindenberg <georg.lindenberg@web.de>
Cc:        freebsd-acpi@freebsd.org
Subject:   Re: Re: managing a fan speed via memory address
Message-ID:  <CAPf62nG%2Bvsazyxam0fQvXoGOSTXEjA77EUQ6gBitBc10ShpDAg@mail.gmail.com>
In-Reply-To: <trinity-f0eae624-c2cf-4fff-95fa-b9f1536cbc61-1683136944972@3c-app-webde-bs51>
References:  <CAPf62nErnFh7WjseZhjyhgohf2j%2BfLCm5of2yir8T=Eyi54NNA@mail.gmail.com> <CAJ-VmonUyHkBBbQSZsL-ur6LYy0eRs%2Buf-qaSjF_WQwVKAXVUQ@mail.gmail.com> <CAPf62nF8DtCCRvzos9taoh7QW6K0K6whCWfBwq4dLEWgsaBeJA@mail.gmail.com> <trinity-f0eae624-c2cf-4fff-95fa-b9f1536cbc61-1683136944972@3c-app-webde-bs51>

next in thread | previous in thread | raw e-mail | index | archive | help
--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 <georg.lindenberg@w=
eb.de>
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 <sys/param.h>
> #include <sys/kernel.h>
> #include <sys/module.h>
>
> /* for testing, aka printf */
> #include <sys/types.h>
> #include <sys/systm.h>
>
> #include <contrib/dev/acpica/include/acpi.h>
> #include <dev/acpica/acpivar.h>
> #include <dev/acpica/acpiio.h>
>
> /* 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" <dmitry.medvedev@gmail.com>
> *An:* "Adrian Chadd" <adrian@freebsd.org>
> *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 <adrian@freebsd.org> =
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

<div dir=3D"ltr">oh!.. will do! much appreciated, Georg!</div><br><div clas=
s=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, May 3, 2023=
 at 8:02=E2=80=AFPM Georg Lindenberg &lt;<a href=3D"mailto:georg.lindenberg=
@web.de">georg.lindenberg@web.de</a>&gt; wrote:<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div><div style=3D"font-family:Verdana;fon=
t-size:12px"><div>=C2=A0</div>

<div>
<div>Hello,</div>

<div>=C2=A0</div>

<div>ACPI can control fans, but it is up to the hardware manufacturer (OEM)=
 to implement it.</div>

<div>=C2=A0</div>

<div>_______________________________</div>

<div>Step 1. Check for ACPI fan control</div>

<div>=C2=A0</div>

<div>The OEM needs to add a device with id &quot;PNP0C0B&quot; to the acpi =
namespace.</div>

<div>In FreeBSD, you can test this with the command: acpidump -d -t | grep =
PNP0C0B</div>

<div>=C2=A0</div>

<div>On Windows, you can download acpi tools at <a href=3D"https://acpica.o=
rg/downloads/binary-tools" target=3D"_blank">https://acpica.org/downloads/b=
inary-tools</a></div>

<div>Then use the command: acpidump.exe | findstr PNP0C0B</div>

<div>=C2=A0</div>

<div>Some fans use IDs which are not documented in the ACPI specification:<=
/div>

<div>=C2=A0=C2=A0=C2=A0 &quot;PNP0C0B&quot;, =C2=A0=C2=A0 =C2=A0=C2=A0=C2=
=A0 =C2=A0/* Generic Fan */ \<br>
=C2=A0=C2=A0 =C2=A0&quot;INT3404&quot;, =C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 /* =
Fan */ \<br>
=C2=A0=C2=A0 =C2=A0&quot;INTC1044&quot;, =C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 /*=
 Fan for Tiger Lake generation */<br>
=C2=A0=C2=A0 =C2=A0&quot;INTC1048&quot;, =C2=A0=C2=A0=C2=A0 /* Fan for Alde=
r Lake generation */<br>
=C2=A0=C2=A0 =C2=A0&quot;INTC1063&quot;, =C2=A0=C2=A0 /* Fan for Meteor Lak=
e generation */<br>
=C2=A0=C2=A0 =C2=A0&quot;INTC10A2&quot;, =C2=A0=C2=A0 /* Fan for Raptor Lak=
e generation */</div>

<div>
<div>=C2=A0</div>

<div>You might want to search for these strings as well.</div>

<div>=C2=A0</div>

<div>__________________________</div>

<div>Step 2. Check for version of ACPI</div>

<div>=C2=A0</div>

<div>Fan version is either 1.0 or 4.0.</div>

<div>=C2=A0</div>

<div>a) Acpi version 1.0</div>

<div>=C2=A0</div>

<div>If you suceed with step 1., then you can communicate with the fan. You=
 can turn it on and off</div>

<div>by putting it in power state D0 or D3.</div>

<div>In C, you would probably use acpi_set_powerstate(dev, ACPI_STATE_D3),<=
/div>

<div>or maybe use acpi power methods, like _ON, _OFF, _PR3, _PR0 (haven&#39=
;t tested it).</div>

<div>=C2=A0</div>

<div>Or maybe an alternative: There is a suggestion on FreeBSD acpi wiki:</=
div>

<div>device_power -- Add a &quot;power&quot; argument to devctl(8) that all=
ows a device to be set into various low power or off states.</div>

<div>Noone has implemented that yet (&quot;not done&quot;). :)</div>

<div>=C2=A0</div>

<div>b) ACPI version 4.0</div>

<div>=C2=A0</div>

<div>To check, whether your fan supports fan levels, you can do this:</div>

<div>=C2=A0</div>

<div>OEM _must_ provide four predefined acpi methods. They are described in=
 detail in the acpi</div>

<div>specification. They are called: _FIF, _FPS, _FSL, _FST</div>

<div>So just use:</div>

<div>acpidump -d -t | grep _FPS</div>

<div>and so on. If all four are present, you can use fan levels! :-)</div>

<div>=C2=A0</div>

<div>In your source code, it could look like this:</div>

<div>=C2=A0</div>

<div>=C2=A0=C2=A0=C2=A0 ACPI_HANDLE=C2=A0=C2=A0 =C2=A0handle;<br>
=C2=A0=C2=A0 =C2=A0ACPI_HANDLE tmp;</div>

<div>=C2=A0</div>

<div>=C2=A0=C2=A0=C2=A0 /* fans are either acpi 1.0 or 4.0 compatible, so c=
heck now. */<br>
=C2=A0=C2=A0=C2=A0 =C2=A0if (ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FI=
F&quot;, &amp;tmp)) &amp;&amp;<br>
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FPS&quot;, &=
amp;tmp)) &amp;&amp;<br>
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FSL&quot;, &=
amp;tmp)) &amp;&amp;<br>
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FST&quot;, &=
amp;tmp))) =C2=A0=C2=A0<br>
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0acpi_fan_initiate_acpi4(dev);</div>

<div>=C2=A0</div>

<div>
<div>=C2=A0=C2=A0=C2=A0 else=C2=A0=C2=A0 =C2=A0/* nothing to do in acpi ver=
sion 1, really */<br>
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0acpi_fan_softc.version =3D 1;</div>

<div>=C2=A0</div>

<div>3. How to set fan levels</div>

<div>=C2=A0</div>

<div>As a driver author, you&#39;d need to decide how you&#39;d want to imp=
lement the fan level. It can be done</div>

<div>via /dev/acpi (and also add code to acpiconf (8)). Or it can be done v=
ia systctls.</div>

<div>=C2=A0</div>

<div>So in your code, you could add a proc sysctl. There are multiple ways =
to implement sysctls,</div>

<div>one way could be this:</div>

<div>=C2=A0</div>

<div>=C2=A0=C2=A0=C2=A0 sysctl_ctx_init(&amp;clist);=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0/* sysctl context */</div>

<div><br>
=C2=A0=C2=A0 =C2=A0struct sysctl_oid *fan_oid =3D device_get_sysctl_tree(de=
v);<br>
=C2=A0=C2=A0 =C2=A0SYSCTL_ADD_PROC(&amp;clist, SYSCTL_CHILDREN(fan_oid), OI=
D_AUTO,<br>
=C2=A0=C2=A0 =C2=A0&quot;Fan level&quot;, CTLTYPE_INT | CTLFLAG_RW, 0, 0,<b=
r>
=C2=A0=C2=A0 =C2=A0acpi_fan_level_sysctl, &quot;I&quot; ,&quot;Fan level&qu=
ot;);</div>

<div>=C2=A0</div>

<div>Or whatever code you like.</div>

<div>=C2=A0</div>

<div>Then you need a sysctl handler:</div>

<div>=C2=A0</div>

<div>static int<br>
acpi_fan_level_sysctl(SYSCTL_HANDLER_ARGS) {</div>

<div>=C2=A0</div>

<div>...</div>

<div>}</div>

<div>=C2=A0</div>

<div>In the handler function you could &quot;handle&quot; the fan level, an=
d probably call</div>

<div>acpi_evaluate_object() on the _FIF, _FPS, _FSL, and _FST methods.</div=
>

<div>=C2=A0</div>

<div>Unfortunately, my laptops don&#39;t support fans at all. So I can&#39;=
t really write a fan driver.</div>

<div>I think it is a good beginners task.</div>

<div>=C2=A0</div>

<div>Basically, if your fan has three or four pins, it might support fan le=
vels. The first two pins are</div>

<div>used for electricity. The third pin is used to upscale or downscale th=
e power (voltage?),</div>

<div>thus increasing or decreasing the fan speed. There is no magic to this=
.</div>

<div>=C2=A0</div>

<div>4. Sceleton acpi driver</div>

<div>=C2=A0</div>

<div>If you need a sceleton acpi driver, that shouldn&#39;t be a problem.</=
div>

<div>FreeBSD puts all acpi drivers (modules) into the acpi subsystem (sys/d=
ev/acpica), instead</div>

<div>of giving them a separate makefile in sys/modules.</div>

<div>=C2=A0</div>

<div>This was my first attempt, without ever testing anything (bugs to be e=
xpected): :-)</div>

<div>=C2=A0</div>

<div>
<div>#include &quot;opt_acpi.h&quot;<br>
#include &lt;sys/param.h&gt;<br>
#include &lt;sys/kernel.h&gt;<br>
#include &lt;sys/module.h&gt;</div>

<div>=C2=A0</div>

<div>/* for testing, aka printf */<br>
#include &lt;sys/types.h&gt;<br>
#include &lt;sys/systm.h&gt;</div>

<div>=C2=A0</div>

<div>#include &lt;contrib/dev/acpica/include/acpi.h&gt;</div>

<div>#include &lt;dev/acpica/acpivar.h&gt;<br>
#include &lt;dev/acpica/acpiio.h&gt;</div>

<div>=C2=A0</div>

<div>/* Hooks for the ACPI CA debugging infrastructure */<br>
#define=C2=A0=C2=A0 =C2=A0_COMPONENT=C2=A0=C2=A0 =C2=A0ACPI_FAN<br>
ACPI_MODULE_NAME(&quot;FAN&quot;)</div>
=C2=A0

<div>
<div>/* driver software context */<br>
struct acpi_fan_softc {<br>
=C2=A0=C2=A0 =C2=A0device_t=C2=A0=C2=A0 =C2=A0dev;<br>
=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 */<br>
};</div>
</div>
</div>

<div>=C2=A0</div>

<div>
<div>static device_method_t acpi_fan_methods[] =3D {<br>
=C2=A0=C2=A0=C2=A0 /* Device interface */<br>
=C2=A0=C2=A0=C2=A0 DEVMETHOD(device_probe,=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =
=C2=A0acpi_fan_probe),<br>
=C2=A0=C2=A0=C2=A0 DEVMETHOD(device_attach,=C2=A0=C2=A0 =C2=A0acpi_fan_atta=
ch),<br>
=C2=A0=C2=A0=C2=A0 DEVMETHOD(device_detach,=C2=A0=C2=A0 =C2=A0acpi_fan_deta=
ch),</div>

<div>=C2=A0=C2=A0=C2=A0 DEVMETHOD_END<br>
};</div>

<div>=C2=A0</div>

<div>static int<br>
acpi_fan_probe(device_t dev)<br>
{<br>
=C2=A0=C2=A0=C2=A0 static char *fan_ids[] =3D { \<br>
=C2=A0=C2=A0 =C2=A0&quot;PNP0C0B&quot;, =C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=
=A0/* Generic Fan */ \<br>
=C2=A0=C2=A0 =C2=A0&quot;INT3404&quot;,=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=
=A0/* Fan */ \<br>
=C2=A0=C2=A0 =C2=A0&quot;INTC1044&quot;,=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=
=A0/* Fan for Tiger Lake generation */ \<br>
=C2=A0=C2=A0 =C2=A0&quot;INTC1048&quot;, =C2=A0=C2=A0 =C2=A0/* Fan for Alde=
r Lake generation */ \<br>
=C2=A0=C2=A0 =C2=A0&quot;INTC1063&quot;, =C2=A0=C2=A0 =C2=A0/* Fan for Mete=
or Lake generation */ \<br>
=C2=A0=C2=A0 =C2=A0&quot;INTC10A2&quot;, =C2=A0=C2=A0 =C2=A0/* Fan for Rapt=
or Lake generation */ \<br>
=C2=A0=C2=A0 =C2=A0NULL };<br>
=C2=A0=C2=A0=C2=A0 int rv;<br>
=C2=A0=C2=A0 =C2=A0<br>
=C2=A0=C2=A0=C2=A0 if (acpi_disabled(&quot;fan&quot;))<br>
=C2=A0=C2=A0 =C2=A0return (ENXIO);<br>
=C2=A0=C2=A0=C2=A0 rv =3D ACPI_ID_PROBE(device_get_parent(dev), dev, fan_id=
s, NULL);<br>
=C2=A0=C2=A0=C2=A0 if (rv &lt;=3D 0)<br>
=C2=A0=C2=A0 =C2=A0device_set_desc(dev, &quot;ACPI FAN&quot;);<br>
=C2=A0=C2=A0=C2=A0 return (rv);<br>
}</div>

<div>=C2=A0</div>

<div>
<div>static int<br>
acpi_fan_attach(device_t dev)<br>
{<br>
=C2=A0=C2=A0 =C2=A0int=C2=A0=C2=A0 =C2=A0error;<br>
=C2=A0=C2=A0 =C2=A0ACPI_HANDLE=C2=A0=C2=A0 =C2=A0handle;<br>
=C2=A0=C2=A0 =C2=A0ACPI_HANDLE tmp;<br>
=C2=A0=C2=A0 =C2=A0struct acpi_fan_softc *sc;</div>

<div>=C2=A0=C2=A0 =C2=A0<br>
=C2=A0=C2=A0=C2=A0 sc =3D device_get_softc(dev);<br>
=C2=A0=C2=A0=C2=A0 handle =3D acpi_get_handle(dev);</div>

<div>=C2=A0</div>

<div>=C2=A0=C2=A0 =C2=A0/* fans are either acpi 1.0 or 4.0 compatible, so c=
heck now. */<br>
=C2=A0=C2=A0 =C2=A0if (ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FIF&quot=
;, &amp;tmp)) &amp;&amp;<br>
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FPS&quot;, &=
amp;tmp)) &amp;&amp;<br>
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FSL&quot;, &=
amp;tmp)) &amp;&amp;<br>
=C2=A0=C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FST&quot;, &=
amp;tmp)))=C2=A0=C2=A0 =C2=A0<br>
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 acpi_fan_softc.version =3D 4;<br>
=C2=A0=C2=A0 =C2=A0<br>
=C2=A0=C2=A0 =C2=A0else=C2=A0=C2=A0 =C2=A0/* nothing to do in acpi version =
1, really */<br>
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0acpi_fan_softc.version =3D 1;</div>

<div>=C2=A0</div>

<div>=C2=A0 return 0;<br>
}</div>

<div>=C2=A0</div>

<div>
<div>static int<br>
acpi_fan_detach(device_t dev) {<br>
=C2=A0=C2=A0 =C2=A0sysctl_ctx_free(&amp;clist);<br>
=C2=A0=C2=A0 =C2=A0return 0;<br>
}</div>

<div>=C2=A0</div>

<div>
<div><br>
static driver_t acpi_fan_driver =3D {<br>
=C2=A0=C2=A0=C2=A0 &quot;fan&quot;,<br>
=C2=A0=C2=A0=C2=A0 acpi_fan_methods,<br>
=C2=A0=C2=A0=C2=A0 sizeof(struct acpi_fan_softc),<br>
};</div>

<div>DRIVER_MODULE(acpi_fan, acpi, acpi_fan_driver, 0, 0);<br>
MODULE_DEPEND(acpi_fan, acpi, 1, 1, 1);</div>
</div>
</div>
</div>
</div>

<div>=C2=A0</div>

<div>_____________________</div>

<div>5. How linux does it</div>

<div>=C2=A0</div>

<div>You can check linux fan driver on github:</div>

<div><a href=3D"https://github.com/torvalds/linux/tree/master/drivers/acpi"=
 target=3D"_blank">https://github.com/torvalds/linux/tree/master/drivers/ac=
pi</a></div>

<div>=C2=A0</div>

<div>They separate the driver into three files.</div>

<div>
<div>fan.h</div>

<div>fan_attr.c</div>

<div>fan_core.c</div>
</div>

<div>=C2=A0</div>

<div>It&#39;s ok to learn from linux. :-)</div>

<div>=C2=A0</div>

<div>=C2=A0</div>

<div>Sorry for long message.</div>

<div>Georg.</div>
</div>

<div name=3D"quote" style=3D"margin:10px 5px 5px 10px;padding:10px 0px 10px=
 10px;border-left:2px solid rgb(195,217,229)">
<div style=3D"margin:0px 0px 10px"><b>Gesendet:</b>=C2=A0Mittwoch, 03. Mai =
2023 um 02:26 Uhr<br>
<b>Von:</b>=C2=A0&quot;Dmitry N. Medvedev&quot; &lt;<a href=3D"mailto:dmitr=
y.medvedev@gmail.com" target=3D"_blank">dmitry.medvedev@gmail.com</a>&gt;<b=
r>
<b>An:</b>=C2=A0&quot;Adrian Chadd&quot; &lt;<a href=3D"mailto:adrian@freeb=
sd.org" target=3D"_blank">adrian@freebsd.org</a>&gt;<br>
<b>Cc:</b>=C2=A0<a href=3D"mailto:freebsd-acpi@freebsd.org" target=3D"_blan=
k">freebsd-acpi@freebsd.org</a><br>
<b>Betreff:</b>=C2=A0Re: managing a fan speed via memory address</div>

<div name=3D"quoted-content">
<div>good morning Adrian,
<div>=C2=A0</div>

<div>1. I am just learning :) Not 100% sure ACPI has anything to do with fa=
n control ( still it looks that it actually does )</div>

<div>-- found the Advanced Configuration and Power Interface Specification =
PDF. Will spend some time grasping the ideas</div>

<div>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 :)</div>

<div>3. there isn&#39;t a single thermal sensor, but the SAS disks report t=
heir temperatures</div>

<div>( via dmidecode if I am not mistaken, or some other program -- I will =
be more sure tomorrow morning ).</div>

<div>so, theoretically I could be able to read their temperature and decide=
 if I would like to send more power to the fan.</div>
</div>
=C2=A0

<div class=3D"gmail_quote">
<div class=3D"gmail_attr">On Wed, May 3, 2023 at 2:14=E2=80=AFAM Adrian Cha=
dd &lt;<a href=3D"mailto:adrian@freebsd.org" target=3D"_blank">adrian@freeb=
sd.org</a>&gt; wrote:</div>

<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">
<div>Is it not an ACPI driver? If not, you could write a quick fan driver!
<div>=C2=A0</div>

<div>Is there a thermal sensor(s) you could read to see how warm they get?<=
/div>

<div>=C2=A0</div>

<div>=C2=A0</div>

<div>=C2=A0</div>

<div>-adrian</div>

<div>=C2=A0</div>
</div>
=C2=A0

<div class=3D"gmail_quote">
<div class=3D"gmail_attr">On Tue, 2 May 2023 at 17:06, Dmitry N. Medvedev &=
lt;<a href=3D"mailto:dmitry.medvedev@gmail.com" target=3D"_blank">dmitry.me=
dvedev@gmail.com</a>&gt; wrote:</div>

<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div>
<div>
<div>
<div>
<div>
<div>good morning,
<div>=C2=A0</div>

<div>Recently I have learned about the dmidecode program and found the addr=
ess of the FRNTFAN port in my HP Z420 machine: 0x0037.</div>

<div>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.</div>

<div>I need a bit of guidance.</div>

<div>=C2=A0</div>

<div><b>The context</b>: 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.</div>

<div>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.</div>

<div>Not sure, of course.</div>

<div>=C2=A0</div>

<div>best regards,</div>

<div>
<div>
<div>
<div>
<div>Dmitry N. Medvedev</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div></div></div>
</blockquote></div>

--000000000000512a4e05fad33cb5--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPf62nG%2Bvsazyxam0fQvXoGOSTXEjA77EUQ6gBitBc10ShpDAg>