Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2bf928b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: f_qdss: Handle async completion of requests during qdss_close"

parents 8fe38a06 8aeb9733
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -423,6 +423,7 @@ static void usb_read_work_fn(struct work_struct *work)
						sizeof(*usb_req), GFP_KERNEL);
			if (!usb_req)
				return;
			init_completion(&usb_req->write_done);
			usb_req->sg = devm_kzalloc(tmcdrvdata->dev,
					sizeof(*(usb_req->sg)) * req_sg_num,
					GFP_KERNEL);
+2 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

#define KMSG_COMPONENT "QDSS diag bridge"
@@ -108,6 +108,7 @@ static int qdss_create_buf_tbl(struct qdss_bridge_drvdata *drvdata)

		buf = kzalloc(drvdata->mtu, GFP_KERNEL);
		usb_req = kzalloc(sizeof(*usb_req), GFP_KERNEL);
		init_completion(&usb_req->write_done);

		entry->buf = buf;
		entry->usb_req = usb_req;
+8 −6
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
/*
 * f_qdss.c -- QDSS function Driver
 *
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/init.h>
@@ -241,6 +241,7 @@ static void qdss_write_complete(struct usb_ep *ep,
	if (!qdss->debug_inface_enabled)
		list_del(&req->list);
	list_add_tail(&req->list, list_pool);
	complete(&d_req->write_done);
	if (req->length != 0) {
		d_req->actual = req->actual;
		d_req->status = req->status;
@@ -925,10 +926,12 @@ int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *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(&d_req->write_done);
	if (usb_ep_queue(qdss->port.data, req, GFP_ATOMIC)) {
		spin_lock_irqsave(&qdss->lock, flags);
		/* Remove from queued pool and add back to data pool */
		list_move_tail(&req->list, &qdss->data_write_pool);
		complete(&d_req->write_done);
		spin_unlock_irqrestore(&qdss->lock, flags);
		pr_err("qdss usb_ep_queue failed\n");
		return -EIO;
@@ -993,6 +996,7 @@ void usb_qdss_close(struct usb_qdss_ch *ch)
	unsigned long flags;
	int status;
	struct usb_request *req;
	struct qdss_request *d_req;

	pr_debug("%s\n", __func__);

@@ -1003,12 +1007,10 @@ void usb_qdss_close(struct usb_qdss_ch *ch)
	while (!list_empty(&qdss->queued_data_pool)) {
		req = list_first_entry(&qdss->queued_data_pool,
				struct usb_request, list);
		d_req = req->context;
		spin_unlock_irqrestore(&qdss_lock, flags);
		if (usb_ep_dequeue(qdss->port.data, req)) {
			spin_lock_irqsave(&qdss_lock, flags);
			list_move_tail(&req->list, &qdss->data_write_pool);
			spin_unlock_irqrestore(&qdss_lock, flags);
		}
		usb_ep_dequeue(qdss->port.data, req);
		wait_for_completion(&d_req->write_done);
		spin_lock_irqsave(&qdss_lock, flags);
	}
	usb_qdss_free_req(ch);
+2 −1
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
@@ -20,6 +20,7 @@ struct qdss_request {
	struct scatterlist *sg;
	unsigned int num_sgs;
	unsigned int num_mapped_sgs;
	struct completion write_done;
};

struct usb_qdss_ch {