Loading drivers/usb/gadget/function/f_gsi.c +104 −1 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ static void *ipc_log_ctxt; } \ } while (0) static struct class *gsi_class; /* Deregister misc device and free instance structures */ static void gsi_rndis_ipa_reset_trigger(struct gsi_data_port *d_port); static void ipa_disconnect_handler(struct gsi_data_port *d_port); Loading Loading @@ -1591,11 +1593,21 @@ static unsigned int gsi_xfer_bitrate(struct usb_gadget *g) return 19 * 64 * 1 * 1000 * 8; } static void gsi_uevent_work(struct work_struct *w) { struct gsi_ctrl_port *c_port = container_of(w, struct gsi_ctrl_port, uevent_work); if (c_port->dev) kobject_uevent(&c_port->dev->kobj, KOBJ_CHANGE); } static int gsi_function_ctrl_port_init(struct f_gsi *gsi) { int ret; char *cdev_name = NULL; int sz = GSI_CTRL_NAME_LEN; struct device *dev; INIT_LIST_HEAD(&gsi->c_port.cpkt_req_q); INIT_LIST_HEAD(&gsi->c_port.cpkt_resp_q); Loading @@ -1603,6 +1615,9 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi) spin_lock_init(&gsi->c_port.lock); init_waitqueue_head(&gsi->c_port.read_wq); INIT_WORK(&gsi->c_port.uevent_work, gsi_uevent_work); gsi->c_port.dev = NULL; gsi->c_port.uevent_wq = NULL; switch (gsi->prot_id) { case USB_PROT_RMNET_IPA: Loading Loading @@ -1632,6 +1647,10 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi) else strlcat(gsi->c_port.name, cdev_name, sz); gsi->c_port.uevent_wq = alloc_workqueue(gsi->c_port.name, WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE, 1); gsi->c_port.ctrl_device.name = gsi->c_port.name; gsi->c_port.ctrl_device.fops = &gsi_ctrl_dev_fops; gsi->c_port.ctrl_device.minor = MISC_DYNAMIC_MINOR; Loading @@ -1643,6 +1662,17 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi) return ret; } dev = device_create(gsi_class, NULL, MKDEV(0, MISC_DYNAMIC_MINOR), &gsi->c_port, gsi->c_port.name); if (IS_ERR(dev)) { log_event_err("%s: device_create failed for (%s)\n", __func__, gsi->c_port.name); misc_deregister(&gsi->c_port.ctrl_device); return PTR_ERR(dev); } gsi->c_port.dev = dev; return 0; } Loading Loading @@ -2081,6 +2111,10 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) gsi->rmnet_dtr_status = line_state; log_event_dbg("%s: USB_CDC_REQ_SET_CONTROL_LINE_STATE DTR:%d\n", __func__, line_state); if (gsi->c_port.uevent_wq) queue_work(gsi->c_port.uevent_wq, &gsi->c_port.uevent_work); gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); value = 0; break; Loading Loading @@ -2445,6 +2479,9 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, gsi->prot_id == USB_PROT_MBIM_IPA) gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); if (gsi->c_port.uevent_wq) queue_work(gsi->c_port.uevent_wq, &gsi->c_port.uevent_work); return 0; notify_ep_disable: Loading Loading @@ -2478,6 +2515,10 @@ static void gsi_disable(struct usb_function *f) } gsi_ctrl_clear_cpkt_queues(gsi, false); if (gsi->c_port.uevent_wq) queue_work(gsi->c_port.uevent_wq, &gsi->c_port.uevent_work); /* send 0 len pkt to qti/qbi/gps to notify state change */ gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); gsi->c_port.notify_req_queued = false; Loading Loading @@ -3680,11 +3721,27 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, static void gsi_free_inst(struct usb_function_instance *f) { struct gsi_opts *opts = container_of(f, struct gsi_opts, func_inst); struct f_gsi *gsi; if (opts) { if (opts->gsi && opts->gsi->c_port.ctrl_device.fops) misc_deregister(&opts->gsi->c_port.ctrl_device); kfree(opts->interf_group); if (opts->gsi && opts->gsi->c_port.dev) { gsi = opts->gsi; dev_set_drvdata(gsi->c_port.dev, NULL); if (gsi->c_port.uevent_wq) { cancel_work_sync(&gsi->c_port.uevent_work); destroy_workqueue(gsi->c_port.uevent_wq); gsi->c_port.uevent_wq = NULL; } device_destroy(gsi_class, gsi->c_port.dev->devt); gsi->c_port.dev = NULL; } } kfree(opts); Loading Loading @@ -3724,9 +3781,46 @@ DECLARE_USB_FUNCTION(gsi, gsi_alloc_inst, gsi_alloc); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("GSI function driver"); static int usb_gsi_uevent(struct device *dev, struct kobj_uevent_env *env) { struct gsi_ctrl_port *c_port = dev_get_drvdata(dev); struct f_gsi *gsi; char *str = "undefined"; if (!c_port) { dev_dbg(dev, "%s: gsi is not initialized\n", __func__); add_uevent_var(env, "STATE=%s", str); return 0; } gsi = c_port_to_gsi(c_port); switch (gsi->prot_id) { case USB_PROT_RMNET_IPA: case USB_PROT_RMNET_ETHER: str = gsi->rmnet_dtr_status ? "connected" : "disconnected"; break; case USB_PROT_MBIM_IPA: case USB_PROT_DIAG_IPA: case USB_PROT_DPL_ETHER: case USB_PROT_GPS_CTRL: str = atomic_read(&gsi->connected) ? "connected" : "disconnected"; break; default: return 0; } add_uevent_var(env, "STATE=%s", str); log_event_dbg("%s:STATE=%s\n", c_port->name, str); return 0; } static int fgsi_init(void) { int i; int i, ret; ipa_usb_wq = alloc_workqueue("k_ipa_usb", WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE, 1); Loading @@ -3745,6 +3839,15 @@ static int fgsi_init(void) if (!ipc_log_ctxt) pr_err("%s: Err allocating ipc_log_ctxt\n", __func__); gsi_class = class_create(THIS_MODULE, "gsi_usb"); if (IS_ERR(gsi_class)) { ret = PTR_ERR(gsi_class); gsi_class = NULL; pr_err("%s: class_create() failed:%d\n", __func__, ret); return ret; } gsi_class->dev_uevent = usb_gsi_uevent; usb_gsi_debugfs_init(); return usb_function_register(&gsiusb_func); } Loading drivers/usb/gadget/function/f_gsi.h +4 −0 Original line number Diff line number Diff line Loading @@ -218,6 +218,10 @@ struct gsi_ctrl_port { unsigned int modem_to_host; unsigned int cpkt_drop_cnt; unsigned int get_encap_cnt; struct device *dev; struct work_struct uevent_work; struct workqueue_struct *uevent_wq; }; struct gsi_data_port { Loading Loading
drivers/usb/gadget/function/f_gsi.c +104 −1 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ static void *ipc_log_ctxt; } \ } while (0) static struct class *gsi_class; /* Deregister misc device and free instance structures */ static void gsi_rndis_ipa_reset_trigger(struct gsi_data_port *d_port); static void ipa_disconnect_handler(struct gsi_data_port *d_port); Loading Loading @@ -1591,11 +1593,21 @@ static unsigned int gsi_xfer_bitrate(struct usb_gadget *g) return 19 * 64 * 1 * 1000 * 8; } static void gsi_uevent_work(struct work_struct *w) { struct gsi_ctrl_port *c_port = container_of(w, struct gsi_ctrl_port, uevent_work); if (c_port->dev) kobject_uevent(&c_port->dev->kobj, KOBJ_CHANGE); } static int gsi_function_ctrl_port_init(struct f_gsi *gsi) { int ret; char *cdev_name = NULL; int sz = GSI_CTRL_NAME_LEN; struct device *dev; INIT_LIST_HEAD(&gsi->c_port.cpkt_req_q); INIT_LIST_HEAD(&gsi->c_port.cpkt_resp_q); Loading @@ -1603,6 +1615,9 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi) spin_lock_init(&gsi->c_port.lock); init_waitqueue_head(&gsi->c_port.read_wq); INIT_WORK(&gsi->c_port.uevent_work, gsi_uevent_work); gsi->c_port.dev = NULL; gsi->c_port.uevent_wq = NULL; switch (gsi->prot_id) { case USB_PROT_RMNET_IPA: Loading Loading @@ -1632,6 +1647,10 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi) else strlcat(gsi->c_port.name, cdev_name, sz); gsi->c_port.uevent_wq = alloc_workqueue(gsi->c_port.name, WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE, 1); gsi->c_port.ctrl_device.name = gsi->c_port.name; gsi->c_port.ctrl_device.fops = &gsi_ctrl_dev_fops; gsi->c_port.ctrl_device.minor = MISC_DYNAMIC_MINOR; Loading @@ -1643,6 +1662,17 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi) return ret; } dev = device_create(gsi_class, NULL, MKDEV(0, MISC_DYNAMIC_MINOR), &gsi->c_port, gsi->c_port.name); if (IS_ERR(dev)) { log_event_err("%s: device_create failed for (%s)\n", __func__, gsi->c_port.name); misc_deregister(&gsi->c_port.ctrl_device); return PTR_ERR(dev); } gsi->c_port.dev = dev; return 0; } Loading Loading @@ -2081,6 +2111,10 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) gsi->rmnet_dtr_status = line_state; log_event_dbg("%s: USB_CDC_REQ_SET_CONTROL_LINE_STATE DTR:%d\n", __func__, line_state); if (gsi->c_port.uevent_wq) queue_work(gsi->c_port.uevent_wq, &gsi->c_port.uevent_work); gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); value = 0; break; Loading Loading @@ -2445,6 +2479,9 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, gsi->prot_id == USB_PROT_MBIM_IPA) gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); if (gsi->c_port.uevent_wq) queue_work(gsi->c_port.uevent_wq, &gsi->c_port.uevent_work); return 0; notify_ep_disable: Loading Loading @@ -2478,6 +2515,10 @@ static void gsi_disable(struct usb_function *f) } gsi_ctrl_clear_cpkt_queues(gsi, false); if (gsi->c_port.uevent_wq) queue_work(gsi->c_port.uevent_wq, &gsi->c_port.uevent_work); /* send 0 len pkt to qti/qbi/gps to notify state change */ gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0); gsi->c_port.notify_req_queued = false; Loading Loading @@ -3680,11 +3721,27 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, static void gsi_free_inst(struct usb_function_instance *f) { struct gsi_opts *opts = container_of(f, struct gsi_opts, func_inst); struct f_gsi *gsi; if (opts) { if (opts->gsi && opts->gsi->c_port.ctrl_device.fops) misc_deregister(&opts->gsi->c_port.ctrl_device); kfree(opts->interf_group); if (opts->gsi && opts->gsi->c_port.dev) { gsi = opts->gsi; dev_set_drvdata(gsi->c_port.dev, NULL); if (gsi->c_port.uevent_wq) { cancel_work_sync(&gsi->c_port.uevent_work); destroy_workqueue(gsi->c_port.uevent_wq); gsi->c_port.uevent_wq = NULL; } device_destroy(gsi_class, gsi->c_port.dev->devt); gsi->c_port.dev = NULL; } } kfree(opts); Loading Loading @@ -3724,9 +3781,46 @@ DECLARE_USB_FUNCTION(gsi, gsi_alloc_inst, gsi_alloc); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("GSI function driver"); static int usb_gsi_uevent(struct device *dev, struct kobj_uevent_env *env) { struct gsi_ctrl_port *c_port = dev_get_drvdata(dev); struct f_gsi *gsi; char *str = "undefined"; if (!c_port) { dev_dbg(dev, "%s: gsi is not initialized\n", __func__); add_uevent_var(env, "STATE=%s", str); return 0; } gsi = c_port_to_gsi(c_port); switch (gsi->prot_id) { case USB_PROT_RMNET_IPA: case USB_PROT_RMNET_ETHER: str = gsi->rmnet_dtr_status ? "connected" : "disconnected"; break; case USB_PROT_MBIM_IPA: case USB_PROT_DIAG_IPA: case USB_PROT_DPL_ETHER: case USB_PROT_GPS_CTRL: str = atomic_read(&gsi->connected) ? "connected" : "disconnected"; break; default: return 0; } add_uevent_var(env, "STATE=%s", str); log_event_dbg("%s:STATE=%s\n", c_port->name, str); return 0; } static int fgsi_init(void) { int i; int i, ret; ipa_usb_wq = alloc_workqueue("k_ipa_usb", WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE, 1); Loading @@ -3745,6 +3839,15 @@ static int fgsi_init(void) if (!ipc_log_ctxt) pr_err("%s: Err allocating ipc_log_ctxt\n", __func__); gsi_class = class_create(THIS_MODULE, "gsi_usb"); if (IS_ERR(gsi_class)) { ret = PTR_ERR(gsi_class); gsi_class = NULL; pr_err("%s: class_create() failed:%d\n", __func__, ret); return ret; } gsi_class->dev_uevent = usb_gsi_uevent; usb_gsi_debugfs_init(); return usb_function_register(&gsiusb_func); } Loading
drivers/usb/gadget/function/f_gsi.h +4 −0 Original line number Diff line number Diff line Loading @@ -218,6 +218,10 @@ struct gsi_ctrl_port { unsigned int modem_to_host; unsigned int cpkt_drop_cnt; unsigned int get_encap_cnt; struct device *dev; struct work_struct uevent_work; struct workqueue_struct *uevent_wq; }; struct gsi_data_port { Loading