Loading drivers/hwtracing/coresight/coresight-byte-cntr.c +1 −1 Original line number Diff line number Diff line Loading @@ -519,7 +519,7 @@ void usb_bypass_notifier(void *priv, unsigned int event, switch (event) { case USB_QDSS_CONNECT: usb_qdss_alloc_req(ch, USB_BUF_NUM, 0); usb_qdss_alloc_req(ch, USB_BUF_NUM); usb_bypass_start(drvdata); queue_work(drvdata->usb_wq, &(drvdata->read_work)); break; Loading drivers/usb/gadget/function/f_qdss.c +56 −108 Original line number Diff line number Diff line Loading @@ -220,7 +220,8 @@ static void qdss_write_complete(struct usb_ep *ep, struct usb_request *req) { struct f_qdss *qdss = ep->driver_data; struct qdss_request *d_req = req->context; struct qdss_req *qreq = req->context; struct qdss_request *d_req = qreq->qdss_req; struct usb_ep *in; struct list_head *list_pool; enum qdss_state state; Loading @@ -239,7 +240,10 @@ static void qdss_write_complete(struct usb_ep *ep, } spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, list_pool); if (!qdss->debug_inface_enabled) list_del(&qreq->list); list_add_tail(&qreq->list, list_pool); complete(&qreq->write_done); if (req->length != 0) { d_req->actual = req->actual; d_req->status = req->status; Loading @@ -250,32 +254,11 @@ static void qdss_write_complete(struct usb_ep *ep, qdss->ch.notify(qdss->ch.priv, state, d_req, NULL); } static void qdss_ctrl_read_complete(struct usb_ep *ep, struct usb_request *req) { struct f_qdss *qdss = ep->driver_data; struct qdss_request *d_req = req->context; unsigned long flags; pr_debug("%s\n", __func__); d_req->actual = req->actual; d_req->status = req->status; spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->ctrl_read_pool); spin_unlock_irqrestore(&qdss->lock, flags); if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, USB_QDSS_CTRL_READ_DONE, d_req, NULL); } void usb_qdss_free_req(struct usb_qdss_ch *ch) { struct f_qdss *qdss; struct usb_request *req; struct list_head *act, *tmp; struct qdss_req *qreq; pr_debug("%s\n", __func__); Loading @@ -286,33 +269,31 @@ void usb_qdss_free_req(struct usb_qdss_ch *ch) } 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); qreq = list_entry(act, struct qdss_req, list); list_del(&qreq->list); usb_ep_free_request(qdss->port.data, qreq->usb_req); kfree(qreq); } list_for_each_safe(act, tmp, &qdss->ctrl_write_pool) { req = list_entry(act, struct usb_request, list); list_del(&req->list); usb_ep_free_request(qdss->port.ctrl_in, req); } qreq = list_entry(act, struct qdss_req, list); list_del(&qreq->list); usb_ep_free_request(qdss->port.ctrl_in, qreq->usb_req); kfree(qreq); list_for_each_safe(act, tmp, &qdss->ctrl_read_pool) { req = list_entry(act, struct usb_request, list); list_del(&req->list); usb_ep_free_request(qdss->port.ctrl_out, req); } } EXPORT_SYMBOL(usb_qdss_free_req); int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf, int no_read_buf) int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf) { struct f_qdss *qdss = ch->priv_usb; struct usb_request *req; struct usb_ep *in; struct list_head *list_pool; int i; struct qdss_req *qreq; pr_debug("%s\n", __func__); Loading @@ -321,10 +302,8 @@ int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf, 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))) { if ((qdss->debug_inface_enabled && no_write_buf <= 0) || (!qdss->debug_inface_enabled && no_write_buf <= 0)) { pr_err("%s: missing params\n", __func__); return -ENODEV; } Loading @@ -338,23 +317,17 @@ int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf, } for (i = 0; i < no_write_buf; i++) { qreq = kzalloc(sizeof(struct qdss_req), GFP_KERNEL); req = usb_ep_alloc_request(in, GFP_ATOMIC); if (!req) { pr_err("%s: ctrl_in allocation err\n", __func__); goto fail; } qreq->usb_req = req; req->context = qreq; req->complete = qdss_write_complete; list_add_tail(&req->list, list_pool); } for (i = 0; i < no_read_buf; i++) { req = usb_ep_alloc_request(qdss->port.ctrl_out, GFP_ATOMIC); if (!req) { pr_err("%s: ctrl_out allocation err\n", __func__); goto fail; } req->complete = qdss_ctrl_read_complete; list_add_tail(&req->list, &qdss->ctrl_read_pool); list_add_tail(&qreq->list, list_pool); init_completion(&qreq->write_done); } return 0; Loading Loading @@ -807,65 +780,21 @@ static struct f_qdss *alloc_usb_qdss(char *channel_name) spin_unlock_irqrestore(&qdss_lock, flags); spin_lock_init(&qdss->lock); INIT_LIST_HEAD(&qdss->ctrl_read_pool); INIT_LIST_HEAD(&qdss->ctrl_write_pool); INIT_LIST_HEAD(&qdss->data_write_pool); INIT_LIST_HEAD(&qdss->queued_data_pool); INIT_WORK(&qdss->connect_w, usb_qdss_connect_work); INIT_WORK(&qdss->disconnect_w, usb_qdss_disconnect_work); return qdss; } int usb_qdss_ctrl_read(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("%s\n", __func__); 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->ctrl_read_pool)) { spin_unlock_irqrestore(&qdss->lock, flags); pr_err("error: %s list is empty\n", __func__); return -EAGAIN; } req = list_first_entry(&qdss->ctrl_read_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.ctrl_out, req, GFP_ATOMIC)) { /* If error add the link to linked list again*/ spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->ctrl_read_pool); spin_unlock_irqrestore(&qdss->lock, flags); pr_err("qdss usb_ep_queue failed\n"); return -EIO; } return 0; } EXPORT_SYMBOL(usb_qdss_ctrl_read); int usb_qdss_ctrl_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; struct qdss_req *qreq; pr_debug("%s\n", __func__); Loading @@ -885,17 +814,18 @@ int usb_qdss_ctrl_write(struct usb_qdss_ch *ch, struct qdss_request *d_req) return -EAGAIN; } req = list_first_entry(&qdss->ctrl_write_pool, struct usb_request, qreq = list_first_entry(&qdss->ctrl_write_pool, struct qdss_req, list); list_del(&req->list); list_del(&qreq->list); spin_unlock_irqrestore(&qdss->lock, flags); qreq->qdss_req = d_req; req = qreq->usb_req; req->buf = d_req->buf; req->length = d_req->length; req->context = d_req; if (usb_ep_queue(qdss->port.ctrl_in, req, GFP_ATOMIC)) { spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->ctrl_write_pool); list_add_tail(&qreq->list, &qdss->ctrl_write_pool); spin_unlock_irqrestore(&qdss->lock, flags); pr_err("%s usb_ep_queue failed\n", __func__); return -EIO; Loading @@ -910,15 +840,16 @@ 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; struct qdss_req *qreq; pr_debug("usb_qdss_ctrl_write\n"); pr_debug("usb_qdss_data_write\n"); if (!qdss) return -ENODEV; spin_lock_irqsave(&qdss->lock, flags); if (qdss->usb_connected == 0) { if (qdss->qdss_close || qdss->usb_connected == 0) { spin_unlock_irqrestore(&qdss->lock, flags); return -EIO; } Loading @@ -929,20 +860,24 @@ int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req) return -EAGAIN; } req = list_first_entry(&qdss->data_write_pool, struct usb_request, qreq = list_first_entry(&qdss->data_write_pool, struct qdss_req, list); list_del(&req->list); list_move_tail(&qreq->list, &qdss->queued_data_pool); spin_unlock_irqrestore(&qdss->lock, flags); qreq->qdss_req = d_req; req = qreq->usb_req; req->buf = d_req->buf; req->length = d_req->length; req->context = d_req; req->sg = d_req->sg; req->num_sgs = d_req->num_sgs; req->num_mapped_sgs = d_req->num_mapped_sgs; reinit_completion(&qreq->write_done); 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); /* Remove from queued pool and add back to data pool */ list_move_tail(&qreq->list, &qdss->data_write_pool); complete(&qreq->write_done); spin_unlock_irqrestore(&qdss->lock, flags); pr_err("qdss usb_ep_queue failed\n"); return -EIO; Loading Loading @@ -989,6 +924,7 @@ struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, ch->priv = priv; ch->notify = notify; ch->app_conn = 1; qdss->qdss_close = false; spin_unlock_irqrestore(&qdss_lock, flags); /* the case USB cabel was connected before qdss called qdss_open */ Loading @@ -1005,6 +941,7 @@ void usb_qdss_close(struct usb_qdss_ch *ch) struct usb_gadget *gadget; unsigned long flags; int status; struct qdss_req *qreq; pr_debug("%s\n", __func__); Loading @@ -1017,6 +954,17 @@ void usb_qdss_close(struct usb_qdss_ch *ch) } qdss = ch->priv_usb; qdss->qdss_close = true; while (!list_empty(&qdss->queued_data_pool)) { qreq = list_first_entry(&qdss->queued_data_pool, struct qdss_req, list); spin_unlock_irqrestore(&qdss_lock, flags); usb_ep_dequeue(qdss->port.data, qreq->usb_req); wait_for_completion(&qreq->write_done); spin_lock_irqsave(&qdss_lock, flags); } usb_qdss_free_req(ch); ch->priv_usb = NULL; if (!qdss || !qdss->usb_connected || !strcmp(qdss->ch.name, USB_QDSS_CH_MDM)) { Loading drivers/usb/gadget/function/f_qdss.h +2 −1 Original line number Diff line number Diff line Loading @@ -49,11 +49,11 @@ struct f_qdss { bool debug_inface_enabled; struct usb_request *endless_req; struct usb_qdss_ch ch; struct list_head ctrl_read_pool; struct list_head ctrl_write_pool; /* for mdm channel SW path */ struct list_head data_write_pool; struct list_head queued_data_pool; struct work_struct connect_w; struct work_struct disconnect_w; Loading @@ -62,6 +62,7 @@ struct f_qdss { unsigned int ctrl_in_enabled:1; unsigned int ctrl_out_enabled:1; struct workqueue_struct *wq; bool qdss_close; }; struct usb_qdss_opts { Loading include/linux/usb/usb_qdss.h +9 −14 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2013, 2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2012-2013, 2017-2020 The Linux Foundation. All rights reserved. */ #ifndef __LINUX_USB_QDSS_H Loading Loading @@ -42,17 +42,22 @@ enum qdss_state { USB_QDSS_CTRL_WRITE_DONE, }; struct qdss_req { struct usb_request *usb_req; struct completion write_done; struct qdss_request *qdss_req; struct list_head list; }; #if IS_ENABLED(CONFIG_USB_F_QDSS) struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, void (*notify)(void *priv, unsigned int event, struct qdss_request *d_req, struct usb_qdss_ch *ch)); void usb_qdss_close(struct usb_qdss_ch *ch); int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int n_write, int n_read); int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int n_write); void usb_qdss_free_req(struct usb_qdss_ch *ch); int usb_qdss_read(struct usb_qdss_ch *ch, struct qdss_request *d_req); int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req); int usb_qdss_ctrl_write(struct usb_qdss_ch *ch, struct qdss_request *d_req); int usb_qdss_ctrl_read(struct usb_qdss_ch *ch, struct qdss_request *d_req); #else static inline struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, void (*n)(void *, unsigned int event, Loading @@ -61,11 +66,6 @@ static inline struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, return ERR_PTR(-ENODEV); } static inline int usb_qdss_read(struct usb_qdss_ch *c, struct qdss_request *d) { return -ENODEV; } static inline int usb_qdss_write(struct usb_qdss_ch *c, struct qdss_request *d) { return -ENODEV; Loading @@ -77,11 +77,6 @@ static inline int usb_qdss_ctrl_write(struct usb_qdss_ch *c, return -ENODEV; } static inline int usb_qdss_ctrl_read(struct usb_qdss_ch *c, struct qdss_request *d) { return -ENODEV; } static inline int usb_qdss_alloc_req(struct usb_qdss_ch *c, int n_wr, int n_rd) { return -ENODEV; Loading Loading
drivers/hwtracing/coresight/coresight-byte-cntr.c +1 −1 Original line number Diff line number Diff line Loading @@ -519,7 +519,7 @@ void usb_bypass_notifier(void *priv, unsigned int event, switch (event) { case USB_QDSS_CONNECT: usb_qdss_alloc_req(ch, USB_BUF_NUM, 0); usb_qdss_alloc_req(ch, USB_BUF_NUM); usb_bypass_start(drvdata); queue_work(drvdata->usb_wq, &(drvdata->read_work)); break; Loading
drivers/usb/gadget/function/f_qdss.c +56 −108 Original line number Diff line number Diff line Loading @@ -220,7 +220,8 @@ static void qdss_write_complete(struct usb_ep *ep, struct usb_request *req) { struct f_qdss *qdss = ep->driver_data; struct qdss_request *d_req = req->context; struct qdss_req *qreq = req->context; struct qdss_request *d_req = qreq->qdss_req; struct usb_ep *in; struct list_head *list_pool; enum qdss_state state; Loading @@ -239,7 +240,10 @@ static void qdss_write_complete(struct usb_ep *ep, } spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, list_pool); if (!qdss->debug_inface_enabled) list_del(&qreq->list); list_add_tail(&qreq->list, list_pool); complete(&qreq->write_done); if (req->length != 0) { d_req->actual = req->actual; d_req->status = req->status; Loading @@ -250,32 +254,11 @@ static void qdss_write_complete(struct usb_ep *ep, qdss->ch.notify(qdss->ch.priv, state, d_req, NULL); } static void qdss_ctrl_read_complete(struct usb_ep *ep, struct usb_request *req) { struct f_qdss *qdss = ep->driver_data; struct qdss_request *d_req = req->context; unsigned long flags; pr_debug("%s\n", __func__); d_req->actual = req->actual; d_req->status = req->status; spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->ctrl_read_pool); spin_unlock_irqrestore(&qdss->lock, flags); if (qdss->ch.notify) qdss->ch.notify(qdss->ch.priv, USB_QDSS_CTRL_READ_DONE, d_req, NULL); } void usb_qdss_free_req(struct usb_qdss_ch *ch) { struct f_qdss *qdss; struct usb_request *req; struct list_head *act, *tmp; struct qdss_req *qreq; pr_debug("%s\n", __func__); Loading @@ -286,33 +269,31 @@ void usb_qdss_free_req(struct usb_qdss_ch *ch) } 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); qreq = list_entry(act, struct qdss_req, list); list_del(&qreq->list); usb_ep_free_request(qdss->port.data, qreq->usb_req); kfree(qreq); } list_for_each_safe(act, tmp, &qdss->ctrl_write_pool) { req = list_entry(act, struct usb_request, list); list_del(&req->list); usb_ep_free_request(qdss->port.ctrl_in, req); } qreq = list_entry(act, struct qdss_req, list); list_del(&qreq->list); usb_ep_free_request(qdss->port.ctrl_in, qreq->usb_req); kfree(qreq); list_for_each_safe(act, tmp, &qdss->ctrl_read_pool) { req = list_entry(act, struct usb_request, list); list_del(&req->list); usb_ep_free_request(qdss->port.ctrl_out, req); } } EXPORT_SYMBOL(usb_qdss_free_req); int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf, int no_read_buf) int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf) { struct f_qdss *qdss = ch->priv_usb; struct usb_request *req; struct usb_ep *in; struct list_head *list_pool; int i; struct qdss_req *qreq; pr_debug("%s\n", __func__); Loading @@ -321,10 +302,8 @@ int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf, 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))) { if ((qdss->debug_inface_enabled && no_write_buf <= 0) || (!qdss->debug_inface_enabled && no_write_buf <= 0)) { pr_err("%s: missing params\n", __func__); return -ENODEV; } Loading @@ -338,23 +317,17 @@ int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf, } for (i = 0; i < no_write_buf; i++) { qreq = kzalloc(sizeof(struct qdss_req), GFP_KERNEL); req = usb_ep_alloc_request(in, GFP_ATOMIC); if (!req) { pr_err("%s: ctrl_in allocation err\n", __func__); goto fail; } qreq->usb_req = req; req->context = qreq; req->complete = qdss_write_complete; list_add_tail(&req->list, list_pool); } for (i = 0; i < no_read_buf; i++) { req = usb_ep_alloc_request(qdss->port.ctrl_out, GFP_ATOMIC); if (!req) { pr_err("%s: ctrl_out allocation err\n", __func__); goto fail; } req->complete = qdss_ctrl_read_complete; list_add_tail(&req->list, &qdss->ctrl_read_pool); list_add_tail(&qreq->list, list_pool); init_completion(&qreq->write_done); } return 0; Loading Loading @@ -807,65 +780,21 @@ static struct f_qdss *alloc_usb_qdss(char *channel_name) spin_unlock_irqrestore(&qdss_lock, flags); spin_lock_init(&qdss->lock); INIT_LIST_HEAD(&qdss->ctrl_read_pool); INIT_LIST_HEAD(&qdss->ctrl_write_pool); INIT_LIST_HEAD(&qdss->data_write_pool); INIT_LIST_HEAD(&qdss->queued_data_pool); INIT_WORK(&qdss->connect_w, usb_qdss_connect_work); INIT_WORK(&qdss->disconnect_w, usb_qdss_disconnect_work); return qdss; } int usb_qdss_ctrl_read(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("%s\n", __func__); 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->ctrl_read_pool)) { spin_unlock_irqrestore(&qdss->lock, flags); pr_err("error: %s list is empty\n", __func__); return -EAGAIN; } req = list_first_entry(&qdss->ctrl_read_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.ctrl_out, req, GFP_ATOMIC)) { /* If error add the link to linked list again*/ spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->ctrl_read_pool); spin_unlock_irqrestore(&qdss->lock, flags); pr_err("qdss usb_ep_queue failed\n"); return -EIO; } return 0; } EXPORT_SYMBOL(usb_qdss_ctrl_read); int usb_qdss_ctrl_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; struct qdss_req *qreq; pr_debug("%s\n", __func__); Loading @@ -885,17 +814,18 @@ int usb_qdss_ctrl_write(struct usb_qdss_ch *ch, struct qdss_request *d_req) return -EAGAIN; } req = list_first_entry(&qdss->ctrl_write_pool, struct usb_request, qreq = list_first_entry(&qdss->ctrl_write_pool, struct qdss_req, list); list_del(&req->list); list_del(&qreq->list); spin_unlock_irqrestore(&qdss->lock, flags); qreq->qdss_req = d_req; req = qreq->usb_req; req->buf = d_req->buf; req->length = d_req->length; req->context = d_req; if (usb_ep_queue(qdss->port.ctrl_in, req, GFP_ATOMIC)) { spin_lock_irqsave(&qdss->lock, flags); list_add_tail(&req->list, &qdss->ctrl_write_pool); list_add_tail(&qreq->list, &qdss->ctrl_write_pool); spin_unlock_irqrestore(&qdss->lock, flags); pr_err("%s usb_ep_queue failed\n", __func__); return -EIO; Loading @@ -910,15 +840,16 @@ 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; struct qdss_req *qreq; pr_debug("usb_qdss_ctrl_write\n"); pr_debug("usb_qdss_data_write\n"); if (!qdss) return -ENODEV; spin_lock_irqsave(&qdss->lock, flags); if (qdss->usb_connected == 0) { if (qdss->qdss_close || qdss->usb_connected == 0) { spin_unlock_irqrestore(&qdss->lock, flags); return -EIO; } Loading @@ -929,20 +860,24 @@ int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req) return -EAGAIN; } req = list_first_entry(&qdss->data_write_pool, struct usb_request, qreq = list_first_entry(&qdss->data_write_pool, struct qdss_req, list); list_del(&req->list); list_move_tail(&qreq->list, &qdss->queued_data_pool); spin_unlock_irqrestore(&qdss->lock, flags); qreq->qdss_req = d_req; req = qreq->usb_req; req->buf = d_req->buf; req->length = d_req->length; req->context = d_req; req->sg = d_req->sg; req->num_sgs = d_req->num_sgs; req->num_mapped_sgs = d_req->num_mapped_sgs; reinit_completion(&qreq->write_done); 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); /* Remove from queued pool and add back to data pool */ list_move_tail(&qreq->list, &qdss->data_write_pool); complete(&qreq->write_done); spin_unlock_irqrestore(&qdss->lock, flags); pr_err("qdss usb_ep_queue failed\n"); return -EIO; Loading Loading @@ -989,6 +924,7 @@ struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, ch->priv = priv; ch->notify = notify; ch->app_conn = 1; qdss->qdss_close = false; spin_unlock_irqrestore(&qdss_lock, flags); /* the case USB cabel was connected before qdss called qdss_open */ Loading @@ -1005,6 +941,7 @@ void usb_qdss_close(struct usb_qdss_ch *ch) struct usb_gadget *gadget; unsigned long flags; int status; struct qdss_req *qreq; pr_debug("%s\n", __func__); Loading @@ -1017,6 +954,17 @@ void usb_qdss_close(struct usb_qdss_ch *ch) } qdss = ch->priv_usb; qdss->qdss_close = true; while (!list_empty(&qdss->queued_data_pool)) { qreq = list_first_entry(&qdss->queued_data_pool, struct qdss_req, list); spin_unlock_irqrestore(&qdss_lock, flags); usb_ep_dequeue(qdss->port.data, qreq->usb_req); wait_for_completion(&qreq->write_done); spin_lock_irqsave(&qdss_lock, flags); } usb_qdss_free_req(ch); ch->priv_usb = NULL; if (!qdss || !qdss->usb_connected || !strcmp(qdss->ch.name, USB_QDSS_CH_MDM)) { Loading
drivers/usb/gadget/function/f_qdss.h +2 −1 Original line number Diff line number Diff line Loading @@ -49,11 +49,11 @@ struct f_qdss { bool debug_inface_enabled; struct usb_request *endless_req; struct usb_qdss_ch ch; struct list_head ctrl_read_pool; struct list_head ctrl_write_pool; /* for mdm channel SW path */ struct list_head data_write_pool; struct list_head queued_data_pool; struct work_struct connect_w; struct work_struct disconnect_w; Loading @@ -62,6 +62,7 @@ struct f_qdss { unsigned int ctrl_in_enabled:1; unsigned int ctrl_out_enabled:1; struct workqueue_struct *wq; bool qdss_close; }; struct usb_qdss_opts { Loading
include/linux/usb/usb_qdss.h +9 −14 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2012-2013, 2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2012-2013, 2017-2020 The Linux Foundation. All rights reserved. */ #ifndef __LINUX_USB_QDSS_H Loading Loading @@ -42,17 +42,22 @@ enum qdss_state { USB_QDSS_CTRL_WRITE_DONE, }; struct qdss_req { struct usb_request *usb_req; struct completion write_done; struct qdss_request *qdss_req; struct list_head list; }; #if IS_ENABLED(CONFIG_USB_F_QDSS) struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, void (*notify)(void *priv, unsigned int event, struct qdss_request *d_req, struct usb_qdss_ch *ch)); void usb_qdss_close(struct usb_qdss_ch *ch); int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int n_write, int n_read); int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int n_write); void usb_qdss_free_req(struct usb_qdss_ch *ch); int usb_qdss_read(struct usb_qdss_ch *ch, struct qdss_request *d_req); int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req); int usb_qdss_ctrl_write(struct usb_qdss_ch *ch, struct qdss_request *d_req); int usb_qdss_ctrl_read(struct usb_qdss_ch *ch, struct qdss_request *d_req); #else static inline struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, void (*n)(void *, unsigned int event, Loading @@ -61,11 +66,6 @@ static inline struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, return ERR_PTR(-ENODEV); } static inline int usb_qdss_read(struct usb_qdss_ch *c, struct qdss_request *d) { return -ENODEV; } static inline int usb_qdss_write(struct usb_qdss_ch *c, struct qdss_request *d) { return -ENODEV; Loading @@ -77,11 +77,6 @@ static inline int usb_qdss_ctrl_write(struct usb_qdss_ch *c, return -ENODEV; } static inline int usb_qdss_ctrl_read(struct usb_qdss_ch *c, struct qdss_request *d) { return -ENODEV; } static inline int usb_qdss_alloc_req(struct usb_qdss_ch *c, int n_wr, int n_rd) { return -ENODEV; Loading