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

Commit 741dd2a9 authored by Mohammed Javid's avatar Mohammed Javid Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: gsb: Block tx data while disconnect in progress



Block tx data while disconnect of ipa gsb bridge in progress.

Change-Id: Id3f20644cb72fb7585be6c26f20024255fcc3252
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent 965d38ea
Loading
Loading
Loading
Loading
+20 −10
Original line number Original line Diff line number Diff line
@@ -160,6 +160,7 @@ struct ipa_gsb_context {
	struct mutex iface_lock[MAX_SUPPORTED_IFACE];
	struct mutex iface_lock[MAX_SUPPORTED_IFACE];
	spinlock_t iface_spinlock[MAX_SUPPORTED_IFACE];
	spinlock_t iface_spinlock[MAX_SUPPORTED_IFACE];
	u32 pm_hdl;
	u32 pm_hdl;
	atomic_t disconnect_in_progress;
};
};


static struct ipa_gsb_context *ipa_gsb_ctx;
static struct ipa_gsb_context *ipa_gsb_ctx;
@@ -922,7 +923,7 @@ static int ipa_gsb_disconnect_sys_pipe(void)


int ipa_bridge_disconnect(u32 hdl)
int ipa_bridge_disconnect(u32 hdl)
{
{
	int ret;
	int ret = 0;


	if (!ipa_gsb_ctx) {
	if (!ipa_gsb_ctx) {
		IPA_GSB_ERR("ipa_gsb_ctx was not initialized\n");
		IPA_GSB_ERR("ipa_gsb_ctx was not initialized\n");
@@ -937,31 +938,33 @@ int ipa_bridge_disconnect(u32 hdl)
	IPA_GSB_DBG("client hdl: %d\n", hdl);
	IPA_GSB_DBG("client hdl: %d\n", hdl);


	mutex_lock(&ipa_gsb_ctx->iface_lock[hdl]);
	mutex_lock(&ipa_gsb_ctx->iface_lock[hdl]);
	atomic_set(&ipa_gsb_ctx->disconnect_in_progress, 1);

	if (!ipa_gsb_ctx->iface[hdl]) {
	if (!ipa_gsb_ctx->iface[hdl]) {
		IPA_GSB_ERR("fail to find interface, hdl: %d\n", hdl);
		IPA_GSB_ERR("fail to find interface, hdl: %d\n", hdl);
		mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
		ret = -EFAULT;
		return -EFAULT;
		goto fail;
	}
	}


	if (!ipa_gsb_ctx->iface[hdl]->is_connected) {
	if (!ipa_gsb_ctx->iface[hdl]->is_connected) {
		IPA_GSB_DBG("iface was not connected\n");
		IPA_GSB_DBG("iface was not connected\n");
		mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
		ret = 0;
		return 0;
		goto fail;
	}
	}


	if (ipa_gsb_ctx->num_connected_iface == 1) {
	if (ipa_gsb_ctx->num_connected_iface == 1) {
		ret = ipa_gsb_disconnect_sys_pipe();
		ret = ipa_gsb_disconnect_sys_pipe();
		if (ret) {
		if (ret) {
			IPA_GSB_ERR("fail to discon pipes\n");
			IPA_GSB_ERR("fail to discon pipes\n");
			mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
			ret = -EFAULT;
			return -EFAULT;
			goto fail;
		}
		}


		ret = ipa_pm_deactivate_sync(ipa_gsb_ctx->pm_hdl);
		ret = ipa_pm_deactivate_sync(ipa_gsb_ctx->pm_hdl);
		if (ret) {
		if (ret) {
			IPA_GSB_ERR("failed to deactivate ipa pm\n");
			IPA_GSB_ERR("failed to deactivate ipa pm\n");
			mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
			ret = -EFAULT;
			return -EFAULT;
			goto fail;
		}
		}
	}
	}


@@ -978,8 +981,10 @@ int ipa_bridge_disconnect(u32 hdl)
			ipa_gsb_ctx->num_resumed_iface);
			ipa_gsb_ctx->num_resumed_iface);
	}
	}


fail:
	atomic_set(&ipa_gsb_ctx->disconnect_in_progress, 0);
	mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
	mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
	return 0;
	return ret;
}
}
EXPORT_SYMBOL(ipa_bridge_disconnect);
EXPORT_SYMBOL(ipa_bridge_disconnect);


@@ -1156,6 +1161,11 @@ int ipa_bridge_tx_dp(u32 hdl, struct sk_buff *skb,
		return -EFAULT;
		return -EFAULT;
	}
	}


	if (unlikely(atomic_read(&ipa_gsb_ctx->disconnect_in_progress))) {
		IPA_GSB_ERR("ipa bridge disconnect_in_progress\n");
		return -EFAULT;
	}

	/* make sure skb has enough headroom */
	/* make sure skb has enough headroom */
	if (unlikely(skb_headroom(skb) < sizeof(struct ipa_gsb_mux_hdr))) {
	if (unlikely(skb_headroom(skb) < sizeof(struct ipa_gsb_mux_hdr))) {
		IPA_GSB_DBG_LOW("skb doesn't have enough headroom\n");
		IPA_GSB_DBG_LOW("skb doesn't have enough headroom\n");