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

Commit bb300aed authored by Chris Lew's avatar Chris Lew
Browse files

net: qrtr: Send BYE message for all nodes on ept



An ept can represent multiple nodes in a system. If an ept unregisters,
qrtr should send a BYE control message for all the nodes that it
represents. Iterate through the node tree to find all the nodes that
belong to the ept.

Change-Id: I641bba615e689f59acecc9ac87fec61c3eecc0d1
Signed-off-by: default avatarChris Lew <clew@codeaurora.org>
parent b92521c1
Loading
Loading
Loading
Loading
+29 −8
Original line number Diff line number Diff line
@@ -638,28 +638,49 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
}
EXPORT_SYMBOL_GPL(qrtr_endpoint_register);

static void qrtr_notify_bye(u32 nid)
{
	struct sockaddr_qrtr src = {AF_QIPCRTR, nid, QRTR_PORT_CTRL};
	struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL};
	struct qrtr_ctrl_pkt *pkt;
	struct sk_buff *skb;

	skb = qrtr_alloc_ctrl_packet(&pkt);
	if (!skb)
		return;

	pkt->cmd = cpu_to_le32(QRTR_TYPE_BYE);
	qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst);
}

/**
 * qrtr_endpoint_unregister - unregister endpoint
 * @ep: endpoint to unregister
 */
void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
{
	struct radix_tree_iter iter;
	struct qrtr_node *node = ep->node;
	struct sockaddr_qrtr src = {AF_QIPCRTR, node->nid, QRTR_PORT_CTRL};
	struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL};
	struct qrtr_ctrl_pkt *pkt;
	struct sk_buff *skb;
	unsigned long flags;
	void __rcu **slot;

	mutex_lock(&node->ep_lock);
	node->ep = NULL;
	mutex_unlock(&node->ep_lock);

	/* Notify the local controller about the event */
	skb = qrtr_alloc_ctrl_packet(&pkt);
	if (skb) {
		pkt->cmd = cpu_to_le32(QRTR_TYPE_BYE);
		qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst);
	down_read(&qrtr_epts_lock);
	spin_lock_irqsave(&qrtr_nodes_lock, flags);
	radix_tree_for_each_slot(slot, &qrtr_nodes, &iter, 0) {
		if (node != *slot)
			continue;

		spin_unlock_irqrestore(&qrtr_nodes_lock, flags);
		qrtr_notify_bye(iter.index);
		spin_lock_irqsave(&qrtr_nodes_lock, flags);
	}
	spin_unlock_irqrestore(&qrtr_nodes_lock, flags);
	up_read(&qrtr_epts_lock);

	/* Wake up any transmitters waiting for resume-tx from the node */
	wake_up_interruptible_all(&node->resume_tx);