Print this page
XXXX introduce drv_sectohz
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/comstar/port/srpt/srpt_stp.c
+++ new/usr/src/uts/common/io/comstar/port/srpt/srpt_stp.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
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 27 * SCSI Target Port I/F for Solaris SCSI RDMA Protocol Target (SRP)
28 28 * port provider module for the COMSTAR framework.
29 29 */
30 30
31 31 #include <sys/cpuvar.h>
32 32 #include <sys/types.h>
33 33 #include <sys/conf.h>
34 34 #include <sys/stat.h>
35 35 #include <sys/file.h>
36 36 #include <sys/ddi.h>
37 37 #include <sys/sunddi.h>
38 38 #include <sys/modctl.h>
39 39 #include <sys/sysmacros.h>
40 40 #include <sys/sdt.h>
41 41 #include <sys/taskq.h>
42 42 #include <sys/atomic.h>
43 43
44 44 #include <sys/stmf.h>
45 45 #include <sys/stmf_ioctl.h>
46 46 #include <sys/portif.h>
47 47
48 48 #include <sys/scsi/generic/persist.h>
49 49 #include <sys/ib/mgt/ibdma/ibdma.h>
50 50
51 51 #include "srp.h"
52 52 #include "srpt_impl.h"
53 53 #include "srpt_cm.h"
54 54 #include "srpt_ioc.h"
55 55 #include "srpt_ch.h"
56 56 #include "srpt_stp.h"
57 57
58 58 extern srpt_ctxt_t *srpt_ctxt;
59 59 extern uint32_t srpt_iu_size;
60 60
61 61 /*
62 62 * STMF LPort Interface Prototypes
63 63 */
64 64 static stmf_status_t srpt_stp_xfer_data(struct scsi_task *task,
65 65 struct stmf_data_buf *dbuf, uint32_t ioflags);
66 66 stmf_status_t srpt_stp_send_status(struct scsi_task *task,
67 67 uint32_t ioflags);
68 68 static void srpt_stp_task_free(struct scsi_task *task);
69 69 static stmf_status_t srpt_stp_abort(struct stmf_local_port *lport,
70 70 int abort_cmd, void *arg, uint32_t flags);
71 71 static void srpt_stp_task_poll(struct scsi_task *task);
72 72 static void srpt_stp_ctl(struct stmf_local_port *lport,
73 73 int cmd, void *arg);
74 74 static stmf_status_t srpt_stp_info(uint32_t cmd,
75 75 struct stmf_local_port *lport, void *arg, uint8_t *buf,
76 76 uint32_t *bufsizep);
77 77 static void srpt_stp_event_handler(struct stmf_local_port *lport,
78 78 int eventid, void *arg, uint32_t flags);
79 79
80 80 static void srpt_format_login_rsp(srp_login_req_t *req,
81 81 srp_login_rsp_t *rsp, uint8_t flags);
82 82 static void srpt_format_login_rej(srp_login_req_t *req,
83 83 srp_login_rej_t *rej, uint32_t reason);
84 84
85 85 static scsi_devid_desc_t *srpt_stp_alloc_scsi_devid_desc(uint64_t guid);
86 86 static void srpt_stp_free_scsi_devid_desc(scsi_devid_desc_t *sdd);
87 87
88 88 extern uint16_t srpt_send_msg_depth;
89 89
90 90 /*
91 91 * srpt_stp_start_srp() - Start SRP service
92 92 *
93 93 * Enable the SRP service for the specified SCSI Target Port.
94 94 */
95 95 int
96 96 srpt_stp_start_srp(srpt_target_port_t *tgt)
97 97 {
98 98 ibt_status_t status;
99 99 ibdma_status_t dma_status;
100 100 int port;
101 101 srpt_ioc_t *ioc;
102 102
103 103 if (tgt == NULL) {
104 104 SRPT_DPRINTF_L1("stp_start_srp, NULL SCSI target port");
105 105 return (IBT_FAILURE);
106 106 }
107 107
108 108 if (tgt->tp_ioc == NULL) {
109 109 SRPT_DPRINTF_L1("stp_start_srp, SCSI target port NULL"
110 110 " IOC pointer");
111 111 return (IBT_FAILURE);
112 112 }
113 113 ioc = tgt->tp_ioc;
114 114
115 115 SRPT_DPRINTF_L2("stp_start_srp, register SRP service for"
116 116 " svc_id (%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
117 117 status = ibt_register_service(srpt_ctxt->sc_ibt_hdl,
118 118 &tgt->tp_ibt_svc_desc, tgt->tp_ibt_svc_id, 1,
119 119 &tgt->tp_ibt_svc_hdl, NULL);
120 120 if (status != IBT_SUCCESS) {
121 121 tgt->tp_ibt_svc_hdl = NULL;
122 122 SRPT_DPRINTF_L1("stp_start_srp, SRP service creation err (%d)",
123 123 status);
124 124 return (status);
125 125 }
126 126
127 127 /*
128 128 * Bind the service associated with the SCSI target port to
129 129 * each active port of the I/O Controller.
130 130 */
131 131 for (port = 0; port < ioc->ioc_attr.hca_nports; port++) {
132 132 status = srpt_ioc_svc_bind(tgt, port+1);
133 133 if (status != IBT_SUCCESS &&
134 134 status != IBT_HCA_PORT_NOT_ACTIVE) {
135 135 SRPT_DPRINTF_L1("start_srp, Unable to bind"
136 136 " service (%d)", status);
137 137 goto srp_start_err;
138 138 }
139 139 }
140 140
141 141 /* don't online if we have no active ports */
142 142 if (tgt->tp_num_active_ports == 0) {
143 143 SRPT_DPRINTF_L2("start_srp, no ports active for svc_id %016llx",
144 144 (u_longlong_t)tgt->tp_ibt_svc_id);
145 145 status = IBT_HCA_PORT_NOT_ACTIVE;
146 146 goto srp_start_err;
147 147 }
148 148
149 149 tgt->tp_srp_enabled = 1;
150 150
151 151 /*
152 152 * Calculate the new I/O Controller profile and either update the
153 153 * profile if previously registered or register it with the IB
154 154 * Device Management Agent.
155 155 */
156 156 SRPT_DPRINTF_L3("start_srp, update I/O Controller profile (%016llx)",
157 157 (u_longlong_t)ioc->ioc_guid);
158 158
159 159 srpt_ioc_init_profile(ioc);
160 160 if (ioc->ioc_ibdma_hdl == NULL) {
161 161 ioc->ioc_ibdma_hdl =
162 162 srpt_ctxt->sc_ibdma_ops.ibdma_register(ioc->ioc_guid,
163 163 &ioc->ioc_profile, &ioc->ioc_svc);
164 164 if (ioc->ioc_ibdma_hdl == NULL) {
165 165 SRPT_DPRINTF_L1("start_srp, Unable to register"
166 166 " I/O Profile for svc_id %016llx",
167 167 (u_longlong_t)tgt->tp_ibt_svc_id);
168 168 status = IBT_FAILURE;
169 169 goto srp_start_err;
170 170 }
171 171 } else {
172 172 dma_status =
173 173 srpt_ctxt->sc_ibdma_ops.ibdma_update(ioc->ioc_ibdma_hdl,
174 174 &ioc->ioc_profile, &ioc->ioc_svc);
175 175 if (dma_status != IBDMA_SUCCESS) {
176 176 SRPT_DPRINTF_L1("start_srp, Unable to update I/O"
177 177 " Profile for svc_id %016llxi (%d)",
178 178 (u_longlong_t)tgt->tp_ibt_svc_id, dma_status);
179 179 status = IBT_FAILURE;
180 180 goto srp_start_err;
181 181 }
182 182 }
183 183
184 184 return (IBT_SUCCESS);
185 185
186 186 srp_start_err:
187 187 tgt->tp_srp_enabled = 0;
188 188 srpt_ioc_svc_unbind_all(tgt);
189 189 tgt->tp_num_active_ports = 0;
190 190 if (tgt->tp_ibt_svc_hdl != NULL) {
191 191 (void) ibt_deregister_service(srpt_ctxt->sc_ibt_hdl,
192 192 tgt->tp_ibt_svc_hdl);
193 193 tgt->tp_ibt_svc_hdl = NULL;
194 194 }
195 195 return (status);
196 196 }
197 197
198 198 /*
199 199 * srpt_stp_stop_srp() - Stop SRP service.
200 200 *
201 201 * Disable the SRP service on the specified SCSI Target Port.
202 202 */
203 203 void
204 204 srpt_stp_stop_srp(srpt_target_port_t *tgt)
205 205 {
206 206 ibt_status_t status;
207 207 ibdma_status_t dma_status;
208 208 srpt_ioc_t *ioc;
209 209 srpt_channel_t *ch;
210 210
211 211 if (tgt == NULL) {
212 212 SRPT_DPRINTF_L2("stp_stop_srp, NULL SCSI Target Port"
213 213 " specified");
214 214 return;
215 215 }
216 216
217 217 if (tgt->tp_ioc == NULL) {
218 218 SRPT_DPRINTF_L2("stp_stop_srp, bad Target, IOC NULL");
219 219 return;
220 220 }
221 221 ioc = tgt->tp_ioc;
222 222
223 223 /*
224 224 * Update the I/O Controller profile to remove the SRP service
225 225 * for this SCSI target port.
226 226 */
227 227 tgt->tp_srp_enabled = 0;
228 228
229 229 if (ioc->ioc_ibdma_hdl != NULL) {
230 230 SRPT_DPRINTF_L3("stp_stop_srp, update I/O Controller"
231 231 " profile (%016llx)", (u_longlong_t)ioc->ioc_guid);
232 232 srpt_ioc_init_profile(ioc);
233 233
234 234 if (ioc->ioc_profile.ioc_service_entries == 0) {
235 235 SRPT_DPRINTF_L3("stp_stop_srp, no services active"
236 236 " unregister IOC profile");
237 237 srpt_ctxt->sc_ibdma_ops.ibdma_unregister(
238 238 ioc->ioc_ibdma_hdl);
239 239 ioc->ioc_ibdma_hdl = NULL;
240 240 } else {
241 241 dma_status = srpt_ctxt->sc_ibdma_ops.ibdma_update(
242 242 ioc->ioc_ibdma_hdl, &ioc->ioc_profile,
243 243 &ioc->ioc_svc);
244 244 if (dma_status != IBDMA_SUCCESS) {
245 245 SRPT_DPRINTF_L1("stp_stop_srp, Unable to"
246 246 " update I/O Profile (%d)", dma_status);
247 247 return;
248 248 }
249 249 }
250 250 }
251 251
252 252 /*
253 253 * Unbind the SRP service associated with the SCSI target port
254 254 * from all of the I/O Controller physical ports.
255 255 */
256 256 SRPT_DPRINTF_L2("stp_stop_srp, unbind and de-register service"
257 257 "(%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
258 258 if (tgt->tp_ibt_svc_hdl != NULL) {
259 259 srpt_ioc_svc_unbind_all(tgt);
260 260 }
261 261
262 262 if (tgt->tp_ibt_svc_hdl != NULL) {
263 263 status = ibt_deregister_service(srpt_ctxt->sc_ibt_hdl,
264 264 tgt->tp_ibt_svc_hdl);
265 265 if (status != IBT_SUCCESS) {
266 266 SRPT_DPRINTF_L1("stp_stop_srp, de-register service"
267 267 " error(%d)", status);
268 268 }
269 269 tgt->tp_ibt_svc_hdl = NULL;
270 270 }
271 271
272 272 /*
273 273 * SRP service is now off-line for this SCSI Target Port.
274 274 * We force a disconnect (i.e. SRP Target Logout) for any
275 275 * active SRP logins.
276 276 */
277 277 mutex_enter(&tgt->tp_ch_list_lock);
278 278 ch = list_head(&tgt->tp_ch_list);
279 279 while (ch != NULL) {
280 280 SRPT_DPRINTF_L3("stp_stop_srp, disconnect ch(%p)",
281 281 (void *)ch);
282 282 srpt_ch_disconnect(ch);
283 283 ch = list_next(&tgt->tp_ch_list, ch);
284 284 }
285 285 mutex_exit(&tgt->tp_ch_list_lock);
286 286
287 287 /*
288 288 * wait for all sessions to terminate before returning
289 289 */
290 290 mutex_enter(&tgt->tp_sess_list_lock);
291 291 while (!list_is_empty(&tgt->tp_sess_list)) {
292 292 cv_wait(&tgt->tp_sess_complete, &tgt->tp_sess_list_lock);
293 293 }
294 294 mutex_exit(&tgt->tp_sess_list_lock);
295 295 }
296 296
297 297 /*
298 298 * srpt_stp_alloc_port() - Allocate SCSI Target Port
299 299 */
300 300 srpt_target_port_t *
301 301 srpt_stp_alloc_port(srpt_ioc_t *ioc, ib_guid_t guid)
302 302 {
303 303 stmf_status_t status;
304 304 srpt_target_port_t *tgt;
305 305 stmf_local_port_t *lport;
306 306 uint64_t temp;
307 307
308 308 if (ioc == NULL) {
309 309 SRPT_DPRINTF_L1("stp_alloc_port, NULL I/O Controller");
310 310 return (NULL);
311 311 }
312 312
313 313 SRPT_DPRINTF_L3("stp_alloc_port, allocate STMF local port");
314 314 lport = stmf_alloc(STMF_STRUCT_STMF_LOCAL_PORT, sizeof (*tgt), 0);
315 315 if (lport == NULL) {
316 316 SRPT_DPRINTF_L1("tgt_alloc_port, stmf_alloc failed");
317 317 return (NULL);
318 318 }
319 319
320 320 tgt = lport->lport_port_private;
321 321 ASSERT(tgt != NULL);
322 322
323 323 mutex_init(&tgt->tp_lock, NULL, MUTEX_DRIVER, NULL);
324 324
325 325 mutex_init(&tgt->tp_ch_list_lock, NULL, MUTEX_DRIVER, NULL);
326 326 cv_init(&tgt->tp_offline_complete, NULL, CV_DRIVER, NULL);
327 327 list_create(&tgt->tp_ch_list, sizeof (srpt_channel_t),
328 328 offsetof(srpt_channel_t, ch_stp_node));
329 329
330 330 mutex_init(&tgt->tp_sess_list_lock, NULL, MUTEX_DRIVER, NULL);
331 331 cv_init(&tgt->tp_sess_complete, NULL, CV_DRIVER, NULL);
332 332 list_create(&tgt->tp_sess_list, sizeof (srpt_session_t),
333 333 offsetof(srpt_session_t, ss_node));
334 334
335 335 tgt->tp_state = SRPT_TGT_STATE_OFFLINE;
336 336 tgt->tp_drv_disabled = 0;
337 337 tgt->tp_srp_enabled = 0;
338 338 tgt->tp_lport = lport;
339 339 tgt->tp_ioc = ioc;
340 340 tgt->tp_ibt_svc_id = guid;
341 341 tgt->tp_ibt_svc_desc.sd_handler = srpt_cm_hdlr;
342 342 tgt->tp_ibt_svc_desc.sd_flags = IBT_SRV_NO_FLAGS;
343 343 temp = h2b64(tgt->tp_ibt_svc_id);
344 344 bcopy(&temp, &tgt->tp_srp_port_id[0], 8);
345 345 temp = h2b64(tgt->tp_ioc->ioc_guid);
346 346 bcopy(&temp, &tgt->tp_srp_port_id[8], 8);
347 347
348 348 tgt->tp_nports = ioc->ioc_attr.hca_nports;
349 349 tgt->tp_hw_port =
350 350 kmem_zalloc(sizeof (srpt_hw_port_t) * tgt->tp_nports, KM_SLEEP);
351 351 tgt->tp_num_active_ports = 0;
352 352 tgt->tp_requested_state = SRPT_TGT_STATE_OFFLINE;
353 353
354 354 tgt->tp_scsi_devid = srpt_stp_alloc_scsi_devid_desc(tgt->tp_ibt_svc_id);
355 355
356 356 lport->lport_id = tgt->tp_scsi_devid;
357 357 lport->lport_pp = srpt_ctxt->sc_pp;
358 358 lport->lport_ds = ioc->ioc_stmf_ds;
359 359 lport->lport_xfer_data = &srpt_stp_xfer_data;
360 360 lport->lport_send_status = &srpt_stp_send_status;
361 361 lport->lport_task_free = &srpt_stp_task_free;
362 362 lport->lport_abort = &srpt_stp_abort;
363 363 lport->lport_abort_timeout = 300; /* 5 minutes */
364 364 lport->lport_task_poll = &srpt_stp_task_poll;
365 365 lport->lport_ctl = &srpt_stp_ctl;
366 366 lport->lport_info = &srpt_stp_info;
367 367 lport->lport_event_handler = &srpt_stp_event_handler;
368 368
369 369 /* set up as alua participating port */
370 370 stmf_set_port_alua(lport);
371 371
372 372 SRPT_DPRINTF_L3("stp_alloc_port, register STMF LPORT");
373 373
374 374 retry_registration:
375 375 status = stmf_register_local_port(lport);
376 376 if (status == STMF_SUCCESS) {
377 377 SRPT_DPRINTF_L3("stp_alloc_port, LPORT successfully"
↓ open down ↓ |
377 lines elided |
↑ open up ↑ |
378 378 " registered");
379 379 return (tgt);
380 380 }
381 381
382 382 if (status == STMF_BUSY) {
383 383 /*
384 384 * This is only done on an administrative thread of
385 385 * execution so it is ok to take a while.
386 386 */
387 387 SRPT_DPRINTF_L3("stp_alloc_port, delaying");
388 - delay(2 * drv_usectohz(1000000));
388 + delay(drv_sectohz(2));
389 389 goto retry_registration;
390 390 }
391 391 SRPT_DPRINTF_L1("stp_alloc_port, STMF register local port err(0x%llx)",
392 392 (u_longlong_t)status);
393 393
394 394 SRPT_DPRINTF_L3("stp_alloc_port, free STMF local port");
395 395 cv_destroy(&tgt->tp_offline_complete);
396 396 mutex_destroy(&tgt->tp_ch_list_lock);
397 397 mutex_destroy(&tgt->tp_lock);
398 398 if (tgt->tp_hw_port) {
399 399 kmem_free(tgt->tp_hw_port,
400 400 sizeof (srpt_hw_port_t) * tgt->tp_nports);
401 401 }
402 402 if (tgt->tp_scsi_devid) {
403 403 srpt_stp_free_scsi_devid_desc(tgt->tp_scsi_devid);
404 404 }
405 405
406 406 stmf_free(lport);
407 407
408 408 return (NULL);
409 409 }
410 410
411 411 /*
412 412 * srpt_stp_free_port() - Free SCSI Target Port
413 413 */
414 414 stmf_status_t
415 415 srpt_stp_free_port(srpt_target_port_t *tgt)
416 416 {
417 417 ASSERT(tgt != NULL);
418 418 ASSERT(list_is_empty(&tgt->tp_sess_list));
419 419 ASSERT(list_is_empty(&tgt->tp_ch_list));
420 420
421 421 list_destroy(&tgt->tp_ch_list);
422 422 list_destroy(&tgt->tp_sess_list);
423 423
424 424 cv_destroy(&tgt->tp_sess_complete);
425 425 cv_destroy(&tgt->tp_offline_complete);
426 426
427 427 mutex_destroy(&tgt->tp_sess_list_lock);
428 428 mutex_destroy(&tgt->tp_ch_list_lock);
429 429 mutex_destroy(&tgt->tp_lock);
430 430
431 431
432 432 SRPT_DPRINTF_L3("stp_free_port, free STMF local port");
433 433 if (tgt->tp_hw_port) {
434 434 kmem_free(tgt->tp_hw_port,
435 435 sizeof (srpt_hw_port_t) * tgt->tp_nports);
436 436 }
437 437
438 438 if (tgt->tp_scsi_devid) {
439 439 srpt_stp_free_scsi_devid_desc(tgt->tp_scsi_devid);
440 440 }
441 441
442 442 stmf_free(tgt->tp_lport);
443 443
444 444 return (STMF_SUCCESS);
445 445 }
446 446
447 447 /*
448 448 * srpt_stp_destroy_port()
449 449 */
450 450 stmf_status_t
451 451 srpt_stp_destroy_port(srpt_target_port_t *tgt)
452 452 {
453 453 stmf_status_t status;
454 454 stmf_change_status_t cstatus;
455 455 uint64_t guid;
456 456
457 457 ASSERT(tgt != NULL);
458 458 ASSERT(tgt->tp_lport != NULL);
459 459
460 460 SRPT_DPRINTF_L3("stp_destroy_port, de-register STMF LPORT");
461 461
462 462 mutex_enter(&tgt->tp_lock);
463 463 if (tgt->tp_drv_disabled != 0) {
464 464 /* already being destroyed, get out now - should not happen */
465 465 mutex_exit(&tgt->tp_lock);
466 466 return (STMF_ALREADY);
467 467 }
468 468
469 469 tgt->tp_drv_disabled = 1;
470 470 guid = tgt->tp_ioc->ioc_guid;
471 471 mutex_exit(&tgt->tp_lock);
472 472
473 473 SRPT_DPRINTF_L2("stp_destroy_port: unbind and de-register"
474 474 " services for GUID(%016llx)", (u_longlong_t)guid);
475 475
476 476 cstatus.st_completion_status = STMF_SUCCESS;
477 477 cstatus.st_additional_info = NULL;
478 478
479 479 status = stmf_ctl(STMF_CMD_LPORT_OFFLINE, tgt->tp_lport, &cstatus);
480 480
481 481 /*
482 482 * Wait for asynchronous target off-line operation
483 483 * to complete and then deregister the target
484 484 * port.
485 485 */
486 486 mutex_enter(&tgt->tp_lock);
487 487 while (tgt->tp_state != SRPT_TGT_STATE_OFFLINE) {
488 488 cv_wait(&tgt->tp_offline_complete, &tgt->tp_lock);
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
489 489 }
490 490 mutex_exit(&tgt->tp_lock);
491 491
492 492 SRPT_DPRINTF_L3("stp_destroy_port: IOC (0x%016llx) Target"
493 493 " SRP off-line complete", (u_longlong_t)guid);
494 494
495 495 /* loop waiting for all I/O to drain */
496 496 for (;;) {
497 497 status = stmf_deregister_local_port(tgt->tp_lport);
498 498 if (status == STMF_BUSY) {
499 - delay(drv_usectohz(1000000));
499 + delay(drv_sectohz(1));
500 500 } else {
501 501 break;
502 502 }
503 503 }
504 504
505 505 if (status == STMF_SUCCESS) {
506 506 SRPT_DPRINTF_L3("stp_destroy_port, LPORT de-register"
507 507 " complete");
508 508 } else {
509 509 /*
510 510 * Something other than a BUSY error, this should not happen.
511 511 */
512 512 SRPT_DPRINTF_L1(
513 513 "stp_destroy_port, de-register STMF error(0x%llx)",
514 514 (u_longlong_t)status);
515 515 }
516 516
517 517 return (status);
518 518 }
519 519
520 520 /*
521 521 * srpt_stp_xfer_data()
522 522 */
523 523 /* ARGSUSED */
524 524 static stmf_status_t
525 525 srpt_stp_xfer_data(struct scsi_task *task, struct stmf_data_buf *dbuf,
526 526 uint32_t ioflags)
527 527 {
528 528 srpt_iu_t *iu;
529 529 srpt_channel_t *ch;
530 530 srpt_ds_dbuf_t *db;
531 531 ibt_send_wr_t wr;
532 532 ibt_wr_ds_t ds;
533 533 ibt_status_t status;
534 534 uint32_t xfer_len;
535 535 uint32_t xferred_len;
536 536 uint32_t rdma_len;
537 537 uint32_t base_offset;
538 538 uint32_t desc_offset;
539 539 srp_direct_desc_t *desc;
540 540
541 541 SRPT_DPRINTF_L3("stp_xfer_data, invoked task (%p), dbuf (%p)",
542 542 (void *)task, (void *)dbuf);
543 543 iu = task->task_port_private;
544 544 ASSERT(iu != NULL);
545 545 ASSERT(iu->iu_ch != NULL);
546 546 /*
547 547 * We should use iu->iu_ch->ch_swqe_posted to throttle
548 548 * send wqe posting. This is very unlikely because we limit
549 549 * the maximum number of initiator descriptors per IU (impact
550 550 * of fragmentation of intiator buffer space) but it could occur
551 551 * if the back-end (STMF) were to use too many small buffers. In
552 552 * that case we would want to return STMF_BUSY.
553 553 */
554 554
555 555 SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_flags (0x%x)",
556 556 dbuf->db_flags);
557 557 SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_data_size (%d)",
558 558 dbuf->db_data_size);
559 559 SRPT_DPRINTF_L4("stp_xfer_data, dbuf->db_relative_offset (%d)",
560 560 dbuf->db_relative_offset);
561 561
562 562 ASSERT((dbuf->db_flags & (DB_DIRECTION_TO_RPORT |
563 563 DB_DIRECTION_FROM_RPORT)) != (DB_DIRECTION_TO_RPORT |
564 564 DB_DIRECTION_FROM_RPORT));
565 565
566 566 db = dbuf->db_port_private;
567 567
568 568 /*
569 569 * Check to see if request will overflow the remote buffer; if so
570 570 * return a bad status and let STMF abort the task.
571 571 */
572 572 if ((dbuf->db_relative_offset + dbuf->db_data_size) >
573 573 iu->iu_tot_xfer_len) {
574 574 SRPT_DPRINTF_L2("stp_xfer_data, overflow of remote buffer");
575 575 return (STMF_FAILURE);
576 576 }
577 577
578 578 db->db_iu = iu;
579 579 wr.wr_trans = IBT_RC_SRV;
580 580 wr.wr_opcode = (dbuf->db_flags & DB_DIRECTION_TO_RPORT) ?
581 581 IBT_WRC_RDMAW : IBT_WRC_RDMAR;
582 582 wr.wr_nds = 1;
583 583 wr.wr_sgl = &ds;
584 584
585 585 /*
586 586 * We know that the data transfer is within the bounds described
587 587 * by our list of remote buffer descriptors. Find the starting
588 588 * point based on the offset for the transfer, then perform the
589 589 * RDMA operations required of this transfer.
590 590 */
591 591 base_offset = 0;
592 592 desc = iu->iu_rdescs;
593 593
594 594 while ((base_offset + desc->dd_len) < dbuf->db_relative_offset) {
595 595 base_offset += desc->dd_len;
596 596 desc++;
597 597 }
598 598
599 599 xfer_len = dbuf->db_data_size;
600 600 xferred_len = 0;
601 601 desc_offset = dbuf->db_relative_offset - base_offset;
602 602
603 603 ch = iu->iu_ch;
604 604
605 605 /*
606 606 * If the channel is no longer connected then return an
607 607 * error and do not initiate I/O. STMF should abort the
608 608 * task.
609 609 */
610 610 rw_enter(&ch->ch_rwlock, RW_READER);
611 611
612 612 if (iu->iu_ch->ch_state == SRPT_CHANNEL_DISCONNECTING) {
613 613 rw_exit(&iu->iu_ch->ch_rwlock);
614 614 return (STMF_FAILURE);
615 615 }
616 616
617 617 while (xfer_len > 0) {
618 618 rdma_len = desc->dd_len - desc_offset;
619 619
620 620 /*
621 621 * We only generate completion entries on the last IB
622 622 * operation associated with any STMF buffer.
623 623 */
624 624 if (rdma_len >= xfer_len) {
625 625 rdma_len = xfer_len;
626 626 wr.wr_flags = IBT_WR_SEND_SIGNAL;
627 627 } else {
628 628 wr.wr_flags = IBT_WR_NO_FLAGS;
629 629 }
630 630
631 631 wr.wr.rc.rcwr.rdma.rdma_raddr = desc->dd_vaddr + desc_offset;
632 632 wr.wr.rc.rcwr.rdma.rdma_rkey = desc->dd_hdl;
633 633 ds.ds_va = db->db_sge.ds_va + xferred_len;
634 634 ds.ds_key = db->db_sge.ds_key;
635 635 ds.ds_len = rdma_len;
636 636
637 637 SRPT_DPRINTF_L4("stp_xfer_data, post RDMA operation");
638 638
639 639 /*
640 640 * If this task is being aborted or has been aborted,
641 641 * do not post additional I/O.
642 642 */
643 643 DTRACE_SRP_8(xfer__start, srpt_channel_t, ch,
644 644 ibt_wr_ds_t, &(db->db_sge), srpt_iu_t, iu,
645 645 ibt_send_wr_t, &wr, uint32_t, rdma_len,
646 646 uint32_t, xferred_len, uint32_t, desc_offset,
647 647 uint32_t, wr.wr_opcode == IBT_WRC_RDMAR ? 0 : 1);
648 648 mutex_enter(&iu->iu_lock);
649 649 if ((iu->iu_flags & (SRPT_IU_SRP_ABORTING |
650 650 SRPT_IU_STMF_ABORTING | SRPT_IU_ABORTED)) != 0) {
651 651 mutex_exit(&iu->iu_lock);
652 652 rw_exit(&iu->iu_ch->ch_rwlock);
653 653 return (STMF_SUCCESS);
654 654 }
655 655
656 656 /*
657 657 * If a non-error CQE will be requested, add a reference to
658 658 * the IU and initialize the work request appropriately.
659 659 */
660 660 if ((wr.wr_flags & IBT_WR_SEND_SIGNAL) != 0) {
661 661 wr.wr_id = srpt_ch_alloc_swqe_wrid(ch,
662 662 SRPT_SWQE_TYPE_DATA, (void *)dbuf);
663 663 if (wr.wr_id == 0) {
664 664 rw_exit(&iu->iu_ch->ch_rwlock);
665 665 mutex_exit(&iu->iu_lock);
666 666 return (STMF_BUSY);
667 667 }
668 668 atomic_inc_32(&iu->iu_sq_posted_cnt);
669 669 } else {
670 670 wr.wr_id = 0;
671 671 }
672 672
673 673 status = ibt_post_send(iu->iu_ch->ch_chan_hdl, &wr, 1, NULL);
674 674 mutex_exit(&iu->iu_lock);
675 675
676 676 if (status != IBT_SUCCESS) {
677 677 /*
678 678 * Could not post to IB transport, report to STMF and
679 679 * and let it initiate an abort of the task.
680 680 */
681 681 SRPT_DPRINTF_L2("stp_xfer_data, post RDMA"
682 682 " error (%d)", status);
683 683
684 684 if ((wr.wr_flags & IBT_WR_SEND_SIGNAL) != 0) {
685 685 srpt_ch_free_swqe_wrid(ch, wr.wr_id);
686 686 atomic_dec_32(&iu->iu_sq_posted_cnt);
687 687 }
688 688 rw_exit(&iu->iu_ch->ch_rwlock);
689 689 return (STMF_FAILURE);
690 690 }
691 691 xferred_len += rdma_len;
692 692 xfer_len -= rdma_len;
693 693 desc_offset = 0;
694 694 desc++;
695 695 }
696 696
697 697 rw_exit(&ch->ch_rwlock);
698 698 return (STMF_SUCCESS);
699 699 }
700 700
701 701 /*
702 702 * srpt_stp_send_mgmt_response() - Return SRP task managment response IU
703 703 */
704 704 ibt_status_t
705 705 srpt_stp_send_mgmt_response(srpt_iu_t *iu, uint8_t srp_rsp,
706 706 uint_t fence)
707 707 {
708 708 srp_rsp_t *rsp;
709 709 srp_rsp_data_t *data;
710 710 uint32_t rsp_length;
711 711 ibt_status_t status;
712 712 uint8_t *bufp;
713 713
714 714 ASSERT(mutex_owned(&iu->iu_lock));
715 715 rsp = iu->iu_buf;
716 716 bufp = (uint8_t *)iu->iu_buf + SRP_RSP_SIZE;
717 717 bzero(rsp, SRP_RSP_SIZE + sizeof (srp_rsp_data_t));
718 718 rsp->rsp_type = SRP_IU_RSP;
719 719
720 720 /*
721 721 * Report ULP credits we have added since last response sent
722 722 * over this channel.
723 723 */
724 724 rsp->rsp_req_limit_delta =
725 725 h2b32(atomic_swap_32(&iu->iu_ch->ch_req_lim_delta, 0));
726 726 rsp->rsp_tag = iu->iu_tag;
727 727
728 728 /* srp_rsp_t is padded out, so use explicit size here */
729 729 rsp_length = SRP_RSP_SIZE;
730 730 if (srp_rsp != SRP_TM_SUCCESS) {
731 731 rsp->rsp_flags |= SRP_RSP_VALID;
732 732 data = (srp_rsp_data_t *)bufp;
733 733 data->rd_rsp_status = srp_rsp;
734 734 rsp->rsp_data_len = h2b32(sizeof (srp_rsp_data_t));
735 735 rsp_length += sizeof (srp_rsp_data_t);
736 736 }
737 737
738 738 SRPT_DPRINTF_L4("stp_send_mgmt_response, sending on ch(%p),"
739 739 " iu(%p), mgmt status(%d)", (void *)iu->iu_ch,
740 740 (void *)iu, srp_rsp);
741 741
742 742 DTRACE_SRP_4(task__response, srpt_channel_t, iu->iu_ch,
743 743 srp_rsp_t, iu->iu_buf, scsi_task_t, iu->iu_stmf_task,
744 744 int8_t, srp_rsp);
745 745
746 746 status = srpt_ch_post_send(iu->iu_ch, iu, rsp_length, fence);
747 747 if (status != IBT_SUCCESS) {
748 748 SRPT_DPRINTF_L2("stp_send_mgmt_response, post "
749 749 "response err(%d)", status);
750 750 }
751 751 return (status);
752 752 }
753 753
754 754 /*
755 755 * srpt_stp_send_response() - Send SRP command response IU
756 756 */
757 757 ibt_status_t
758 758 srpt_stp_send_response(srpt_iu_t *iu, uint8_t scsi_status,
759 759 uint8_t flags, uint32_t resid, uint16_t sense_length,
760 760 uint8_t *sense_data, uint_t fence)
761 761 {
762 762 srp_rsp_t *rsp;
763 763 uint32_t rsp_length;
764 764 uint8_t *bufp;
765 765 ibt_status_t status;
766 766
767 767 ASSERT(mutex_owned(&iu->iu_lock));
768 768 rsp = iu->iu_buf;
769 769 bufp = (uint8_t *)iu->iu_buf + SRP_RSP_SIZE;
770 770 bzero(rsp, SRP_RSP_SIZE);
771 771 rsp->rsp_type = SRP_IU_RSP;
772 772
773 773 /*
774 774 * Report ULP credits we have added since last response sent
775 775 * over this channel.
776 776 */
777 777 rsp->rsp_req_limit_delta =
778 778 h2b32(atomic_swap_32(&iu->iu_ch->ch_req_lim_delta, 0));
779 779 rsp->rsp_tag = iu->iu_tag;
780 780 rsp->rsp_status = scsi_status;
781 781
782 782 rsp_length = SRP_RSP_SIZE;
783 783
784 784 if (resid != 0) {
785 785 rsp->rsp_flags |= flags;
786 786
787 787 if ((flags & SRP_RSP_DO_OVER) ||
788 788 (flags & SRP_RSP_DO_UNDER)) {
789 789 rsp->rsp_do_resid_cnt = h2b32(resid);
790 790 } else if ((flags & SRP_RSP_DI_OVER) ||
791 791 (flags & SRP_RSP_DI_UNDER)) {
792 792 rsp->rsp_di_resid_cnt = h2b32(resid);
793 793 }
794 794 }
795 795
796 796 if (sense_length != 0) {
797 797 rsp->rsp_flags |= SRP_RSP_SNS_VALID;
798 798 if (SRP_RSP_SIZE + sense_length >
799 799 iu->iu_ch->ch_ti_iu_len) {
800 800 sense_length = iu->iu_ch->ch_ti_iu_len -
801 801 SRP_RSP_SIZE;
802 802 }
803 803 bcopy(sense_data, bufp, sense_length);
804 804 rsp->rsp_sense_data_len = h2b32(sense_length);
805 805 rsp_length += sense_length;
806 806 }
807 807
808 808 SRPT_DPRINTF_L4("stp_send_reponse, sending on ch(%p),"
809 809 " iu(%p), length(%d)", (void *)iu->iu_ch,
810 810 (void *)iu, rsp_length);
811 811
812 812 DTRACE_SRP_4(task__response, srpt_channel_t, iu->iu_ch,
813 813 srp_rsp_t, iu->iu_buf, scsi_task_t, iu->iu_stmf_task,
814 814 uint8_t, scsi_status);
815 815
816 816 status = srpt_ch_post_send(iu->iu_ch, iu, rsp_length, fence);
817 817 if (status != IBT_SUCCESS) {
818 818 SRPT_DPRINTF_L2("stp_send_response, post response err(%d)",
819 819 status);
820 820 }
821 821 return (status);
822 822 }
823 823
824 824 /*
825 825 * srpt_stp_send_status()
826 826 */
827 827 /* ARGSUSED */
828 828 stmf_status_t
829 829 srpt_stp_send_status(struct scsi_task *task, uint32_t ioflags)
830 830 {
831 831 srpt_iu_t *iu;
832 832 ibt_status_t status;
833 833
834 834 ASSERT(task != NULL);
835 835 iu = task->task_port_private;
836 836
837 837 ASSERT(iu != NULL);
838 838
839 839 mutex_enter(&iu->iu_lock);
840 840
841 841 ASSERT(iu->iu_ch != NULL);
842 842
843 843 SRPT_DPRINTF_L3("stp_send_status, invoked task (%p)"
844 844 ", task_completion_status (%d)"
845 845 ", task_resid (%d)"
846 846 ", task_status_ctrl (%d)"
847 847 ", task_scsi_status (%d)"
848 848 ", task_sense_length (%d)"
849 849 ", task_sense_data (%p)",
850 850 (void *)task,
851 851 (int)task->task_completion_status,
852 852 task->task_resid,
853 853 task->task_status_ctrl,
854 854 task->task_scsi_status,
855 855 task->task_sense_length,
856 856 (void *)task->task_sense_data);
857 857
858 858 DTRACE_SRP_4(scsi__response, srpt_channel_t, iu->iu_ch,
859 859 srp_rsp_t, iu->iu_buf, scsi_task_t, task,
860 860 int8_t, task->task_scsi_status);
861 861
862 862 if ((iu->iu_flags & (SRPT_IU_STMF_ABORTING |
863 863 SRPT_IU_SRP_ABORTING | SRPT_IU_ABORTED)) != 0) {
864 864 mutex_exit(&iu->iu_lock);
865 865 return (STMF_FAILURE);
866 866 }
867 867
868 868 /*
869 869 * Indicate future aborts can not be initiated (although
870 870 * we will handle any that have been requested since the
871 871 * last I/O completed and before we are sending status).
872 872 */
873 873 iu->iu_flags |= SRPT_IU_RESP_SENT;
874 874
875 875 /*
876 876 * Send SRP command response or SRP task mgmt response.
877 877 */
878 878 if (task->task_mgmt_function == 0) {
879 879 uint8_t rsp_flags = 0;
880 880 uint32_t resbytes = 0;
881 881
882 882 if (task->task_status_ctrl == TASK_SCTRL_OVER) {
883 883 resbytes = task->task_resid;
884 884
885 885 if (task->task_flags & TF_READ_DATA) {
886 886 SRPT_DPRINTF_L3(
887 887 "stp_send_status, data out overrun");
888 888 rsp_flags |= SRP_RSP_DO_OVER;
889 889 } else if (task->task_flags & TF_WRITE_DATA) {
890 890 SRPT_DPRINTF_L3(
891 891 "stp_send_status, data in overrun");
892 892 rsp_flags |= SRP_RSP_DI_OVER;
893 893 }
894 894 } else if (task->task_status_ctrl == TASK_SCTRL_UNDER) {
895 895 resbytes = task->task_resid;
896 896
897 897 if (task->task_flags & TF_READ_DATA) {
898 898 SRPT_DPRINTF_L3(
899 899 "stp_send_status, data out underrun");
900 900 rsp_flags |= SRP_RSP_DO_UNDER;
901 901 } else if (task->task_flags & TF_WRITE_DATA) {
902 902 SRPT_DPRINTF_L3(
903 903 "stp_send_status, data in underrun");
904 904 rsp_flags |= SRP_RSP_DI_UNDER;
905 905 }
906 906 }
907 907
908 908 status = srpt_stp_send_response(iu,
909 909 task->task_scsi_status, rsp_flags, resbytes,
910 910 task->task_sense_length, task->task_sense_data, 0);
911 911 } else {
912 912 status = srpt_stp_send_mgmt_response(iu,
913 913 (task->task_scsi_status ?
914 914 SRP_TM_FAILED : SRP_TM_SUCCESS),
915 915 SRPT_FENCE_SEND);
916 916 }
917 917
918 918 /*
919 919 * If we have an error posting the response return bad status
920 920 * to STMF and let it initiate an abort for the task.
921 921 */
922 922 if (status != IBT_SUCCESS) {
923 923 SRPT_DPRINTF_L2("stp_send_status, post response err(%d)",
924 924 status);
925 925
926 926 /* clear the response sent flag since it never went out */
927 927 iu->iu_flags &= ~SRPT_IU_RESP_SENT;
928 928
929 929 mutex_exit(&iu->iu_lock);
930 930 return (STMF_FAILURE);
931 931 }
932 932 mutex_exit(&iu->iu_lock);
933 933 return (STMF_SUCCESS);
934 934 }
935 935
936 936 /*
937 937 * srpt_stp_task_free() - STMF call-back.
938 938 */
939 939 static void
940 940 srpt_stp_task_free(struct scsi_task *task)
941 941 {
942 942 srpt_iu_t *iu;
943 943 srpt_channel_t *ch;
944 944
945 945 SRPT_DPRINTF_L3("stp_task_free, invoked task (%p)",
946 946 (void *)task);
947 947
948 948 iu = task->task_port_private;
949 949 ASSERT(iu != NULL);
950 950
951 951 mutex_enter(&iu->iu_lock);
952 952 ch = iu->iu_ch;
953 953 mutex_exit(&iu->iu_lock);
954 954
955 955 ASSERT(ch != NULL);
956 956 ASSERT(ch->ch_session != NULL);
957 957
958 958 /*
959 959 * Do not hold IU lock while task is being removed from
960 960 * the session list - possible deadlock if cleaning up
961 961 * channel when this is called.
962 962 */
963 963 srpt_stp_remove_task(ch->ch_session, iu);
964 964
965 965 mutex_enter(&iu->iu_lock);
966 966 iu->iu_stmf_task = NULL;
967 967
968 968 srpt_ioc_repost_recv_iu(iu->iu_ioc, iu);
969 969
970 970 mutex_exit(&iu->iu_lock);
971 971
972 972 srpt_ch_release_ref(ch, 0);
973 973 }
974 974
975 975 /*
976 976 * srpt_stp_abort() - STMF call-back.
977 977 */
978 978 /* ARGSUSED */
979 979 static stmf_status_t
980 980 srpt_stp_abort(struct stmf_local_port *lport, int abort_cmd,
981 981 void *arg, uint32_t flags)
982 982 {
983 983 struct scsi_task *task;
984 984 srpt_iu_t *iu;
985 985 stmf_status_t status;
986 986
987 987 SRPT_DPRINTF_L3("stp_abort, invoked lport (%p), arg (%p)",
988 988 (void *)lport, (void *)arg);
989 989
990 990 task = (struct scsi_task *)arg;
991 991 ASSERT(task != NULL);
992 992
993 993 iu = (srpt_iu_t *)task->task_port_private;
994 994 ASSERT(iu != NULL);
995 995
996 996 mutex_enter(&iu->iu_lock);
997 997
998 998 /*
999 999 * If no I/O is outstanding then immediately transition to
1000 1000 * aborted state. If any I/O is in progress OR we've sent the
1001 1001 * completion response, then indicate that an STMF abort has been
1002 1002 * requested and ask STMF to call us back later to complete the abort.
1003 1003 */
1004 1004 if ((iu->iu_flags & SRPT_IU_RESP_SENT) ||
1005 1005 (iu->iu_sq_posted_cnt > 0)) {
1006 1006 SRPT_DPRINTF_L3("stp_abort, deferring abort request. "
1007 1007 "%d outstanding I/O for IU %p",
1008 1008 iu->iu_sq_posted_cnt, (void *)iu);
1009 1009 iu->iu_flags |= SRPT_IU_STMF_ABORTING;
1010 1010 status = STMF_BUSY;
1011 1011 } else {
1012 1012 SRPT_DPRINTF_L3("stp_abort, no outstanding I/O for %p",
1013 1013 (void *)iu);
1014 1014 iu->iu_flags |= SRPT_IU_ABORTED;
1015 1015 /* Synchronous abort - STMF will call task_free */
1016 1016 status = STMF_ABORT_SUCCESS;
1017 1017 }
1018 1018
1019 1019 mutex_exit(&iu->iu_lock);
1020 1020 return (status);
1021 1021 }
1022 1022
1023 1023 /*
1024 1024 * srpt_stp_task_poll() - STMF call-back
1025 1025 */
1026 1026 static void
1027 1027 srpt_stp_task_poll(struct scsi_task *task)
1028 1028 {
1029 1029 SRPT_DPRINTF_L3("stp_task_poll, invoked, task (%p)",
1030 1030 (void *)task);
1031 1031 }
1032 1032
1033 1033 /*
1034 1034 * srpt_stp_ctl() - STMF call-back
1035 1035 */
1036 1036 static void
1037 1037 srpt_stp_ctl(struct stmf_local_port *lport, int cmd, void *arg)
1038 1038 {
1039 1039 stmf_state_change_info_t *sc_info = arg;
1040 1040 stmf_change_status_t cstatus;
1041 1041 stmf_status_t status;
1042 1042 srpt_target_port_t *tgt;
1043 1043 char *why;
1044 1044
1045 1045 ASSERT(sc_info != NULL);
1046 1046 ASSERT(lport != NULL);
1047 1047
1048 1048 tgt = lport->lport_port_private;
1049 1049 ASSERT(tgt->tp_ioc != NULL);
1050 1050
1051 1051 why = sc_info->st_additional_info;
1052 1052 if (why == NULL) {
1053 1053 why = "<null>";
1054 1054 }
1055 1055
1056 1056 SRPT_DPRINTF_L2("stp_ctl, invoked for LPORT (0x%016llx), cmd (%d), "
1057 1057 "info (%s)", (u_longlong_t)tgt->tp_ibt_svc_id, cmd, why);
1058 1058
1059 1059 cstatus.st_completion_status = STMF_SUCCESS;
1060 1060 cstatus.st_additional_info = NULL;
1061 1061
1062 1062 switch (cmd) {
1063 1063 case STMF_CMD_LPORT_ONLINE:
1064 1064 SRPT_DPRINTF_L2("stp_ctl, LPORT_ONLINE command,"
1065 1065 " st_rflags(0x%llx)", (u_longlong_t)sc_info->st_rflags);
1066 1066 /*
1067 1067 * If the SCSI Target Port is not enabled by the driver,
1068 1068 * don't start and instead return busy. This is a
1069 1069 * creation/destruction transitional state and the will
1070 1070 * either go away or become enabled.
1071 1071 */
1072 1072 mutex_enter(&tgt->tp_lock);
1073 1073
1074 1074 tgt->tp_requested_state = SRPT_TGT_STATE_ONLINE;
1075 1075
1076 1076 if (tgt->tp_drv_disabled != 0) {
1077 1077 SRPT_DPRINTF_L1("stp_ctl, set LPORT_ONLINE failed - "
1078 1078 "LPORT (0x%016llx) BUSY",
1079 1079 (u_longlong_t)tgt->tp_ibt_svc_id);
1080 1080 cstatus.st_completion_status = STMF_BUSY;
1081 1081 } else if ((tgt->tp_state == SRPT_TGT_STATE_ONLINE) ||
1082 1082 (tgt->tp_state == SRPT_TGT_STATE_ONLINING)) {
1083 1083 cstatus.st_completion_status = STMF_ALREADY;
1084 1084 } else if (tgt->tp_state != SRPT_TGT_STATE_OFFLINE) {
1085 1085 cstatus.st_completion_status = STMF_INVALID_ARG;
1086 1086 } else {
1087 1087 tgt->tp_state = SRPT_TGT_STATE_ONLINING;
1088 1088 status = srpt_stp_start_srp(tgt);
1089 1089 if (status != IBT_SUCCESS) {
1090 1090 tgt->tp_state = SRPT_TGT_STATE_OFFLINE;
1091 1091 cstatus.st_completion_status = STMF_INVALID_ARG;
1092 1092 if (tgt->tp_num_active_ports == 0) {
1093 1093 SRPT_DPRINTF_L1(
1094 1094 "stp_ctl, no ports active "
1095 1095 "for HCA 0x%016llx. Target will "
1096 1096 "not be placed online.",
1097 1097 (u_longlong_t)tgt->tp_ibt_svc_id);
1098 1098 }
1099 1099 }
1100 1100 }
1101 1101 mutex_exit(&tgt->tp_lock);
1102 1102 SRPT_DPRINTF_L3("stp_ctl, (0x%016llx) LPORT_ONLINE command"
1103 1103 " status (0x%llx)", (u_longlong_t)tgt->tp_ibt_svc_id,
1104 1104 (u_longlong_t)cstatus.st_completion_status);
1105 1105 status = stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, lport,
1106 1106 &cstatus);
1107 1107 if (status != STMF_SUCCESS) {
1108 1108 SRPT_DPRINTF_L1("stp_ctl, ONLINE_COMPLETE returned"
1109 1109 " error(0x%llx)", (u_longlong_t)status);
1110 1110 }
1111 1111 break;
1112 1112
1113 1113 case STMF_CMD_LPORT_OFFLINE:
1114 1114 SRPT_DPRINTF_L2("stp_ctl, LPORT_OFFLINE command,"
1115 1115 " st_rflags(0x%llx)", (u_longlong_t)sc_info->st_rflags);
1116 1116 mutex_enter(&tgt->tp_lock);
1117 1117
1118 1118 /*
1119 1119 * Only keep persistent state if explicitly requested by user
1120 1120 * action, such as stmfadm offline-target or
1121 1121 * svcadm disable stmf.
1122 1122 * If not requested by the user, this was likely triggered by
1123 1123 * not having any HCA ports active.
1124 1124 */
1125 1125 if (sc_info->st_rflags & STMF_RFLAG_USER_REQUEST) {
1126 1126 tgt->tp_requested_state = SRPT_TGT_STATE_OFFLINE;
1127 1127 }
1128 1128
1129 1129 if ((tgt->tp_state == SRPT_TGT_STATE_OFFLINE) ||
1130 1130 (tgt->tp_state == SRPT_TGT_STATE_OFFLINING)) {
1131 1131 cstatus.st_completion_status = STMF_ALREADY;
1132 1132 } else if (tgt->tp_state != SRPT_TGT_STATE_ONLINE) {
1133 1133 cstatus.st_completion_status = STMF_INVALID_ARG;
1134 1134 } else {
1135 1135 tgt->tp_state = SRPT_TGT_STATE_OFFLINING;
1136 1136 srpt_stp_stop_srp(tgt);
1137 1137 }
1138 1138 mutex_exit(&tgt->tp_lock);
1139 1139 SRPT_DPRINTF_L3("stp_ctl, notify STMF OFFLINE complete"
1140 1140 " (0x%016llx)", (u_longlong_t)tgt->tp_ibt_svc_id);
1141 1141 status = stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE,
1142 1142 lport, &cstatus);
1143 1143 if (status != STMF_SUCCESS) {
1144 1144 SRPT_DPRINTF_L1("stp_ctl, OFFLINE_COMPLETE returned"
1145 1145 " error(0x%llx)", (u_longlong_t)status);
1146 1146 }
1147 1147 break;
1148 1148
1149 1149 case STMF_ACK_LPORT_ONLINE_COMPLETE:
1150 1150 SRPT_DPRINTF_L2("stp_ctl, LPORT_ONLINE_COMPLETE ACK from"
1151 1151 " STMF");
1152 1152 mutex_enter(&tgt->tp_lock);
1153 1153 if (tgt->tp_state == SRPT_TGT_STATE_ONLINING) {
1154 1154 SRPT_DPRINTF_L2("stp_ctl, LPORT is ONLINE");
1155 1155 tgt->tp_state = SRPT_TGT_STATE_ONLINE;
1156 1156 } else {
1157 1157 SRPT_DPRINTF_L2("stp_ctl, LPORT not on-lining");
1158 1158 }
1159 1159 mutex_exit(&tgt->tp_lock);
1160 1160 break;
1161 1161
1162 1162 case STMF_ACK_LPORT_OFFLINE_COMPLETE:
1163 1163 SRPT_DPRINTF_L2("stp_ctl, LPORT_OFFLINE_COMPLETE ACK from"
1164 1164 " STMF");
1165 1165 mutex_enter(&tgt->tp_lock);
1166 1166 if (tgt->tp_state == SRPT_TGT_STATE_OFFLINING) {
1167 1167 SRPT_DPRINTF_L2("stp_ctl, LPORT is OFFLINE");
1168 1168 tgt->tp_state = SRPT_TGT_STATE_OFFLINE;
1169 1169 cv_broadcast(&tgt->tp_offline_complete);
1170 1170 } else {
1171 1171 SRPT_DPRINTF_L2("stp_ctl, LPORT not off-lining");
1172 1172 }
1173 1173 mutex_exit(&tgt->tp_lock);
1174 1174 break;
1175 1175
1176 1176 default:
1177 1177 SRPT_DPRINTF_L2("stp_ctl, cmd (%d) not handled",
1178 1178 cmd);
1179 1179 break;
1180 1180 }
1181 1181 }
1182 1182
1183 1183 /*
1184 1184 * srpt_stp_info() - STMF call-back
1185 1185 */
1186 1186 /* ARGSUSED */
1187 1187 static stmf_status_t
1188 1188 srpt_stp_info(uint32_t cmd, struct stmf_local_port *lport,
1189 1189 void *arg, uint8_t *buf, uint32_t *bufsizep)
1190 1190 {
1191 1191 SRPT_DPRINTF_L3("stp_info, invoked");
1192 1192 return (STMF_SUCCESS);
1193 1193 }
1194 1194
1195 1195 /*
1196 1196 * srpt_stp_event_handler() - STMF call-back
1197 1197 */
1198 1198 /* ARGSUSED */
1199 1199 static void
1200 1200 srpt_stp_event_handler(struct stmf_local_port *lport, int eventid,
1201 1201 void *arg, uint32_t flags)
1202 1202 {
1203 1203 SRPT_DPRINTF_L3("stp_event_handler, invoked");
1204 1204 }
1205 1205
1206 1206 /*
1207 1207 * srpt_stp_alloc_scsi_devid_desc()
1208 1208 *
1209 1209 * Allocate and initialize a SCSI device ID descriptor for
1210 1210 * the SRP protocol. Names are eui.GUID format.
1211 1211 *
1212 1212 * Both extension and guid are passed in host order.
1213 1213 */
1214 1214 static scsi_devid_desc_t *
1215 1215 srpt_stp_alloc_scsi_devid_desc(uint64_t guid)
1216 1216 {
1217 1217 scsi_devid_desc_t *sdd;
1218 1218
1219 1219 sdd = kmem_zalloc(sizeof (*sdd) + SRPT_EUI_ID_LEN + 1, KM_SLEEP);
1220 1220 sdd->protocol_id = PROTOCOL_SRP;
1221 1221 sdd->piv = 1;
1222 1222 sdd->code_set = CODE_SET_ASCII;
1223 1223 sdd->association = ID_IS_TARGET_PORT;
1224 1224 sdd->ident_length = SRPT_EUI_ID_LEN;
1225 1225 (void) sprintf((char *)sdd->ident, "eui.%016llX", (u_longlong_t)guid);
1226 1226 return (sdd);
1227 1227 }
1228 1228
1229 1229 /*
1230 1230 * srpt_stp_free_scsi_devid_desc()
1231 1231 *
1232 1232 * Free a SRPT SCSI device ID descriptor previously allocated via
1233 1233 * srpt_stp_alloc_scsi_devid_desc().
1234 1234 */
1235 1235 static void
1236 1236 srpt_stp_free_scsi_devid_desc(scsi_devid_desc_t *sdd)
1237 1237 {
1238 1238 kmem_free(sdd, sizeof (*sdd) + SRPT_EUI_ID_LEN + 1);
1239 1239 }
1240 1240
1241 1241 /*
1242 1242 * srpt_stp_alloc_session()
1243 1243 */
1244 1244 srpt_session_t *
1245 1245 srpt_stp_alloc_session(srpt_target_port_t *tgt,
1246 1246 uint8_t *i_id, uint8_t *t_id, uint8_t port,
1247 1247 char *local_gid, char *remote_gid)
1248 1248 {
1249 1249 stmf_status_t status;
1250 1250 srpt_session_t *ss;
1251 1251 stmf_scsi_session_t *stmf_ss;
1252 1252 uint64_t i_guid;
1253 1253 scsi_srp_transport_id_t *srptpd;
1254 1254
1255 1255 ASSERT(tgt != NULL);
1256 1256 SRPT_DPRINTF_L3("stp_alloc_session, invoked");
1257 1257
1258 1258 mutex_enter(&tgt->tp_sess_list_lock);
1259 1259
1260 1260 i_guid = BE_IN64(&i_id[8]);
1261 1261
1262 1262 stmf_ss = stmf_alloc(STMF_STRUCT_SCSI_SESSION,
1263 1263 sizeof (srpt_session_t), 0);
1264 1264 if (stmf_ss == NULL) {
1265 1265 SRPT_DPRINTF_L2("stp_alloc_session, stmf_alloc"
1266 1266 " returned NULL");
1267 1267 mutex_exit(&tgt->tp_sess_list_lock);
1268 1268 return (NULL);
1269 1269 }
1270 1270 ss = stmf_ss->ss_port_private;
1271 1271 ASSERT(ss != NULL);
1272 1272
1273 1273 rw_init(&ss->ss_rwlock, NULL, RW_DRIVER, NULL);
1274 1274 list_create(&ss->ss_task_list, sizeof (srpt_iu_t),
1275 1275 offsetof(srpt_iu_t, iu_ss_task_node));
1276 1276
1277 1277 stmf_ss->ss_rport_id = srpt_stp_alloc_scsi_devid_desc(i_guid);
1278 1278 /* Setup remote port transport id */
1279 1279 stmf_ss->ss_rport = stmf_remote_port_alloc(
1280 1280 sizeof (scsi_srp_transport_id_t));
1281 1281 stmf_ss->ss_rport->rport_tptid->protocol_id = PROTOCOL_SRP;
1282 1282 stmf_ss->ss_rport->rport_tptid->format_code = 0;
1283 1283 srptpd = (scsi_srp_transport_id_t *)stmf_ss->ss_rport->rport_tptid;
1284 1284 bcopy(i_id, srptpd->srp_name, SRP_PORT_ID_LEN);
1285 1285
1286 1286 stmf_ss->ss_lport = tgt->tp_lport;
1287 1287
1288 1288 ss->ss_ss = stmf_ss;
1289 1289 ss->ss_hw_port = port;
1290 1290 ss->ss_tgt = tgt;
1291 1291 bcopy(i_id, ss->ss_i_id, SRP_PORT_ID_LEN);
1292 1292 bcopy(t_id, ss->ss_t_id, SRP_PORT_ID_LEN);
1293 1293
1294 1294 /*
1295 1295 * Set the alias to include the initiator extension, this will enable
1296 1296 * the administrator to identify multiple unique sessions originating
1297 1297 * from the same initiator.
1298 1298 */
1299 1299 (void) strlcpy(ss->ss_i_gid, remote_gid, SRPT_ALIAS_LEN);
1300 1300 (void) strlcpy(ss->ss_t_gid, local_gid, SRPT_ALIAS_LEN);
1301 1301 EUI_STR(ss->ss_i_name, BE_IN64(&ss->ss_i_id[8]));
1302 1302 EUI_STR(ss->ss_t_name, BE_IN64(&ss->ss_t_id[0]));
1303 1303 ALIAS_STR(ss->ss_i_alias, BE_IN64(&ss->ss_i_id[0]),
1304 1304 BE_IN64(&ss->ss_i_id[8]));
1305 1305 ALIAS_STR(ss->ss_t_alias, BE_IN64(&ss->ss_t_id[0]),
1306 1306 BE_IN64(&ss->ss_t_id[8]));
1307 1307 stmf_ss->ss_rport_alias = ss->ss_i_alias;
1308 1308
1309 1309 status = stmf_register_scsi_session(tgt->tp_lport, stmf_ss);
1310 1310 if (status != STMF_SUCCESS) {
1311 1311 SRPT_DPRINTF_L1("stp_alloc_session, STMF register session"
1312 1312 " err(0x%llx)", (u_longlong_t)status);
1313 1313 list_destroy(&ss->ss_task_list);
1314 1314 rw_destroy(&ss->ss_rwlock);
1315 1315 srpt_stp_free_scsi_devid_desc(stmf_ss->ss_rport_id);
1316 1316 stmf_remote_port_free(stmf_ss->ss_rport);
1317 1317 stmf_free(stmf_ss);
1318 1318 mutex_exit(&tgt->tp_sess_list_lock);
1319 1319 return (NULL);
1320 1320 }
1321 1321
1322 1322 list_insert_tail(&tgt->tp_sess_list, ss);
1323 1323 mutex_exit(&tgt->tp_sess_list_lock);
1324 1324 return (ss);
1325 1325 }
1326 1326
1327 1327 /*
1328 1328 * srpt_stp_free_session()
1329 1329 */
1330 1330 void
1331 1331 srpt_stp_free_session(srpt_session_t *session)
1332 1332 {
1333 1333 stmf_scsi_session_t *stmf_ss;
1334 1334 srpt_target_port_t *tgt;
1335 1335
1336 1336 ASSERT(session != NULL);
1337 1337
1338 1338 tgt = session->ss_tgt;
1339 1339
1340 1340 ASSERT(tgt != NULL);
1341 1341
1342 1342 SRPT_DPRINTF_L3("stp_free_session, invoked");
1343 1343
1344 1344 mutex_enter(&tgt->tp_sess_list_lock);
1345 1345
1346 1346 stmf_ss = session->ss_ss;
1347 1347
1348 1348 list_destroy(&session->ss_task_list);
1349 1349 rw_destroy(&session->ss_rwlock);
1350 1350
1351 1351 stmf_deregister_scsi_session(tgt->tp_lport, stmf_ss);
1352 1352 srpt_stp_free_scsi_devid_desc(stmf_ss->ss_rport_id);
1353 1353 stmf_remote_port_free(stmf_ss->ss_rport);
1354 1354 list_remove(&tgt->tp_sess_list, session);
1355 1355 cv_signal(&tgt->tp_sess_complete);
1356 1356 mutex_exit(&tgt->tp_sess_list_lock);
1357 1357 stmf_free(stmf_ss);
1358 1358 }
1359 1359
1360 1360 /*
1361 1361 * srpt_stp_login() - SRP SCSI Target port login
1362 1362 */
1363 1363 srpt_channel_t *
1364 1364 srpt_stp_login(srpt_target_port_t *tgt, srp_login_req_t *login,
1365 1365 srp_login_rsp_t *login_rsp, srp_login_rej_t *login_rej,
1366 1366 uint8_t login_port, char *local_gid, char *remote_gid)
1367 1367 {
1368 1368 uint32_t reason;
1369 1369 uint32_t req_it_ui_len;
1370 1370 uint8_t rsp_flags;
1371 1371 srpt_ioc_t *ioc;
1372 1372 srpt_channel_t *ch = NULL;
1373 1373 srpt_channel_t *next_ch = NULL;
1374 1374 srpt_session_t *session = NULL;
1375 1375 srpt_session_t sess;
1376 1376
1377 1377 ASSERT(tgt != NULL);
1378 1378 ASSERT(login != NULL);
1379 1379 ASSERT(login_rsp != NULL);
1380 1380 ASSERT(login_rej != NULL);
1381 1381
1382 1382 /* Store the string representation of connection info */
1383 1383 /* for Dtrace probes */
1384 1384 bzero(&sess, sizeof (srpt_session_t));
1385 1385 (void) strlcpy(sess.ss_i_gid, remote_gid, SRPT_ALIAS_LEN);
1386 1386 (void) strlcpy(sess.ss_t_gid, local_gid, SRPT_ALIAS_LEN);
1387 1387 EUI_STR(sess.ss_i_name,
1388 1388 BE_IN64(&login->lreq_initiator_port_id[8]));
1389 1389 EUI_STR(sess.ss_t_name,
1390 1390 BE_IN64(&login->lreq_target_port_id[0]));
1391 1391 ALIAS_STR(sess.ss_i_alias,
1392 1392 BE_IN64(&login->lreq_initiator_port_id[0]),
1393 1393 BE_IN64(&login->lreq_initiator_port_id[8]));
1394 1394 ALIAS_STR(sess.ss_t_alias,
1395 1395 BE_IN64(&login->lreq_target_port_id[0]),
1396 1396 BE_IN64(&login->lreq_target_port_id[8]));
1397 1397
1398 1398 DTRACE_SRP_2(login__command, srpt_session_t, &sess,
1399 1399 srp_login_req_t, login);
1400 1400
1401 1401 /*
1402 1402 * The target lock taken here serializes logins to this target
1403 1403 * and prevents an STMF target port from starting a control
1404 1404 * operation to transition the target state while a login is
1405 1405 * being processed.
1406 1406 */
1407 1407 bzero(login_rsp, sizeof (srp_login_rsp_t));
1408 1408 bzero(login_rej, sizeof (srp_login_rej_t));
1409 1409 mutex_enter(&tgt->tp_lock);
1410 1410 ioc = tgt->tp_ioc;
1411 1411 if (ioc == NULL) {
1412 1412 SRPT_DPRINTF_L1("stp_login, NULL I/O Controller");
1413 1413 reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1414 1414 goto reject_login;
1415 1415 }
1416 1416
1417 1417 /*
1418 1418 * Validate that the SRP Target ID in the login request specifies
1419 1419 * this I/O Controller SCSI Target Port.
1420 1420 */
1421 1421 if (memcmp(login->lreq_target_port_id, tgt->tp_srp_port_id,
1422 1422 SRP_PORT_ID_LEN) != 0) {
1423 1423 SRPT_DPRINTF_L2("stp_login, SRP CM SVC target ID mismatch."
1424 1424 " Incoming TgtID 0x%016llx:0x%016llx",
1425 1425 (u_longlong_t)BE_IN64(&login->lreq_target_port_id[0]),
1426 1426 (u_longlong_t)BE_IN64(&login->lreq_target_port_id[8]));
1427 1427
1428 1428 reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1429 1429 goto reject_login;
1430 1430 }
1431 1431
1432 1432 if (tgt->tp_state != SRPT_TGT_STATE_ONLINE) {
1433 1433 SRPT_DPRINTF_L2("stp_login, SRP Login target not on-line");
1434 1434 reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1435 1435 goto reject_login;
1436 1436 }
1437 1437
1438 1438 /*
1439 1439 * Initiator requested IU size must be as large as the specification
1440 1440 * minimum and no greater than what we chose to support.
1441 1441 */
1442 1442 req_it_ui_len = b2h32(login->lreq_req_it_iu_len);
1443 1443 SRPT_DPRINTF_L2("stp_login, requested iu size = %d", req_it_ui_len);
1444 1444 if (req_it_ui_len > srpt_iu_size) {
1445 1445 SRPT_DPRINTF_L2("stp_login, SRP Login IU size (%d) too large",
1446 1446 req_it_ui_len);
1447 1447 reason = SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE;
1448 1448 goto reject_login;
1449 1449 }
1450 1450 if (req_it_ui_len < SRP_MIN_IU_SIZE) {
1451 1451 SRPT_DPRINTF_L2("stp_login, SRP Login IU size (%d) too small",
1452 1452 req_it_ui_len);
1453 1453 reason = SRP_LOGIN_REJ_NO_REASON;
1454 1454 goto reject_login;
1455 1455 }
1456 1456
1457 1457 SRPT_DPRINTF_L2("stp_login, login req InitID 0x%016llx:0x%016llx",
1458 1458 (u_longlong_t)BE_IN64(&login->lreq_initiator_port_id[0]),
1459 1459 (u_longlong_t)BE_IN64(&login->lreq_initiator_port_id[8]));
1460 1460 SRPT_DPRINTF_L2("stp_login, login req TgtID 0x%016llx:0x%016llx",
1461 1461 (u_longlong_t)BE_IN64(&login->lreq_target_port_id[0]),
1462 1462 (u_longlong_t)BE_IN64(&login->lreq_target_port_id[8]));
1463 1463
1464 1464 /*
1465 1465 * Processing is based on either single channel or multi-channel
1466 1466 * operation. In single channel, all current logins for this
1467 1467 * same I_T_Nexus should be logged out. In multi-channel
1468 1468 * mode we would add an additional channel to an existing
1469 1469 * I_T_Nexus if one currently exists (i.e. reference the
1470 1470 * same SCSI session).
1471 1471 */
1472 1472 rsp_flags = SRP_MULTI_CH_RESULT_NO_EXISTING;
1473 1473
1474 1474 switch (login->lreq_req_flags & SRP_LOGIN_MULTI_CH_MASK) {
1475 1475
1476 1476 case SRP_LOGIN_MULTI_CH_SINGLE:
1477 1477 /*
1478 1478 * Only a single channel may be associated with a I_T_Nexus.
1479 1479 * Disconnect any channel with the same SRP Initiator and
1480 1480 * SRP target IDs.
1481 1481 */
1482 1482 mutex_enter(&tgt->tp_ch_list_lock);
1483 1483 ch = list_head(&tgt->tp_ch_list);
1484 1484 while (ch != NULL) {
1485 1485 SRPT_DPRINTF_L3("stp_login, compare session,"
1486 1486 " ch_state(%d)", ch->ch_state);
1487 1487 next_ch = list_next(&tgt->tp_ch_list, ch);
1488 1488
1489 1489 if (ch->ch_state != SRPT_CHANNEL_CONNECTING &&
1490 1490 ch->ch_state != SRPT_CHANNEL_CONNECTED) {
1491 1491 SRPT_DPRINTF_L3("stp_login, compare session,"
1492 1492 " channel not active");
1493 1493 ch = next_ch;
1494 1494 continue;
1495 1495 }
1496 1496
1497 1497 ASSERT(ch->ch_session != NULL);
1498 1498 SRPT_DPRINTF_L3("stp_login, compare session"
1499 1499 " I_ID 0x%016llx:0x%016llx",
1500 1500 (u_longlong_t)b2h64(*((uint64_t *)(void *)
1501 1501 &ch->ch_session->ss_i_id[0])),
1502 1502 (u_longlong_t)b2h64(*((uint64_t *)(void *)
1503 1503 &ch->ch_session->ss_i_id[8])));
1504 1504 SRPT_DPRINTF_L3("stp_login, compare session"
1505 1505 " T_ID 0x%016llx:0x%016llx",
1506 1506 (u_longlong_t)b2h64(*((uint64_t *)(void *)
1507 1507 &ch->ch_session->ss_t_id[0])),
1508 1508 (u_longlong_t)b2h64(*((uint64_t *)(void *)
1509 1509 &ch->ch_session->ss_t_id[8])));
1510 1510 if ((bcmp(login->lreq_initiator_port_id,
1511 1511 ch->ch_session->ss_i_id,
1512 1512 SRP_PORT_ID_LEN) == 0) &&
1513 1513 (bcmp(login->lreq_target_port_id,
1514 1514 ch->ch_session->ss_t_id,
1515 1515 SRP_PORT_ID_LEN) == 0)) {
1516 1516 /*
1517 1517 * if a session is in the process of connecting,
1518 1518 * reject subsequent equivalent requests.
1519 1519 */
1520 1520 if (ch->ch_state == SRPT_CHANNEL_CONNECTING) {
1521 1521 reason = SRP_LOGIN_REJ_INIT_CH_LIMIT;
1522 1522 mutex_exit(&tgt->tp_ch_list_lock);
1523 1523 goto reject_login;
1524 1524 }
1525 1525
1526 1526 SRPT_DPRINTF_L2("stp_login, terminate"
1527 1527 " existing login");
1528 1528 rsp_flags =
1529 1529 SRP_MULTI_CH_RESULT_TERM_EXISTING;
1530 1530 srpt_ch_disconnect(ch);
1531 1531 }
1532 1532
1533 1533 ch = next_ch;
1534 1534 }
1535 1535 mutex_exit(&tgt->tp_ch_list_lock);
1536 1536
1537 1537 /* Create the new session for this SRP login */
1538 1538 session = srpt_stp_alloc_session(tgt,
1539 1539 login->lreq_initiator_port_id,
1540 1540 login->lreq_target_port_id, login_port,
1541 1541 local_gid, remote_gid);
1542 1542 if (session == NULL) {
1543 1543 SRPT_DPRINTF_L2("stp_login, session allocation"
1544 1544 " failed");
1545 1545 reason = SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS;
1546 1546 goto reject_login;
1547 1547 }
1548 1548 break;
1549 1549
1550 1550 case SRP_LOGIN_MULTI_CH_MULTIPLE:
1551 1551 SRPT_DPRINTF_L2("stp_login, multichannel not supported yet");
1552 1552 reason = SRP_LOGIN_REJ_MULTI_CH_NOT_SUPPORTED;
1553 1553 goto reject_login;
1554 1554 /* break via goto */
1555 1555
1556 1556 default:
1557 1557 SRPT_DPRINTF_L2("stp_login, invalid multichannel field (%d)",
1558 1558 login->lreq_req_flags & SRP_LOGIN_MULTI_CH_MASK);
1559 1559 reason = SRP_LOGIN_REJ_NO_REASON;
1560 1560 goto reject_login;
1561 1561 /* break via goto */
1562 1562 }
1563 1563
1564 1564 /*
1565 1565 * Create new RDMA channel for this SRP login request.
1566 1566 * The channel is returned with a single reference which
1567 1567 * represents the reference held by the CM.
1568 1568 */
1569 1569 ch = srpt_ch_alloc(tgt, login_port);
1570 1570 if (ch == NULL) {
1571 1571 SRPT_DPRINTF_L2("stp_login, unable to alloc RDMA channel");
1572 1572 reason = SRP_LOGIN_REJ_INSUFFICIENT_CH_RESOURCES;
1573 1573 srpt_stp_free_session(session);
1574 1574 goto reject_login;
1575 1575 }
1576 1576 ch->ch_session = session;
1577 1577 ch->ch_ti_iu_len = b2h32(login->lreq_req_it_iu_len);
1578 1578
1579 1579 /*
1580 1580 * Add another reference to the channel which represents
1581 1581 * a reference placed by the target port and add it to
1582 1582 * the store of channels logged in for this target port.
1583 1583 */
1584 1584 srpt_ch_add_ref(ch);
1585 1585 mutex_enter(&tgt->tp_ch_list_lock);
1586 1586 list_insert_tail(&tgt->tp_ch_list, ch);
1587 1587 mutex_exit(&tgt->tp_ch_list_lock);
1588 1588
1589 1589 srpt_format_login_rsp(login, login_rsp, rsp_flags);
1590 1590 mutex_exit(&tgt->tp_lock);
1591 1591 SRPT_DPRINTF_L2("stp_login, login successful");
1592 1592
1593 1593 DTRACE_SRP_3(login__response, srpt_session_t, &sess,
1594 1594 srp_login_rsp_t, login_rsp, srp_login_rej_t, login_rej)
1595 1595
1596 1596 return (ch);
1597 1597
1598 1598 reject_login:
1599 1599 srpt_format_login_rej(login, login_rej, reason);
1600 1600 mutex_exit(&tgt->tp_lock);
1601 1601
1602 1602 DTRACE_SRP_3(login__response, srpt_session_t, &sess,
1603 1603 srp_login_rsp_t, login_rsp, srp_login_rej_t, login_rej);
1604 1604
1605 1605 return (NULL);
1606 1606 }
1607 1607
1608 1608 /*
1609 1609 * srpt_stp_logout() - SRP logout
1610 1610 *
1611 1611 * Logout is not normally initiated in-band, but is so, just
1612 1612 * initiate a disconnect.
1613 1613 */
1614 1614 void
1615 1615 srpt_stp_logout(srpt_channel_t *ch)
1616 1616 {
1617 1617 DTRACE_SRP_1(logout__command, srpt_channel_t, ch);
1618 1618 SRPT_DPRINTF_L2("stp_logout, invoked for ch (%p)", (void *)ch);
1619 1619 srpt_ch_disconnect(ch);
1620 1620 }
1621 1621
1622 1622 /*
1623 1623 * srpt_format_login_rej() - Format login reject IU
1624 1624 */
1625 1625 static void
1626 1626 srpt_format_login_rej(srp_login_req_t *req, srp_login_rej_t *rej,
1627 1627 uint32_t reason)
1628 1628 {
1629 1629 rej->lrej_type = SRP_IU_LOGIN_REJ;
1630 1630 rej->lrej_reason = h2b32(reason);
1631 1631 rej->lrej_tag = req->lreq_tag;
1632 1632 rej->lrej_sup_buf_format =
1633 1633 h2b16(SRP_DIRECT_BUFR_DESC | SRP_INDIRECT_BUFR_DESC);
1634 1634 }
1635 1635
1636 1636 /*
1637 1637 * srpt_format_login_rsp() - Format login response IU
1638 1638 */
1639 1639 static void
1640 1640 srpt_format_login_rsp(srp_login_req_t *req, srp_login_rsp_t *rsp,
1641 1641 uint8_t flags)
1642 1642 {
1643 1643 rsp->lrsp_type = SRP_IU_LOGIN_RSP;
1644 1644 rsp->lrsp_req_limit_delta = h2b32((uint32_t)srpt_send_msg_depth);
1645 1645 rsp->lrsp_tag = req->lreq_tag;
1646 1646
1647 1647 rsp->lrsp_max_it_iu_len = req->lreq_req_it_iu_len;
1648 1648 /* by def. > min T_IU_LEN */
1649 1649 rsp->lrsp_max_ti_iu_len = req->lreq_req_it_iu_len;
1650 1650
1651 1651 rsp->lrsp_sup_buf_format =
1652 1652 h2b16(SRP_DIRECT_BUFR_DESC | SRP_INDIRECT_BUFR_DESC);
1653 1653 rsp->lrsp_rsp_flags = flags;
1654 1654 }
1655 1655
1656 1656 /*
1657 1657 * srpt_stp_add_task()
1658 1658 */
1659 1659 void
1660 1660 srpt_stp_add_task(srpt_session_t *session, srpt_iu_t *iu)
1661 1661 {
1662 1662 rw_enter(&session->ss_rwlock, RW_WRITER);
1663 1663 list_insert_tail(&session->ss_task_list, iu);
1664 1664 rw_exit(&session->ss_rwlock);
1665 1665 }
1666 1666
1667 1667 /*
1668 1668 * srpt_stp_remove_task()
1669 1669 */
1670 1670 void
1671 1671 srpt_stp_remove_task(srpt_session_t *session, srpt_iu_t *iu)
1672 1672 {
1673 1673 rw_enter(&session->ss_rwlock, RW_WRITER);
1674 1674
1675 1675 ASSERT(!list_is_empty(&session->ss_task_list));
1676 1676
1677 1677 list_remove(&session->ss_task_list, iu);
1678 1678 rw_exit(&session->ss_rwlock);
1679 1679 }
↓ open down ↓ |
1170 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX