Merge "msm: ipc: Send Resume_Tx from the client/server context"
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 64986d0..dd90c9e 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -98,6 +98,7 @@
#define IPC_ROUTER_LOG_EVENT_ERROR 0x00
#define IPC_ROUTER_LOG_EVENT_TX 0x01
#define IPC_ROUTER_LOG_EVENT_RX 0x02
+#define IPC_ROUTER_DUMMY_DEST_NODE 0xFFFFFFFF
static LIST_HEAD(control_ports);
static DECLARE_RWSEM(control_ports_lock_lha5);
@@ -926,7 +927,8 @@
static int msm_ipc_router_send_control_msg(
struct msm_ipc_router_xprt_info *xprt_info,
- union rr_control_msg *msg)
+ union rr_control_msg *msg,
+ uint32_t dst_node_id)
{
struct rr_packet *pkt;
struct sk_buff *ipc_rtr_pkt;
@@ -986,7 +988,10 @@
hdr->src_port_id = IPC_ROUTER_ADDRESS;
hdr->confirm_rx = 0;
hdr->size = sizeof(*msg);
- hdr->dst_node_id = xprt_info->remote_node_id;
+ if (hdr->type == IPC_ROUTER_CTRL_CMD_RESUME_TX)
+ hdr->dst_node_id = dst_node_id;
+ else
+ hdr->dst_node_id = xprt_info->remote_node_id;
hdr->dst_port_id = IPC_ROUTER_ADDRESS;
skb_queue_tail(pkt_fragment_q, ipc_rtr_pkt);
pkt->pkt_fragment_q = pkt_fragment_q;
@@ -1031,7 +1036,7 @@
ctl.srv.port_id =
server_port->server_addr.port_id;
msm_ipc_router_send_control_msg(xprt_info,
- &ctl);
+ &ctl, IPC_ROUTER_DUMMY_DEST_NODE);
}
}
}
@@ -1132,7 +1137,8 @@
down_read(&xprt_info_list_lock_lha5);
list_for_each_entry(xprt_info, &xprt_info_list, list) {
- msm_ipc_router_send_control_msg(xprt_info, ctl);
+ msm_ipc_router_send_control_msg(xprt_info, ctl,
+ IPC_ROUTER_DUMMY_DEST_NODE);
}
up_read(&xprt_info_list_lock_lha5);
@@ -1150,7 +1156,8 @@
down_read(&xprt_info_list_lock_lha5);
list_for_each_entry(fwd_xprt_info, &xprt_info_list, list) {
if (xprt_info->xprt->link_id != fwd_xprt_info->xprt->link_id)
- msm_ipc_router_send_control_msg(fwd_xprt_info, ctl);
+ msm_ipc_router_send_control_msg(fwd_xprt_info, ctl,
+ IPC_ROUTER_DUMMY_DEST_NODE);
}
up_read(&xprt_info_list_lock_lha5);
@@ -1252,7 +1259,8 @@
list_for_each_entry(tmp_xprt_info, &xprt_info_list, list) {
if (tmp_xprt_info != xprt_info)
continue;
- msm_ipc_router_send_control_msg(tmp_xprt_info, &msg);
+ msm_ipc_router_send_control_msg(tmp_xprt_info, &msg,
+ IPC_ROUTER_DUMMY_DEST_NODE);
break;
}
up_read(&xprt_info_list_lock_lha5);
@@ -1498,7 +1506,8 @@
/* Send a reply HELLO message */
memset(&ctl, 0, sizeof(ctl));
ctl.cmd = IPC_ROUTER_CTRL_CMD_HELLO;
- rc = msm_ipc_router_send_control_msg(xprt_info, &ctl);
+ rc = msm_ipc_router_send_control_msg(xprt_info, &ctl,
+ IPC_ROUTER_DUMMY_DEST_NODE);
if (rc < 0) {
pr_err("%s: Error sending reply HELLO message\n", __func__);
return rc;
@@ -1751,7 +1760,6 @@
struct msm_ipc_port *port_ptr;
struct sk_buff *head_skb;
struct msm_ipc_router_remote_port *rport_ptr;
- uint32_t resume_tx, resume_tx_node_id, resume_tx_port_id;
struct msm_ipc_router_xprt_info *xprt_info =
container_of(work,
@@ -1814,10 +1822,6 @@
#endif
#endif
- resume_tx = hdr->confirm_rx;
- resume_tx_node_id = hdr->dst_node_id;
- resume_tx_port_id = hdr->dst_port_id;
-
down_read(&local_ports_lock_lha2);
port_ptr = msm_ipc_router_lookup_local_port(hdr->dst_port_id);
if (!port_ptr) {
@@ -1825,7 +1829,7 @@
hdr->dst_port_id);
up_read(&local_ports_lock_lha2);
release_pkt(pkt);
- goto process_done;
+ return;
}
down_read(&routing_table_lock_lha3);
@@ -1841,26 +1845,12 @@
hdr->src_port_id);
up_read(&routing_table_lock_lha3);
up_read(&local_ports_lock_lha2);
- goto process_done;
+ return;
}
}
up_read(&routing_table_lock_lha3);
post_pkt_to_port(port_ptr, pkt, 0);
up_read(&local_ports_lock_lha2);
-
-process_done:
- if (resume_tx) {
- union rr_control_msg msg;
- memset(&msg, 0, sizeof(msg));
- msg.cmd = IPC_ROUTER_CTRL_CMD_RESUME_TX;
- msg.cli.node_id = resume_tx_node_id;
- msg.cli.port_id = resume_tx_port_id;
-
- RR("x RESUME_TX id=%d:%08x\n",
- msg.cli.node_id, msg.cli.port_id);
- msm_ipc_router_send_control_msg(xprt_info, &msg);
- }
-
}
return;
@@ -2239,11 +2229,56 @@
return 0;
}
+/**
+ * msm_ipc_router_send_resume_tx() - Send Resume_Tx message
+ * @data: Pointer to received data packet that has confirm_rx bit set
+ *
+ * @return: On success, number of bytes transferred is returned, else
+ * standard linux error code is returned.
+ *
+ * This function sends the Resume_Tx event to the remote node that
+ * sent the data with confirm_rx field set. In case of a multi-hop
+ * scenario also, this function makes sure that the destination node_id
+ * to which the resume_tx event should reach is right.
+ */
+static int msm_ipc_router_send_resume_tx(void *data)
+{
+ union rr_control_msg msg;
+ struct rr_header *hdr = (struct rr_header *)data;
+ struct msm_ipc_routing_table_entry *rt_entry;
+ int ret;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.cmd = IPC_ROUTER_CTRL_CMD_RESUME_TX;
+ msg.cli.node_id = hdr->dst_node_id;
+ msg.cli.port_id = hdr->dst_port_id;
+ down_read(&routing_table_lock_lha3);
+ rt_entry = lookup_routing_table(hdr->src_node_id);
+ if (!rt_entry) {
+ pr_err("%s: %d Node is not present",
+ __func__, hdr->src_node_id);
+ up_read(&routing_table_lock_lha3);
+ return -ENODEV;
+ }
+ RR("x RESUME_TX id=%d:%08x\n",
+ msg.cli.node_id, msg.cli.port_id);
+ ret = msm_ipc_router_send_control_msg(rt_entry->xprt_info, &msg,
+ hdr->src_node_id);
+ up_read(&routing_table_lock_lha3);
+ if (ret < 0)
+ pr_err("%s: Send Resume_Tx Failed SRC_NODE: %d SRC_PORT: %d DEST_NODE: %d",
+ __func__, hdr->dst_node_id, hdr->dst_port_id,
+ hdr->src_node_id);
+
+ return ret;
+}
+
int msm_ipc_router_read(struct msm_ipc_port *port_ptr,
struct sk_buff_head **data,
size_t buf_len)
{
struct rr_packet *pkt;
+ struct sk_buff *head_skb;
int ret;
if (!port_ptr || !data)
@@ -2265,8 +2300,15 @@
wake_unlock(&port_ptr->port_rx_wake_lock);
*data = pkt->pkt_fragment_q;
ret = pkt->length;
- kfree(pkt);
mutex_unlock(&port_ptr->port_rx_q_lock_lhb3);
+ kfree(pkt);
+ head_skb = skb_peek(*data);
+ if (!head_skb) {
+ pr_err("%s: Socket Buffer not found", __func__);
+ return -EFAULT;
+ }
+ if (((struct rr_header *)(head_skb->data))->confirm_rx)
+ msm_ipc_router_send_resume_tx((void *)(head_skb->data));
return ret;
}