aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/mad_rmpp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 19:47:34 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 19:47:34 -0400
commit89fbb69c4f285019ba5e029963dc11cc6beb078a (patch)
treed918cd1ba0ef9afa692cef281afee2f6d6634a1e /drivers/infiniband/core/mad_rmpp.c
parent7efe5d7c3e3a82e43b0f8fb29c6797317bce7a9a (diff)
parent4cce3390c998600f6648e075e475cf8f6dd8cebe (diff)
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
Diffstat (limited to 'drivers/infiniband/core/mad_rmpp.c')
-rw-r--r--drivers/infiniband/core/mad_rmpp.c114
1 files changed, 52 insertions, 62 deletions
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index e23836d0e21b..3249e1d8c07b 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -103,12 +103,12 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
103static int data_offset(u8 mgmt_class) 103static int data_offset(u8 mgmt_class)
104{ 104{
105 if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) 105 if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
106 return offsetof(struct ib_sa_mad, data); 106 return IB_MGMT_SA_HDR;
107 else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && 107 else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
108 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) 108 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
109 return offsetof(struct ib_vendor_mad, data); 109 return IB_MGMT_VENDOR_HDR;
110 else 110 else
111 return offsetof(struct ib_rmpp_mad, data); 111 return IB_MGMT_RMPP_HDR;
112} 112}
113 113
114static void format_ack(struct ib_rmpp_mad *ack, 114static void format_ack(struct ib_rmpp_mad *ack,
@@ -135,55 +135,52 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
135 struct ib_mad_recv_wc *recv_wc) 135 struct ib_mad_recv_wc *recv_wc)
136{ 136{
137 struct ib_mad_send_buf *msg; 137 struct ib_mad_send_buf *msg;
138 struct ib_send_wr *bad_send_wr; 138 int ret;
139 int hdr_len, ret;
140 139
141 hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
142 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, 140 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
143 recv_wc->wc->pkey_index, rmpp_recv->ah, 1, 141 recv_wc->wc->pkey_index, 1, IB_MGMT_RMPP_HDR,
144 hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len, 142 IB_MGMT_RMPP_DATA, GFP_KERNEL);
145 GFP_KERNEL);
146 if (!msg) 143 if (!msg)
147 return; 144 return;
148 145
149 format_ack((struct ib_rmpp_mad *) msg->mad, 146 format_ack(msg->mad, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad,
150 (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); 147 rmpp_recv);
151 ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr, 148 msg->ah = rmpp_recv->ah;
152 &bad_send_wr); 149 ret = ib_post_send_mad(msg, NULL);
153 if (ret) 150 if (ret)
154 ib_free_send_mad(msg); 151 ib_free_send_mad(msg);
155} 152}
156 153
157static int alloc_response_msg(struct ib_mad_agent *agent, 154static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
158 struct ib_mad_recv_wc *recv_wc, 155 struct ib_mad_recv_wc *recv_wc)
159 struct ib_mad_send_buf **msg)
160{ 156{
161 struct ib_mad_send_buf *m; 157 struct ib_mad_send_buf *msg;
162 struct ib_ah *ah; 158 struct ib_ah *ah;
163 int hdr_len;
164 159
165 ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc, 160 ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc,
166 recv_wc->recv_buf.grh, agent->port_num); 161 recv_wc->recv_buf.grh, agent->port_num);
167 if (IS_ERR(ah)) 162 if (IS_ERR(ah))
168 return PTR_ERR(ah); 163 return (void *) ah;
169 164
170 hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr); 165 msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
171 m = ib_create_send_mad(agent, recv_wc->wc->src_qp, 166 recv_wc->wc->pkey_index, 1,
172 recv_wc->wc->pkey_index, ah, 1, hdr_len, 167 IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA,
173 sizeof(struct ib_rmpp_mad) - hdr_len, 168 GFP_KERNEL);
174 GFP_KERNEL); 169 if (IS_ERR(msg))
175 if (IS_ERR(m)) {
176 ib_destroy_ah(ah); 170 ib_destroy_ah(ah);
177 return PTR_ERR(m); 171 else
178 } 172 msg->ah = ah;
179 *msg = m; 173
180 return 0; 174 return msg;
181} 175}
182 176
183static void free_msg(struct ib_mad_send_buf *msg) 177void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc)
184{ 178{
185 ib_destroy_ah(msg->send_wr.wr.ud.ah); 179 struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad;
186 ib_free_send_mad(msg); 180
181 if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK)
182 ib_destroy_ah(mad_send_wc->send_buf->ah);
183 ib_free_send_mad(mad_send_wc->send_buf);
187} 184}
188 185
189static void nack_recv(struct ib_mad_agent_private *agent, 186static void nack_recv(struct ib_mad_agent_private *agent,
@@ -191,14 +188,13 @@ static void nack_recv(struct ib_mad_agent_private *agent,
191{ 188{
192 struct ib_mad_send_buf *msg; 189 struct ib_mad_send_buf *msg;
193 struct ib_rmpp_mad *rmpp_mad; 190 struct ib_rmpp_mad *rmpp_mad;
194 struct ib_send_wr *bad_send_wr;
195 int ret; 191 int ret;
196 192
197 ret = alloc_response_msg(&agent->agent, recv_wc, &msg); 193 msg = alloc_response_msg(&agent->agent, recv_wc);
198 if (ret) 194 if (IS_ERR(msg))
199 return; 195 return;
200 196
201 rmpp_mad = (struct ib_rmpp_mad *) msg->mad; 197 rmpp_mad = msg->mad;
202 memcpy(rmpp_mad, recv_wc->recv_buf.mad, 198 memcpy(rmpp_mad, recv_wc->recv_buf.mad,
203 data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class)); 199 data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class));
204 200
@@ -210,9 +206,11 @@ static void nack_recv(struct ib_mad_agent_private *agent,
210 rmpp_mad->rmpp_hdr.seg_num = 0; 206 rmpp_mad->rmpp_hdr.seg_num = 0;
211 rmpp_mad->rmpp_hdr.paylen_newwin = 0; 207 rmpp_mad->rmpp_hdr.paylen_newwin = 0;
212 208
213 ret = ib_post_send_mad(&agent->agent, &msg->send_wr, &bad_send_wr); 209 ret = ib_post_send_mad(msg, NULL);
214 if (ret) 210 if (ret) {
215 free_msg(msg); 211 ib_destroy_ah(msg->ah);
212 ib_free_send_mad(msg);
213 }
216} 214}
217 215
218static void recv_timeout_handler(void *data) 216static void recv_timeout_handler(void *data)
@@ -585,7 +583,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
585 int timeout; 583 int timeout;
586 u32 paylen; 584 u32 paylen;
587 585
588 rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr; 586 rmpp_mad = mad_send_wr->send_buf.mad;
589 ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE); 587 ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
590 rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(mad_send_wr->seg_num); 588 rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(mad_send_wr->seg_num);
591 589
@@ -612,7 +610,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
612 } 610 }
613 611
614 /* 2 seconds for an ACK until we can find the packet lifetime */ 612 /* 2 seconds for an ACK until we can find the packet lifetime */
615 timeout = mad_send_wr->send_wr.wr.ud.timeout_ms; 613 timeout = mad_send_wr->send_buf.timeout_ms;
616 if (!timeout || timeout > 2000) 614 if (!timeout || timeout > 2000)
617 mad_send_wr->timeout = msecs_to_jiffies(2000); 615 mad_send_wr->timeout = msecs_to_jiffies(2000);
618 mad_send_wr->seg_num++; 616 mad_send_wr->seg_num++;
@@ -640,7 +638,7 @@ static void abort_send(struct ib_mad_agent_private *agent, __be64 tid,
640 638
641 wc.status = IB_WC_REM_ABORT_ERR; 639 wc.status = IB_WC_REM_ABORT_ERR;
642 wc.vendor_err = rmpp_status; 640 wc.vendor_err = rmpp_status;
643 wc.wr_id = mad_send_wr->wr_id; 641 wc.send_buf = &mad_send_wr->send_buf;
644 ib_mad_complete_send_wr(mad_send_wr, &wc); 642 ib_mad_complete_send_wr(mad_send_wr, &wc);
645 return; 643 return;
646out: 644out:
@@ -694,12 +692,12 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
694 692
695 if (seg_num > mad_send_wr->last_ack) { 693 if (seg_num > mad_send_wr->last_ack) {
696 mad_send_wr->last_ack = seg_num; 694 mad_send_wr->last_ack = seg_num;
697 mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries; 695 mad_send_wr->retries = mad_send_wr->send_buf.retries;
698 } 696 }
699 mad_send_wr->newwin = newwin; 697 mad_send_wr->newwin = newwin;
700 if (mad_send_wr->last_ack == mad_send_wr->total_seg) { 698 if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
701 /* If no response is expected, the ACK completes the send */ 699 /* If no response is expected, the ACK completes the send */
702 if (!mad_send_wr->send_wr.wr.ud.timeout_ms) { 700 if (!mad_send_wr->send_buf.timeout_ms) {
703 struct ib_mad_send_wc wc; 701 struct ib_mad_send_wc wc;
704 702
705 ib_mark_mad_done(mad_send_wr); 703 ib_mark_mad_done(mad_send_wr);
@@ -707,13 +705,13 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
707 705
708 wc.status = IB_WC_SUCCESS; 706 wc.status = IB_WC_SUCCESS;
709 wc.vendor_err = 0; 707 wc.vendor_err = 0;
710 wc.wr_id = mad_send_wr->wr_id; 708 wc.send_buf = &mad_send_wr->send_buf;
711 ib_mad_complete_send_wr(mad_send_wr, &wc); 709 ib_mad_complete_send_wr(mad_send_wr, &wc);
712 return; 710 return;
713 } 711 }
714 if (mad_send_wr->refcount == 1) 712 if (mad_send_wr->refcount == 1)
715 ib_reset_mad_timeout(mad_send_wr, mad_send_wr-> 713 ib_reset_mad_timeout(mad_send_wr,
716 send_wr.wr.ud.timeout_ms); 714 mad_send_wr->send_buf.timeout_ms);
717 } else if (mad_send_wr->refcount == 1 && 715 } else if (mad_send_wr->refcount == 1 &&
718 mad_send_wr->seg_num < mad_send_wr->newwin && 716 mad_send_wr->seg_num < mad_send_wr->newwin &&
719 mad_send_wr->seg_num <= mad_send_wr->total_seg) { 717 mad_send_wr->seg_num <= mad_send_wr->total_seg) {
@@ -842,7 +840,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr)
842 struct ib_rmpp_mad *rmpp_mad; 840 struct ib_rmpp_mad *rmpp_mad;
843 int i, total_len, ret; 841 int i, total_len, ret;
844 842
845 rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr; 843 rmpp_mad = mad_send_wr->send_buf.mad;
846 if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & 844 if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
847 IB_MGMT_RMPP_FLAG_ACTIVE)) 845 IB_MGMT_RMPP_FLAG_ACTIVE))
848 return IB_RMPP_RESULT_UNHANDLED; 846 return IB_RMPP_RESULT_UNHANDLED;
@@ -863,7 +861,7 @@ int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr)
863 861
864 mad_send_wr->total_seg = (total_len - mad_send_wr->data_offset) / 862 mad_send_wr->total_seg = (total_len - mad_send_wr->data_offset) /
865 (sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset); 863 (sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset);
866 mad_send_wr->pad = total_len - offsetof(struct ib_rmpp_mad, data) - 864 mad_send_wr->pad = total_len - IB_MGMT_RMPP_HDR -
867 be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); 865 be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
868 866
869 /* We need to wait for the final ACK even if there isn't a response */ 867 /* We need to wait for the final ACK even if there isn't a response */
@@ -878,23 +876,15 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
878 struct ib_mad_send_wc *mad_send_wc) 876 struct ib_mad_send_wc *mad_send_wc)
879{ 877{
880 struct ib_rmpp_mad *rmpp_mad; 878 struct ib_rmpp_mad *rmpp_mad;
881 struct ib_mad_send_buf *msg;
882 int ret; 879 int ret;
883 880
884 rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr; 881 rmpp_mad = mad_send_wr->send_buf.mad;
885 if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & 882 if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
886 IB_MGMT_RMPP_FLAG_ACTIVE)) 883 IB_MGMT_RMPP_FLAG_ACTIVE))
887 return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */ 884 return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
888 885
889 if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) { 886 if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA)
890 msg = (struct ib_mad_send_buf *) (unsigned long)
891 mad_send_wc->wr_id;
892 if (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_ACK)
893 ib_free_send_mad(msg);
894 else
895 free_msg(msg);
896 return IB_RMPP_RESULT_INTERNAL; /* ACK, STOP, or ABORT */ 887 return IB_RMPP_RESULT_INTERNAL; /* ACK, STOP, or ABORT */
897 }
898 888
899 if (mad_send_wc->status != IB_WC_SUCCESS || 889 if (mad_send_wc->status != IB_WC_SUCCESS ||
900 mad_send_wr->status != IB_WC_SUCCESS) 890 mad_send_wr->status != IB_WC_SUCCESS)
@@ -905,7 +895,7 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
905 895
906 if (mad_send_wr->last_ack == mad_send_wr->total_seg) { 896 if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
907 mad_send_wr->timeout = 897 mad_send_wr->timeout =
908 msecs_to_jiffies(mad_send_wr->send_wr.wr.ud.timeout_ms); 898 msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms);
909 return IB_RMPP_RESULT_PROCESSED; /* Send done */ 899 return IB_RMPP_RESULT_PROCESSED; /* Send done */
910 } 900 }
911 901
@@ -926,7 +916,7 @@ int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr)
926 struct ib_rmpp_mad *rmpp_mad; 916 struct ib_rmpp_mad *rmpp_mad;
927 int ret; 917 int ret;
928 918
929 rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr; 919 rmpp_mad = mad_send_wr->send_buf.mad;
930 if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & 920 if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
931 IB_MGMT_RMPP_FLAG_ACTIVE)) 921 IB_MGMT_RMPP_FLAG_ACTIVE))
932 return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */ 922 return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */