Skip to content

Commit

Permalink
Record time of last write and delay if necessary
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksa Savic <savicaleksa83@gmail.com>
  • Loading branch information
aleksamagicka committed Jul 29, 2023
1 parent f8e9dd4 commit 6f9789c
Showing 1 changed file with 22 additions and 21 deletions.
43 changes: 22 additions & 21 deletions aquacomputer_d5next.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/seq_file.h>
Expand Down Expand Up @@ -71,6 +72,8 @@ static const char *const aqc_device_names[] = {
#define CTRL_REPORT_ID 0x03
#define AQUAERO_CTRL_REPORT_ID 0x0b

#define CTRL_REPORT_WRITE_DELAY 200 /* ms */

/*
* The HID report that the official software always sends
* after writing values, same for all devices, except Aquaero
Expand Down Expand Up @@ -661,6 +664,9 @@ struct aqc_data {
int secondary_ctrl_report_size;
u8 *secondary_ctrl_report;

ktime_t last_ctrl_report_write;
int ctrl_report_write_delay; /* Delay between two ctrl report writes, in ms */

int buffer_size;
/*
* Used for writing reports (where supported) and reading
Expand Down Expand Up @@ -812,6 +818,17 @@ static int aqc_send_ctrl_data(struct aqc_data *priv)
int ret;
u16 checksum;

/*
* If previous write is too close to this one, delay the current write to give
* enough time to the device to process the previous operation.
*/
if (priv->ctrl_report_write_delay) {
s64 delta = ktime_us_delta(ktime_get(), priv->last_ctrl_report_write);

if (delta < priv->ctrl_report_write_delay)
msleep(priv->ctrl_report_write_delay - delta);
}

/* Checksum is not needed for Aquaero and Aquastream XT */
if (priv->kind != aquaero && priv->kind != aquastreamxt) {
/* Init and xorout value for CRC-16/USB is 0xffff */
Expand All @@ -837,27 +854,7 @@ static int aqc_send_ctrl_data(struct aqc_data *priv)
if (ret < 0)
return ret;

/*
* Wait 200ms before returning to make sure that the device actually processed both reports
* and saved ctrl data to memory. Otherwise, an aqc_get_ctrl_data() call made shortly after
* may fail with -EPIPE because the device is still busy and can't provide data. This can
* happen when userspace tools, such as fancontrol or liquidctl, write to sysfs entries in
* quick succession (for example, setting pwmX_enable and pwmX attributes at once).
*
* 200ms was found to be the sweet spot between fixing the issue and not significantly
* prolonging the call. Quadro, Octo, D5 Next and Aquaero are currently known to be
* affected.
*/
switch (priv->kind) {
case quadro:
case octo:
case d5next:
case aquaero:
msleep(200);
break;
default:
break;
}
priv->last_ctrl_report_write = ktime_get();

return ret;
}
Expand Down Expand Up @@ -2817,6 +2814,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)

priv->buffer_size = AQUAERO_CTRL_REPORT_SIZE;
priv->temp_ctrl_offset = AQUAERO_TEMP_CTRL_OFFSET;
priv->ctrl_report_write_delay = CTRL_REPORT_WRITE_DELAY;

priv->temp_label = label_temp_sensors;
priv->virtual_temp_label = label_virtual_temp_sensors;
Expand Down Expand Up @@ -2847,6 +2845,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_cycle_count_offset = AQC_POWER_CYCLES;
priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE;
priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET;
priv->ctrl_report_write_delay = CTRL_REPORT_WRITE_DELAY;

priv->temp_label = label_d5next_temp;
priv->virtual_temp_label = label_virtual_temp_sensors;
Expand Down Expand Up @@ -2902,6 +2901,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_cycle_count_offset = AQC_POWER_CYCLES;
priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET;
priv->ctrl_report_write_delay = CTRL_REPORT_WRITE_DELAY;

priv->temp_label = label_temp_sensors;
priv->virtual_temp_label = label_virtual_temp_sensors;
Expand Down Expand Up @@ -2931,6 +2931,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)

priv->power_cycle_count_offset = AQC_POWER_CYCLES;
priv->buffer_size = QUADRO_CTRL_REPORT_SIZE;
priv->ctrl_report_write_delay = CTRL_REPORT_WRITE_DELAY;
priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET;
priv->flow_pulses_ctrl_offset = QUADRO_FLOW_PULSES_CTRL_OFFSET;

Expand Down

0 comments on commit 6f9789c

Please sign in to comment.