#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hid.h>
#include <linux/idr.h>
#include <linux/cdev.h>
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/usb/func_utils.h>
#include <linux/usb/g_hid.h>
#include <uapi/linux/usb/g_hid.h>
#include "u_hid.h"
#define HIDG_MINORS …
#define GET_REPORT_TIMEOUT_MS …
static int major, minors;
static const struct class hidg_class = …;
static DEFINE_IDA(hidg_ida);
static DEFINE_MUTEX(hidg_ida_lock);
struct report_entry { … };
struct f_hidg_req_list { … };
struct f_hidg { … };
static inline struct f_hidg *func_to_hidg(struct usb_function *f)
{ … }
static void hidg_release(struct device *dev)
{ … }
static struct usb_interface_descriptor hidg_interface_desc = …;
static struct hid_descriptor hidg_desc = …;
static struct usb_endpoint_descriptor hidg_ss_in_ep_desc = …;
static struct usb_ss_ep_comp_descriptor hidg_ss_in_comp_desc = …;
static struct usb_endpoint_descriptor hidg_ss_out_ep_desc = …;
static struct usb_ss_ep_comp_descriptor hidg_ss_out_comp_desc = …;
static struct usb_descriptor_header *hidg_ss_descriptors_intout[] = …;
static struct usb_descriptor_header *hidg_ss_descriptors_ssreport[] = …;
static struct usb_endpoint_descriptor hidg_hs_in_ep_desc = …;
static struct usb_endpoint_descriptor hidg_hs_out_ep_desc = …;
static struct usb_descriptor_header *hidg_hs_descriptors_intout[] = …;
static struct usb_descriptor_header *hidg_hs_descriptors_ssreport[] = …;
static struct usb_endpoint_descriptor hidg_fs_in_ep_desc = …;
static struct usb_endpoint_descriptor hidg_fs_out_ep_desc = …;
static struct usb_descriptor_header *hidg_fs_descriptors_intout[] = …;
static struct usb_descriptor_header *hidg_fs_descriptors_ssreport[] = …;
#define CT_FUNC_HID_IDX …
static struct usb_string ct_func_string_defs[] = …;
static struct usb_gadget_strings ct_func_string_table = …;
static struct usb_gadget_strings *ct_func_strings[] = …;
static ssize_t f_hidg_intout_read(struct file *file, char __user *buffer,
size_t count, loff_t *ptr)
{ … }
#define READ_COND_SSREPORT …
static ssize_t f_hidg_ssreport_read(struct file *file, char __user *buffer,
size_t count, loff_t *ptr)
{ … }
static ssize_t f_hidg_read(struct file *file, char __user *buffer,
size_t count, loff_t *ptr)
{ … }
static void f_hidg_req_complete(struct usb_ep *ep, struct usb_request *req)
{ … }
static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
size_t count, loff_t *offp)
{ … }
static struct report_entry *f_hidg_search_for_report(struct f_hidg *hidg, u8 report_id)
{ … }
static void get_report_workqueue_handler(struct work_struct *work)
{ … }
static int f_hidg_get_report_id(struct file *file, __u8 __user *buffer)
{ … }
static int f_hidg_get_report(struct file *file, struct usb_hidg_report __user *buffer)
{ … }
static long f_hidg_ioctl(struct file *file, unsigned int code, unsigned long arg)
{ … }
static __poll_t f_hidg_poll(struct file *file, poll_table *wait)
{ … }
#undef WRITE_COND
#undef READ_COND_SSREPORT
#undef READ_COND_INTOUT
#undef GET_REPORT_COND
static int f_hidg_release(struct inode *inode, struct file *fd)
{ … }
static int f_hidg_open(struct inode *inode, struct file *fd)
{ … }
static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep,
unsigned length)
{ … }
static void hidg_intout_complete(struct usb_ep *ep, struct usb_request *req)
{ … }
static void hidg_ssreport_complete(struct usb_ep *ep, struct usb_request *req)
{ … }
static void hidg_get_report_complete(struct usb_ep *ep, struct usb_request *req)
{ … }
static int hidg_setup(struct usb_function *f,
const struct usb_ctrlrequest *ctrl)
{ … }
static void hidg_disable(struct usb_function *f)
{ … }
static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
{ … }
#ifdef CONFIG_COMPAT
static long f_hidg_compat_ioctl(struct file *file, unsigned int code,
unsigned long value)
{ … }
#endif
static const struct file_operations f_hidg_fops = …;
static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
{ … }
static inline int hidg_get_minor(void)
{ … }
static inline struct f_hid_opts *to_f_hid_opts(struct config_item *item)
{ … }
static void hid_attr_release(struct config_item *item)
{ … }
static struct configfs_item_operations hidg_item_ops = …;
#define F_HID_OPT(name, prec, limit) …
F_HID_OPT(…);
F_HID_OPT(…);
F_HID_OPT(…);
F_HID_OPT(…);
static ssize_t f_hid_opts_report_desc_show(struct config_item *item, char *page)
{ … }
static ssize_t f_hid_opts_report_desc_store(struct config_item *item,
const char *page, size_t len)
{ … }
CONFIGFS_ATTR(…);
static ssize_t f_hid_opts_dev_show(struct config_item *item, char *page)
{ … }
CONFIGFS_ATTR_RO(…);
static struct configfs_attribute *hid_attrs[] = …;
static const struct config_item_type hid_func_type = …;
static inline void hidg_put_minor(int minor)
{ … }
static void hidg_free_inst(struct usb_function_instance *f)
{ … }
static struct usb_function_instance *hidg_alloc_inst(void)
{ … }
static void hidg_free(struct usb_function *f)
{ … }
static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
{ … }
static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
{ … }
DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc);
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
int ghid_setup(struct usb_gadget *g, int count)
{ … }
void ghid_cleanup(void)
{ … }