tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: aibs(4): ASUSTeK AI Booster (ACPI ATK0110) hardware monitor with limit support
2009/12/30 Jukka Ruohonen <jruohonen%iki.fi@localhost>:
> On Wed, Dec 30, 2009 at 03:49:35AM -0500, Constantine Aleksandrovich Murenin
> wrote:
>>
>> Attached patch provides support for the hardware monitoring capabilities
>> that are present in many modern desktop motherboards from ASUS featuring
>> the ATK0110 ACPI device.
>
> Hi. Few small comments, all of them more or less trivial.
>
>> +struct aibs_sensor {
>> + envsys_data_t s;
>> + int64_t i;
>> + int64_t l;
>> + int64_t h;
>> +};
>
> The correct type for these would probably be uint64_t, given the relation to
> the type ACPI_INTEGER, which AFAIR is an unsigned 64-bit integer (from ACPI
> 2.0 onwards). Or maybe even plain ACPI_INTEGER?
Yes, this sounds good -- I'll try changing all of these to ACPI_INTEGER.
>> + case ENVSYS_SVOLTS_DC:
>> + name[0] = 'V';
>> + break;
>> + default:
>> + return;
>> + }
>> +
>> + b.Length = ACPI_ALLOCATE_BUFFER;
>
> This could be ACPI_ALLOCATE_LOCAL_BUFFER.
ACPI_ALLOCATE_LOCAL_BUFFER is not documented in the latest
http://www.acpica.org/download/acpica-reference.pdf (Revision 1.26,
from October 2009). Is there any principal difference between the
two?
>> + s = AcpiEvaluateObjectTyped(sc->sc_node->ad_handle, name, NULL, &b,
>> + ACPI_TYPE_PACKAGE);
>> + if (ACPI_FAILURE(s)) {
>> + aprint_error_dev(self, "%s not found\n", name);
>> + return;
>> + }
>
> This is just a personal preference, but I would use acpi_eval_struct() and
> verify the type manually, given that AcpiEvaluateObjectTyped() is just a
> wrapper around AcpiEvaluateObject(). Maybe we should have something like
> acpi_eval_struct_typed() though.
>
>> + bp = b.Pointer;
>> + o = bp->Package.Elements;
>> + if (o[0].Type != ACPI_TYPE_INTEGER) {
>> + aprint_error_dev(self, "%s[0]: invalid type\n", name);
>> + AcpiOsFree(b.Pointer);
>
> Use the ACPI_FREE macro instead of calling AcpiOsFree() directly.
ACPICA Reference, Section 3.2.2.2, "ACPI Allocates Return Buffers",
explicitly suggests the use of AcpiOsFree(). Is it wrong?
>> + as = malloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO);
>
> I reckon that there is no reason to prefer malloc(9) instead of kmem(9).
I didn't use kmem(9) since that would require knowing the size of the
structure on kmem_free(9).
>> + for (i = 0, o++; i < n; i++, o++) {
>
> Would it be possible to use the utility function acpi_foreach_package_object()
> here? It could clarify the loop, which I think is more readable in the
> original aiboost(4).
Actually, the original aiboost(4) also uses pointer arithmetics in a
for loop similar to mine. :-)
Thanks for pointing out this function, I'll take a further look if
it'll be more useful. I'd prefer the driver to be as cross-portable
as possible, though, and acpica functions seem like a natural choice
for such a direction.
>> + as[i].i = oi[0].Integer.Value;
>> + strlcpy(as[i].s.desc, oi[1].String.Pointer,
>> + sizeof(as[i].s.desc));
>
> Is there a guarantee that "oi[1].String.Pointer" is not NULL?
I'd certainly expect so, since NULL is not a string, and oi[1].Type is
ACPI_TYPE_STRING.
>> + aprint_verbose_dev(self, "%c%i: "
>> + "0x%08llx %20s %5lli / %5lli 0x%llx\n",
>> + name[0], i,
>> + as[i].i, as[i].s.desc, as[i].l, as[i].h,
>> + oi[4].Integer.Value);
>
> These should probably be %"PRId64" (or %"PRIx64" with uint64_t).
Sure, looks good... Actually, what's the purpose of this? Is
sizeof(unsigned long long) greater than sizeof(uint64_t) on amd64? If
not, then why do you have to change llx to lx? :/
>> + sysmon_envsys_sensor_attach(sc->sc_sme, &as[i].s);
>> + }
>
> The return value from sysmon_envsys_attach() could be validated, as there is
> no proof what is in "oi[1].String.Pointer" (i.e. could it be empty string or
> duplicate or something similar due buggy firmware?).
Yes, sure, overlooked that during the porting...
>> +static int
>> +aibs_detach(device_t self, int flags)
>> +{
>> + struct aibs_softc *sc = device_private(self);
>> +
>> + sysmon_envsys_unregister(sc->sc_sme);
>> + if (sc->sc_asens_volt != NULL)
>> + free(sc->sc_asens_volt, M_DEVBUF);
>> + if (sc->sc_asens_temp != NULL)
>> + free(sc->sc_asens_temp, M_DEVBUF);
>> + if (sc->sc_asens_fan != NULL)
>> + free(sc->sc_asens_fan, M_DEVBUF);
>> + return 0;
>> +}
>
> I wonder if the detach routine is needed at all?
As David pointed out, for drvctl -d. :-)
C.
Home |
Main Index |
Thread Index |
Old Index