From nobody Wed May 03 18:02:25 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 4QBPtG06qZz495yP for ; Wed, 3 May 2023 18:02:30 +0000 (UTC) (envelope-from georg.lindenberg@web.de) Received: from mout.web.de (mout.web.de [212.227.15.14]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "mout.web.de", Issuer "Telekom Security ServerID OV Class 2 CA" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QBPtD4zCTz3GYj for ; Wed, 3 May 2023 18:02:28 +0000 (UTC) (envelope-from georg.lindenberg@web.de) Authentication-Results: mx1.freebsd.org; dkim=pass header.d=web.de header.s=s29768273 header.b=bJ4qHIal; spf=pass (mx1.freebsd.org: domain of georg.lindenberg@web.de designates 212.227.15.14 as permitted sender) smtp.mailfrom=georg.lindenberg@web.de; dmarc=pass (policy=none) header.from=web.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=s29768273; t=1683136945; i=georg.lindenberg@web.de; bh=LIrjfJ6rvwHIN5mCW2B1qS6zx9ITVkRjmkkfpKkAfdA=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=bJ4qHIal3MgrmgJQeSZru1pQlsUaHLkMNGnDzH1X6lbMEzvmu9rxemP/+3nGOPNPN DZ5BuJi6xuLDL37jHd4M3YQxlkYpHgROUjOtp7NGo6LqdmNlcB26yQidGi/YArTVBH kQ8VLZBgPxsBh90GqeBYdzKeKgMzAScOzr0CQLQCGR3+rAAKqzJbwRvn4a1R8OQx3z 4PWNVH3BdOKXt3xXBXxiVYDpjjk6xAJYKFsN4pzd9gVoQFzWqJHUA6kCK5fYAvDz00 mKUFoQt5cYzH7XPwGeXXgjvOorx5Asid8uMZ9wsFR9WlTmLvEdG8mi4khVBIsm3KA1 A7+aeZMQC2hWQ== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [217.72.213.59] ([217.72.213.59]) by web-mail.web.de (3c-app-webde-bs51.server.lan [172.19.170.107]) (via HTTP); Wed, 3 May 2023 20:02:25 +0200 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 Message-ID: From: Georg Lindenberg To: "Dmitry N. Medvedev" Cc: freebsd-acpi@freebsd.org Subject: Aw: Re: managing a fan speed via memory address Content-Type: text/html; charset=UTF-8 Date: Wed, 3 May 2023 20:02:25 +0200 Importance: normal Sensitivity: Normal In-Reply-To: References: X-UI-Message-Type: mail X-Priority: 3 X-Provags-ID: V03:K1:tXaCWBiUcVIRhz3K/oLm4yBP23rJ4KT2nEyMjTvETmRt480fhRrxm2YnmxZ3SJwHIR1qi cUInHTvpid7Gp/hi//FUMXLxCuVNBxyittPjyF4sIN2kXQT5JhSwG7/uwIk0pj8XYqhZyc9PMH+N 3UrDTq3dsCpXJvspXqjW5yrrL2WkoDdTc+xGqI8QGExx2uBd3wzVhf59X/Z7Xe4zah6wDdRrTzS5 /zwgc2QXUxMnBHkNNFlkJKoWRyJRY8gbVaQvuuFnP2cBthsL6PTMUc0UnLAGsFRSdl3sVzLwxFPx a4= X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:ALPPiGZsLxI=;RX/i6NskOHZihfzSep4KCkoQQ5Z +MIdrEfvRZCtePS1k8MCl6wpCtxrVpZ8ASUOfOvmRjw6nwyikr83CaroFgfNFhR6oT60IZC5S hIHSIJNPBpCsC7qSXkff/UsBMsMoHDlpCjW2OPFBgrd+tQzsOZfqalWUwqT0tE3YqkrjR1PKR brpXp/twOizVJYQuBT7kYSMeC5udmiQ/N1q4NHjt0ZhhdXm7h0kw9q27UgigT7ejutRB6WU1z O3a3ngwdqzBYhEcAtfpLfguNAo/yYY/ZX92z+/Y6UPDdnMEd1SJhmQMxBIAvWWuQW+jy7lyd9 d7eoWzRcGJqAYJWAclZNt3pq93LEerdWasfLxrSesuiPlsxgzEKq+rQQVxEQj1144SkL/0Cb3 +9xiqLuLUDoLsaHGulJEKhTnWJb7yu14Zy+/EL1LLybUkmv1pOZodM3PikVdaeFii4PpN3YPT +MXYqQ9JuDjJLcmfVUl8/7++U712BHfzREk38nCx10HYR//Esh+3Y2NgcgoOgUIx71SvxRxZ+ xwJ9GKIATd/vS4MGdj8Z4Yyi51qqrflyVTapYeMq+CYkrg0uQkaifDr/JpT+gYr3stHtrGiEb 4bx+tK/luk+RVnXVasAez5EDm1cPo+QT+N14wKvqhDhTXmEpgjQUh5gCilPv+IFuJtRa1sgek n58eIK8nNatwq7hjDQSehm3Ak4Ch1oUuV0gXOf19wSVSbrYeGFeEoV5c4i2D3XEzRwhV5YwvC sBtnEp9Q3izA8vp2hM1BWXWMFWP1DfCubV/ZnnLNLx8qlwhP5cksZ6b+//0nJqM31a2e6Di1Z RXuwLGIQVEz0Rd8bltyaU/2RXBWJLtNn9M3lnrQ4ewyzM= X-Spamd-Result: default: False [-2.73 / 15.00]; DWL_DNSWL_LOW(-1.00)[web.de:dkim]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_SPAM_SHORT(0.57)[0.570]; DMARC_POLICY_ALLOW(-0.50)[web.de,none]; MID_RHS_NOT_FQDN(0.50)[]; R_DKIM_ALLOW(-0.20)[web.de:s=s29768273]; MIME_HTML_ONLY(0.20)[]; R_SPF_ALLOW(-0.20)[+ip4:212.227.15.0/25]; RCVD_IN_DNSWL_LOW(-0.10)[212.227.15.14:from]; TO_MATCH_ENVRCPT_SOME(0.00)[]; RWL_MAILSPIKE_POSSIBLE(0.00)[212.227.15.14:from]; MLMMJ_DEST(0.00)[freebsd-acpi@freebsd.org]; FROM_HAS_DN(0.00)[]; TAGGED_RCPT(0.00)[]; TO_DN_SOME(0.00)[]; ASN(0.00)[asn:8560, ipnet:212.227.0.0/16, country:DE]; RCPT_COUNT_TWO(0.00)[2]; HAS_X_PRIO_THREE(0.00)[3]; DKIM_TRACE(0.00)[web.de:+]; FREEMAIL_FROM(0.00)[web.de]; ARC_NA(0.00)[]; FREEMAIL_TO(0.00)[gmail.com]; RCVD_TLS_LAST(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; FREEMAIL_ENVFROM(0.00)[web.de]; MIME_TRACE(0.00)[0:~]; RCVD_COUNT_TWO(0.00)[2] X-Rspamd-Queue-Id: 4QBPtD4zCTz3GYj X-Spamd-Bar: -- X-ThisMailContainsUnwantedMimeParts: N
 
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 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 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 = 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 = 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 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 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[] = {
    /* 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[] = { \
    "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 = ACPI_ID_PROBE(device_get_parent(dev), dev, fan_ids, NULL);
    if (rv <= 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 = device_get_softc(dev);
    handle = 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 = 4;
    
    else    /* nothing to do in acpi version 1, really */
        acpi_fan_softc.version = 1;
 
  return 0;
}
 
static int
acpi_fan_detach(device_t dev) {
    sysctl_ctx_free(&clist);
    return 0;
}
 

static driver_t acpi_fan_driver = {
    "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 AM 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 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