net: qrtr: mhi: synchronize qrtr and mhi preparation

A dl callback can be received anytime after mhi_prepare_for_transfer
has been called. There is a window where the callback may happen
before the probe initializes the qrtr_mhi_dev state. Move
mhi_prepare_for_transfer after the registering the endpoint.

Once moved, the reverse can happen where qrtr will try to send a packet
before the channels are prepared. Add a wait in the sending path to
ensure the channels are prepared before trying to do a ul transfer.

Change-Id: Ib5bf34ec8c1fa56a8ce29c89449d062de7133846
Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
Signed-off-by: Chris Lew <quic_clew@quicinc.com>
This commit is contained in:
Chris Lew 2022-10-11 13:15:10 -07:00
parent 405ddae2c7
commit 3f161d1572

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/mhi.h>
@ -15,6 +16,7 @@ struct qrtr_mhi_dev {
struct qrtr_endpoint ep;
struct mhi_device *mhi_dev;
struct device *dev;
struct completion prepared;
};
/* From MHI to QRTR */
@ -53,6 +55,10 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
if (skb->sk)
sock_hold(skb->sk);
rc = wait_for_completion_interruptible(&qdev->prepared);
if (rc)
goto free_skb;
rc = skb_linearize(skb);
if (rc)
goto free_skb;
@ -85,6 +91,7 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
qdev->mhi_dev = mhi_dev;
qdev->dev = &mhi_dev->dev;
qdev->ep.xmit = qcom_mhi_qrtr_send;
init_completion(&qdev->prepared);
dev_set_drvdata(&mhi_dev->dev, qdev);
rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO);
@ -97,6 +104,7 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev,
qrtr_endpoint_unregister(&qdev->ep);
return rc;
}
complete_all(&qdev->prepared);
dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n");