drivers/usb/gadget/function/f_hid.c
Source file repositories/reference/linux-study-clean/drivers/usb/gadget/function/f_hid.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/gadget/function/f_hid.c- Extension
.c- Size
- 44291 bytes
- Lines
- 1701
- Domain
- Driver Families
- Bucket
- drivers/usb
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/kernel.hlinux/module.hlinux/hid.hlinux/idr.hlinux/cdev.hlinux/mutex.hlinux/poll.hlinux/uaccess.hlinux/wait.hlinux/sched.hlinux/workqueue.hlinux/usb/func_utils.hlinux/usb/g_hid.huapi/linux/usb/g_hid.hu_hid.h
Detected Declarations
struct report_entrystruct f_hidg_req_liststruct f_hidgfunction hidg_releasefunction f_hidg_intout_readfunction f_hidg_ssreport_readfunction f_hidg_readfunction f_hidg_req_completefunction f_hidg_writefunction list_for_eachfunction get_report_workqueue_handlerfunction f_hidg_get_report_idfunction f_hidg_get_reportfunction f_hidg_ioctlfunction f_hidg_pollfunction f_hidg_releasefunction f_hidg_openfunction hidg_intout_completefunction hidg_ssreport_completefunction hidg_get_report_completefunction hidg_disablefunction list_for_each_entry_safefunction hidg_set_altfunction f_hidg_compat_ioctlfunction hidg_bindfunction hidg_get_minorfunction hid_attr_releasefunction f_hid_opts_report_desc_showfunction f_hid_opts_report_desc_storefunction f_hid_opts_interval_showfunction f_hid_opts_interval_storefunction f_hid_opts_dev_showfunction hidg_put_minorfunction hidg_free_instfunction hidg_freefunction hidg_unbindfunction ghid_setupfunction ghid_cleanup
Annotated Snippet
static const struct file_operations f_hidg_fops = {
.owner = THIS_MODULE,
.open = f_hidg_open,
.release = f_hidg_release,
.write = f_hidg_write,
.read = f_hidg_read,
.poll = f_hidg_poll,
.unlocked_ioctl = f_hidg_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = f_hidg_compat_ioctl,
#endif
.llseek = noop_llseek,
};
static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
{
struct usb_ep *ep;
struct f_hidg *hidg = func_to_hidg(f);
struct usb_string *us;
int status;
hidg->get_req = usb_ep_alloc_request(c->cdev->gadget->ep0, GFP_ATOMIC);
if (!hidg->get_req)
return -ENOMEM;
hidg->get_req->zero = 0;
hidg->get_req->complete = hidg_get_report_complete;
hidg->get_req->context = hidg;
hidg->get_report_returned = true;
/* maybe allocate device-global string IDs, and patch descriptors */
us = usb_gstrings_attach(c->cdev, ct_func_strings,
ARRAY_SIZE(ct_func_string_defs));
if (IS_ERR(us))
return PTR_ERR(us);
hidg_interface_desc.iInterface = us[CT_FUNC_HID_IDX].id;
/* allocate instance-specific interface IDs, and patch descriptors */
status = usb_interface_id(c, f);
if (status < 0)
goto fail;
hidg_interface_desc.bInterfaceNumber = status;
/* allocate instance-specific endpoints */
status = -ENODEV;
ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
if (!ep)
goto fail;
hidg->in_ep = ep;
hidg->out_ep = NULL;
if (hidg->use_out_ep) {
ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc);
if (!ep)
goto fail;
hidg->out_ep = ep;
}
/* used only if use_out_ep == 1 */
hidg->set_report_buf = NULL;
/* set descriptor dynamic values */
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
hidg_interface_desc.bNumEndpoints = hidg->use_out_ep ? 2 : 1;
hidg->protocol = HID_REPORT_PROTOCOL;
hidg->idle = 1;
hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
hidg_ss_in_comp_desc.wBytesPerInterval =
cpu_to_le16(hidg->report_length);
hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
hidg_ss_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
/* IN endpoints: FS default=10ms, HS default=4ยต-frame; user override if set */
if (!hidg->interval_user_set) {
hidg_fs_in_ep_desc.bInterval = 10;
hidg_hs_in_ep_desc.bInterval = 4;
hidg_ss_in_ep_desc.bInterval = 4;
} else {
hidg_fs_in_ep_desc.bInterval = hidg->interval;
hidg_hs_in_ep_desc.bInterval = hidg->interval;
hidg_ss_in_ep_desc.bInterval = hidg->interval;
}
hidg_ss_out_comp_desc.wBytesPerInterval =
cpu_to_le16(hidg->report_length);
hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
/*
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/hid.h`, `linux/idr.h`, `linux/cdev.h`, `linux/mutex.h`, `linux/poll.h`, `linux/uaccess.h`.
- Detected declarations: `struct report_entry`, `struct f_hidg_req_list`, `struct f_hidg`, `function hidg_release`, `function f_hidg_intout_read`, `function f_hidg_ssreport_read`, `function f_hidg_read`, `function f_hidg_req_complete`, `function f_hidg_write`, `function list_for_each`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.