Loading drivers/usb/gadget/function/f_gsi.c +216 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,12 @@ #include "f_gsi.h" #include "rndis.h" struct usb_gsi_debugfs { struct dentry *debugfs_root; }; static struct usb_gsi_debugfs debugfs; static bool qti_packet_debug; module_param(qti_packet_debug, bool, 0644); MODULE_PARM_DESC(qti_packet_debug, "Print QTI Packet's Raw Data"); Loading Loading @@ -173,6 +179,212 @@ static int gsi_wakeup_host(struct f_gsi *gsi) return ret; } static void gsi_rw_timer_func(struct timer_list *t) { struct f_gsi *gsi = from_timer(gsi, t, gsi_rw_timer); if (!atomic_read(&gsi->connected)) { log_event_dbg("%s: gsi not connected.. bail-out\n", __func__); gsi->debugfs_rw_timer_enable = 0; return; } log_event_dbg("%s: calling gsi_wakeup_host\n", __func__); gsi_wakeup_host(gsi); if (gsi->debugfs_rw_timer_enable) { log_event_dbg("%s: re-arm the timer\n", __func__); mod_timer(&gsi->gsi_rw_timer, jiffies + msecs_to_jiffies(gsi->gsi_rw_timer_interval)); } } static struct f_gsi *get_connected_gsi(void) { struct f_gsi *connected_gsi; bool gsi_connected = false; int i; for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++) { if (inst_status[i].opts) connected_gsi = inst_status[i].opts->gsi; else continue; if (connected_gsi && atomic_read(&connected_gsi->connected)) { gsi_connected = true; break; } } if (!gsi_connected) connected_gsi = NULL; return connected_gsi; } #define DEFAULT_RW_TIMER_INTERVAL 500 /* in ms */ static ssize_t usb_gsi_rw_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { struct f_gsi *gsi; u8 input; int ret; gsi = get_connected_gsi(); if (!gsi) { log_event_dbg("%s: gsi not connected\n", __func__); goto err; } if (ubuf == NULL) { log_event_dbg("%s: buffer is Null.\n", __func__); goto err; } ret = kstrtou8_from_user(ubuf, count, 0, &input); if (ret) { log_event_err("%s: Invalid value. err:%d\n", __func__, ret); goto err; } if (gsi->debugfs_rw_timer_enable == !!input) { if (!!input) log_event_dbg("%s: RW already enabled\n", __func__); else log_event_dbg("%s: RW already disabled\n", __func__); goto err; } gsi->debugfs_rw_timer_enable = !!input; if (gsi->debugfs_rw_timer_enable) { mod_timer(&gsi->gsi_rw_timer, jiffies + msecs_to_jiffies(gsi->gsi_rw_timer_interval)); log_event_dbg("%s: timer initialized\n", __func__); } else { del_timer_sync(&gsi->gsi_rw_timer); log_event_dbg("%s: timer deleted\n", __func__); } err: return count; } static int usb_gsi_rw_show(struct seq_file *s, void *unused) { struct f_gsi *gsi; gsi = get_connected_gsi(); if (!gsi) { log_event_dbg("%s: gsi not connected\n", __func__); return 0; } seq_printf(s, "%d\n", gsi->debugfs_rw_timer_enable); return 0; } static int usb_gsi_rw_open(struct inode *inode, struct file *f) { return single_open(f, usb_gsi_rw_show, inode->i_private); } static const struct file_operations fops_usb_gsi_rw = { .open = usb_gsi_rw_open, .read = seq_read, .write = usb_gsi_rw_write, .owner = THIS_MODULE, .llseek = seq_lseek, .release = seq_release, }; static ssize_t usb_gsi_rw_timer_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { struct f_gsi *gsi; u16 timer_val; int ret; gsi = get_connected_gsi(); if (!gsi) { log_event_dbg("%s: gsi not connected\n", __func__); goto err; } if (ubuf == NULL) { log_event_dbg("%s: buffer is NULL.\n", __func__); goto err; } ret = kstrtou16_from_user(ubuf, count, 0, &timer_val); if (ret) { log_event_err("%s: Invalid value. err:%d\n", __func__, ret); goto err; } if (timer_val <= 0 || timer_val > 10000) { log_event_err("%s: value must be > 0 and < 10000.\n", __func__); goto err; } gsi->gsi_rw_timer_interval = timer_val; err: return count; } static int usb_gsi_rw_timer_show(struct seq_file *s, void *unused) { struct f_gsi *gsi; gsi = get_connected_gsi(); if (!gsi) { log_event_dbg("%s: gsi not connected\n", __func__); return 0; } seq_printf(s, "%ums\n", gsi->gsi_rw_timer_interval); return 0; } static int usb_gsi_rw_timer_open(struct inode *inode, struct file *f) { return single_open(f, usb_gsi_rw_timer_show, inode->i_private); } static const struct file_operations fops_usb_gsi_rw_timer = { .open = usb_gsi_rw_timer_open, .read = seq_read, .write = usb_gsi_rw_timer_write, .owner = THIS_MODULE, .llseek = seq_lseek, .release = seq_release, }; static int usb_gsi_debugfs_init(void) { debugfs.debugfs_root = debugfs_create_dir("usb_gsi", NULL); if (!debugfs.debugfs_root) return -ENOMEM; debugfs_create_file("remote_wakeup_enable", 0600, debugfs.debugfs_root, inst_status, &fops_usb_gsi_rw); debugfs_create_file("remote_wakeup_interval", 0600, debugfs.debugfs_root, inst_status, &fops_usb_gsi_rw_timer); return 0; } static void usb_gsi_debugfs_exit(void) { debugfs_remove_recursive(debugfs.debugfs_root); } /* * Callback for when when network interface is up * and userspace is ready to answer DHCP requests, or remote wakeup Loading Loading @@ -3083,6 +3295,8 @@ static struct f_gsi *gsi_function_init(enum ipa_usb_teth_prot prot_id) kfree(gsi); goto error; } gsi->gsi_rw_timer_interval = DEFAULT_RW_TIMER_INTERVAL; timer_setup(&gsi->gsi_rw_timer, gsi_rw_timer_func, 0); return gsi; error: Loading Loading @@ -3473,6 +3687,7 @@ static int fgsi_init(void) major = MAJOR(dev); usb_gsi_debugfs_init(); return usb_function_register(&gsiusb_func); } module_init(fgsi_init); Loading @@ -3489,5 +3704,6 @@ static void __exit fgsi_exit(void) } class_destroy(gsi_class); usb_gsi_debugfs_exit(); } module_exit(fgsi_exit); drivers/usb/gadget/function/f_gsi.h +7 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/debugfs.h> #include <linux/ipa_usb.h> #include <linux/ipc_logging.h> #include <linux/timer.h> #define GSI_RMNET_CTRL_NAME "rmnet_ctrl" #define GSI_MBIM_CTRL_NAME "android_mbim" Loading Loading @@ -274,6 +275,12 @@ struct f_gsi { struct gsi_ctrl_port c_port; void *ipc_log_ctxt; bool rmnet_dtr_status; /* To test remote wakeup using debugfs */ struct timer_list gsi_rw_timer; u8 debugfs_rw_timer_enable; u16 gsi_rw_timer_interval; }; static inline struct f_gsi *func_to_gsi(struct usb_function *f) Loading Loading
drivers/usb/gadget/function/f_gsi.c +216 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,12 @@ #include "f_gsi.h" #include "rndis.h" struct usb_gsi_debugfs { struct dentry *debugfs_root; }; static struct usb_gsi_debugfs debugfs; static bool qti_packet_debug; module_param(qti_packet_debug, bool, 0644); MODULE_PARM_DESC(qti_packet_debug, "Print QTI Packet's Raw Data"); Loading Loading @@ -173,6 +179,212 @@ static int gsi_wakeup_host(struct f_gsi *gsi) return ret; } static void gsi_rw_timer_func(struct timer_list *t) { struct f_gsi *gsi = from_timer(gsi, t, gsi_rw_timer); if (!atomic_read(&gsi->connected)) { log_event_dbg("%s: gsi not connected.. bail-out\n", __func__); gsi->debugfs_rw_timer_enable = 0; return; } log_event_dbg("%s: calling gsi_wakeup_host\n", __func__); gsi_wakeup_host(gsi); if (gsi->debugfs_rw_timer_enable) { log_event_dbg("%s: re-arm the timer\n", __func__); mod_timer(&gsi->gsi_rw_timer, jiffies + msecs_to_jiffies(gsi->gsi_rw_timer_interval)); } } static struct f_gsi *get_connected_gsi(void) { struct f_gsi *connected_gsi; bool gsi_connected = false; int i; for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++) { if (inst_status[i].opts) connected_gsi = inst_status[i].opts->gsi; else continue; if (connected_gsi && atomic_read(&connected_gsi->connected)) { gsi_connected = true; break; } } if (!gsi_connected) connected_gsi = NULL; return connected_gsi; } #define DEFAULT_RW_TIMER_INTERVAL 500 /* in ms */ static ssize_t usb_gsi_rw_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { struct f_gsi *gsi; u8 input; int ret; gsi = get_connected_gsi(); if (!gsi) { log_event_dbg("%s: gsi not connected\n", __func__); goto err; } if (ubuf == NULL) { log_event_dbg("%s: buffer is Null.\n", __func__); goto err; } ret = kstrtou8_from_user(ubuf, count, 0, &input); if (ret) { log_event_err("%s: Invalid value. err:%d\n", __func__, ret); goto err; } if (gsi->debugfs_rw_timer_enable == !!input) { if (!!input) log_event_dbg("%s: RW already enabled\n", __func__); else log_event_dbg("%s: RW already disabled\n", __func__); goto err; } gsi->debugfs_rw_timer_enable = !!input; if (gsi->debugfs_rw_timer_enable) { mod_timer(&gsi->gsi_rw_timer, jiffies + msecs_to_jiffies(gsi->gsi_rw_timer_interval)); log_event_dbg("%s: timer initialized\n", __func__); } else { del_timer_sync(&gsi->gsi_rw_timer); log_event_dbg("%s: timer deleted\n", __func__); } err: return count; } static int usb_gsi_rw_show(struct seq_file *s, void *unused) { struct f_gsi *gsi; gsi = get_connected_gsi(); if (!gsi) { log_event_dbg("%s: gsi not connected\n", __func__); return 0; } seq_printf(s, "%d\n", gsi->debugfs_rw_timer_enable); return 0; } static int usb_gsi_rw_open(struct inode *inode, struct file *f) { return single_open(f, usb_gsi_rw_show, inode->i_private); } static const struct file_operations fops_usb_gsi_rw = { .open = usb_gsi_rw_open, .read = seq_read, .write = usb_gsi_rw_write, .owner = THIS_MODULE, .llseek = seq_lseek, .release = seq_release, }; static ssize_t usb_gsi_rw_timer_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { struct f_gsi *gsi; u16 timer_val; int ret; gsi = get_connected_gsi(); if (!gsi) { log_event_dbg("%s: gsi not connected\n", __func__); goto err; } if (ubuf == NULL) { log_event_dbg("%s: buffer is NULL.\n", __func__); goto err; } ret = kstrtou16_from_user(ubuf, count, 0, &timer_val); if (ret) { log_event_err("%s: Invalid value. err:%d\n", __func__, ret); goto err; } if (timer_val <= 0 || timer_val > 10000) { log_event_err("%s: value must be > 0 and < 10000.\n", __func__); goto err; } gsi->gsi_rw_timer_interval = timer_val; err: return count; } static int usb_gsi_rw_timer_show(struct seq_file *s, void *unused) { struct f_gsi *gsi; gsi = get_connected_gsi(); if (!gsi) { log_event_dbg("%s: gsi not connected\n", __func__); return 0; } seq_printf(s, "%ums\n", gsi->gsi_rw_timer_interval); return 0; } static int usb_gsi_rw_timer_open(struct inode *inode, struct file *f) { return single_open(f, usb_gsi_rw_timer_show, inode->i_private); } static const struct file_operations fops_usb_gsi_rw_timer = { .open = usb_gsi_rw_timer_open, .read = seq_read, .write = usb_gsi_rw_timer_write, .owner = THIS_MODULE, .llseek = seq_lseek, .release = seq_release, }; static int usb_gsi_debugfs_init(void) { debugfs.debugfs_root = debugfs_create_dir("usb_gsi", NULL); if (!debugfs.debugfs_root) return -ENOMEM; debugfs_create_file("remote_wakeup_enable", 0600, debugfs.debugfs_root, inst_status, &fops_usb_gsi_rw); debugfs_create_file("remote_wakeup_interval", 0600, debugfs.debugfs_root, inst_status, &fops_usb_gsi_rw_timer); return 0; } static void usb_gsi_debugfs_exit(void) { debugfs_remove_recursive(debugfs.debugfs_root); } /* * Callback for when when network interface is up * and userspace is ready to answer DHCP requests, or remote wakeup Loading Loading @@ -3083,6 +3295,8 @@ static struct f_gsi *gsi_function_init(enum ipa_usb_teth_prot prot_id) kfree(gsi); goto error; } gsi->gsi_rw_timer_interval = DEFAULT_RW_TIMER_INTERVAL; timer_setup(&gsi->gsi_rw_timer, gsi_rw_timer_func, 0); return gsi; error: Loading Loading @@ -3473,6 +3687,7 @@ static int fgsi_init(void) major = MAJOR(dev); usb_gsi_debugfs_init(); return usb_function_register(&gsiusb_func); } module_init(fgsi_init); Loading @@ -3489,5 +3704,6 @@ static void __exit fgsi_exit(void) } class_destroy(gsi_class); usb_gsi_debugfs_exit(); } module_exit(fgsi_exit);
drivers/usb/gadget/function/f_gsi.h +7 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/debugfs.h> #include <linux/ipa_usb.h> #include <linux/ipc_logging.h> #include <linux/timer.h> #define GSI_RMNET_CTRL_NAME "rmnet_ctrl" #define GSI_MBIM_CTRL_NAME "android_mbim" Loading Loading @@ -274,6 +275,12 @@ struct f_gsi { struct gsi_ctrl_port c_port; void *ipc_log_ctxt; bool rmnet_dtr_status; /* To test remote wakeup using debugfs */ struct timer_list gsi_rw_timer; u8 debugfs_rw_timer_enable; u16 gsi_rw_timer_interval; }; static inline struct f_gsi *func_to_gsi(struct usb_function *f) Loading