Loading drivers/usb/gadget/function/f_qdss.c +119 −25 Original line number Original line Diff line number Diff line Loading @@ -183,15 +183,28 @@ struct usb_qdss_opts *to_fi_usb_qdss_opts(struct usb_function_instance *fi) } } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ static void qdss_ctrl_write_complete(struct usb_ep *ep, static void qdss_write_complete(struct usb_ep *ep, struct usb_request *req) struct usb_request *req) { { struct f_qdss *qdss = ep->driver_data; struct f_qdss *qdss = ep->driver_data; struct qdss_request *d_req = req->context; struct qdss_request *d_req = req->context; struct usb_ep *in; struct list_head *list_pool; enum qdss_state state; unsigned long flags; unsigned long flags; pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); if (qdss->debug_inface_enabled) { in = qdss->port.ctrl_in; list_pool = &qdss->ctrl_write_pool; state = USB_QDSS_CTRL_WRITE_DONE; } else { in = qdss->port.data; list_pool = &qdss->data_write_pool; state = USB_QDSS_DATA_WRITE_DONE; } if (!req->status) { if (!req->status) { /* send zlp */ /* send zlp */ if ((req->length >= ep->maxpacket) && if ((req->length >= ep->maxpacket) && Loading @@ -199,13 +212,13 @@ static void qdss_ctrl_write_complete(struct usb_ep *ep, req->length = 0; req->length = 0; d_req->actual = req->actual; d_req->actual = req->actual; d_req->status = req->status; d_req->status = req->status; if (!usb_ep_queue(qdss->port.ctrl_in, req, GFP_ATOMIC)) if (!usb_ep_queue(in, req, GFP_ATOMIC)) return; return; } } } } spin_lock_irqsave(&qdss->lock, flags); spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->ctrl_write_pool); list_add_tail(&req->list, list_pool); if (req->length != 0) { if (req->length != 0) { d_req->actual = req->actual; d_req->actual = req->actual; d_req->status = req->status; d_req->status = req->status; Loading @@ -213,8 +226,7 @@ static void qdss_ctrl_write_complete(struct usb_ep *ep, spin_unlock_irqrestore(&qdss->lock, flags); spin_unlock_irqrestore(&qdss->lock, flags); if (qdss->ch.notify) if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, USB_QDSS_CTRL_WRITE_DONE, d_req, qdss->ch.notify(qdss->ch.priv, state, d_req, NULL); NULL); } } static void qdss_ctrl_read_complete(struct usb_ep *ep, static void qdss_ctrl_read_complete(struct usb_ep *ep, Loading Loading @@ -252,6 +264,12 @@ void usb_qdss_free_req(struct usb_qdss_ch *ch) return; return; } } list_for_each_safe(act, tmp, &qdss->data_write_pool) { req = list_entry(act, struct usb_request, list); list_del(&req->list); usb_ep_free_request(qdss->port.data, req); } list_for_each_safe(act, tmp, &qdss->ctrl_write_pool) { list_for_each_safe(act, tmp, &qdss->ctrl_write_pool) { req = list_entry(act, struct usb_request, list); req = list_entry(act, struct usb_request, list); list_del(&req->list); list_del(&req->list); Loading @@ -271,23 +289,41 @@ int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf, { { struct f_qdss *qdss = ch->priv_usb; struct f_qdss *qdss = ch->priv_usb; struct usb_request *req; struct usb_request *req; struct usb_ep *in; struct list_head *list_pool; int i; int i; pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); if (no_write_buf <= 0 || no_read_buf <= 0 || !qdss) { if (!qdss) { pr_err("%s: %s closed\n", __func__, ch->name); return -ENODEV; } if ((qdss->debug_inface_enabled && (no_write_buf <= 0 || no_read_buf <= 0)) || (!qdss->debug_inface_enabled && (no_write_buf <= 0 || no_read_buf))) { pr_err("%s: missing params\n", __func__); pr_err("%s: missing params\n", __func__); return -ENODEV; return -ENODEV; } } if (qdss->debug_inface_enabled) { in = qdss->port.ctrl_in; list_pool = &qdss->ctrl_write_pool; } else { in = qdss->port.data; list_pool = &qdss->data_write_pool; } for (i = 0; i < no_write_buf; i++) { for (i = 0; i < no_write_buf; i++) { req = usb_ep_alloc_request(qdss->port.ctrl_in, GFP_ATOMIC); req = usb_ep_alloc_request(in, GFP_ATOMIC); if (!req) { if (!req) { pr_err("%s: ctrl_in allocation err\n", __func__); pr_err("%s: ctrl_in allocation err\n", __func__); goto fail; goto fail; } } req->complete = qdss_ctrl_write_complete; req->complete = qdss_write_complete; list_add_tail(&req->list, &qdss->ctrl_write_pool); list_add_tail(&req->list, list_pool); } } for (i = 0; i < no_read_buf; i++) { for (i = 0; i < no_read_buf; i++) { Loading Loading @@ -378,6 +414,10 @@ static int qdss_bind(struct usb_configuration *c, struct usb_function *f) qdss_ctrl_intf_desc.iInterface = id; qdss_ctrl_intf_desc.iInterface = id; } } /* for non-accelerated path keep tx fifo size 1k */ if (!strcmp(qdss->ch.name, USB_QDSS_CH_MDM)) qdss_data_ep_comp_desc.bMaxBurst = 0; ep = usb_ep_autoconfig_ss(gadget, &qdss_ss_data_desc, ep = usb_ep_autoconfig_ss(gadget, &qdss_ss_data_desc, &qdss_data_ep_comp_desc); &qdss_data_ep_comp_desc); if (!ep) { if (!ep) { Loading Loading @@ -491,21 +531,20 @@ static void usb_qdss_disconnect_work(struct work_struct *work) qdss = container_of(work, struct f_qdss, disconnect_w); qdss = container_of(work, struct f_qdss, disconnect_w); pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); /* * Uninitialized init data i.e. ep specific operation. * Notify qdss to cancel all active transfers. */ if (qdss->ch.app_conn) { status = uninit_data(qdss->port.data); if (status) pr_err("%s: uninit_data error\n", __func__); /* Notify qdss to cancel all active transfers */ if (qdss->ch.notify) if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, qdss->ch.notify(qdss->ch.priv, USB_QDSS_DISCONNECT, USB_QDSS_DISCONNECT, NULL, NULL, NULL); NULL); /* Uninitialized init data i.e. ep specific operation */ if (qdss->ch.app_conn && !strcmp(qdss->ch.name, USB_QDSS_CH_MSM)) { status = uninit_data(qdss->port.data); if (status) pr_err("%s: uninit_data error\n", __func__); status = set_qdss_data_connection(qdss, 0); status = set_qdss_data_connection(qdss, 0); if (status) if (status) pr_err("qdss_disconnect error"); pr_err("qdss_disconnect error"); Loading Loading @@ -562,15 +601,16 @@ static void usb_qdss_connect_work(struct work_struct *work) } } pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); if (!strcmp(qdss->ch.name, USB_QDSS_CH_MDM)) goto notify; status = set_qdss_data_connection(qdss, 1); status = set_qdss_data_connection(qdss, 1); if (status) { if (status) { pr_err("set_qdss_data_connection error(%d)", status); pr_err("set_qdss_data_connection error(%d)", status); return; return; } } if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, USB_QDSS_CONNECT, NULL, &qdss->ch); spin_lock_irqsave(&qdss->lock, flags); spin_lock_irqsave(&qdss->lock, flags); req = qdss->endless_req; req = qdss->endless_req; spin_unlock_irqrestore(&qdss->lock, flags); spin_unlock_irqrestore(&qdss->lock, flags); Loading @@ -578,8 +618,15 @@ static void usb_qdss_connect_work(struct work_struct *work) return; return; status = usb_ep_queue(qdss->port.data, req, GFP_ATOMIC); status = usb_ep_queue(qdss->port.data, req, GFP_ATOMIC); if (status) if (status) { pr_err("%s: usb_ep_queue error (%d)\n", __func__, status); pr_err("%s: usb_ep_queue error (%d)\n", __func__, status); return; } notify: if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, USB_QDSS_CONNECT, NULL, &qdss->ch); } } static int qdss_set_alt(struct usb_function *f, unsigned int intf, static int qdss_set_alt(struct usb_function *f, unsigned int intf, Loading Loading @@ -722,6 +769,7 @@ static struct f_qdss *alloc_usb_qdss(char *channel_name) spin_lock_init(&qdss->lock); spin_lock_init(&qdss->lock); INIT_LIST_HEAD(&qdss->ctrl_read_pool); INIT_LIST_HEAD(&qdss->ctrl_read_pool); INIT_LIST_HEAD(&qdss->ctrl_write_pool); INIT_LIST_HEAD(&qdss->ctrl_write_pool); INIT_LIST_HEAD(&qdss->data_write_pool); INIT_WORK(&qdss->connect_w, usb_qdss_connect_work); INIT_WORK(&qdss->connect_w, usb_qdss_connect_work); INIT_WORK(&qdss->disconnect_w, usb_qdss_disconnect_work); INIT_WORK(&qdss->disconnect_w, usb_qdss_disconnect_work); Loading Loading @@ -817,6 +865,50 @@ int usb_qdss_ctrl_write(struct usb_qdss_ch *ch, struct qdss_request *d_req) } } EXPORT_SYMBOL(usb_qdss_ctrl_write); EXPORT_SYMBOL(usb_qdss_ctrl_write); int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req) { struct f_qdss *qdss = ch->priv_usb; unsigned long flags; struct usb_request *req = NULL; pr_debug("usb_qdss_ctrl_write\n"); if (!qdss) return -ENODEV; spin_lock_irqsave(&qdss->lock, flags); if (qdss->usb_connected == 0) { spin_unlock_irqrestore(&qdss->lock, flags); return -EIO; } if (list_empty(&qdss->data_write_pool)) { pr_err("error: usb_qdss_data_write list is empty\n"); spin_unlock_irqrestore(&qdss->lock, flags); return -EAGAIN; } req = list_first_entry(&qdss->data_write_pool, struct usb_request, list); list_del(&req->list); spin_unlock_irqrestore(&qdss->lock, flags); req->buf = d_req->buf; req->length = d_req->length; req->context = d_req; if (usb_ep_queue(qdss->port.data, req, GFP_ATOMIC)) { spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->data_write_pool); spin_unlock_irqrestore(&qdss->lock, flags); pr_err("qdss usb_ep_queue failed\n"); return -EIO; } return 0; } EXPORT_SYMBOL(usb_qdss_write); struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, void (*notify)(void *priv, unsigned int event, void (*notify)(void *priv, unsigned int event, struct qdss_request *d_req, struct usb_qdss_ch *)) struct qdss_request *d_req, struct usb_qdss_ch *)) Loading Loading @@ -874,7 +966,9 @@ void usb_qdss_close(struct usb_qdss_ch *ch) pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); spin_lock_irqsave(&qdss_lock, flags); spin_lock_irqsave(&qdss_lock, flags); if (!qdss || !qdss->usb_connected) { ch->priv_usb = NULL; if (!qdss || !qdss->usb_connected || !strcmp(qdss->ch.name, USB_QDSS_CH_MDM)) { ch->app_conn = 0; ch->app_conn = 0; spin_unlock_irqrestore(&qdss_lock, flags); spin_unlock_irqrestore(&qdss_lock, flags); return; return; Loading drivers/usb/gadget/function/f_qdss.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -59,6 +59,10 @@ struct f_qdss { struct usb_qdss_ch ch; struct usb_qdss_ch ch; struct list_head ctrl_read_pool; struct list_head ctrl_read_pool; struct list_head ctrl_write_pool; struct list_head ctrl_write_pool; /* for mdm channel SW path */ struct list_head data_write_pool; struct work_struct connect_w; struct work_struct connect_w; struct work_struct disconnect_w; struct work_struct disconnect_w; spinlock_t lock; spinlock_t lock; Loading include/linux/usb/usb_qdss.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -15,6 +15,9 @@ #include <linux/kernel.h> #include <linux/kernel.h> #define USB_QDSS_CH_MDM "qdss_mdm" #define USB_QDSS_CH_MSM "qdss" struct qdss_request { struct qdss_request { char *buf; char *buf; int length; int length; Loading Loading
drivers/usb/gadget/function/f_qdss.c +119 −25 Original line number Original line Diff line number Diff line Loading @@ -183,15 +183,28 @@ struct usb_qdss_opts *to_fi_usb_qdss_opts(struct usb_function_instance *fi) } } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ static void qdss_ctrl_write_complete(struct usb_ep *ep, static void qdss_write_complete(struct usb_ep *ep, struct usb_request *req) struct usb_request *req) { { struct f_qdss *qdss = ep->driver_data; struct f_qdss *qdss = ep->driver_data; struct qdss_request *d_req = req->context; struct qdss_request *d_req = req->context; struct usb_ep *in; struct list_head *list_pool; enum qdss_state state; unsigned long flags; unsigned long flags; pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); if (qdss->debug_inface_enabled) { in = qdss->port.ctrl_in; list_pool = &qdss->ctrl_write_pool; state = USB_QDSS_CTRL_WRITE_DONE; } else { in = qdss->port.data; list_pool = &qdss->data_write_pool; state = USB_QDSS_DATA_WRITE_DONE; } if (!req->status) { if (!req->status) { /* send zlp */ /* send zlp */ if ((req->length >= ep->maxpacket) && if ((req->length >= ep->maxpacket) && Loading @@ -199,13 +212,13 @@ static void qdss_ctrl_write_complete(struct usb_ep *ep, req->length = 0; req->length = 0; d_req->actual = req->actual; d_req->actual = req->actual; d_req->status = req->status; d_req->status = req->status; if (!usb_ep_queue(qdss->port.ctrl_in, req, GFP_ATOMIC)) if (!usb_ep_queue(in, req, GFP_ATOMIC)) return; return; } } } } spin_lock_irqsave(&qdss->lock, flags); spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->ctrl_write_pool); list_add_tail(&req->list, list_pool); if (req->length != 0) { if (req->length != 0) { d_req->actual = req->actual; d_req->actual = req->actual; d_req->status = req->status; d_req->status = req->status; Loading @@ -213,8 +226,7 @@ static void qdss_ctrl_write_complete(struct usb_ep *ep, spin_unlock_irqrestore(&qdss->lock, flags); spin_unlock_irqrestore(&qdss->lock, flags); if (qdss->ch.notify) if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, USB_QDSS_CTRL_WRITE_DONE, d_req, qdss->ch.notify(qdss->ch.priv, state, d_req, NULL); NULL); } } static void qdss_ctrl_read_complete(struct usb_ep *ep, static void qdss_ctrl_read_complete(struct usb_ep *ep, Loading Loading @@ -252,6 +264,12 @@ void usb_qdss_free_req(struct usb_qdss_ch *ch) return; return; } } list_for_each_safe(act, tmp, &qdss->data_write_pool) { req = list_entry(act, struct usb_request, list); list_del(&req->list); usb_ep_free_request(qdss->port.data, req); } list_for_each_safe(act, tmp, &qdss->ctrl_write_pool) { list_for_each_safe(act, tmp, &qdss->ctrl_write_pool) { req = list_entry(act, struct usb_request, list); req = list_entry(act, struct usb_request, list); list_del(&req->list); list_del(&req->list); Loading @@ -271,23 +289,41 @@ int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf, { { struct f_qdss *qdss = ch->priv_usb; struct f_qdss *qdss = ch->priv_usb; struct usb_request *req; struct usb_request *req; struct usb_ep *in; struct list_head *list_pool; int i; int i; pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); if (no_write_buf <= 0 || no_read_buf <= 0 || !qdss) { if (!qdss) { pr_err("%s: %s closed\n", __func__, ch->name); return -ENODEV; } if ((qdss->debug_inface_enabled && (no_write_buf <= 0 || no_read_buf <= 0)) || (!qdss->debug_inface_enabled && (no_write_buf <= 0 || no_read_buf))) { pr_err("%s: missing params\n", __func__); pr_err("%s: missing params\n", __func__); return -ENODEV; return -ENODEV; } } if (qdss->debug_inface_enabled) { in = qdss->port.ctrl_in; list_pool = &qdss->ctrl_write_pool; } else { in = qdss->port.data; list_pool = &qdss->data_write_pool; } for (i = 0; i < no_write_buf; i++) { for (i = 0; i < no_write_buf; i++) { req = usb_ep_alloc_request(qdss->port.ctrl_in, GFP_ATOMIC); req = usb_ep_alloc_request(in, GFP_ATOMIC); if (!req) { if (!req) { pr_err("%s: ctrl_in allocation err\n", __func__); pr_err("%s: ctrl_in allocation err\n", __func__); goto fail; goto fail; } } req->complete = qdss_ctrl_write_complete; req->complete = qdss_write_complete; list_add_tail(&req->list, &qdss->ctrl_write_pool); list_add_tail(&req->list, list_pool); } } for (i = 0; i < no_read_buf; i++) { for (i = 0; i < no_read_buf; i++) { Loading Loading @@ -378,6 +414,10 @@ static int qdss_bind(struct usb_configuration *c, struct usb_function *f) qdss_ctrl_intf_desc.iInterface = id; qdss_ctrl_intf_desc.iInterface = id; } } /* for non-accelerated path keep tx fifo size 1k */ if (!strcmp(qdss->ch.name, USB_QDSS_CH_MDM)) qdss_data_ep_comp_desc.bMaxBurst = 0; ep = usb_ep_autoconfig_ss(gadget, &qdss_ss_data_desc, ep = usb_ep_autoconfig_ss(gadget, &qdss_ss_data_desc, &qdss_data_ep_comp_desc); &qdss_data_ep_comp_desc); if (!ep) { if (!ep) { Loading Loading @@ -491,21 +531,20 @@ static void usb_qdss_disconnect_work(struct work_struct *work) qdss = container_of(work, struct f_qdss, disconnect_w); qdss = container_of(work, struct f_qdss, disconnect_w); pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); /* * Uninitialized init data i.e. ep specific operation. * Notify qdss to cancel all active transfers. */ if (qdss->ch.app_conn) { status = uninit_data(qdss->port.data); if (status) pr_err("%s: uninit_data error\n", __func__); /* Notify qdss to cancel all active transfers */ if (qdss->ch.notify) if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, qdss->ch.notify(qdss->ch.priv, USB_QDSS_DISCONNECT, USB_QDSS_DISCONNECT, NULL, NULL, NULL); NULL); /* Uninitialized init data i.e. ep specific operation */ if (qdss->ch.app_conn && !strcmp(qdss->ch.name, USB_QDSS_CH_MSM)) { status = uninit_data(qdss->port.data); if (status) pr_err("%s: uninit_data error\n", __func__); status = set_qdss_data_connection(qdss, 0); status = set_qdss_data_connection(qdss, 0); if (status) if (status) pr_err("qdss_disconnect error"); pr_err("qdss_disconnect error"); Loading Loading @@ -562,15 +601,16 @@ static void usb_qdss_connect_work(struct work_struct *work) } } pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); if (!strcmp(qdss->ch.name, USB_QDSS_CH_MDM)) goto notify; status = set_qdss_data_connection(qdss, 1); status = set_qdss_data_connection(qdss, 1); if (status) { if (status) { pr_err("set_qdss_data_connection error(%d)", status); pr_err("set_qdss_data_connection error(%d)", status); return; return; } } if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, USB_QDSS_CONNECT, NULL, &qdss->ch); spin_lock_irqsave(&qdss->lock, flags); spin_lock_irqsave(&qdss->lock, flags); req = qdss->endless_req; req = qdss->endless_req; spin_unlock_irqrestore(&qdss->lock, flags); spin_unlock_irqrestore(&qdss->lock, flags); Loading @@ -578,8 +618,15 @@ static void usb_qdss_connect_work(struct work_struct *work) return; return; status = usb_ep_queue(qdss->port.data, req, GFP_ATOMIC); status = usb_ep_queue(qdss->port.data, req, GFP_ATOMIC); if (status) if (status) { pr_err("%s: usb_ep_queue error (%d)\n", __func__, status); pr_err("%s: usb_ep_queue error (%d)\n", __func__, status); return; } notify: if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, USB_QDSS_CONNECT, NULL, &qdss->ch); } } static int qdss_set_alt(struct usb_function *f, unsigned int intf, static int qdss_set_alt(struct usb_function *f, unsigned int intf, Loading Loading @@ -722,6 +769,7 @@ static struct f_qdss *alloc_usb_qdss(char *channel_name) spin_lock_init(&qdss->lock); spin_lock_init(&qdss->lock); INIT_LIST_HEAD(&qdss->ctrl_read_pool); INIT_LIST_HEAD(&qdss->ctrl_read_pool); INIT_LIST_HEAD(&qdss->ctrl_write_pool); INIT_LIST_HEAD(&qdss->ctrl_write_pool); INIT_LIST_HEAD(&qdss->data_write_pool); INIT_WORK(&qdss->connect_w, usb_qdss_connect_work); INIT_WORK(&qdss->connect_w, usb_qdss_connect_work); INIT_WORK(&qdss->disconnect_w, usb_qdss_disconnect_work); INIT_WORK(&qdss->disconnect_w, usb_qdss_disconnect_work); Loading Loading @@ -817,6 +865,50 @@ int usb_qdss_ctrl_write(struct usb_qdss_ch *ch, struct qdss_request *d_req) } } EXPORT_SYMBOL(usb_qdss_ctrl_write); EXPORT_SYMBOL(usb_qdss_ctrl_write); int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req) { struct f_qdss *qdss = ch->priv_usb; unsigned long flags; struct usb_request *req = NULL; pr_debug("usb_qdss_ctrl_write\n"); if (!qdss) return -ENODEV; spin_lock_irqsave(&qdss->lock, flags); if (qdss->usb_connected == 0) { spin_unlock_irqrestore(&qdss->lock, flags); return -EIO; } if (list_empty(&qdss->data_write_pool)) { pr_err("error: usb_qdss_data_write list is empty\n"); spin_unlock_irqrestore(&qdss->lock, flags); return -EAGAIN; } req = list_first_entry(&qdss->data_write_pool, struct usb_request, list); list_del(&req->list); spin_unlock_irqrestore(&qdss->lock, flags); req->buf = d_req->buf; req->length = d_req->length; req->context = d_req; if (usb_ep_queue(qdss->port.data, req, GFP_ATOMIC)) { spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->data_write_pool); spin_unlock_irqrestore(&qdss->lock, flags); pr_err("qdss usb_ep_queue failed\n"); return -EIO; } return 0; } EXPORT_SYMBOL(usb_qdss_write); struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, void (*notify)(void *priv, unsigned int event, void (*notify)(void *priv, unsigned int event, struct qdss_request *d_req, struct usb_qdss_ch *)) struct qdss_request *d_req, struct usb_qdss_ch *)) Loading Loading @@ -874,7 +966,9 @@ void usb_qdss_close(struct usb_qdss_ch *ch) pr_debug("%s\n", __func__); pr_debug("%s\n", __func__); spin_lock_irqsave(&qdss_lock, flags); spin_lock_irqsave(&qdss_lock, flags); if (!qdss || !qdss->usb_connected) { ch->priv_usb = NULL; if (!qdss || !qdss->usb_connected || !strcmp(qdss->ch.name, USB_QDSS_CH_MDM)) { ch->app_conn = 0; ch->app_conn = 0; spin_unlock_irqrestore(&qdss_lock, flags); spin_unlock_irqrestore(&qdss_lock, flags); return; return; Loading
drivers/usb/gadget/function/f_qdss.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -59,6 +59,10 @@ struct f_qdss { struct usb_qdss_ch ch; struct usb_qdss_ch ch; struct list_head ctrl_read_pool; struct list_head ctrl_read_pool; struct list_head ctrl_write_pool; struct list_head ctrl_write_pool; /* for mdm channel SW path */ struct list_head data_write_pool; struct work_struct connect_w; struct work_struct connect_w; struct work_struct disconnect_w; struct work_struct disconnect_w; spinlock_t lock; spinlock_t lock; Loading
include/linux/usb/usb_qdss.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -15,6 +15,9 @@ #include <linux/kernel.h> #include <linux/kernel.h> #define USB_QDSS_CH_MDM "qdss_mdm" #define USB_QDSS_CH_MSM "qdss" struct qdss_request { struct qdss_request { char *buf; char *buf; int length; int length; Loading