drivers/hid/hid-core.c
Source file repositories/reference/linux-study-clean/drivers/hid/hid-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hid/hid-core.c- Extension
.c- Size
- 81920 bytes
- Lines
- 3229
- Domain
- Driver Families
- Bucket
- drivers/hid
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/module.hlinux/slab.hlinux/init.hlinux/kernel.hlinux/list.hlinux/mm.hlinux/spinlock.hlinux/unaligned.hasm/byteorder.hlinux/input.hlinux/wait.hlinux/vmalloc.hlinux/sched.hlinux/semaphore.hlinux/hid.hlinux/hiddev.hlinux/hid-debug.hlinux/hidraw.hhid-ids.h
Detected Declarations
struct hid_dynidfunction snto32function s32tonfunction open_collectionfunction close_collectionfunction hid_lookup_collectionfunction complete_usagefunction hid_add_usagefunction hid_add_fieldfunction item_udatafunction item_sdatafunction hid_parser_globalfunction hid_parser_localfunction hid_concatenate_last_usage_pagefunction hid_parser_mainfunction hid_parser_reservedfunction freefunction hid_open_reportfunction hid_free_bpf_rdescfunction hiddev_freefunction hid_device_releasefunction hid_scan_input_usagefunction hid_scan_feature_usagefunction hid_scan_collectionfunction hid_scan_mainfunction hid_scan_reportfunction parsefunction hid_get_reportfunction hid_calculate_multiplierfunction hid_apply_multiplier_to_fieldfunction hid_apply_multiplierfunction hid_setup_resolution_multiplierfunction hid_parse_collectionsfunction functionfunction __extractfunction hid_field_extractfunction __implementfunction implementfunction searchfunction hid_match_reportfunction hid_match_usagefunction hid_process_eventfunction hid_array_value_is_validfunction processingfunction hid_input_var_fieldfunction processingfunction processingfunction __hid_insert_field_entry
Annotated Snippet
static ssize_t new_id_store(struct device_driver *drv, const char *buf,
size_t count)
{
struct hid_driver *hdrv = to_hid_driver(drv);
struct hid_dynid *dynid;
__u32 bus, vendor, product;
unsigned long driver_data = 0;
int ret;
ret = sscanf(buf, "%x %x %x %lx",
&bus, &vendor, &product, &driver_data);
if (ret < 3)
return -EINVAL;
dynid = kzalloc_obj(*dynid);
if (!dynid)
return -ENOMEM;
dynid->id.bus = bus;
dynid->id.group = HID_GROUP_ANY;
dynid->id.vendor = vendor;
dynid->id.product = product;
dynid->id.driver_data = driver_data;
spin_lock(&hdrv->dyn_lock);
list_add_tail(&dynid->list, &hdrv->dyn_list);
spin_unlock(&hdrv->dyn_lock);
ret = driver_attach(&hdrv->driver);
return ret ? : count;
}
static DRIVER_ATTR_WO(new_id);
static struct attribute *hid_drv_attrs[] = {
&driver_attr_new_id.attr,
NULL,
};
ATTRIBUTE_GROUPS(hid_drv);
static void hid_free_dynids(struct hid_driver *hdrv)
{
struct hid_dynid *dynid, *n;
spin_lock(&hdrv->dyn_lock);
list_for_each_entry_safe(dynid, n, &hdrv->dyn_list, list) {
list_del(&dynid->list);
kfree(dynid);
}
spin_unlock(&hdrv->dyn_lock);
}
const struct hid_device_id *hid_match_device(struct hid_device *hdev,
struct hid_driver *hdrv)
{
struct hid_dynid *dynid;
spin_lock(&hdrv->dyn_lock);
list_for_each_entry(dynid, &hdrv->dyn_list, list) {
if (hid_match_one_id(hdev, &dynid->id)) {
spin_unlock(&hdrv->dyn_lock);
return &dynid->id;
}
}
spin_unlock(&hdrv->dyn_lock);
return hid_match_id(hdev, hdrv->id_table);
}
EXPORT_SYMBOL_GPL(hid_match_device);
static int hid_bus_match(struct device *dev, const struct device_driver *drv)
{
struct hid_driver *hdrv = to_hid_driver(drv);
struct hid_device *hdev = to_hid_device(dev);
return hid_match_device(hdev, hdrv) != NULL;
}
/**
* hid_compare_device_paths - check if both devices share the same path
* @hdev_a: hid device
* @hdev_b: hid device
* @separator: char to use as separator
*
* Check if two devices share the same path up to the last occurrence of
* the separator char. Both paths must exist (i.e., zero-length paths
* don't match).
*/
bool hid_compare_device_paths(struct hid_device *hdev_a,
struct hid_device *hdev_b, char separator)
Annotation
- Immediate include surface: `linux/module.h`, `linux/slab.h`, `linux/init.h`, `linux/kernel.h`, `linux/list.h`, `linux/mm.h`, `linux/spinlock.h`, `linux/unaligned.h`.
- Detected declarations: `struct hid_dynid`, `function snto32`, `function s32ton`, `function open_collection`, `function close_collection`, `function hid_lookup_collection`, `function complete_usage`, `function hid_add_usage`, `function hid_add_field`, `function item_udata`.
- Atlas domain: Driver Families / drivers/hid.
- Implementation status: pattern 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.