drivers/hwmon/corsair-cpro.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/corsair-cpro.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/corsair-cpro.c- Extension
.c- Size
- 15886 bytes
- Lines
- 697
- Domain
- Driver Families
- Bucket
- drivers/hwmon
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitops.hlinux/completion.hlinux/debugfs.hlinux/hid.hlinux/hwmon.hlinux/kernel.hlinux/module.hlinux/mutex.hlinux/seq_file.hlinux/slab.hlinux/spinlock.hlinux/types.h
Detected Declarations
struct ccp_devicefunction ccp_get_errnofunction send_usb_cmdfunction ccp_raw_eventfunction get_datafunction set_pwmfunction set_targetfunction ccp_read_stringfunction ccp_readfunction ccp_writefunction ccp_is_visiblefunction get_fan_cnctfunction get_temp_cnctfunction get_fw_versionfunction get_bl_versionfunction firmware_showfunction bootloader_showfunction ccp_debugfs_initfunction ccp_probefunction ccp_removefunction ccp_initfunction ccp_exit
Annotated Snippet
struct ccp_device {
struct hid_device *hdev;
struct device *hwmon_dev;
struct dentry *debugfs;
/* For reinitializing the completion below */
spinlock_t wait_input_report_lock;
struct completion wait_input_report;
struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */
u8 *cmd_buffer;
u8 *buffer;
int buffer_recv_size; /* number of received bytes in buffer */
int target[NUM_FANS];
DECLARE_BITMAP(temp_cnct, NUM_TEMP_SENSORS);
DECLARE_BITMAP(fan_cnct, NUM_FANS);
char fan_label[NUM_FANS][LABEL_LENGTH];
u8 firmware_ver[3];
u8 bootloader_ver[2];
};
/* converts response error in buffer to errno */
static int ccp_get_errno(struct ccp_device *ccp)
{
switch (ccp->buffer[0]) {
case 0x00: /* success */
return 0;
case 0x01: /* called invalid command */
return -EOPNOTSUPP;
case 0x10: /* called GET_VOLT / GET_TMP with invalid arguments */
return -EINVAL;
case 0x11: /* requested temps of disconnected sensors */
case 0x12: /* requested pwm of not pwm controlled channels */
return -ENODATA;
default:
hid_dbg(ccp->hdev, "unknown device response error: %d", ccp->buffer[0]);
return -EIO;
}
}
/* send command, check for error in response, response in ccp->buffer */
static int send_usb_cmd(struct ccp_device *ccp, u8 command, u8 byte1, u8 byte2, u8 byte3)
{
unsigned long t;
int ret;
memset(ccp->cmd_buffer, 0x00, OUT_BUFFER_SIZE);
ccp->cmd_buffer[0] = command;
ccp->cmd_buffer[1] = byte1;
ccp->cmd_buffer[2] = byte2;
ccp->cmd_buffer[3] = byte3;
/*
* Disable raw event parsing for a moment to safely reinitialize the
* completion. Reinit is done because hidraw could have triggered
* the raw event parsing and marked the ccp->wait_input_report
* completion as done.
*/
spin_lock_bh(&ccp->wait_input_report_lock);
reinit_completion(&ccp->wait_input_report);
spin_unlock_bh(&ccp->wait_input_report_lock);
ret = hid_hw_output_report(ccp->hdev, ccp->cmd_buffer, OUT_BUFFER_SIZE);
if (ret < 0)
return ret;
t = wait_for_completion_timeout(&ccp->wait_input_report, msecs_to_jiffies(REQ_TIMEOUT));
if (!t)
return -ETIMEDOUT;
if (ccp->buffer_recv_size != IN_BUFFER_SIZE)
return -EPROTO;
return ccp_get_errno(ccp);
}
static int ccp_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
{
struct ccp_device *ccp = hid_get_drvdata(hdev);
/* only copy buffer when requested */
spin_lock(&ccp->wait_input_report_lock);
if (!completion_done(&ccp->wait_input_report)) {
memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
ccp->buffer_recv_size = size;
complete_all(&ccp->wait_input_report);
}
spin_unlock(&ccp->wait_input_report_lock);
return 0;
}
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/completion.h`, `linux/debugfs.h`, `linux/hid.h`, `linux/hwmon.h`, `linux/kernel.h`, `linux/module.h`, `linux/mutex.h`.
- Detected declarations: `struct ccp_device`, `function ccp_get_errno`, `function send_usb_cmd`, `function ccp_raw_event`, `function get_data`, `function set_pwm`, `function set_target`, `function ccp_read_string`, `function ccp_read`, `function ccp_write`.
- Atlas domain: Driver Families / drivers/hwmon.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.