aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorSteve Welch <swelch@systemfabricworks.com>2007-10-23 18:06:10 -0400
committerRoland Dreier <rolandd@cisco.com>2008-01-25 17:15:25 -0500
commit727792da2bc22e2ce125faef84aeca3b3e2f4a90 (patch)
tree8df1442f057fa137679440f7a2aa18c12eb6c01b /drivers/infiniband
parentf9b403532235520ec248c024f621efcaf6ba7b93 (diff)
IB/mad: Enable loopback of DR SMP responses from userspace
The local loopback of an outgoing DR SMP response is limited to those that originate at the driver specific SMA implementation during the driver specific process_mad() function. This patch enables a returning DR SMP originating in userspace (or elsewhere) to be delivered to the local managment stack. In this specific case the driver process_mad() function does not consume or process the MAD, so a reponse mad has not be created and the original MAD must manually be copied to the MAD buffer that is to be handed off to the local agent. Signed-off-by: Steve Welch <swelch@systemfabricworks.com> Acked-by: Hal Rosenstock <hal@xsigo.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/mad.c6
-rw-r--r--drivers/infiniband/core/smi.h18
2 files changed, 20 insertions, 4 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index f82900d30b9a..649335a03312 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -701,7 +701,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
701 } 701 }
702 702
703 /* Check to post send on QP or process locally */ 703 /* Check to post send on QP or process locally */
704 if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD) 704 if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD &&
705 smi_check_local_returning_smp(smp, device) == IB_SMI_DISCARD)
705 goto out; 706 goto out;
706 707
707 local = kmalloc(sizeof *local, GFP_ATOMIC); 708 local = kmalloc(sizeof *local, GFP_ATOMIC);
@@ -752,8 +753,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
752 port_priv = ib_get_mad_port(mad_agent_priv->agent.device, 753 port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
753 mad_agent_priv->agent.port_num); 754 mad_agent_priv->agent.port_num);
754 if (port_priv) { 755 if (port_priv) {
755 mad_priv->mad.mad.mad_hdr.tid = 756 memcpy(&mad_priv->mad.mad, smp, sizeof(struct ib_mad));
756 ((struct ib_mad *)smp)->mad_hdr.tid;
757 recv_mad_agent = find_mad_agent(port_priv, 757 recv_mad_agent = find_mad_agent(port_priv,
758 &mad_priv->mad.mad); 758 &mad_priv->mad.mad);
759 } 759 }
diff --git a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h
index 1cfc2984434f..aff96bac49b4 100644
--- a/drivers/infiniband/core/smi.h
+++ b/drivers/infiniband/core/smi.h
@@ -59,7 +59,8 @@ extern enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
59 u8 node_type, int port_num); 59 u8 node_type, int port_num);
60 60
61/* 61/*
62 * Return 1 if the SMP should be handled by the local SMA/SM via process_mad 62 * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM
63 * via process_mad
63 */ 64 */
64static inline enum smi_action smi_check_local_smp(struct ib_smp *smp, 65static inline enum smi_action smi_check_local_smp(struct ib_smp *smp,
65 struct ib_device *device) 66 struct ib_device *device)
@@ -71,4 +72,19 @@ static inline enum smi_action smi_check_local_smp(struct ib_smp *smp,
71 (smp->hop_ptr == smp->hop_cnt + 1)) ? 72 (smp->hop_ptr == smp->hop_cnt + 1)) ?
72 IB_SMI_HANDLE : IB_SMI_DISCARD); 73 IB_SMI_HANDLE : IB_SMI_DISCARD);
73} 74}
75
76/*
77 * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM
78 * via process_mad
79 */
80static inline enum smi_action smi_check_local_returning_smp(struct ib_smp *smp,
81 struct ib_device *device)
82{
83 /* C14-13:3 -- We're at the end of the DR segment of path */
84 /* C14-13:4 -- Hop Pointer == 0 -> give to SM */
85 return ((device->process_mad &&
86 ib_get_smp_direction(smp) &&
87 !smp->hop_ptr) ? IB_SMI_HANDLE : IB_SMI_DISCARD);
88}
89
74#endif /* __SMI_H_ */ 90#endif /* __SMI_H_ */