Skip to content

Commit e0cd85d

Browse files
aleksamagickagroeck
authored andcommitted
hwmon: (corsair-cpro) Use a separate buffer for sending commands
Introduce cmd_buffer, a separate buffer for storing only the command that is sent to the device. Before this separation, the existing buffer was shared for both the command and the report received in ccp_raw_event(), which was copied into it. However, because of hidraw, the raw event parsing may be triggered in the middle of sending a command, resulting in outputting gibberish to the device. Using a separate buffer resolves this. Fixes: 40c3a44 ("hwmon: add Corsair Commander Pro driver") Signed-off-by: Aleksa Savic <savicaleksa83@gmail.com> Acked-by: Marius Zachmann <mail@mariuszachmann.de> Link: https://lore.kernel.org/r/20240504092504.24158-2-savicaleksa83@gmail.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent e67572c commit e0cd85d

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

drivers/hwmon/corsair-cpro.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct ccp_device {
7979
struct device *hwmon_dev;
8080
struct completion wait_input_report;
8181
struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */
82+
u8 *cmd_buffer;
8283
u8 *buffer;
8384
int target[6];
8485
DECLARE_BITMAP(temp_cnct, NUM_TEMP_SENSORS);
@@ -111,15 +112,15 @@ static int send_usb_cmd(struct ccp_device *ccp, u8 command, u8 byte1, u8 byte2,
111112
unsigned long t;
112113
int ret;
113114

114-
memset(ccp->buffer, 0x00, OUT_BUFFER_SIZE);
115-
ccp->buffer[0] = command;
116-
ccp->buffer[1] = byte1;
117-
ccp->buffer[2] = byte2;
118-
ccp->buffer[3] = byte3;
115+
memset(ccp->cmd_buffer, 0x00, OUT_BUFFER_SIZE);
116+
ccp->cmd_buffer[0] = command;
117+
ccp->cmd_buffer[1] = byte1;
118+
ccp->cmd_buffer[2] = byte2;
119+
ccp->cmd_buffer[3] = byte3;
119120

120121
reinit_completion(&ccp->wait_input_report);
121122

122-
ret = hid_hw_output_report(ccp->hdev, ccp->buffer, OUT_BUFFER_SIZE);
123+
ret = hid_hw_output_report(ccp->hdev, ccp->cmd_buffer, OUT_BUFFER_SIZE);
123124
if (ret < 0)
124125
return ret;
125126

@@ -492,7 +493,11 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
492493
if (!ccp)
493494
return -ENOMEM;
494495

495-
ccp->buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
496+
ccp->cmd_buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
497+
if (!ccp->cmd_buffer)
498+
return -ENOMEM;
499+
500+
ccp->buffer = devm_kmalloc(&hdev->dev, IN_BUFFER_SIZE, GFP_KERNEL);
496501
if (!ccp->buffer)
497502
return -ENOMEM;
498503

0 commit comments

Comments
 (0)