diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-28 19:47:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-28 19:47:34 -0400 |
commit | 89fbb69c4f285019ba5e029963dc11cc6beb078a (patch) | |
tree | d918cd1ba0ef9afa692cef281afee2f6d6634a1e /drivers/infiniband/core/mad_rmpp.c | |
parent | 7efe5d7c3e3a82e43b0f8fb29c6797317bce7a9a (diff) | |
parent | 4cce3390c998600f6648e075e475cf8f6dd8cebe (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.c | 114 |
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) | |||
103 | static int data_offset(u8 mgmt_class) | 103 | static 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 | ||
114 | static void format_ack(struct ib_rmpp_mad *ack, | 114 | static 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 | ||
157 | static int alloc_response_msg(struct ib_mad_agent *agent, | 154 | static 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 | ||
183 | static void free_msg(struct ib_mad_send_buf *msg) | 177 | void 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 | ||
189 | static void nack_recv(struct ib_mad_agent_private *agent, | 186 | static 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 | ||
218 | static void recv_timeout_handler(void *data) | 216 | static 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; |
646 | out: | 644 | out: |
@@ -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 */ |