Print this page
10689 srpt_cm_conn_closed_hdlr() needs a smatch fix
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/comstar/port/srpt/srpt_cm.c
+++ new/usr/src/uts/common/io/comstar/port/srpt/srpt_cm.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 + * Copyright 2019, Joyent, Inc.
28 + */
29 +
30 +/*
27 31 * IB CM handlers for s Solaris SCSI RDMA Protocol Target (SRP)
28 32 * transport port provider module for the COMSTAR framework.
29 33 */
30 34
31 35 #include <sys/cpuvar.h>
32 36 #include <sys/types.h>
33 37 #include <sys/conf.h>
34 38 #include <sys/stat.h>
35 39 #include <sys/file.h>
36 40 #include <sys/ddi.h>
37 41 #include <sys/sunddi.h>
38 42 #include <sys/modctl.h>
39 43 #include <sys/sysmacros.h>
40 44 #include <sys/sdt.h>
41 45 #include <sys/taskq.h>
42 46 #include <sys/ib/ibtl/ibti.h>
43 47
44 48 #include <sys/stmf.h>
45 49 #include <sys/stmf_ioctl.h>
46 50 #include <sys/portif.h>
47 51
48 52 #include "srp.h"
49 53 #include "srpt_impl.h"
50 54 #include "srpt_cm.h"
51 55 #include "srpt_stp.h"
52 56 #include "srpt_ch.h"
53 57
54 58 extern uint16_t srpt_send_msg_depth;
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
55 59 extern srpt_ctxt_t *srpt_ctxt;
56 60
57 61 /*
58 62 * srpt_cm_req_hdlr() - Login request
59 63 *
60 64 * CM has called back with a CM REQ message associated with an
61 65 * SRP initiator login request.
62 66 */
63 67 static ibt_cm_status_t
64 68 srpt_cm_req_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event,
65 - ibt_cm_return_args_t *ret_args, void *ret_priv_data,
66 - ibt_priv_data_len_t ret_priv_data_len)
69 + ibt_cm_return_args_t *ret_args, void *ret_priv_data,
70 + ibt_priv_data_len_t ret_priv_data_len)
67 71 {
68 72 ibt_cm_status_t status;
69 73 ibt_cm_req_rcv_t *req;
70 74 srp_login_req_t login;
71 75 srp_login_rej_t login_rej;
72 76 srp_login_rsp_t login_rsp;
73 77 srpt_channel_t *ch = NULL;
74 78 char remote_gid[SRPT_ALIAS_LEN];
75 79 char local_gid[SRPT_ALIAS_LEN];
76 80
77 81 ASSERT(tgt != NULL);
78 82 req = &event->cm_event.req;
79 83
80 84 if (event->cm_priv_data_len < sizeof (srp_login_req_t)) {
81 85 SRPT_DPRINTF_L2("cm_req_hdlr, IU size expected (>= %d),"
82 86 " received size (%d)", (uint_t)sizeof (srp_login_req_t),
83 87 event->cm_priv_data_len);
84 88 return (IBT_CM_REJECT);
85 89 }
86 90
87 91 if (event->cm_priv_data == NULL) {
88 92 SRPT_DPRINTF_L2("cm_req_hdlr, NULL ULP private data pointer");
89 93 return (IBT_CM_REJECT);
90 94 }
91 95
92 96 if (ret_priv_data_len < sizeof (srp_login_rej_t)) {
93 97 SRPT_DPRINTF_L2("cm_req_hdlr, return private len too"
94 98 " small (%d)", ret_priv_data_len);
95 99 return (IBT_CM_REJECT);
96 100 }
97 101
98 102 if (ret_priv_data == NULL) {
99 103 SRPT_DPRINTF_L2("cm_req_hdlr, NULL ULP return private data"
100 104 " pointer");
101 105 return (IBT_CM_REJECT);
102 106 }
103 107
104 108 /*
105 109 * Copy to avoid potential alignment problems, process login
106 110 * creating a new channel and possibly session.
107 111 */
108 112 bcopy(event->cm_priv_data, &login, sizeof (login));
109 113
110 114 ALIAS_STR(local_gid,
111 115 req->req_prim_addr.av_sgid.gid_prefix,
112 116 req->req_prim_addr.av_sgid.gid_guid);
113 117 ALIAS_STR(remote_gid,
114 118 req->req_prim_addr.av_dgid.gid_prefix,
115 119 req->req_prim_addr.av_dgid.gid_guid);
116 120
117 121 ch = srpt_stp_login(tgt, &login, &login_rsp,
118 122 &login_rej, req->req_prim_hca_port, local_gid, remote_gid);
119 123 if (ch != NULL) {
120 124 bcopy(&login_rsp, ret_priv_data, SRP_LOGIN_RSP_SIZE);
121 125 ret_args->cm_ret_len = SRP_LOGIN_RSP_SIZE;
122 126
123 127 SRPT_DPRINTF_L3("cm_req_hdlr, rsp priv len(%d)"
124 128 " ch created on port(%d)"
125 129 ", cm_req_hdlr, req ra_out(%d), ra_in(%d)"
126 130 ", retry(%d)",
127 131 ret_args->cm_ret_len, req->req_prim_hca_port,
128 132 req->req_rdma_ra_out, req->req_rdma_ra_in,
129 133 req->req_retry_cnt);
130 134
131 135 ret_args->cm_ret.rep.cm_channel = ch->ch_chan_hdl;
132 136 ret_args->cm_ret.rep.cm_rdma_ra_out =
133 137 min(tgt->tp_ioc->ioc_attr.hca_max_rdma_out_chan,
134 138 req->req_rdma_ra_in);
135 139 ret_args->cm_ret.rep.cm_rdma_ra_in =
136 140 min(tgt->tp_ioc->ioc_attr.hca_max_rdma_in_chan,
137 141 req->req_rdma_ra_out);
138 142 ret_args->cm_ret.rep.cm_rnr_retry_cnt = req->req_retry_cnt;
139 143
140 144 SRPT_DPRINTF_L3("cm_req_hdlr, hca_max_rdma_in_chan (%d)"
141 145 ", hca_max_rdma_out_chan (%d)"
142 146 ", updated ra_out(%d), ra_in(%d), retry(%d)",
143 147 tgt->tp_ioc->ioc_attr.hca_max_rdma_in_chan,
144 148 tgt->tp_ioc->ioc_attr.hca_max_rdma_out_chan,
145 149 ret_args->cm_ret.rep.cm_rdma_ra_out,
146 150 ret_args->cm_ret.rep.cm_rdma_ra_in,
147 151 ret_args->cm_ret.rep.cm_rnr_retry_cnt);
148 152 status = IBT_CM_ACCEPT;
149 153
150 154 } else {
151 155 bcopy(&login_rej, ret_priv_data, sizeof (login_rej));
152 156 ret_args->cm_ret_len = sizeof (login_rej);
153 157 status = IBT_CM_REJECT;
154 158 }
155 159
156 160 return (status);
157 161 }
158 162
159 163 /*
160 164 * srpt_cm_conn_est_hdlr() - Connection established
161 165 *
162 166 * CM has called back to inform us that a connection attempt has
163 167 * completed (explicit or implicit) and may now be used.
164 168 */
165 169 /* ARGSUSED */
166 170 static ibt_cm_status_t
167 171 srpt_cm_conn_est_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event)
168 172 {
169 173 srpt_channel_t *ch;
170 174
171 175 ASSERT(tgt != NULL);
172 176 ASSERT(event != NULL);
173 177
174 178 ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
175 179 ASSERT(ch != NULL);
176 180
177 181 SRPT_DPRINTF_L3("cm_conn_est_hdlr, invoked for ch(%p)",
178 182 (void *)ch);
179 183
180 184 rw_enter(&ch->ch_rwlock, RW_WRITER);
181 185 if (ch->ch_state != SRPT_CHANNEL_CONNECTING &&
182 186 ch->ch_state != SRPT_CHANNEL_CONNECTED) {
183 187 SRPT_DPRINTF_L2("cm_conn_est_hdlr, invalid ch state (%d)",
184 188 ch->ch_state);
185 189 rw_exit(&ch->ch_rwlock);
186 190 return (IBT_CM_REJECT);
187 191 }
188 192
189 193 ch->ch_state = SRPT_CHANNEL_CONNECTED;
190 194
191 195 rw_exit(&ch->ch_rwlock);
192 196 return (IBT_CM_ACCEPT);
193 197 }
194 198
195 199 /*
196 200 * srpt_cm_conn_closed_hdlr() - Channel closed
197 201 *
198 202 * CM callback indicating a channel has been completely closed.
199 203 */
200 204 /* ARGSUSED */
201 205 static ibt_cm_status_t
202 206 srpt_cm_conn_closed_hdlr(srpt_target_port_t *tgt, ibt_cm_event_t *event)
203 207 {
204 208 ibt_cm_status_t status = IBT_CM_ACCEPT;
205 209 srpt_channel_t *ch;
206 210
207 211 ASSERT(tgt != NULL);
208 212 ASSERT(event != NULL);
209 213
210 214 ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
211 215 ASSERT(ch != NULL);
212 216
213 217 SRPT_DPRINTF_L3("cm_conn_closed_hdlr, invoked for chan_hdl(%p),"
214 218 " event(%d)", (void *)ch->ch_chan_hdl,
215 219 event->cm_event.closed);
216 220
217 221 switch (event->cm_event.closed) {
218 222
219 223 case IBT_CM_CLOSED_DREP_RCVD:
220 224 case IBT_CM_CLOSED_DREQ_TIMEOUT:
221 225 case IBT_CM_CLOSED_DUP:
222 226 case IBT_CM_CLOSED_ABORT:
223 227 case IBT_CM_CLOSED_ALREADY:
224 228 /*
225 229 * These cases indicate the SRP target initiated
226 230 * the closing of the channel and it is now closed.
227 231 * Cleanup the channel (which will remove the targets
228 232 * reference) and then release CM's reference.
229 233 */
230 234 SRPT_DPRINTF_L3("cm_conn_closed_hdlr, local close call-back");
231 235 srpt_ch_cleanup(ch);
232 236 srpt_ch_release_ref(ch, 1);
233 237 break;
234 238
235 239 case IBT_CM_CLOSED_DREQ_RCVD:
236 240 case IBT_CM_CLOSED_REJ_RCVD:
↓ open down ↓ |
160 lines elided |
↑ open up ↑ |
237 241 case IBT_CM_CLOSED_STALE:
238 242 /*
239 243 * These cases indicate that the SRP initiator is closing
240 244 * the channel. CM will have already closed the RC channel,
241 245 * so simply initiate cleanup which will remove the target
242 246 * ports reference to the channel and then release the
243 247 * reference held by the CM.
244 248 */
245 249 SRPT_DPRINTF_L3("cm_conn_closed_hdlr, remote close,"
246 250 " free channel");
247 - if (ch != NULL) {
248 - srpt_ch_cleanup(ch);
249 - srpt_ch_release_ref(ch, 1);
250 - } else {
251 - SRPT_DPRINTF_L2("cm_conn_closed_hdlr, NULL channel");
252 - }
251 + srpt_ch_cleanup(ch);
252 + srpt_ch_release_ref(ch, 1);
253 253 break;
254 254
255 255 default:
256 256 SRPT_DPRINTF_L2("cm_conn_closed_hdlr, unknown close type (%d)",
257 257 event->cm_event.closed);
258 258 status = IBT_CM_DEFAULT;
259 259 break;
260 260 }
261 261 return (status);
262 262 }
263 263
264 264 /*
265 265 * srpt_cm_failure_hdlr() - Called when the channel is in error. Cleanup
266 266 * and release the channel.
267 267 */
268 268 static ibt_cm_status_t
269 269 srpt_cm_failure_hdlr(ibt_cm_event_t *event)
270 270 {
271 271 srpt_channel_t *ch;
272 272
273 273 ASSERT(event != NULL);
274 274
275 275 ch = (srpt_channel_t *)ibt_get_chan_private(event->cm_channel);
276 276 ASSERT(ch != NULL);
277 277
278 278 SRPT_DPRINTF_L3("cm_failure_hdlr, chan_hdl: 0x%p, code: %d"
279 279 "msg: %d reason: %d", (void *)event->cm_channel,
280 280 event->cm_event.failed.cf_code,
281 281 event->cm_event.failed.cf_msg,
282 282 event->cm_event.failed.cf_reason);
283 283
284 284 srpt_ch_cleanup(ch);
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
285 285 srpt_ch_release_ref(ch, 1);
286 286
287 287 return (IBT_CM_ACCEPT);
288 288 }
289 289
290 290 /*
291 291 * srpt_cm_hdlr() - CM call-back handler.
292 292 */
293 293 ibt_cm_status_t
294 294 srpt_cm_hdlr(void *cm_private, ibt_cm_event_t *event,
295 - ibt_cm_return_args_t *ret_args, void *ret_priv_data,
296 - ibt_priv_data_len_t ret_len_max)
295 + ibt_cm_return_args_t *ret_args, void *ret_priv_data,
296 + ibt_priv_data_len_t ret_len_max)
297 297 {
298 298 ibt_cm_status_t status = IBT_CM_ACCEPT;
299 299
300 300 switch (event->cm_type) {
301 301
302 302 case IBT_CM_EVENT_REQ_RCV:
303 303 SRPT_DPRINTF_L3("cm_hdlr, REQ received");
304 304 status = srpt_cm_req_hdlr((srpt_target_port_t *)cm_private,
305 305 event, ret_args, ret_priv_data, ret_len_max);
306 306 break;
307 307
308 308 case IBT_CM_EVENT_REP_RCV:
309 309 SRPT_DPRINTF_L3("cm_hdlr, REP received");
310 310 break;
311 311
312 312 case IBT_CM_EVENT_MRA_RCV:
313 313 SRPT_DPRINTF_L3("cm_hdlr, MRA received");
314 314 break;
315 315
316 316 case IBT_CM_EVENT_CONN_EST:
317 317 SRPT_DPRINTF_L3("cm_hdlr, Connection established");
318 318 status = srpt_cm_conn_est_hdlr(
319 319 (srpt_target_port_t *)cm_private, event);
320 320 break;
321 321
322 322 case IBT_CM_EVENT_CONN_CLOSED:
323 323 SRPT_DPRINTF_L3("cm_hdlr, Connection closed");
324 324 status = srpt_cm_conn_closed_hdlr(
325 325 (srpt_target_port_t *)cm_private, event);
326 326 break;
327 327
328 328 case IBT_CM_EVENT_FAILURE:
329 329 SRPT_DPRINTF_L3("cm_hdlr, Event failure");
330 330 status = srpt_cm_failure_hdlr(event);
331 331 break;
332 332
333 333 case IBT_CM_EVENT_LAP_RCV:
334 334 SRPT_DPRINTF_L3("cm_hdlr, LAP received");
335 335 break;
336 336
337 337 case IBT_CM_EVENT_APR_RCV:
338 338 SRPT_DPRINTF_L3("cm_hdlr, APR received");
339 339 break;
340 340
341 341 default:
342 342 SRPT_DPRINTF_L3("cm_hdlr, unknown event received");
343 343 break;
344 344 }
345 345
346 346 return (status);
347 347 }
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX