Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 May 2023 03:12:20 +0200
From:      "Dmitry N. Medvedev" <dmitry.medvedev@gmail.com>
To:        Georg Lindenberg <georg.lindenberg@web.de>
Cc:        freebsd-acpi@freebsd.org
Subject:   Re: Re: Re: managing a fan speed via memory address
Message-ID:  <CAPf62nE9NF3cHDerChda%2BOCLUWP6NYyKmqc0=S_k532wm_2kxw@mail.gmail.com>
In-Reply-To: <trinity-341ba45a-95df-4524-9775-515c509933d5-1683265891170@msvc-mesg-web109>
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> <CAPf62nHvfXJz1tJ00DpCPtvzXUpZdWotEgK%2BFFWjP2brikTkNQ@mail.gmail.com> <trinity-341ba45a-95df-4524-9775-515c509933d5-1683265891170@msvc-mesg-web109>

next in thread | previous in thread | raw e-mail | index | archive | help
--000000000000e10e6305fafc199d
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

okay, it's resolved now:

according to this --
https://h30434.www3.hp.com/t5/Desktop-Hardware-and-Upgrade-Questions/contro=
lling-front-fan-on-Z420/m-p/8681322/highlight/true#M232123

"It is not possible to control the individual fan speeds on the Z420
motherboard. The only available setting in the BIOS is to control the
system fans idle speed."



On Fri, May 5, 2023 at 7:51=E2=80=AFAM Georg Lindenberg <georg.lindenberg@w=
eb.de>
wrote:

> If the fan ID is not present in acpidump, then the fan is not in the acpi
> namespace, and thus it is not visible to the operating system (aka
> FreeBSD). At least according to the acpi documentation. :-)
>
> Maybe there is a another way to access the fan (bios?), that I am not
> aware of.
> Good luck.
>
> > Gesendet: Donnerstag, den 04.05.2023 um 15:45 Uhr
> > Von: "Dmitry N. Medvedev" <dmitry.medvedev@gmail.com>
> > An: "Georg Lindenberg" <georg.lindenberg@web.de>
> > Cc: freebsd-acpi@freebsd.org
> > Betreff: Re: Re: managing a fan speed via memory address
> >
> > hi Georg,
> >
> > it's become even more confusing -- none of the IDs from #1 exist in
> > acpidump output :(
> >
> > researching further
> >
> > On Wed, May 3, 2023 at 8:02=E2=80=AFPM Georg Lindenberg <georg.lindenbe=
rg@web.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. Yo=
u
> 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),
> > > 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 i=
n
> > > 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 probabl=
y
> call
> > > acpi_evaluate_object() on the _FIF, _FPS, _FSL, and _FST methods.
> > >
> > > Unfortunately, my laptops don't support fans at all. So I can't reall=
y
> > > 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 t=
he
> > > power (voltage?),
> > > thus increasing or decreasing the fan speed. There is no magic to thi=
s.
> > >
> > > 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 f=
an
> > > 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 d=
o
> 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 thei=
r
> > > 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 decid=
e
> 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.o=
rg>
> 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 to
> > >>> 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
> changing
> > >>> the value at the said address.
> > >>> Not sure, of course.
> > >>>
> > >>> best regards,
> > >>> Dmitry N. Medvedev
> > >>>
> > >>
>

--000000000000e10e6305fafc199d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">okay, it&#39;s resolved now:<div><br></div><div>according =
to this -- <a href=3D"https://h30434.www3.hp.com/t5/Desktop-Hardware-and-Up=
grade-Questions/controlling-front-fan-on-Z420/m-p/8681322/highlight/true#M2=
32123">https://h30434.www3.hp.com/t5/Desktop-Hardware-and-Upgrade-Questions=
/controlling-front-fan-on-Z420/m-p/8681322/highlight/true#M232123</a></div>=
<div><br></div><div>&quot;It is not possible to control the individual fan =
speeds on the Z420 motherboard. The only available setting in the BIOS is t=
o control the system fans idle speed.&quot;</div><div><br></div><div><br></=
div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_at=
tr">On Fri, May 5, 2023 at 7:51=E2=80=AFAM 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;bo=
rder-left:1px solid rgb(204,204,204);padding-left:1ex">If the fan ID is not=
 present in acpidump, then the fan is not in the acpi namespace, and thus i=
t is not visible to the operating system (aka FreeBSD). At least according =
to the acpi documentation. :-)<br>
<br>
Maybe there is a another way to access the fan (bios?), that I am not aware=
 of.<br>
Good luck.<br>
<br>
&gt; Gesendet: Donnerstag, den 04.05.2023 um 15:45 Uhr<br>
&gt; Von: &quot;Dmitry N. Medvedev&quot; &lt;<a href=3D"mailto:dmitry.medve=
dev@gmail.com" target=3D"_blank">dmitry.medvedev@gmail.com</a>&gt;<br>
&gt; An: &quot;Georg Lindenberg&quot; &lt;<a href=3D"mailto:georg.lindenber=
g@web.de" target=3D"_blank">georg.lindenberg@web.de</a>&gt;<br>
&gt; Cc: <a href=3D"mailto:freebsd-acpi@freebsd.org" target=3D"_blank">free=
bsd-acpi@freebsd.org</a><br>
&gt; Betreff: Re: Re: managing a fan speed via memory address<br>
&gt; <br>
&gt; hi Georg,<br>
&gt; <br>
&gt; it&#39;s become even more confusing -- none of the IDs from #1 exist i=
n<br>
&gt; acpidump output :(<br>
&gt; <br>
&gt; researching further<br>
&gt; <br>
&gt; On Wed, May 3, 2023 at 8:02=E2=80=AFPM Georg Lindenberg &lt;<a href=3D=
"mailto:georg.lindenberg@web.de" target=3D"_blank">georg.lindenberg@web.de<=
/a>&gt;<br>
&gt; wrote:<br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; Hello,<br>
&gt; &gt;<br>
&gt; &gt; ACPI can control fans, but it is up to the hardware manufacturer =
(OEM) to<br>
&gt; &gt; implement it.<br>
&gt; &gt;<br>
&gt; &gt; _______________________________<br>
&gt; &gt; Step 1. Check for ACPI fan control<br>
&gt; &gt;<br>
&gt; &gt; The OEM needs to add a device with id &quot;PNP0C0B&quot; to the =
acpi namespace.<br>
&gt; &gt; In FreeBSD, you can test this with the command: acpidump -d -t | =
grep<br>
&gt; &gt; PNP0C0B<br>
&gt; &gt;<br>
&gt; &gt; On Windows, you can download acpi tools at<br>
&gt; &gt; <a href=3D"https://acpica.org/downloads/binary-tools" rel=3D"nore=
ferrer" target=3D"_blank">https://acpica.org/downloads/binary-tools</a><br>;
&gt; &gt; Then use the command: acpidump.exe | findstr PNP0C0B<br>
&gt; &gt;<br>
&gt; &gt; Some fans use IDs which are not documented in the ACPI specificat=
ion:<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;PNP0C0B&quot;,=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0/* Generic Fan */ \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INT3404&quot;,=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 /* Fan */ \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INTC1044&quot;,=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 /* Fan for Tiger Lake generation */<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INTC1048&quot;,=C2=A0 =C2=A0 =C2=A0/* Fa=
n for Alder Lake generation */<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INTC1063&quot;,=C2=A0 =C2=A0 /* Fan for =
Meteor Lake generation */<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INTC10A2&quot;,=C2=A0 =C2=A0 /* Fan for =
Raptor Lake generation */<br>
&gt; &gt;<br>
&gt; &gt; You might want to search for these strings as well.<br>
&gt; &gt;<br>
&gt; &gt; __________________________<br>
&gt; &gt; Step 2. Check for version of ACPI<br>
&gt; &gt;<br>
&gt; &gt; Fan version is either 1.0 or 4.0.<br>
&gt; &gt;<br>
&gt; &gt; a) Acpi version 1.0<br>
&gt; &gt;<br>
&gt; &gt; If you suceed with step 1., then you can communicate with the fan=
. You can<br>
&gt; &gt; turn it on and off<br>
&gt; &gt; by putting it in power state D0 or D3.<br>
&gt; &gt; In C, you would probably use acpi_set_powerstate(dev, ACPI_STATE_=
D3),<br>
&gt; &gt; or maybe use acpi power methods, like _ON, _OFF, _PR3, _PR0 (have=
n&#39;t<br>
&gt; &gt; tested it).<br>
&gt; &gt;<br>
&gt; &gt; Or maybe an alternative: There is a suggestion on FreeBSD acpi wi=
ki:<br>
&gt; &gt; device_power -- Add a &quot;power&quot; argument to devctl(8) tha=
t allows a device<br>
&gt; &gt; to be set into various low power or off states.<br>
&gt; &gt; Noone has implemented that yet (&quot;not done&quot;). :)<br>
&gt; &gt;<br>
&gt; &gt; b) ACPI version 4.0<br>
&gt; &gt;<br>
&gt; &gt; To check, whether your fan supports fan levels, you can do this:<=
br>
&gt; &gt;<br>
&gt; &gt; OEM _must_ provide four predefined acpi methods. They are describ=
ed in<br>
&gt; &gt; detail in the acpi<br>
&gt; &gt; specification. They are called: _FIF, _FPS, _FSL, _FST<br>
&gt; &gt; So just use:<br>
&gt; &gt; acpidump -d -t | grep _FPS<br>
&gt; &gt; and so on. If all four are present, you can use fan levels! :-)<b=
r>
&gt; &gt;<br>
&gt; &gt; In your source code, it could look like this:<br>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_HANDLE=C2=A0 =C2=A0 handle;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_HANDLE tmp;<br>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0/* fans are either acpi 1.0 or 4.0 compatible,=
 so check now. */<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0 if (ACPI_SUCCESS(acpi_get_handle(handle, &quo=
t;_FIF&quot;, &amp;tmp)) &amp;&amp;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FP=
S&quot;, &amp;tmp)) &amp;&amp;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FS=
L&quot;, &amp;tmp)) &amp;&amp;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FS=
T&quot;, &amp;tmp)))<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0acpi_fan_initiate_acpi4(dev);<br=
>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0else=C2=A0 =C2=A0 /* nothing to do in acpi ver=
sion 1, really */<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0acpi_fan_softc.version =3D 1;<br=
>
&gt; &gt;<br>
&gt; &gt; 3. How to set fan levels<br>
&gt; &gt;<br>
&gt; &gt; As a driver author, you&#39;d need to decide how you&#39;d want t=
o implement the<br>
&gt; &gt; fan level. It can be done<br>
&gt; &gt; via /dev/acpi (and also add code to acpiconf (8)). Or it can be d=
one via<br>
&gt; &gt; systctls.<br>
&gt; &gt;<br>
&gt; &gt; So in your code, you could add a proc sysctl. There are multiple =
ways to<br>
&gt; &gt; implement sysctls,<br>
&gt; &gt; one way could be this:<br>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0sysctl_ctx_init(&amp;clist);=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 /* sysctl context */<br>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0struct sysctl_oid *fan_oid =3D device_get_sysc=
tl_tree(dev);<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0SYSCTL_ADD_PROC(&amp;clist, SYSCTL_CHILDREN(fa=
n_oid), OID_AUTO,<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;Fan level&quot;, CTLTYPE_INT | CTLFLAG_R=
W, 0, 0,<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0acpi_fan_level_sysctl, &quot;I&quot; ,&quot;Fa=
n level&quot;);<br>
&gt; &gt;<br>
&gt; &gt; Or whatever code you like.<br>
&gt; &gt;<br>
&gt; &gt; Then you need a sysctl handler:<br>
&gt; &gt;<br>
&gt; &gt; static int<br>
&gt; &gt; acpi_fan_level_sysctl(SYSCTL_HANDLER_ARGS) {<br>
&gt; &gt;<br>
&gt; &gt; ...<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; In the handler function you could &quot;handle&quot; the fan leve=
l, and probably call<br>
&gt; &gt; acpi_evaluate_object() on the _FIF, _FPS, _FSL, and _FST methods.=
<br>
&gt; &gt;<br>
&gt; &gt; Unfortunately, my laptops don&#39;t support fans at all. So I can=
&#39;t really<br>
&gt; &gt; write a fan driver.<br>
&gt; &gt; I think it is a good beginners task.<br>
&gt; &gt;<br>
&gt; &gt; Basically, if your fan has three or four pins, it might support f=
an<br>
&gt; &gt; levels. The first two pins are<br>
&gt; &gt; used for electricity. The third pin is used to upscale or downsca=
le the<br>
&gt; &gt; power (voltage?),<br>
&gt; &gt; thus increasing or decreasing the fan speed. There is no magic to=
 this.<br>
&gt; &gt;<br>
&gt; &gt; 4. Sceleton acpi driver<br>
&gt; &gt;<br>
&gt; &gt; If you need a sceleton acpi driver, that shouldn&#39;t be a probl=
em.<br>
&gt; &gt; FreeBSD puts all acpi drivers (modules) into the acpi subsystem<b=
r>
&gt; &gt; (sys/dev/acpica), instead<br>
&gt; &gt; of giving them a separate makefile in sys/modules.<br>
&gt; &gt;<br>
&gt; &gt; This was my first attempt, without ever testing anything (bugs to=
 be<br>
&gt; &gt; expected): :-)<br>
&gt; &gt;<br>
&gt; &gt; #include &quot;opt_acpi.h&quot;<br>
&gt; &gt; #include &lt;sys/param.h&gt;<br>
&gt; &gt; #include &lt;sys/kernel.h&gt;<br>
&gt; &gt; #include &lt;sys/module.h&gt;<br>
&gt; &gt;<br>
&gt; &gt; /* for testing, aka printf */<br>
&gt; &gt; #include &lt;sys/types.h&gt;<br>
&gt; &gt; #include &lt;sys/systm.h&gt;<br>
&gt; &gt;<br>
&gt; &gt; #include &lt;contrib/dev/acpica/include/acpi.h&gt;<br>
&gt; &gt; #include &lt;dev/acpica/acpivar.h&gt;<br>
&gt; &gt; #include &lt;dev/acpica/acpiio.h&gt;<br>
&gt; &gt;<br>
&gt; &gt; /* Hooks for the ACPI CA debugging infrastructure */<br>
&gt; &gt; #define=C2=A0 =C2=A0 _COMPONENT=C2=A0 =C2=A0 ACPI_FAN<br>
&gt; &gt; ACPI_MODULE_NAME(&quot;FAN&quot;)<br>
&gt; &gt;<br>
&gt; &gt; /* driver software context */<br>
&gt; &gt; struct acpi_fan_softc {<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0device_t=C2=A0 =C2=A0 dev;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0int=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 v=
ersion;=C2=A0 =C2=A0 /* either ACPI 1.0 or 4.0 */<br>
&gt; &gt; };<br>
&gt; &gt;<br>
&gt; &gt; static device_method_t acpi_fan_methods[] =3D {<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0/* Device interface */<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0DEVMETHOD(device_probe,=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 acpi_fan_probe),<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0DEVMETHOD(device_attach,=C2=A0 =C2=A0 acpi_fan=
_attach),<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0DEVMETHOD(device_detach,=C2=A0 =C2=A0 acpi_fan=
_detach),<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0DEVMETHOD_END<br>
&gt; &gt; };<br>
&gt; &gt;<br>
&gt; &gt; static int<br>
&gt; &gt; acpi_fan_probe(device_t dev)<br>
&gt; &gt; {<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0static char *fan_ids[] =3D { \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;PNP0C0B&quot;,=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0/* Generic Fan */ \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INT3404&quot;,=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 /* Fan */ \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INTC1044&quot;,=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 /* Fan for Tiger Lake generation */ \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INTC1048&quot;,=C2=A0 =C2=A0 =C2=A0/* Fa=
n for Alder Lake generation */ \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INTC1063&quot;,=C2=A0 =C2=A0 =C2=A0/* Fa=
n for Meteor Lake generation */ \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;INTC10A2&quot;,=C2=A0 =C2=A0 =C2=A0/* Fa=
n for Raptor Lake generation */ \<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0NULL };<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0int rv;<br>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0if (acpi_disabled(&quot;fan&quot;))<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0return (ENXIO);<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0rv =3D ACPI_ID_PROBE(device_get_parent(dev), d=
ev, fan_ids, NULL);<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0if (rv &lt;=3D 0)<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0device_set_desc(dev, &quot;ACPI FAN&quot;);<br=
>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0return (rv);<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; static int<br>
&gt; &gt; acpi_fan_attach(device_t dev)<br>
&gt; &gt; {<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0int=C2=A0 =C2=A0 error;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_HANDLE=C2=A0 =C2=A0 handle;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_HANDLE tmp;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0struct acpi_fan_softc *sc;<br>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0sc =3D device_get_softc(dev);<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0handle =3D acpi_get_handle(dev);<br>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0/* fans are either acpi 1.0 or 4.0 compatible,=
 so check now. */<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0if (ACPI_SUCCESS(acpi_get_handle(handle, &quot=
;_FIF&quot;, &amp;tmp)) &amp;&amp;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FP=
S&quot;, &amp;tmp)) &amp;&amp;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FS=
L&quot;, &amp;tmp)) &amp;&amp;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0ACPI_SUCCESS(acpi_get_handle(handle, &quot;_FS=
T&quot;, &amp;tmp)))<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0acpi_fan_softc.version =3D 4;<br=
>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0else=C2=A0 =C2=A0 /* nothing to do in acpi ver=
sion 1, really */<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0acpi_fan_softc.version =3D 1;<br=
>
&gt; &gt;<br>
&gt; &gt;=C2=A0 =C2=A0return 0;<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; static int<br>
&gt; &gt; acpi_fan_detach(device_t dev) {<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0sysctl_ctx_free(&amp;clist);<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0return 0;<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; static driver_t acpi_fan_driver =3D {<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0&quot;fan&quot;,<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0acpi_fan_methods,<br>
&gt; &gt;=C2=A0 =C2=A0 =C2=A0sizeof(struct acpi_fan_softc),<br>
&gt; &gt; };<br>
&gt; &gt; DRIVER_MODULE(acpi_fan, acpi, acpi_fan_driver, 0, 0);<br>
&gt; &gt; MODULE_DEPEND(acpi_fan, acpi, 1, 1, 1);<br>
&gt; &gt;<br>
&gt; &gt; _____________________<br>
&gt; &gt; 5. How linux does it<br>
&gt; &gt;<br>
&gt; &gt; You can check linux fan driver on github:<br>
&gt; &gt; <a href=3D"https://github.com/torvalds/linux/tree/master/drivers/=
acpi" rel=3D"noreferrer" target=3D"_blank">https://github.com/torvalds/linu=
x/tree/master/drivers/acpi</a><br>
&gt; &gt;<br>
&gt; &gt; They separate the driver into three files.<br>
&gt; &gt; fan.h<br>
&gt; &gt; fan_attr.c<br>
&gt; &gt; fan_core.c<br>
&gt; &gt;<br>
&gt; &gt; It&#39;s ok to learn from linux. :-)<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; Sorry for long message.<br>
&gt; &gt; Georg.<br>
&gt; &gt; *Gesendet:* Mittwoch, 03. Mai 2023 um 02:26 Uhr<br>
&gt; &gt; *Von:* &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>
&gt; &gt; *An:* &quot;Adrian Chadd&quot; &lt;<a href=3D"mailto:adrian@freeb=
sd.org" target=3D"_blank">adrian@freebsd.org</a>&gt;<br>
&gt; &gt; *Cc:* <a href=3D"mailto:freebsd-acpi@freebsd.org" target=3D"_blan=
k">freebsd-acpi@freebsd.org</a><br>
&gt; &gt; *Betreff:* Re: managing a fan speed via memory address<br>
&gt; &gt; good morning Adrian,<br>
&gt; &gt;<br>
&gt; &gt; 1. I am just learning :) Not 100% sure ACPI has anything to do wi=
th fan<br>
&gt; &gt; control ( still it looks that it actually does )<br>
&gt; &gt; -- found the Advanced Configuration and Power Interface Specifica=
tion PDF.<br>
&gt; &gt; Will spend some time grasping the ideas<br>
&gt; &gt; 2. to quickly write any driver I will have to first find out how =
to do it<br>
&gt; &gt; :) any guidance ( preferable in textual form will be greatly appr=
eciated )<br>
&gt; &gt; will learn it :)<br>
&gt; &gt; 3. there isn&#39;t a single thermal sensor, but the SAS disks rep=
ort their<br>
&gt; &gt; temperatures<br>
&gt; &gt; ( via dmidecode if I am not mistaken, or some other program -- I =
will be<br>
&gt; &gt; more sure tomorrow morning ).<br>
&gt; &gt; so, theoretically I could be able to read their temperature and d=
ecide if<br>
&gt; &gt; I would like to send more power to the fan.<br>
&gt; &gt;<br>
&gt; &gt; On Wed, May 3, 2023 at 2:14=E2=80=AFAM Adrian Chadd &lt;<a href=
=3D"mailto:adrian@freebsd.org" target=3D"_blank">adrian@freebsd.org</a>&gt;=
 wrote:<br>
&gt; &gt;<br>
&gt; &gt;&gt; Is it not an ACPI driver? If not, you could write a quick fan=
 driver!<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Is there a thermal sensor(s) you could read to see how warm t=
hey get?<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; -adrian<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; On Tue, 2 May 2023 at 17:06, Dmitry N. Medvedev &lt;<br>
&gt; &gt;&gt; <a href=3D"mailto:dmitry.medvedev@gmail.com" target=3D"_blank=
">dmitry.medvedev@gmail.com</a>&gt; wrote:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; good morning,<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; Recently I have learned about the dmidecode program and f=
ound the<br>
&gt; &gt;&gt;&gt; address of the FRNTFAN port in my HP Z420 machine: 0x0037=
.<br>
&gt; &gt;&gt;&gt; Since I am a complete newbie, I would like to learn if th=
ere is a way to<br>
&gt; &gt;&gt;&gt; read and change the value at this address.<br>
&gt; &gt;&gt;&gt; I need a bit of guidance.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; *The context*: I have added 8 SAS disks to the machine, p=
ut noctua fan<br>
&gt; &gt;&gt;&gt; in front of them and connected the fan to the FRNTFAN por=
t on the<br>
&gt; &gt;&gt;&gt; motherboard.<br>
&gt; &gt;&gt;&gt; It looks like the fan works, but I am sure the disks woul=
d benefit if<br>
&gt; &gt;&gt;&gt; the fan produced more pressure. Which I fantasize I could=
 do via changing<br>
&gt; &gt;&gt;&gt; the value at the said address.<br>
&gt; &gt;&gt;&gt; Not sure, of course.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; best regards,<br>
&gt; &gt;&gt;&gt; Dmitry N. Medvedev<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;<br>
</blockquote></div>

--000000000000e10e6305fafc199d--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPf62nE9NF3cHDerChda%2BOCLUWP6NYyKmqc0=S_k532wm_2kxw>