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