On Mon, Oct 25, 2021 at 10:20:17PM +0300, Andy Shevchenko wrote: > On Fri, Oct 22, 2021 at 11:00:29PM +0300, Denis Pauk wrote: > > Linux HWMON sensors driver for ASUS motherboards to read > > sensors from the embedded controller. > > > > Many ASUS motherboards do not publish all the available > > sensors via the Super I/O chip but the missing ones are > > available through the embedded controller (EC) registers. > > > > This driver implements reading those sensor data via the > > WMI method BREC, which is known to be present in all ASUS > > motherboards based on the AMD 500 series chipsets (and > > probably is available in other models too). The driver > > needs to know exact register addresses for the sensors and > > thus support for each motherboard has to be added explicitly. > > > > The EC registers do not provide critical values for the > > sensors and as such they are not published to the HWMON. > > > > Supported motherboards: > > * PRIME X570-PRO > > * Pro WS X570-ACE > > * ROG CROSSHAIR VIII HERO > > * ROG CROSSHAIR VIII DARK HERO > > * ROG CROSSHAIR VIII FORMULA > > * ROG STRIX X570-E GAMING > > * ROG STRIX B550-E GAMING > > Below is a follow up, I have not compiled it. > Feel free to take fully or partially. ... > -static int asus_wmi_ec_decode_reply_buffer(const u8 *inp, u8 *out, u32 length) > +static int asus_wmi_ec_decode_reply_buffer(const u8 *in, u32 length, u8 *out) > { > char buffer[ASUSWMI_MAX_BUF_LEN * 2]; > - const char *pos = buffer; > - const u8 *data = inp + 2; > u32 len; > > - /* Minimum of size of response and size of ACPI result*/ > - len = min_t(u32, inp[0] / 4, (length - 2) / 4); > - len = min_t(u32, len, ASUSWMI_MAX_BUF_LEN); > + /* Minimum of size of response and size of ACPI result (in bytes) */ > + len = min_t(u32, in[0], length - 2); Of course this should be len = min_t(u32, get_unaligned_le16(in), length - 2); (compare to the opposite below). > - utf16s_to_utf8s((wchar_t *)data, len * 2, UTF16_LITTLE_ENDIAN, buffer, len * 2); > + utf16s_to_utf8s((wchar_t *)(in + 2), len / 2, UTF16_LITTLE_ENDIAN, buffer, sizeof(buffer)); > > - return hex2bin(out, pos, len); > + return hex2bin(out, buffer, len / 2); > } > > -static void asus_wmi_ec_encode_registers(const u16 *registers, u8 len, char *out) > +static void asus_wmi_ec_encode_registers(const u8 *in, u32 length, char *out) > { > char buffer[ASUSWMI_MAX_BUF_LEN * 2]; > - char *pos = buffer; > - unsigned int i; > - u8 byte; > - > - *out++ = len * 8; > - *out++ = 0; > - > - for (i = 0; i < len; i++) { > - byte = registers[i] >> 8; > - pos = bin2hex(pos, &byte, 1); > - byte = registers[i]; > - pos = bin2hex(pos, &byte, 1); > - } > + u16 len = nr_registers * 2; > + > + put_unaligned_le16(len * 2, out); > + > + bin2hex(buffer, in, len); > > - utf8s_to_utf16s(buffer, len * 4, UTF16_LITTLE_ENDIAN, (wchar_t *)out, len * 4); > + utf8s_to_utf16s(buffer, len * 2, UTF16_LITTLE_ENDIAN, (wchar_t *)(out + 2), len); > } -- With Best Regards, Andy Shevchenko