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 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23 * 24 * Copyright 2014, 2015 Nexenta Systems, Inc. All rights reserved. 25 */ 26 27 #include <sys/cpuvar.h> 28 #include <sys/types.h> 29 #include <sys/conf.h> 30 #include <sys/stat.h> 31 #include <sys/file.h> 32 #include <sys/ddi.h> 33 #include <sys/sunddi.h> 34 #include <sys/modctl.h> 35 #include <sys/sysmacros.h> 36 #include <sys/socket.h> 37 #include <sys/strsubr.h> 38 #include <sys/nvpair.h> 39 40 #include <sys/stmf.h> 41 #include <sys/stmf_ioctl.h> 42 #include <sys/portif.h> 43 #include <sys/idm/idm.h> 44 #include <sys/idm/idm_conn_sm.h> 45 46 #include "iscsit_isns.h" 47 #include "iscsit.h" 48 49 #define ISCSIT_VERSION BUILD_DATE "-1.18dev" 50 #define ISCSIT_NAME_VERSION "COMSTAR ISCSIT v" ISCSIT_VERSION 51 52 /* 53 * DDI entry points. 54 */ 55 static int iscsit_drv_attach(dev_info_t *, ddi_attach_cmd_t); 56 static int iscsit_drv_detach(dev_info_t *, ddi_detach_cmd_t); 57 static int iscsit_drv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 58 static int iscsit_drv_open(dev_t *, int, int, cred_t *); 59 static int iscsit_drv_close(dev_t, int, int, cred_t *); 60 static boolean_t iscsit_drv_busy(void); 61 static int iscsit_drv_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 62 63 extern struct mod_ops mod_miscops; 64 65 66 static struct cb_ops iscsit_cb_ops = { 67 iscsit_drv_open, /* cb_open */ 68 iscsit_drv_close, /* cb_close */ 69 nodev, /* cb_strategy */ 70 nodev, /* cb_print */ 71 nodev, /* cb_dump */ 72 nodev, /* cb_read */ 73 nodev, /* cb_write */ 74 iscsit_drv_ioctl, /* cb_ioctl */ 75 nodev, /* cb_devmap */ 76 nodev, /* cb_mmap */ 77 nodev, /* cb_segmap */ 78 nochpoll, /* cb_chpoll */ 79 ddi_prop_op, /* cb_prop_op */ 80 NULL, /* cb_streamtab */ 81 D_MP, /* cb_flag */ 82 CB_REV, /* cb_rev */ 83 nodev, /* cb_aread */ 84 nodev, /* cb_awrite */ 85 }; 86 87 static struct dev_ops iscsit_dev_ops = { 88 DEVO_REV, /* devo_rev */ 89 0, /* devo_refcnt */ 90 iscsit_drv_getinfo, /* devo_getinfo */ 91 nulldev, /* devo_identify */ 92 nulldev, /* devo_probe */ 93 iscsit_drv_attach, /* devo_attach */ 94 iscsit_drv_detach, /* devo_detach */ 95 nodev, /* devo_reset */ 96 &iscsit_cb_ops, /* devo_cb_ops */ 97 NULL, /* devo_bus_ops */ 98 NULL, /* devo_power */ 99 ddi_quiesce_not_needed, /* quiesce */ 100 }; 101 102 static struct modldrv modldrv = { 103 &mod_driverops, 104 "iSCSI Target", 105 &iscsit_dev_ops, 106 }; 107 108 static struct modlinkage modlinkage = { 109 MODREV_1, 110 &modldrv, 111 NULL, 112 }; 113 114 115 iscsit_global_t iscsit_global; 116 117 kmem_cache_t *iscsit_status_pdu_cache; 118 119 boolean_t iscsit_sm_logging = B_FALSE; 120 121 kmutex_t login_sm_session_mutex; 122 123 static idm_status_t iscsit_init(dev_info_t *dip); 124 static idm_status_t iscsit_enable_svc(iscsit_hostinfo_t *hostinfo); 125 static void iscsit_disable_svc(void); 126 127 static int 128 iscsit_check_cmdsn_and_queue(idm_pdu_t *rx_pdu); 129 130 static void 131 iscsit_add_pdu_to_queue(iscsit_sess_t *ist, idm_pdu_t *rx_pdu); 132 133 static idm_pdu_t * 134 iscsit_remove_pdu_from_queue(iscsit_sess_t *ist, uint32_t cmdsn); 135 136 static void 137 iscsit_process_pdu_in_queue(iscsit_sess_t *ist); 138 139 static void 140 iscsit_rxpdu_queue_monitor_session(iscsit_sess_t *ist); 141 142 static void 143 iscsit_rxpdu_queue_monitor(void *arg); 144 145 static void 146 iscsit_post_staged_pdu(idm_pdu_t *rx_pdu); 147 148 static void 149 iscsit_post_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu); 150 151 static void 152 iscsit_op_scsi_task_mgmt(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 153 154 static void 155 iscsit_pdu_op_noop(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 156 157 static void 158 iscsit_pdu_op_login_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 159 160 void 161 iscsit_pdu_op_text_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 162 163 static void 164 iscsit_pdu_op_logout_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 165 166 int iscsit_cmd_window(); 167 168 static int 169 iscsit_sna_lt(uint32_t sn1, uint32_t sn2); 170 171 void 172 iscsit_set_cmdsn(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 173 174 static void 175 iscsit_deferred_dispatch(idm_pdu_t *rx_pdu); 176 177 static void 178 iscsit_deferred(void *rx_pdu_void); 179 180 static idm_status_t 181 iscsit_conn_accept(idm_conn_t *ic); 182 183 static idm_status_t 184 iscsit_ffp_enabled(idm_conn_t *ic); 185 186 static idm_status_t 187 iscsit_ffp_disabled(idm_conn_t *ic, idm_ffp_disable_t disable_class); 188 189 static idm_status_t 190 iscsit_conn_lost(idm_conn_t *ic); 191 192 static idm_status_t 193 iscsit_conn_destroy(idm_conn_t *ic); 194 195 static stmf_data_buf_t * 196 iscsit_dbuf_alloc(scsi_task_t *task, uint32_t size, uint32_t *pminsize, 197 uint32_t flags); 198 199 static void 200 iscsit_dbuf_free(stmf_dbuf_store_t *ds, stmf_data_buf_t *dbuf); 201 202 static void 203 iscsit_buf_xfer_cb(idm_buf_t *idb, idm_status_t status); 204 205 static void 206 iscsit_send_good_status_done(idm_pdu_t *pdu, idm_status_t status); 207 208 static void 209 iscsit_send_status_done(idm_pdu_t *pdu, idm_status_t status); 210 211 static stmf_status_t 212 iscsit_idm_to_stmf(idm_status_t idmrc); 213 214 static iscsit_task_t * 215 iscsit_task_alloc(iscsit_conn_t *ict); 216 217 static void 218 iscsit_task_free(iscsit_task_t *itask); 219 220 static iscsit_task_t * 221 iscsit_tm_task_alloc(iscsit_conn_t *ict); 222 223 static void 224 iscsit_tm_task_free(iscsit_task_t *itask); 225 226 static idm_status_t 227 iscsit_task_start(iscsit_task_t *itask); 228 229 static void 230 iscsit_task_done(iscsit_task_t *itask); 231 232 static int 233 iscsit_status_pdu_constructor(void *pdu_void, void *arg, int flags); 234 235 static void 236 iscsit_pp_cb(struct stmf_port_provider *pp, int cmd, void *arg, uint32_t flags); 237 238 static it_cfg_status_t 239 iscsit_config_merge(it_config_t *cfg); 240 241 static idm_status_t 242 iscsit_login_fail(idm_conn_t *ic); 243 244 static boolean_t iscsit_cmdsn_in_window(iscsit_conn_t *ict, uint32_t cmdsn); 245 static void iscsit_send_direct_scsi_resp(iscsit_conn_t *ict, idm_pdu_t *rx_pdu, 246 uint8_t response, uint8_t cmd_status); 247 static void iscsit_send_task_mgmt_resp(idm_pdu_t *tm_resp_pdu, 248 uint8_t tm_status); 249 250 /* 251 * MC/S: Out-of-order commands are staged on a session-wide wait 252 * queue until a system-tunable threshold is reached. A separate 253 * thread is used to scan the staging queue on all the session, 254 * If a delayed PDU does not arrive within a timeout, the target 255 * will advance to the staged PDU that is next in sequence, skipping 256 * over the missing PDU(s) to go past a hole in the sequence. 257 */ 258 volatile int rxpdu_queue_threshold = ISCSIT_RXPDU_QUEUE_THRESHOLD; 259 260 static kmutex_t iscsit_rxpdu_queue_monitor_mutex; 261 kthread_t *iscsit_rxpdu_queue_monitor_thr_id; 262 static kt_did_t iscsit_rxpdu_queue_monitor_thr_did; 263 static boolean_t iscsit_rxpdu_queue_monitor_thr_running; 264 static kcondvar_t iscsit_rxpdu_queue_monitor_cv; 265 266 int 267 _init(void) 268 { 269 int rc; 270 271 rw_init(&iscsit_global.global_rwlock, NULL, RW_DRIVER, NULL); 272 mutex_init(&iscsit_global.global_state_mutex, NULL, 273 MUTEX_DRIVER, NULL); 274 iscsit_global.global_svc_state = ISE_DETACHED; 275 276 mutex_init(&iscsit_rxpdu_queue_monitor_mutex, NULL, 277 MUTEX_DRIVER, NULL); 278 mutex_init(&login_sm_session_mutex, NULL, MUTEX_DRIVER, NULL); 279 iscsit_rxpdu_queue_monitor_thr_id = NULL; 280 iscsit_rxpdu_queue_monitor_thr_running = B_FALSE; 281 cv_init(&iscsit_rxpdu_queue_monitor_cv, NULL, CV_DEFAULT, NULL); 282 283 if ((rc = mod_install(&modlinkage)) != 0) { 284 mutex_destroy(&iscsit_global.global_state_mutex); 285 rw_destroy(&iscsit_global.global_rwlock); 286 return (rc); 287 } 288 289 return (rc); 290 } 291 292 int 293 _info(struct modinfo *modinfop) 294 { 295 return (mod_info(&modlinkage, modinfop)); 296 } 297 298 int 299 _fini(void) 300 { 301 int rc; 302 303 rc = mod_remove(&modlinkage); 304 305 if (rc == 0) { 306 mutex_destroy(&iscsit_rxpdu_queue_monitor_mutex); 307 mutex_destroy(&login_sm_session_mutex); 308 cv_destroy(&iscsit_rxpdu_queue_monitor_cv); 309 mutex_destroy(&iscsit_global.global_state_mutex); 310 rw_destroy(&iscsit_global.global_rwlock); 311 } 312 313 return (rc); 314 } 315 316 /* 317 * DDI entry points. 318 */ 319 320 /* ARGSUSED */ 321 static int 322 iscsit_drv_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, 323 void **result) 324 { 325 ulong_t instance = getminor((dev_t)arg); 326 327 switch (cmd) { 328 case DDI_INFO_DEVT2DEVINFO: 329 *result = iscsit_global.global_dip; 330 return (DDI_SUCCESS); 331 332 case DDI_INFO_DEVT2INSTANCE: 333 *result = (void *)instance; 334 return (DDI_SUCCESS); 335 336 default: 337 break; 338 } 339 340 return (DDI_FAILURE); 341 } 342 343 static int 344 iscsit_drv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 345 { 346 if (cmd != DDI_ATTACH) { 347 return (DDI_FAILURE); 348 } 349 350 if (ddi_get_instance(dip) != 0) { 351 /* we only allow instance 0 to attach */ 352 return (DDI_FAILURE); 353 } 354 355 /* create the minor node */ 356 if (ddi_create_minor_node(dip, ISCSIT_MODNAME, S_IFCHR, 0, 357 DDI_PSEUDO, 0) != DDI_SUCCESS) { 358 cmn_err(CE_WARN, "iscsit_drv_attach: " 359 "failed creating minor node"); 360 return (DDI_FAILURE); 361 } 362 363 if (iscsit_init(dip) != IDM_STATUS_SUCCESS) { 364 cmn_err(CE_WARN, "iscsit_drv_attach: " 365 "failed to initialize"); 366 ddi_remove_minor_node(dip, NULL); 367 return (DDI_FAILURE); 368 } 369 370 iscsit_global.global_svc_state = ISE_DISABLED; 371 iscsit_global.global_dip = dip; 372 373 return (DDI_SUCCESS); 374 } 375 376 /*ARGSUSED*/ 377 static int 378 iscsit_drv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 379 { 380 if (cmd != DDI_DETACH) 381 return (DDI_FAILURE); 382 383 /* 384 * drv_detach is called in a context that owns the 385 * device node for the /dev/pseudo device. If this thread blocks 386 * for any resource, other threads that need the /dev/pseudo device 387 * may end up in a deadlock with this thread.Hence, we use a 388 * separate lock just for the structures that drv_detach needs 389 * to access. 390 */ 391 mutex_enter(&iscsit_global.global_state_mutex); 392 if (iscsit_drv_busy()) { 393 mutex_exit(&iscsit_global.global_state_mutex); 394 return (EBUSY); 395 } 396 397 iscsit_global.global_dip = NULL; 398 ddi_remove_minor_node(dip, NULL); 399 400 ldi_ident_release(iscsit_global.global_li); 401 iscsit_global.global_svc_state = ISE_DETACHED; 402 403 mutex_exit(&iscsit_global.global_state_mutex); 404 405 return (DDI_SUCCESS); 406 } 407 408 /*ARGSUSED*/ 409 static int 410 iscsit_drv_open(dev_t *devp, int flag, int otyp, cred_t *credp) 411 { 412 return (0); 413 } 414 415 /* ARGSUSED */ 416 static int 417 iscsit_drv_close(dev_t dev, int flag, int otyp, cred_t *credp) 418 { 419 return (0); 420 } 421 422 static boolean_t 423 iscsit_drv_busy(void) 424 { 425 ASSERT(MUTEX_HELD(&iscsit_global.global_state_mutex)); 426 427 switch (iscsit_global.global_svc_state) { 428 case ISE_DISABLED: 429 case ISE_DETACHED: 430 return (B_FALSE); 431 default: 432 return (B_TRUE); 433 } 434 /* NOTREACHED */ 435 } 436 437 /* ARGSUSED */ 438 static int 439 iscsit_drv_ioctl(dev_t drv, int cmd, intptr_t argp, int flag, cred_t *cred, 440 int *retval) 441 { 442 iscsit_ioc_set_config_t setcfg; 443 iscsit_ioc_set_config32_t setcfg32; 444 char *cfg_pnvlist = NULL; 445 nvlist_t *cfg_nvlist = NULL; 446 it_config_t *cfg = NULL; 447 idm_status_t idmrc; 448 int rc = 0; 449 450 if (drv_priv(cred) != 0) { 451 return (EPERM); 452 } 453 454 mutex_enter(&iscsit_global.global_state_mutex); 455 456 /* 457 * Validate ioctl requests against global service state 458 */ 459 switch (iscsit_global.global_svc_state) { 460 case ISE_ENABLED: 461 if (cmd == ISCSIT_IOC_DISABLE_SVC) { 462 iscsit_global.global_svc_state = ISE_DISABLING; 463 } else if (cmd == ISCSIT_IOC_ENABLE_SVC) { 464 /* Already enabled */ 465 mutex_exit(&iscsit_global.global_state_mutex); 466 return (0); 467 } else { 468 iscsit_global.global_svc_state = ISE_BUSY; 469 } 470 break; 471 case ISE_DISABLED: 472 if (cmd == ISCSIT_IOC_ENABLE_SVC) { 473 iscsit_global.global_svc_state = ISE_ENABLING; 474 } else if (cmd == ISCSIT_IOC_DISABLE_SVC) { 475 /* Already disabled */ 476 mutex_exit(&iscsit_global.global_state_mutex); 477 return (0); 478 } else { 479 rc = EFAULT; 480 } 481 break; 482 case ISE_BUSY: 483 case ISE_ENABLING: 484 case ISE_DISABLING: 485 rc = EAGAIN; 486 break; 487 case ISE_DETACHED: 488 default: 489 rc = EFAULT; 490 break; 491 } 492 493 mutex_exit(&iscsit_global.global_state_mutex); 494 if (rc != 0) 495 return (rc); 496 497 /* Handle ioctl request (enable/disable have already been handled) */ 498 switch (cmd) { 499 case ISCSIT_IOC_SET_CONFIG: 500 /* Any errors must set state back to ISE_ENABLED */ 501 switch (ddi_model_convert_from(flag & FMODELS)) { 502 case DDI_MODEL_ILP32: 503 if (ddi_copyin((void *)argp, &setcfg32, 504 sizeof (iscsit_ioc_set_config32_t), flag) != 0) { 505 rc = EFAULT; 506 goto cleanup; 507 } 508 509 setcfg.set_cfg_pnvlist = 510 (char *)((uintptr_t)setcfg32.set_cfg_pnvlist); 511 setcfg.set_cfg_vers = setcfg32.set_cfg_vers; 512 setcfg.set_cfg_pnvlist_len = 513 setcfg32.set_cfg_pnvlist_len; 514 break; 515 case DDI_MODEL_NONE: 516 if (ddi_copyin((void *)argp, &setcfg, 517 sizeof (iscsit_ioc_set_config_t), flag) != 0) { 518 rc = EFAULT; 519 goto cleanup; 520 } 521 break; 522 default: 523 rc = EFAULT; 524 goto cleanup; 525 } 526 527 /* Check API version */ 528 if (setcfg.set_cfg_vers != ISCSIT_API_VERS0) { 529 rc = EINVAL; 530 goto cleanup; 531 } 532 533 /* Config is in packed nvlist format so unpack it */ 534 cfg_pnvlist = kmem_alloc(setcfg.set_cfg_pnvlist_len, 535 KM_SLEEP); 536 ASSERT(cfg_pnvlist != NULL); 537 538 if (ddi_copyin(setcfg.set_cfg_pnvlist, cfg_pnvlist, 539 setcfg.set_cfg_pnvlist_len, flag) != 0) { 540 rc = EFAULT; 541 goto cleanup; 542 } 543 544 rc = nvlist_unpack(cfg_pnvlist, setcfg.set_cfg_pnvlist_len, 545 &cfg_nvlist, KM_SLEEP); 546 if (rc != 0) { 547 goto cleanup; 548 } 549 550 /* Translate nvlist */ 551 rc = it_nv_to_config(cfg_nvlist, &cfg); 552 if (rc != 0) { 553 cmn_err(CE_WARN, "Configuration is invalid"); 554 goto cleanup; 555 } 556 557 /* Update config */ 558 rc = iscsit_config_merge(cfg); 559 /* FALLTHROUGH */ 560 561 cleanup: 562 if (cfg) 563 it_config_free_cmn(cfg); 564 if (cfg_pnvlist) 565 kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len); 566 nvlist_free(cfg_nvlist); 567 568 /* 569 * Now that the reconfig is complete set our state back to 570 * enabled. 571 */ 572 mutex_enter(&iscsit_global.global_state_mutex); 573 iscsit_global.global_svc_state = ISE_ENABLED; 574 mutex_exit(&iscsit_global.global_state_mutex); 575 break; 576 case ISCSIT_IOC_ENABLE_SVC: { 577 iscsit_hostinfo_t hostinfo; 578 579 if (ddi_copyin((void *)argp, &hostinfo.length, 580 sizeof (hostinfo.length), flag) != 0) { 581 mutex_enter(&iscsit_global.global_state_mutex); 582 iscsit_global.global_svc_state = ISE_DISABLED; 583 mutex_exit(&iscsit_global.global_state_mutex); 584 return (EFAULT); 585 } 586 587 if (hostinfo.length > sizeof (hostinfo.fqhn)) 588 hostinfo.length = sizeof (hostinfo.fqhn); 589 590 if (ddi_copyin((void *)((caddr_t)argp + 591 sizeof (hostinfo.length)), &hostinfo.fqhn, 592 hostinfo.length, flag) != 0) { 593 mutex_enter(&iscsit_global.global_state_mutex); 594 iscsit_global.global_svc_state = ISE_DISABLED; 595 mutex_exit(&iscsit_global.global_state_mutex); 596 return (EFAULT); 597 } 598 599 idmrc = iscsit_enable_svc(&hostinfo); 600 mutex_enter(&iscsit_global.global_state_mutex); 601 if (idmrc == IDM_STATUS_SUCCESS) { 602 iscsit_global.global_svc_state = ISE_ENABLED; 603 } else { 604 rc = EIO; 605 iscsit_global.global_svc_state = ISE_DISABLED; 606 } 607 mutex_exit(&iscsit_global.global_state_mutex); 608 break; 609 } 610 case ISCSIT_IOC_DISABLE_SVC: 611 iscsit_disable_svc(); 612 mutex_enter(&iscsit_global.global_state_mutex); 613 iscsit_global.global_svc_state = ISE_DISABLED; 614 mutex_exit(&iscsit_global.global_state_mutex); 615 break; 616 617 default: 618 rc = EINVAL; 619 mutex_enter(&iscsit_global.global_state_mutex); 620 iscsit_global.global_svc_state = ISE_ENABLED; 621 mutex_exit(&iscsit_global.global_state_mutex); 622 } 623 624 return (rc); 625 } 626 627 static idm_status_t 628 iscsit_init(dev_info_t *dip) 629 { 630 int rc; 631 632 rc = ldi_ident_from_dip(dip, &iscsit_global.global_li); 633 ASSERT(rc == 0); /* Failure indicates invalid argument */ 634 635 iscsit_global.global_svc_state = ISE_DISABLED; 636 637 return (IDM_STATUS_SUCCESS); 638 } 639 640 /* 641 * iscsit_enable_svc 642 * 643 * registers all the configured targets and target portals with STMF 644 */ 645 static idm_status_t 646 iscsit_enable_svc(iscsit_hostinfo_t *hostinfo) 647 { 648 stmf_port_provider_t *pp; 649 stmf_dbuf_store_t *dbuf_store; 650 boolean_t did_iscsit_isns_init; 651 idm_status_t retval = IDM_STATUS_SUCCESS; 652 653 ASSERT(iscsit_global.global_svc_state == ISE_ENABLING); 654 655 /* 656 * Make sure that can tell if we have partially allocated 657 * in case we need to exit and tear down anything allocated. 658 */ 659 iscsit_global.global_tsih_pool = NULL; 660 iscsit_global.global_dbuf_store = NULL; 661 iscsit_status_pdu_cache = NULL; 662 pp = NULL; 663 iscsit_global.global_pp = NULL; 664 iscsit_global.global_default_tpg = NULL; 665 did_iscsit_isns_init = B_FALSE; 666 iscsit_global.global_dispatch_taskq = NULL; 667 668 /* Setup remaining fields in iscsit_global_t */ 669 idm_refcnt_init(&iscsit_global.global_refcnt, 670 &iscsit_global); 671 672 avl_create(&iscsit_global.global_discovery_sessions, 673 iscsit_sess_avl_compare, sizeof (iscsit_sess_t), 674 offsetof(iscsit_sess_t, ist_tgt_ln)); 675 676 avl_create(&iscsit_global.global_target_list, 677 iscsit_tgt_avl_compare, sizeof (iscsit_tgt_t), 678 offsetof(iscsit_tgt_t, target_global_ln)); 679 680 list_create(&iscsit_global.global_deleted_target_list, 681 sizeof (iscsit_tgt_t), 682 offsetof(iscsit_tgt_t, target_global_deleted_ln)); 683 684 avl_create(&iscsit_global.global_tpg_list, 685 iscsit_tpg_avl_compare, sizeof (iscsit_tpg_t), 686 offsetof(iscsit_tpg_t, tpg_global_ln)); 687 688 avl_create(&iscsit_global.global_ini_list, 689 iscsit_ini_avl_compare, sizeof (iscsit_ini_t), 690 offsetof(iscsit_ini_t, ini_global_ln)); 691 692 iscsit_global.global_tsih_pool = vmem_create("iscsit_tsih_pool", 693 (void *)1, ISCSI_MAX_TSIH, 1, NULL, NULL, NULL, 0, 694 VM_SLEEP | VMC_IDENTIFIER); 695 696 /* 697 * Setup STMF dbuf store. Our buffers are bound to a specific 698 * connection so we really can't let STMF cache buffers for us. 699 * Consequently we'll just allocate one global buffer store. 700 */ 701 dbuf_store = stmf_alloc(STMF_STRUCT_DBUF_STORE, 0, 0); 702 if (dbuf_store == NULL) { 703 retval = IDM_STATUS_FAIL; 704 goto tear_down_and_return; 705 } 706 dbuf_store->ds_alloc_data_buf = iscsit_dbuf_alloc; 707 dbuf_store->ds_free_data_buf = iscsit_dbuf_free; 708 dbuf_store->ds_port_private = NULL; 709 iscsit_global.global_dbuf_store = dbuf_store; 710 711 /* Status PDU cache */ 712 iscsit_status_pdu_cache = kmem_cache_create("iscsit_status_pdu_cache", 713 sizeof (idm_pdu_t) + sizeof (iscsi_scsi_rsp_hdr_t), 8, 714 &iscsit_status_pdu_constructor, 715 NULL, NULL, NULL, NULL, KM_SLEEP); 716 717 /* Default TPG and portal */ 718 iscsit_global.global_default_tpg = iscsit_tpg_createdefault(); 719 if (iscsit_global.global_default_tpg == NULL) { 720 retval = IDM_STATUS_FAIL; 721 goto tear_down_and_return; 722 } 723 724 /* initialize isns client */ 725 (void) iscsit_isns_init(hostinfo); 726 did_iscsit_isns_init = B_TRUE; 727 728 /* Register port provider */ 729 pp = stmf_alloc(STMF_STRUCT_PORT_PROVIDER, 0, 0); 730 if (pp == NULL) { 731 retval = IDM_STATUS_FAIL; 732 goto tear_down_and_return; 733 } 734 735 pp->pp_portif_rev = PORTIF_REV_1; 736 pp->pp_instance = 0; 737 pp->pp_name = ISCSIT_MODNAME; 738 pp->pp_cb = iscsit_pp_cb; 739 740 iscsit_global.global_pp = pp; 741 742 743 if (stmf_register_port_provider(pp) != STMF_SUCCESS) { 744 retval = IDM_STATUS_FAIL; 745 goto tear_down_and_return; 746 } 747 748 iscsit_global.global_dispatch_taskq = taskq_create("iscsit_dispatch", 749 1, minclsyspri, 16, 16, TASKQ_PREPOPULATE); 750 751 /* Scan staged PDUs, meaningful in MC/S situations */ 752 iscsit_rxpdu_queue_monitor_start(); 753 754 return (IDM_STATUS_SUCCESS); 755 756 tear_down_and_return: 757 758 if (iscsit_global.global_dispatch_taskq) { 759 taskq_destroy(iscsit_global.global_dispatch_taskq); 760 iscsit_global.global_dispatch_taskq = NULL; 761 } 762 763 if (did_iscsit_isns_init) 764 iscsit_isns_fini(); 765 766 if (iscsit_global.global_default_tpg) { 767 iscsit_tpg_destroydefault(iscsit_global.global_default_tpg); 768 iscsit_global.global_default_tpg = NULL; 769 } 770 771 if (iscsit_global.global_pp) 772 iscsit_global.global_pp = NULL; 773 774 if (pp) 775 stmf_free(pp); 776 777 if (iscsit_status_pdu_cache) { 778 kmem_cache_destroy(iscsit_status_pdu_cache); 779 iscsit_status_pdu_cache = NULL; 780 } 781 782 if (iscsit_global.global_dbuf_store) { 783 stmf_free(iscsit_global.global_dbuf_store); 784 iscsit_global.global_dbuf_store = NULL; 785 } 786 787 if (iscsit_global.global_tsih_pool) { 788 vmem_destroy(iscsit_global.global_tsih_pool); 789 iscsit_global.global_tsih_pool = NULL; 790 } 791 792 avl_destroy(&iscsit_global.global_ini_list); 793 avl_destroy(&iscsit_global.global_tpg_list); 794 list_destroy(&iscsit_global.global_deleted_target_list); 795 avl_destroy(&iscsit_global.global_target_list); 796 avl_destroy(&iscsit_global.global_discovery_sessions); 797 798 idm_refcnt_destroy(&iscsit_global.global_refcnt); 799 800 return (retval); 801 } 802 803 /* 804 * iscsit_disable_svc 805 * 806 * clean up all existing connections and deregister targets from STMF 807 */ 808 static void 809 iscsit_disable_svc(void) 810 { 811 iscsit_sess_t *sess; 812 813 ASSERT(iscsit_global.global_svc_state == ISE_DISABLING); 814 815 iscsit_rxpdu_queue_monitor_stop(); 816 817 /* tear down discovery sessions */ 818 for (sess = avl_first(&iscsit_global.global_discovery_sessions); 819 sess != NULL; 820 sess = AVL_NEXT(&iscsit_global.global_discovery_sessions, sess)) 821 iscsit_sess_close(sess); 822 823 /* 824 * Passing NULL to iscsit_config_merge tells it to go to an empty 825 * config. 826 */ 827 (void) iscsit_config_merge(NULL); 828 829 /* 830 * Wait until there are no more global references 831 */ 832 idm_refcnt_wait_ref(&iscsit_global.global_refcnt); 833 idm_refcnt_destroy(&iscsit_global.global_refcnt); 834 835 /* 836 * Default TPG must be destroyed after global_refcnt is 0. 837 */ 838 iscsit_tpg_destroydefault(iscsit_global.global_default_tpg); 839 840 avl_destroy(&iscsit_global.global_discovery_sessions); 841 list_destroy(&iscsit_global.global_deleted_target_list); 842 avl_destroy(&iscsit_global.global_target_list); 843 avl_destroy(&iscsit_global.global_tpg_list); 844 avl_destroy(&iscsit_global.global_ini_list); 845 846 taskq_destroy(iscsit_global.global_dispatch_taskq); 847 848 iscsit_isns_fini(); 849 850 stmf_free(iscsit_global.global_dbuf_store); 851 iscsit_global.global_dbuf_store = NULL; 852 853 (void) stmf_deregister_port_provider(iscsit_global.global_pp); 854 stmf_free(iscsit_global.global_pp); 855 iscsit_global.global_pp = NULL; 856 857 kmem_cache_destroy(iscsit_status_pdu_cache); 858 iscsit_status_pdu_cache = NULL; 859 860 vmem_destroy(iscsit_global.global_tsih_pool); 861 iscsit_global.global_tsih_pool = NULL; 862 } 863 864 void 865 iscsit_global_hold() 866 { 867 /* 868 * To take out a global hold, we must either own the global 869 * state mutex or we must be running inside of an ioctl that 870 * has set the global state to ISE_BUSY, ISE_DISABLING, or 871 * ISE_ENABLING. We don't track the "owner" for these flags, 872 * so just checking if they are set is enough for now. 873 */ 874 ASSERT((iscsit_global.global_svc_state == ISE_ENABLING) || 875 (iscsit_global.global_svc_state == ISE_DISABLING) || 876 (iscsit_global.global_svc_state == ISE_BUSY) || 877 MUTEX_HELD(&iscsit_global.global_state_mutex)); 878 879 idm_refcnt_hold(&iscsit_global.global_refcnt); 880 } 881 882 void 883 iscsit_global_rele() 884 { 885 idm_refcnt_rele(&iscsit_global.global_refcnt); 886 } 887 888 void 889 iscsit_global_wait_ref() 890 { 891 idm_refcnt_wait_ref(&iscsit_global.global_refcnt); 892 } 893 894 /* 895 * IDM callbacks 896 */ 897 898 /*ARGSUSED*/ 899 void 900 iscsit_rx_pdu(idm_conn_t *ic, idm_pdu_t *rx_pdu) 901 { 902 iscsit_conn_t *ict = ic->ic_handle; 903 switch (IDM_PDU_OPCODE(rx_pdu)) { 904 case ISCSI_OP_SCSI_CMD: 905 ASSERT(0); /* Shouldn't happen */ 906 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 907 break; 908 case ISCSI_OP_SNACK_CMD: 909 /* 910 * We'll need to handle this when we support ERL1/2. For 911 * now we treat it as a protocol error. 912 */ 913 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 914 idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL); 915 break; 916 case ISCSI_OP_SCSI_TASK_MGT_MSG: 917 if (iscsit_check_cmdsn_and_queue(rx_pdu)) { 918 iscsit_set_cmdsn(ict, rx_pdu); 919 iscsit_op_scsi_task_mgmt(ict, rx_pdu); 920 } 921 break; 922 case ISCSI_OP_NOOP_OUT: 923 case ISCSI_OP_LOGIN_CMD: 924 case ISCSI_OP_TEXT_CMD: 925 case ISCSI_OP_LOGOUT_CMD: 926 /* 927 * If/when we switch to userland processing these PDU's 928 * will be handled by iscsitd. 929 */ 930 iscsit_deferred_dispatch(rx_pdu); 931 break; 932 default: 933 /* Protocol error */ 934 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 935 idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL); 936 break; 937 } 938 } 939 940 /*ARGSUSED*/ 941 void 942 iscsit_rx_pdu_error(idm_conn_t *ic, idm_pdu_t *rx_pdu, idm_status_t status) 943 { 944 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 945 } 946 947 /* 948 * iscsit_rx_scsi_rsp -- cause the connection to be closed if response rx'd 949 * 950 * A target sends an SCSI Response PDU, it should never receive one. 951 * This has been seen when running the Codemonicon suite of tests which 952 * does negative testing of the protocol. If such a condition occurs using 953 * a normal initiator it most likely means there's data corruption in the 954 * header and that's grounds for dropping the connection as well. 955 */ 956 void 957 iscsit_rx_scsi_rsp(idm_conn_t *ic, idm_pdu_t *rx_pdu) 958 { 959 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 960 idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL); 961 } 962 963 void 964 iscsit_task_aborted(idm_task_t *idt, idm_status_t status) 965 { 966 iscsit_task_t *itask = idt->idt_private; 967 968 switch (status) { 969 case IDM_STATUS_SUSPENDED: 970 break; 971 case IDM_STATUS_ABORTED: 972 mutex_enter(&itask->it_mutex); 973 itask->it_aborted = B_TRUE; 974 /* 975 * We rely on the fact that STMF tracks outstanding 976 * buffer transfers and will free all of our buffers 977 * before freeing the task so we don't need to 978 * explicitly free the buffers from iscsit/idm 979 */ 980 if (itask->it_stmf_abort) { 981 mutex_exit(&itask->it_mutex); 982 /* 983 * Task is no longer active 984 */ 985 iscsit_task_done(itask); 986 987 /* 988 * STMF has already asked for this task to be aborted 989 * 990 * STMF specification is wrong... says to return 991 * STMF_ABORTED, the code actually looks for 992 * STMF_ABORT_SUCCESS. 993 */ 994 stmf_task_lport_aborted(itask->it_stmf_task, 995 STMF_ABORT_SUCCESS, STMF_IOF_LPORT_DONE); 996 return; 997 } else { 998 mutex_exit(&itask->it_mutex); 999 /* 1000 * Tell STMF to stop processing the task. 1001 */ 1002 stmf_abort(STMF_QUEUE_TASK_ABORT, itask->it_stmf_task, 1003 STMF_ABORTED, NULL); 1004 return; 1005 } 1006 /*NOTREACHED*/ 1007 default: 1008 ASSERT(0); 1009 } 1010 } 1011 1012 /*ARGSUSED*/ 1013 idm_status_t 1014 iscsit_client_notify(idm_conn_t *ic, idm_client_notify_t icn, 1015 uintptr_t data) 1016 { 1017 idm_status_t rc = IDM_STATUS_SUCCESS; 1018 1019 /* 1020 * IDM client notifications will never occur at interrupt level 1021 * since they are generated from the connection state machine which 1022 * running on taskq threads. 1023 * 1024 */ 1025 switch (icn) { 1026 case CN_CONNECT_ACCEPT: 1027 rc = iscsit_conn_accept(ic); /* No data */ 1028 break; 1029 case CN_FFP_ENABLED: 1030 rc = iscsit_ffp_enabled(ic); /* No data */ 1031 break; 1032 case CN_FFP_DISABLED: 1033 /* 1034 * Data indicates whether this was the result of an 1035 * explicit logout request. 1036 */ 1037 rc = iscsit_ffp_disabled(ic, (idm_ffp_disable_t)data); 1038 break; 1039 case CN_CONNECT_LOST: 1040 rc = iscsit_conn_lost(ic); 1041 break; 1042 case CN_CONNECT_DESTROY: 1043 rc = iscsit_conn_destroy(ic); 1044 break; 1045 case CN_LOGIN_FAIL: 1046 /* 1047 * Force the login state machine to completion 1048 */ 1049 rc = iscsit_login_fail(ic); 1050 break; 1051 default: 1052 rc = IDM_STATUS_REJECT; 1053 break; 1054 } 1055 1056 return (rc); 1057 } 1058 1059 /* 1060 * iscsit_update_statsn is invoked for all the PDUs which have the StatSN 1061 * field in the header. The StatSN is incremented if the IDM_PDU_ADVANCE_STATSN 1062 * flag is set in the pdu flags field. The StatSN is connection-wide and is 1063 * protected by the mutex ict_statsn_mutex. For Data-In PDUs, if the flag 1064 * IDM_TASK_PHASECOLLAPSE_REQ is set, the status (phase-collapse) is also filled 1065 */ 1066 void 1067 iscsit_update_statsn(idm_task_t *idm_task, idm_pdu_t *pdu) 1068 { 1069 iscsi_scsi_rsp_hdr_t *rsp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr; 1070 iscsit_conn_t *ict = (iscsit_conn_t *)pdu->isp_ic->ic_handle; 1071 iscsit_task_t *itask = NULL; 1072 scsi_task_t *task = NULL; 1073 1074 mutex_enter(&ict->ict_statsn_mutex); 1075 rsp->statsn = htonl(ict->ict_statsn); 1076 if (pdu->isp_flags & IDM_PDU_ADVANCE_STATSN) 1077 ict->ict_statsn++; 1078 mutex_exit(&ict->ict_statsn_mutex); 1079 1080 /* 1081 * The last SCSI Data PDU passed for a command may also contain the 1082 * status if the status indicates termination with no expections, i.e. 1083 * no sense data or response involved. If the command completes with 1084 * an error, then the response and sense data will be sent in a 1085 * separate iSCSI Response PDU. 1086 */ 1087 if ((idm_task) && (idm_task->idt_flags & IDM_TASK_PHASECOLLAPSE_REQ)) { 1088 itask = idm_task->idt_private; 1089 task = itask->it_stmf_task; 1090 1091 rsp->cmd_status = task->task_scsi_status; 1092 rsp->flags |= ISCSI_FLAG_DATA_STATUS; 1093 if (task->task_status_ctrl & TASK_SCTRL_OVER) { 1094 rsp->flags |= ISCSI_FLAG_CMD_OVERFLOW; 1095 } else if (task->task_status_ctrl & TASK_SCTRL_UNDER) { 1096 rsp->flags |= ISCSI_FLAG_CMD_UNDERFLOW; 1097 } 1098 rsp->residual_count = htonl(task->task_resid); 1099 1100 /* 1101 * Removing the task from the session task list 1102 * just before the status is sent in the last 1103 * Data PDU transfer 1104 */ 1105 iscsit_task_done(itask); 1106 } 1107 } 1108 1109 void 1110 iscsit_build_hdr(idm_task_t *idm_task, idm_pdu_t *pdu, uint8_t opcode) 1111 { 1112 iscsit_task_t *itask = idm_task->idt_private; 1113 iscsi_data_rsp_hdr_t *dh = (iscsi_data_rsp_hdr_t *)pdu->isp_hdr; 1114 1115 /* 1116 * We acquired iscsit_sess_t.ist_sn_mutex in iscsit_xfer_scsi_data 1117 */ 1118 ASSERT(MUTEX_HELD(&itask->it_ict->ict_sess->ist_sn_mutex)); 1119 /* 1120 * On incoming data, the target transfer tag and Lun is only 1121 * provided by the target if the A bit is set, Since the target 1122 * does not currently support Error Recovery Level 1, the A 1123 * bit is never set. 1124 */ 1125 dh->opcode = opcode; 1126 dh->itt = itask->it_itt; 1127 dh->ttt = ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_SCSI_DATA_RSP) ? 1128 ISCSI_RSVD_TASK_TAG : itask->it_ttt; 1129 1130 dh->expcmdsn = htonl(itask->it_ict->ict_sess->ist_expcmdsn); 1131 dh->maxcmdsn = htonl(itask->it_ict->ict_sess->ist_maxcmdsn); 1132 1133 /* 1134 * IDM must set: 1135 * 1136 * data.flags and rtt.flags 1137 * data.dlength 1138 * data.datasn 1139 * data.offset 1140 * statsn, residual_count and cmd_status (for phase collapse) 1141 * rtt.rttsn 1142 * rtt.data_offset 1143 * rtt.data_length 1144 */ 1145 } 1146 1147 void 1148 iscsit_keepalive(idm_conn_t *ic) 1149 { 1150 idm_pdu_t *nop_in_pdu; 1151 iscsi_nop_in_hdr_t *nop_in; 1152 iscsit_conn_t *ict = ic->ic_handle; 1153 1154 /* 1155 * IDM noticed the connection has been idle for too long so it's 1156 * time to provoke some activity. Build and transmit an iSCSI 1157 * nop-in PDU -- when the initiator responds it will be counted 1158 * as "activity" and keep the connection alive. 1159 * 1160 * We don't actually care about the response here at the iscsit level 1161 * so we will just throw it away without looking at it when it arrives. 1162 */ 1163 nop_in_pdu = idm_pdu_alloc(sizeof (*nop_in), 0); 1164 idm_pdu_init(nop_in_pdu, ic, NULL, NULL); 1165 nop_in = (iscsi_nop_in_hdr_t *)nop_in_pdu->isp_hdr; 1166 bzero(nop_in, sizeof (*nop_in)); 1167 nop_in->opcode = ISCSI_OP_NOOP_IN; 1168 nop_in->flags = ISCSI_FLAG_FINAL; 1169 nop_in->itt = ISCSI_RSVD_TASK_TAG; 1170 /* 1171 * When the target sends a NOP-In as a Ping, the target transfer tag 1172 * is set to a valid (not reserved) value and the initiator task tag 1173 * is set to ISCSI_RSVD_TASK_TAG (0xffffffff). In this case the StatSN 1174 * will always contain the next sequence number but the StatSN for the 1175 * connection is not advanced after this PDU is sent. 1176 */ 1177 nop_in_pdu->isp_flags |= IDM_PDU_SET_STATSN; 1178 /* 1179 * This works because we don't currently allocate ttt's anywhere else 1180 * in iscsit so as long as we stay out of IDM's range we are safe. 1181 * If we need to allocate ttt's for other PDU's in the future this will 1182 * need to be improved. 1183 */ 1184 mutex_enter(&ict->ict_mutex); 1185 nop_in->ttt = ict->ict_keepalive_ttt; 1186 ict->ict_keepalive_ttt++; 1187 if (ict->ict_keepalive_ttt == ISCSI_RSVD_TASK_TAG) 1188 ict->ict_keepalive_ttt = IDM_TASKIDS_MAX; 1189 mutex_exit(&ict->ict_mutex); 1190 1191 iscsit_pdu_tx(nop_in_pdu); 1192 } 1193 1194 static idm_status_t 1195 iscsit_conn_accept(idm_conn_t *ic) 1196 { 1197 iscsit_conn_t *ict; 1198 1199 /* 1200 * We need to get a global hold here to ensure that the service 1201 * doesn't get shutdown prior to establishing a session. This 1202 * gets released in iscsit_conn_destroy(). 1203 */ 1204 mutex_enter(&iscsit_global.global_state_mutex); 1205 if (iscsit_global.global_svc_state != ISE_ENABLED) { 1206 mutex_exit(&iscsit_global.global_state_mutex); 1207 return (IDM_STATUS_FAIL); 1208 } 1209 iscsit_global_hold(); 1210 mutex_exit(&iscsit_global.global_state_mutex); 1211 1212 /* 1213 * Allocate an associated iscsit structure to represent this 1214 * connection. We shouldn't really create a session until we 1215 * get the first login PDU. 1216 */ 1217 ict = kmem_zalloc(sizeof (*ict), KM_SLEEP); 1218 1219 ict->ict_ic = ic; 1220 ict->ict_statsn = 1; 1221 ict->ict_keepalive_ttt = IDM_TASKIDS_MAX; /* Avoid IDM TT range */ 1222 ic->ic_handle = ict; 1223 mutex_init(&ict->ict_mutex, NULL, MUTEX_DRIVER, NULL); 1224 mutex_init(&ict->ict_statsn_mutex, NULL, MUTEX_DRIVER, NULL); 1225 idm_refcnt_init(&ict->ict_refcnt, ict); 1226 1227 /* 1228 * Initialize login state machine 1229 */ 1230 if (iscsit_login_sm_init(ict) != IDM_STATUS_SUCCESS) { 1231 iscsit_global_rele(); 1232 /* 1233 * Cleanup the ict after idm notifies us about this failure 1234 */ 1235 return (IDM_STATUS_FAIL); 1236 } 1237 1238 return (IDM_STATUS_SUCCESS); 1239 } 1240 1241 idm_status_t 1242 iscsit_conn_reinstate(iscsit_conn_t *reinstate_ict, iscsit_conn_t *new_ict) 1243 { 1244 idm_status_t result; 1245 1246 /* 1247 * Note in new connection state that this connection is 1248 * reinstating an existing connection. 1249 */ 1250 new_ict->ict_reinstating = B_TRUE; 1251 new_ict->ict_reinstate_conn = reinstate_ict; 1252 new_ict->ict_statsn = reinstate_ict->ict_statsn; 1253 1254 /* 1255 * Now generate connection state machine event to existing connection 1256 * so that it starts the cleanup process. 1257 */ 1258 result = idm_conn_reinstate_event(reinstate_ict->ict_ic, 1259 new_ict->ict_ic); 1260 1261 return (result); 1262 } 1263 1264 void 1265 iscsit_conn_hold(iscsit_conn_t *ict) 1266 { 1267 idm_refcnt_hold(&ict->ict_refcnt); 1268 } 1269 1270 void 1271 iscsit_conn_rele(iscsit_conn_t *ict) 1272 { 1273 idm_refcnt_rele(&ict->ict_refcnt); 1274 } 1275 1276 void 1277 iscsit_conn_dispatch_hold(iscsit_conn_t *ict) 1278 { 1279 idm_refcnt_hold(&ict->ict_dispatch_refcnt); 1280 } 1281 1282 void 1283 iscsit_conn_dispatch_rele(iscsit_conn_t *ict) 1284 { 1285 idm_refcnt_rele(&ict->ict_dispatch_refcnt); 1286 } 1287 1288 static idm_status_t 1289 iscsit_login_fail(idm_conn_t *ic) 1290 { 1291 iscsit_conn_t *ict = ic->ic_handle; 1292 1293 /* Generate login state machine event */ 1294 iscsit_login_sm_event(ict, ILE_LOGIN_CONN_ERROR, NULL); 1295 1296 return (IDM_STATUS_SUCCESS); 1297 } 1298 1299 static idm_status_t 1300 iscsit_ffp_enabled(idm_conn_t *ic) 1301 { 1302 iscsit_conn_t *ict = ic->ic_handle; 1303 1304 /* Generate session state machine event */ 1305 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_LOGGED_IN, ict); 1306 1307 return (IDM_STATUS_SUCCESS); 1308 } 1309 1310 static idm_status_t 1311 iscsit_ffp_disabled(idm_conn_t *ic, idm_ffp_disable_t disable_class) 1312 { 1313 iscsit_conn_t *ict = ic->ic_handle; 1314 1315 /* Generate session state machine event */ 1316 switch (disable_class) { 1317 case FD_CONN_FAIL: 1318 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FFP_FAIL, ict); 1319 break; 1320 case FD_CONN_LOGOUT: 1321 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FFP_DISABLE, ict); 1322 break; 1323 case FD_SESS_LOGOUT: 1324 iscsit_sess_sm_event(ict->ict_sess, SE_SESSION_CLOSE, ict); 1325 break; 1326 default: 1327 ASSERT(0); 1328 } 1329 1330 return (IDM_STATUS_SUCCESS); 1331 } 1332 1333 static idm_status_t 1334 iscsit_conn_lost(idm_conn_t *ic) 1335 { 1336 iscsit_conn_t *ict = ic->ic_handle; 1337 iscsit_sess_t *ist = ict->ict_sess; 1338 iscsit_cbuf_t *cbuf; 1339 idm_pdu_t *rx_pdu; 1340 int i; 1341 1342 mutex_enter(&ict->ict_mutex); 1343 ict->ict_lost = B_TRUE; 1344 mutex_exit(&ict->ict_mutex); 1345 /* 1346 * scrub the staging queue for all PDUs on this connection 1347 */ 1348 if (ist != NULL) { 1349 mutex_enter(&ist->ist_sn_mutex); 1350 for (cbuf = ist->ist_rxpdu_queue, i = 0; 1351 ((cbuf->cb_num_elems > 0) && (i < ISCSIT_RXPDU_QUEUE_LEN)); 1352 i++) { 1353 if (((rx_pdu = cbuf->cb_buffer[i]) != NULL) && 1354 (rx_pdu->isp_ic == ic)) { 1355 /* conn is lost, drop the pdu */ 1356 DTRACE_PROBE3(scrubbing__staging__queue, 1357 iscsit_sess_t *, ist, idm_conn_t *, ic, 1358 idm_pdu_t *, rx_pdu); 1359 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 1360 cbuf->cb_buffer[i] = NULL; 1361 cbuf->cb_num_elems--; 1362 iscsit_conn_dispatch_rele(ict); 1363 } 1364 } 1365 mutex_exit(&ist->ist_sn_mutex); 1366 } 1367 /* 1368 * Make sure there aren't any PDU's transitioning from the receive 1369 * handler to the dispatch taskq. 1370 */ 1371 idm_refcnt_wait_ref(&ict->ict_dispatch_refcnt); 1372 1373 return (IDM_STATUS_SUCCESS); 1374 } 1375 1376 static idm_status_t 1377 iscsit_conn_destroy(idm_conn_t *ic) 1378 { 1379 iscsit_conn_t *ict = ic->ic_handle; 1380 1381 mutex_enter(&ict->ict_mutex); 1382 ict->ict_destroyed = B_TRUE; 1383 mutex_exit(&ict->ict_mutex); 1384 1385 /* Generate session state machine event */ 1386 if (ict->ict_sess != NULL) { 1387 /* 1388 * Session state machine will call iscsit_conn_destroy_done() 1389 * when it has removed references to this connection. 1390 */ 1391 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FAIL, ict); 1392 } 1393 1394 idm_refcnt_wait_ref(&ict->ict_refcnt); 1395 /* 1396 * The session state machine does not need to post 1397 * events to IDM any longer, so it is safe to set 1398 * the idm connection reference to NULL 1399 */ 1400 ict->ict_ic = NULL; 1401 1402 /* Reap the login state machine */ 1403 iscsit_login_sm_fini(ict); 1404 1405 /* Clean up any text command remnants */ 1406 iscsit_text_cmd_fini(ict); 1407 1408 mutex_destroy(&ict->ict_mutex); 1409 idm_refcnt_destroy(&ict->ict_refcnt); 1410 kmem_free(ict, sizeof (*ict)); 1411 1412 iscsit_global_rele(); 1413 1414 return (IDM_STATUS_SUCCESS); 1415 } 1416 1417 void 1418 iscsit_conn_logout(iscsit_conn_t *ict) 1419 { 1420 /* 1421 * If the iscsi connection is active, then 1422 * logout the IDM connection by sending a 1423 * CE_LOGOUT_SESSION_SUCCESS, else, no action 1424 * needs to be taken because the connection 1425 * is already in the teardown process. 1426 */ 1427 mutex_enter(&ict->ict_mutex); 1428 if (ict->ict_lost == B_FALSE && ict->ict_destroyed == B_FALSE) { 1429 idm_conn_event(ict->ict_ic, CE_LOGOUT_SESSION_SUCCESS, NULL); 1430 } 1431 mutex_exit(&ict->ict_mutex); 1432 } 1433 1434 /* 1435 * STMF-related functions 1436 * 1437 * iSCSI to STMF mapping 1438 * 1439 * Session == ? 1440 * Connection == bound to local port but not itself a local port 1441 * Target 1442 * Target portal (group?) == local port (really but we're not going to do this) 1443 * iscsit needs to map connections to local ports (whatever we decide 1444 * they are) 1445 * Target == ? 1446 */ 1447 1448 /*ARGSUSED*/ 1449 static stmf_data_buf_t * 1450 iscsit_dbuf_alloc(scsi_task_t *task, uint32_t size, uint32_t *pminsize, 1451 uint32_t flags) 1452 { 1453 iscsit_task_t *itask = task->task_port_private; 1454 idm_buf_t *idm_buffer; 1455 iscsit_buf_t *ibuf; 1456 stmf_data_buf_t *result; 1457 uint32_t bsize; 1458 1459 /* 1460 * If the requested size is larger than MaxBurstLength and the 1461 * given pminsize is also larger than MaxBurstLength, then the 1462 * allocation fails (dbuf = NULL) and pminsize is modified to 1463 * be equal to MaxBurstLength. stmf/sbd then should re-invoke 1464 * this function with the corrected values for transfer. 1465 */ 1466 ASSERT(pminsize); 1467 if (size <= itask->it_ict->ict_op.op_max_burst_length) { 1468 bsize = size; 1469 } else if (*pminsize <= itask->it_ict->ict_op.op_max_burst_length) { 1470 bsize = itask->it_ict->ict_op.op_max_burst_length; 1471 } else { 1472 *pminsize = itask->it_ict->ict_op.op_max_burst_length; 1473 return (NULL); 1474 } 1475 1476 /* Alloc buffer */ 1477 idm_buffer = idm_buf_alloc(itask->it_ict->ict_ic, NULL, bsize); 1478 if (idm_buffer != NULL) { 1479 result = stmf_alloc(STMF_STRUCT_DATA_BUF, 1480 sizeof (iscsit_buf_t), 0); 1481 if (result != NULL) { 1482 /* Fill in stmf_data_buf_t */ 1483 ibuf = result->db_port_private; 1484 ibuf->ibuf_idm_buf = idm_buffer; 1485 ibuf->ibuf_stmf_buf = result; 1486 ibuf->ibuf_is_immed = B_FALSE; 1487 result->db_flags = DB_DONT_CACHE; 1488 result->db_buf_size = bsize; 1489 result->db_data_size = bsize; 1490 result->db_sglist_length = 1; 1491 result->db_sglist[0].seg_addr = idm_buffer->idb_buf; 1492 result->db_sglist[0].seg_length = 1493 idm_buffer->idb_buflen; 1494 return (result); 1495 } 1496 1497 /* Couldn't get the stmf_data_buf_t so free the buffer */ 1498 idm_buf_free(idm_buffer); 1499 } 1500 1501 return (NULL); 1502 } 1503 1504 /*ARGSUSED*/ 1505 static void 1506 iscsit_dbuf_free(stmf_dbuf_store_t *ds, stmf_data_buf_t *dbuf) 1507 { 1508 iscsit_buf_t *ibuf = dbuf->db_port_private; 1509 1510 if (ibuf->ibuf_is_immed) { 1511 /* 1512 * The iscsit_buf_t structure itself will be freed with its 1513 * associated task. Here we just need to free the PDU that 1514 * held the immediate data. 1515 */ 1516 idm_pdu_complete(ibuf->ibuf_immed_data_pdu, IDM_STATUS_SUCCESS); 1517 ibuf->ibuf_immed_data_pdu = 0; 1518 } else { 1519 idm_buf_free(ibuf->ibuf_idm_buf); 1520 stmf_free(dbuf); 1521 } 1522 } 1523 1524 /*ARGSUSED*/ 1525 stmf_status_t 1526 iscsit_xfer_scsi_data(scsi_task_t *task, stmf_data_buf_t *dbuf, 1527 uint32_t ioflags) 1528 { 1529 iscsit_task_t *iscsit_task = task->task_port_private; 1530 iscsit_sess_t *ict_sess = iscsit_task->it_ict->ict_sess; 1531 iscsit_buf_t *ibuf = dbuf->db_port_private; 1532 int idm_rc; 1533 1534 /* 1535 * If we are aborting then we can ignore this request 1536 */ 1537 if (iscsit_task->it_stmf_abort) { 1538 return (STMF_SUCCESS); 1539 } 1540 1541 /* 1542 * If it's not immediate data then start the transfer 1543 */ 1544 ASSERT(ibuf->ibuf_is_immed == B_FALSE); 1545 if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) { 1546 /* 1547 * The DB_SEND_STATUS_GOOD flag in the STMF data buffer allows 1548 * the port provider to phase-collapse, i.e. send the status 1549 * along with the final data PDU for the command. The port 1550 * provider passes this request to the transport layer by 1551 * setting a flag IDM_TASK_PHASECOLLAPSE_REQ in the task. 1552 */ 1553 if (dbuf->db_flags & DB_SEND_STATUS_GOOD) 1554 iscsit_task->it_idm_task->idt_flags |= 1555 IDM_TASK_PHASECOLLAPSE_REQ; 1556 /* 1557 * IDM will call iscsit_build_hdr so lock now to serialize 1558 * access to the SN values. We need to lock here to enforce 1559 * lock ordering 1560 */ 1561 mutex_enter(&ict_sess->ist_sn_mutex); 1562 idm_rc = idm_buf_tx_to_ini(iscsit_task->it_idm_task, 1563 ibuf->ibuf_idm_buf, dbuf->db_relative_offset, 1564 dbuf->db_data_size, &iscsit_buf_xfer_cb, dbuf); 1565 mutex_exit(&ict_sess->ist_sn_mutex); 1566 1567 return (iscsit_idm_to_stmf(idm_rc)); 1568 } else if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) { 1569 /* Grab the SN lock (see comment above) */ 1570 mutex_enter(&ict_sess->ist_sn_mutex); 1571 idm_rc = idm_buf_rx_from_ini(iscsit_task->it_idm_task, 1572 ibuf->ibuf_idm_buf, dbuf->db_relative_offset, 1573 dbuf->db_data_size, &iscsit_buf_xfer_cb, dbuf); 1574 mutex_exit(&ict_sess->ist_sn_mutex); 1575 1576 return (iscsit_idm_to_stmf(idm_rc)); 1577 } 1578 1579 /* What are we supposed to do if there is no direction? */ 1580 return (STMF_INVALID_ARG); 1581 } 1582 1583 static void 1584 iscsit_buf_xfer_cb(idm_buf_t *idb, idm_status_t status) 1585 { 1586 iscsit_task_t *itask = idb->idb_task_binding->idt_private; 1587 stmf_data_buf_t *dbuf = idb->idb_cb_arg; 1588 1589 dbuf->db_xfer_status = iscsit_idm_to_stmf(status); 1590 1591 /* 1592 * If the task has been aborted then we don't need to call STMF 1593 */ 1594 if (itask->it_stmf_abort) { 1595 return; 1596 } 1597 1598 /* 1599 * For ISCSI over TCP (not iSER), the last SCSI Data PDU passed 1600 * for a successful command contains the status as requested by 1601 * by COMSTAR (via the DB_SEND_STATUS_GOOD flag). But the iSER 1602 * transport does not support phase-collapse. So pretend we are 1603 * COMSTAR and send the status in a separate PDU now. 1604 */ 1605 if (idb->idb_task_binding->idt_flags & IDM_TASK_PHASECOLLAPSE_SUCCESS) { 1606 /* 1607 * Mark task complete and notify COMSTAR 1608 * that the status has been sent. 1609 */ 1610 itask->it_idm_task->idt_state = TASK_COMPLETE; 1611 stmf_send_status_done(itask->it_stmf_task, 1612 iscsit_idm_to_stmf(status), STMF_IOF_LPORT_DONE); 1613 } else if ((dbuf->db_flags & DB_SEND_STATUS_GOOD) && 1614 status == IDM_STATUS_SUCCESS) { 1615 1616 /* 1617 * The iscsi target port provider - for iSER, emulates the 1618 * DB_SEND_STATUS_GOOD optimization if requested by STMF; 1619 * it sends the status in a separate PDU after the data 1620 * transfer. In this case the port provider should first 1621 * call stmf_data_xfer_done() to mark the transfer complete 1622 * and then send the status. Although STMF will free the 1623 * buffer at the time the task is freed, even if the transfer 1624 * is not marked complete, this behavior makes statistics 1625 * gathering and task state tracking more difficult than it 1626 * needs to be. 1627 */ 1628 stmf_data_xfer_done(itask->it_stmf_task, dbuf, 0); 1629 if (iscsit_send_scsi_status(itask->it_stmf_task, 0) 1630 != STMF_SUCCESS) { 1631 stmf_send_status_done(itask->it_stmf_task, 1632 STMF_FAILURE, STMF_IOF_LPORT_DONE); 1633 } 1634 } else { 1635 stmf_data_xfer_done(itask->it_stmf_task, dbuf, 0); 1636 /* don't touch dbuf after stmf_data_xfer_done */ 1637 } 1638 } 1639 1640 1641 /*ARGSUSED*/ 1642 stmf_status_t 1643 iscsit_send_scsi_status(scsi_task_t *task, uint32_t ioflags) 1644 { 1645 iscsit_task_t *itask = task->task_port_private; 1646 iscsi_scsi_rsp_hdr_t *rsp; 1647 idm_pdu_t *pdu; 1648 int resp_datalen; 1649 1650 /* 1651 * If this task is aborted then we don't need to respond. 1652 */ 1653 if (itask->it_stmf_abort) { 1654 return (STMF_SUCCESS); 1655 } 1656 1657 /* 1658 * If this is a task management status, handle it elsewhere. 1659 */ 1660 if (task->task_mgmt_function != TM_NONE) { 1661 /* 1662 * Don't wait for the PDU completion to tell STMF 1663 * the task is done -- it doesn't really matter and 1664 * it makes life complicated if STMF later asks us to 1665 * abort the request and we don't know whether the 1666 * status has been sent or not. 1667 */ 1668 itask->it_tm_responded = B_TRUE; 1669 iscsit_send_task_mgmt_resp(itask->it_tm_pdu, 1670 (task->task_completion_status == STMF_SUCCESS) ? 1671 SCSI_TCP_TM_RESP_COMPLETE : SCSI_TCP_TM_RESP_FUNC_NOT_SUPP); 1672 stmf_send_status_done(task, STMF_SUCCESS, 1673 STMF_IOF_LPORT_DONE); 1674 return (STMF_SUCCESS); 1675 } 1676 1677 /* 1678 * Remove the task from the session task list 1679 */ 1680 iscsit_task_done(itask); 1681 1682 /* 1683 * Send status 1684 */ 1685 mutex_enter(&itask->it_idm_task->idt_mutex); 1686 if ((itask->it_idm_task->idt_state == TASK_ACTIVE) && 1687 (task->task_completion_status == STMF_SUCCESS) && 1688 (task->task_sense_length == 0) && 1689 (task->task_resid == 0)) { 1690 itask->it_idm_task->idt_state = TASK_COMPLETE; 1691 /* PDU callback releases task hold */ 1692 idm_task_hold(itask->it_idm_task); 1693 mutex_exit(&itask->it_idm_task->idt_mutex); 1694 /* 1695 * Fast path. Cached status PDU's are already 1696 * initialized. We just need to fill in 1697 * connection and task information. StatSN is 1698 * incremented by 1 for every status sent a 1699 * connection. 1700 */ 1701 pdu = kmem_cache_alloc(iscsit_status_pdu_cache, KM_SLEEP); 1702 pdu->isp_ic = itask->it_ict->ict_ic; 1703 pdu->isp_private = itask; 1704 pdu->isp_flags |= IDM_PDU_SET_STATSN | IDM_PDU_ADVANCE_STATSN; 1705 1706 rsp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr; 1707 rsp->itt = itask->it_itt; 1708 /* 1709 * ExpDataSN is the number of R2T and Data-In (read) 1710 * PDUs the target has sent for the SCSI command. 1711 * 1712 * Since there is no support for bidirectional transfer 1713 * yet, either idt_exp_datasn or idt_exp_rttsn, but not 1714 * both is valid at any time 1715 */ 1716 rsp->expdatasn = (itask->it_idm_task->idt_exp_datasn != 0) ? 1717 htonl(itask->it_idm_task->idt_exp_datasn): 1718 htonl(itask->it_idm_task->idt_exp_rttsn); 1719 rsp->cmd_status = task->task_scsi_status; 1720 iscsit_pdu_tx(pdu); 1721 return (STMF_SUCCESS); 1722 } else { 1723 if (itask->it_idm_task->idt_state != TASK_ACTIVE) { 1724 mutex_exit(&itask->it_idm_task->idt_mutex); 1725 return (STMF_FAILURE); 1726 } 1727 itask->it_idm_task->idt_state = TASK_COMPLETE; 1728 /* PDU callback releases task hold */ 1729 idm_task_hold(itask->it_idm_task); 1730 mutex_exit(&itask->it_idm_task->idt_mutex); 1731 1732 resp_datalen = (task->task_sense_length == 0) ? 0 : 1733 (task->task_sense_length + sizeof (uint16_t)); 1734 1735 pdu = idm_pdu_alloc(sizeof (iscsi_hdr_t), resp_datalen); 1736 idm_pdu_init(pdu, itask->it_ict->ict_ic, itask, 1737 iscsit_send_status_done); 1738 pdu->isp_flags |= IDM_PDU_SET_STATSN | IDM_PDU_ADVANCE_STATSN; 1739 1740 rsp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr; 1741 bzero(rsp, sizeof (*rsp)); 1742 rsp->opcode = ISCSI_OP_SCSI_RSP; 1743 1744 rsp->flags = ISCSI_FLAG_FINAL; 1745 if (task->task_status_ctrl & TASK_SCTRL_OVER) { 1746 rsp->flags |= ISCSI_FLAG_CMD_OVERFLOW; 1747 } else if (task->task_status_ctrl & TASK_SCTRL_UNDER) { 1748 rsp->flags |= ISCSI_FLAG_CMD_UNDERFLOW; 1749 } 1750 1751 rsp->bi_residual_count = 0; 1752 rsp->residual_count = htonl(task->task_resid); 1753 rsp->itt = itask->it_itt; 1754 rsp->response = ISCSI_STATUS_CMD_COMPLETED; 1755 rsp->expdatasn = (itask->it_idm_task->idt_exp_datasn != 0) ? 1756 htonl(itask->it_idm_task->idt_exp_datasn): 1757 htonl(itask->it_idm_task->idt_exp_rttsn); 1758 rsp->cmd_status = task->task_scsi_status; 1759 if (task->task_sense_length != 0) { 1760 /* 1761 * Add a byte to provide the sense length in 1762 * the response 1763 */ 1764 *(uint16_t *)((void *)pdu->isp_data) = 1765 htons(task->task_sense_length); 1766 bcopy(task->task_sense_data, 1767 (uint8_t *)pdu->isp_data + 1768 sizeof (uint16_t), 1769 task->task_sense_length); 1770 hton24(rsp->dlength, resp_datalen); 1771 } 1772 1773 DTRACE_PROBE5(iscsi__scsi__response, 1774 iscsit_conn_t *, itask->it_ict, 1775 uint8_t, rsp->response, 1776 uint8_t, rsp->cmd_status, 1777 idm_pdu_t *, pdu, 1778 scsi_task_t *, task); 1779 1780 iscsit_pdu_tx(pdu); 1781 1782 return (STMF_SUCCESS); 1783 } 1784 } 1785 1786 /*ARGSUSED*/ 1787 static void 1788 iscsit_send_good_status_done(idm_pdu_t *pdu, idm_status_t status) 1789 { 1790 iscsit_task_t *itask; 1791 boolean_t aborted; 1792 1793 itask = pdu->isp_private; 1794 aborted = itask->it_stmf_abort; 1795 1796 /* 1797 * After releasing the hold the task may be freed at any time so 1798 * don't touch it. 1799 */ 1800 idm_task_rele(itask->it_idm_task); 1801 if (!aborted) { 1802 stmf_send_status_done(itask->it_stmf_task, 1803 iscsit_idm_to_stmf(pdu->isp_status), STMF_IOF_LPORT_DONE); 1804 } 1805 kmem_cache_free(iscsit_status_pdu_cache, pdu); 1806 } 1807 1808 /*ARGSUSED*/ 1809 static void 1810 iscsit_send_status_done(idm_pdu_t *pdu, idm_status_t status) 1811 { 1812 iscsit_task_t *itask; 1813 boolean_t aborted; 1814 1815 itask = pdu->isp_private; 1816 aborted = itask->it_stmf_abort; 1817 1818 /* 1819 * After releasing the hold the task may be freed at any time so 1820 * don't touch it. 1821 */ 1822 idm_task_rele(itask->it_idm_task); 1823 if (!aborted) { 1824 stmf_send_status_done(itask->it_stmf_task, 1825 iscsit_idm_to_stmf(pdu->isp_status), STMF_IOF_LPORT_DONE); 1826 } 1827 idm_pdu_free(pdu); 1828 } 1829 1830 1831 void 1832 iscsit_lport_task_free(scsi_task_t *task) 1833 { 1834 iscsit_task_t *itask = task->task_port_private; 1835 1836 /* We only call idm_task_start for regular tasks, not task management */ 1837 if (task->task_mgmt_function == TM_NONE) { 1838 idm_task_done(itask->it_idm_task); 1839 iscsit_task_free(itask); 1840 return; 1841 } else { 1842 iscsit_tm_task_free(itask); 1843 } 1844 } 1845 1846 /*ARGSUSED*/ 1847 stmf_status_t 1848 iscsit_abort(stmf_local_port_t *lport, int abort_cmd, void *arg, uint32_t flags) 1849 { 1850 scsi_task_t *st = (scsi_task_t *)arg; 1851 iscsit_task_t *iscsit_task; 1852 idm_task_t *idt; 1853 1854 /* 1855 * If this is a task management request then there's really not much to 1856 * do. 1857 */ 1858 if (st->task_mgmt_function != TM_NONE) { 1859 return (STMF_ABORT_SUCCESS); 1860 } 1861 1862 /* 1863 * Regular task, start cleaning up 1864 */ 1865 iscsit_task = st->task_port_private; 1866 idt = iscsit_task->it_idm_task; 1867 mutex_enter(&iscsit_task->it_mutex); 1868 iscsit_task->it_stmf_abort = B_TRUE; 1869 if (iscsit_task->it_aborted) { 1870 mutex_exit(&iscsit_task->it_mutex); 1871 /* 1872 * Task is no longer active 1873 */ 1874 iscsit_task_done(iscsit_task); 1875 1876 /* 1877 * STMF specification is wrong... says to return 1878 * STMF_ABORTED, the code actually looks for 1879 * STMF_ABORT_SUCCESS. 1880 */ 1881 return (STMF_ABORT_SUCCESS); 1882 } else { 1883 mutex_exit(&iscsit_task->it_mutex); 1884 /* 1885 * Call IDM to abort the task. Due to a variety of 1886 * circumstances the task may already be in the process of 1887 * aborting. 1888 * We'll let IDM worry about rationalizing all that except 1889 * for one particular instance. If the state of the task 1890 * is TASK_COMPLETE, we need to indicate to the framework 1891 * that we are in fact done. This typically happens with 1892 * framework-initiated task management type requests 1893 * (e.g. abort task). 1894 */ 1895 if (idt->idt_state == TASK_COMPLETE) { 1896 idm_refcnt_wait_ref(&idt->idt_refcnt); 1897 return (STMF_ABORT_SUCCESS); 1898 } else { 1899 idm_task_abort(idt->idt_ic, idt, AT_TASK_MGMT_ABORT); 1900 return (STMF_SUCCESS); 1901 } 1902 } 1903 1904 /*NOTREACHED*/ 1905 } 1906 1907 /*ARGSUSED*/ 1908 void 1909 iscsit_ctl(stmf_local_port_t *lport, int cmd, void *arg) 1910 { 1911 iscsit_tgt_t *iscsit_tgt; 1912 1913 ASSERT((cmd == STMF_CMD_LPORT_ONLINE) || 1914 (cmd == STMF_ACK_LPORT_ONLINE_COMPLETE) || 1915 (cmd == STMF_CMD_LPORT_OFFLINE) || 1916 (cmd == STMF_ACK_LPORT_OFFLINE_COMPLETE)); 1917 1918 iscsit_tgt = (iscsit_tgt_t *)lport->lport_port_private; 1919 1920 switch (cmd) { 1921 case STMF_CMD_LPORT_ONLINE: 1922 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_ONLINE_REQ); 1923 break; 1924 case STMF_CMD_LPORT_OFFLINE: 1925 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_OFFLINE_REQ); 1926 break; 1927 case STMF_ACK_LPORT_ONLINE_COMPLETE: 1928 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_ONLINE_COMPLETE_ACK); 1929 break; 1930 case STMF_ACK_LPORT_OFFLINE_COMPLETE: 1931 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_OFFLINE_COMPLETE_ACK); 1932 break; 1933 1934 default: 1935 break; 1936 } 1937 } 1938 1939 static stmf_status_t 1940 iscsit_idm_to_stmf(idm_status_t idmrc) 1941 { 1942 switch (idmrc) { 1943 case IDM_STATUS_SUCCESS: 1944 return (STMF_SUCCESS); 1945 default: 1946 return (STMF_FAILURE); 1947 } 1948 /*NOTREACHED*/ 1949 } 1950 1951 void 1952 iscsit_op_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu) 1953 { 1954 iscsit_conn_t *ict = ic->ic_handle; 1955 1956 if (iscsit_check_cmdsn_and_queue(rx_pdu)) { 1957 iscsit_post_scsi_cmd(ic, rx_pdu); 1958 } 1959 iscsit_process_pdu_in_queue(ict->ict_sess); 1960 } 1961 1962 /* 1963 * ISCSI protocol 1964 */ 1965 1966 void 1967 iscsit_post_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu) 1968 { 1969 iscsit_conn_t *ict; 1970 iscsit_task_t *itask; 1971 scsi_task_t *task; 1972 iscsit_buf_t *ibuf; 1973 iscsi_scsi_cmd_hdr_t *iscsi_scsi = 1974 (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr; 1975 iscsi_addl_hdr_t *ahs_hdr; 1976 uint16_t addl_cdb_len = 0; 1977 1978 ict = ic->ic_handle; 1979 1980 itask = iscsit_task_alloc(ict); 1981 if (itask == NULL) { 1982 /* Finish processing request */ 1983 iscsit_set_cmdsn(ict, rx_pdu); 1984 1985 iscsit_send_direct_scsi_resp(ict, rx_pdu, 1986 ISCSI_STATUS_CMD_COMPLETED, STATUS_BUSY); 1987 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1988 return; 1989 } 1990 1991 /* 1992 * Note CmdSN and ITT in task. IDM will have already validated this 1993 * request against the connection state so we don't need to check 1994 * that (the connection may have changed state in the meantime but 1995 * we will catch that when we try to send a response) 1996 */ 1997 itask->it_cmdsn = ntohl(iscsi_scsi->cmdsn); 1998 itask->it_itt = iscsi_scsi->itt; 1999 2000 /* 2001 * Check for extended CDB AHS 2002 */ 2003 if (iscsi_scsi->hlength > 0) { 2004 ahs_hdr = (iscsi_addl_hdr_t *)iscsi_scsi; 2005 addl_cdb_len = ((ahs_hdr->ahs_hlen_hi << 8) | 2006 ahs_hdr->ahs_hlen_lo) - 1; /* Adjust for reserved byte */ 2007 if (((addl_cdb_len + 4) / sizeof (uint32_t)) > 2008 iscsi_scsi->hlength) { 2009 /* Mangled header info, drop it */ 2010 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2011 return; 2012 } 2013 } 2014 2015 ict = rx_pdu->isp_ic->ic_handle; /* IDM client private */ 2016 2017 /* 2018 * Add task to session list. This function will also check to 2019 * ensure that the task does not already exist. 2020 */ 2021 if (iscsit_task_start(itask) != IDM_STATUS_SUCCESS) { 2022 /* 2023 * Task exists, free all resources and reject. Don't 2024 * update expcmdsn in this case because RFC 3720 says 2025 * "The CmdSN of the rejected command PDU (if it is a 2026 * non-immediate command) MUST NOT be considered received 2027 * by the target (i.e., a command sequence gap must be 2028 * assumed for the CmdSN), even though the CmdSN of the 2029 * rejected command PDU may be reliably ascertained. Upon 2030 * receiving the Reject, the initiator MUST plug the CmdSN 2031 * gap in order to continue to use the session. The gap 2032 * may be plugged either by transmitting a command PDU 2033 * with the same CmdSN, or by aborting the task (see section 2034 * 6.9 on how an abort may plug a CmdSN gap)." (Section 6.3) 2035 */ 2036 iscsit_task_free(itask); 2037 iscsit_send_reject(ict, rx_pdu, ISCSI_REJECT_TASK_IN_PROGRESS); 2038 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2039 return; 2040 } 2041 2042 /* Update sequence numbers */ 2043 iscsit_set_cmdsn(ict, rx_pdu); 2044 2045 /* 2046 * Allocate STMF task 2047 */ 2048 itask->it_stmf_task = stmf_task_alloc( 2049 itask->it_ict->ict_sess->ist_lport, 2050 itask->it_ict->ict_sess->ist_stmf_sess, iscsi_scsi->lun, 2051 16 + addl_cdb_len, 0); 2052 if (itask->it_stmf_task == NULL) { 2053 /* 2054 * Either stmf really couldn't get memory for a task or, 2055 * more likely, the LU is currently in reset. Either way 2056 * we have no choice but to fail the request. 2057 */ 2058 iscsit_task_done(itask); 2059 iscsit_task_free(itask); 2060 iscsit_send_direct_scsi_resp(ict, rx_pdu, 2061 ISCSI_STATUS_CMD_COMPLETED, STATUS_BUSY); 2062 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2063 return; 2064 } 2065 2066 task = itask->it_stmf_task; 2067 task->task_port_private = itask; 2068 2069 bcopy(iscsi_scsi->lun, task->task_lun_no, sizeof (task->task_lun_no)); 2070 2071 /* 2072 * iSCSI and Comstar use the same values. Should we rely on this 2073 * or translate them bit-wise? 2074 */ 2075 2076 task->task_flags = 2077 (((iscsi_scsi->flags & ISCSI_FLAG_CMD_READ) ? TF_READ_DATA : 0) | 2078 ((iscsi_scsi->flags & ISCSI_FLAG_CMD_WRITE) ? TF_WRITE_DATA : 0) | 2079 ((rx_pdu->isp_datalen == 0) ? 0 : TF_INITIAL_BURST)); 2080 2081 switch (iscsi_scsi->flags & ISCSI_FLAG_CMD_ATTR_MASK) { 2082 case ISCSI_ATTR_UNTAGGED: 2083 break; 2084 case ISCSI_ATTR_SIMPLE: 2085 task->task_additional_flags |= TF_ATTR_SIMPLE_QUEUE; 2086 break; 2087 case ISCSI_ATTR_ORDERED: 2088 task->task_additional_flags |= TF_ATTR_ORDERED_QUEUE; 2089 break; 2090 case ISCSI_ATTR_HEAD_OF_QUEUE: 2091 task->task_additional_flags |= TF_ATTR_HEAD_OF_QUEUE; 2092 break; 2093 case ISCSI_ATTR_ACA: 2094 task->task_additional_flags |= TF_ATTR_ACA; 2095 break; 2096 default: 2097 /* Protocol error but just take it, treat as untagged */ 2098 break; 2099 } 2100 2101 2102 task->task_additional_flags = 0; 2103 task->task_priority = 0; 2104 task->task_mgmt_function = TM_NONE; 2105 2106 /* 2107 * This "task_max_nbufs" doesn't map well to BIDI. We probably need 2108 * parameter for each direction. "MaxOutstandingR2T" may very well 2109 * be set to one which could prevent us from doing simultaneous 2110 * transfers in each direction. 2111 */ 2112 task->task_max_nbufs = (iscsi_scsi->flags & ISCSI_FLAG_CMD_WRITE) ? 2113 ict->ict_op.op_max_outstanding_r2t : STMF_BUFS_MAX; 2114 task->task_cmd_seq_no = ntohl(iscsi_scsi->itt); 2115 task->task_expected_xfer_length = ntohl(iscsi_scsi->data_length); 2116 2117 /* Copy CDB */ 2118 bcopy(iscsi_scsi->scb, task->task_cdb, 16); 2119 if (addl_cdb_len > 0) { 2120 bcopy(ahs_hdr->ahs_extscb, task->task_cdb + 16, addl_cdb_len); 2121 } 2122 2123 DTRACE_ISCSI_3(scsi__command, idm_conn_t *, ic, 2124 iscsi_scsi_cmd_hdr_t *, (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr, 2125 scsi_task_t *, task); 2126 2127 /* 2128 * Copy the transport header into the task handle from the PDU 2129 * handle. The transport header describes this task's remote tagged 2130 * buffer. 2131 */ 2132 if (rx_pdu->isp_transport_hdrlen != 0) { 2133 bcopy(rx_pdu->isp_transport_hdr, 2134 itask->it_idm_task->idt_transport_hdr, 2135 rx_pdu->isp_transport_hdrlen); 2136 } 2137 2138 /* 2139 * Tell IDM about our new active task 2140 */ 2141 idm_task_start(itask->it_idm_task, (uintptr_t)itask->it_itt); 2142 2143 /* 2144 * If we have any immediate data then setup the immediate buffer 2145 * context that comes with the task 2146 */ 2147 if (rx_pdu->isp_datalen) { 2148 ibuf = itask->it_immed_data; 2149 ibuf->ibuf_immed_data_pdu = rx_pdu; 2150 ibuf->ibuf_stmf_buf->db_data_size = rx_pdu->isp_datalen; 2151 ibuf->ibuf_stmf_buf->db_buf_size = rx_pdu->isp_datalen; 2152 ibuf->ibuf_stmf_buf->db_relative_offset = 0; 2153 ibuf->ibuf_stmf_buf->db_sglist[0].seg_length = 2154 rx_pdu->isp_datalen; 2155 ibuf->ibuf_stmf_buf->db_sglist[0].seg_addr = rx_pdu->isp_data; 2156 2157 DTRACE_ISCSI_8(xfer__start, idm_conn_t *, ic, 2158 uintptr_t, ibuf->ibuf_stmf_buf->db_sglist[0].seg_addr, 2159 uint32_t, ibuf->ibuf_stmf_buf->db_relative_offset, 2160 uint64_t, 0, uint32_t, 0, uint32_t, 0, /* no raddr */ 2161 uint32_t, rx_pdu->isp_datalen, int, XFER_BUF_TX_TO_INI); 2162 2163 /* 2164 * For immediate data transfer, there is no callback from 2165 * stmf to indicate that the initial burst of data is 2166 * transferred successfully. In some cases, the task can 2167 * get freed before execution returns from stmf_post_task. 2168 * Although this xfer-start/done probe accurately tracks 2169 * the size of the transfer, it does only provide a best 2170 * effort on the timing of the transfer. 2171 */ 2172 DTRACE_ISCSI_8(xfer__done, idm_conn_t *, ic, 2173 uintptr_t, ibuf->ibuf_stmf_buf->db_sglist[0].seg_addr, 2174 uint32_t, ibuf->ibuf_stmf_buf->db_relative_offset, 2175 uint64_t, 0, uint32_t, 0, uint32_t, 0, /* no raddr */ 2176 uint32_t, rx_pdu->isp_datalen, int, XFER_BUF_TX_TO_INI); 2177 stmf_post_task(task, ibuf->ibuf_stmf_buf); 2178 } else { 2179 2180 stmf_post_task(task, NULL); 2181 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2182 } 2183 } 2184 2185 void 2186 iscsit_deferred_dispatch(idm_pdu_t *rx_pdu) 2187 { 2188 iscsit_conn_t *ict = rx_pdu->isp_ic->ic_handle; 2189 2190 /* 2191 * If this isn't a login packet, we need a session. Otherwise 2192 * this is a protocol error (perhaps one IDM should've caught?). 2193 */ 2194 if (IDM_PDU_OPCODE(rx_pdu) != ISCSI_OP_LOGIN_CMD && 2195 ict->ict_sess == NULL) { 2196 DTRACE_PROBE2(iscsi__idm__deferred__no__session, 2197 iscsit_conn_t *, ict, idm_pdu_t *, rx_pdu); 2198 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 2199 return; 2200 } 2201 2202 /* 2203 * If the connection has been lost then ignore new PDU's 2204 */ 2205 mutex_enter(&ict->ict_mutex); 2206 if (ict->ict_lost) { 2207 mutex_exit(&ict->ict_mutex); 2208 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 2209 return; 2210 } 2211 2212 /* 2213 * Grab a hold on the connection to prevent it from going away 2214 * between now and when the taskq function is called. 2215 */ 2216 iscsit_conn_dispatch_hold(ict); 2217 mutex_exit(&ict->ict_mutex); 2218 2219 taskq_dispatch_ent(iscsit_global.global_dispatch_taskq, 2220 iscsit_deferred, rx_pdu, 0, &rx_pdu->isp_tqent); 2221 } 2222 2223 static void 2224 iscsit_deferred(void *rx_pdu_void) 2225 { 2226 idm_pdu_t *rx_pdu = rx_pdu_void; 2227 idm_conn_t *ic = rx_pdu->isp_ic; 2228 iscsit_conn_t *ict = ic->ic_handle; 2229 2230 /* 2231 * NOP and Task Management Commands can be marked for immediate 2232 * delivery. Commands marked as 'Immediate' are to be considered 2233 * for execution as soon as they arrive on the target. So these 2234 * should not be checked for sequence order and put in a queue. 2235 * The CmdSN is not advanced for Immediate Commands. 2236 */ 2237 switch (IDM_PDU_OPCODE(rx_pdu)) { 2238 case ISCSI_OP_NOOP_OUT: 2239 if (iscsit_check_cmdsn_and_queue(rx_pdu)) { 2240 iscsit_set_cmdsn(ict, rx_pdu); 2241 iscsit_pdu_op_noop(ict, rx_pdu); 2242 } 2243 break; 2244 case ISCSI_OP_LOGIN_CMD: 2245 iscsit_pdu_op_login_cmd(ict, rx_pdu); 2246 iscsit_conn_dispatch_rele(ict); 2247 return; 2248 case ISCSI_OP_TEXT_CMD: 2249 if (iscsit_check_cmdsn_and_queue(rx_pdu)) { 2250 iscsit_set_cmdsn(ict, rx_pdu); 2251 iscsit_pdu_op_text_cmd(ict, rx_pdu); 2252 } 2253 break; 2254 case ISCSI_OP_LOGOUT_CMD: 2255 if (iscsit_check_cmdsn_and_queue(rx_pdu)) { 2256 iscsit_set_cmdsn(ict, rx_pdu); 2257 iscsit_pdu_op_logout_cmd(ict, rx_pdu); 2258 } 2259 break; 2260 default: 2261 /* Protocol error. IDM should have caught this */ 2262 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 2263 ASSERT(0); 2264 break; 2265 } 2266 /* 2267 * Check if there are other PDUs in the session staging queue 2268 * waiting to be posted to SCSI layer. 2269 */ 2270 iscsit_process_pdu_in_queue(ict->ict_sess); 2271 2272 iscsit_conn_dispatch_rele(ict); 2273 } 2274 2275 static void 2276 iscsit_send_direct_scsi_resp(iscsit_conn_t *ict, idm_pdu_t *rx_pdu, 2277 uint8_t response, uint8_t cmd_status) 2278 { 2279 idm_pdu_t *rsp_pdu; 2280 idm_conn_t *ic; 2281 iscsi_scsi_rsp_hdr_t *resp; 2282 iscsi_scsi_cmd_hdr_t *req = 2283 (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr; 2284 2285 ic = ict->ict_ic; 2286 2287 rsp_pdu = idm_pdu_alloc(sizeof (iscsi_scsi_rsp_hdr_t), 0); 2288 idm_pdu_init(rsp_pdu, ic, NULL, NULL); 2289 /* 2290 * StatSN is incremented by 1 for every response sent on 2291 * a connection except for responses sent as a result of 2292 * a retry or SNACK 2293 */ 2294 rsp_pdu->isp_flags |= IDM_PDU_SET_STATSN | IDM_PDU_ADVANCE_STATSN; 2295 2296 resp = (iscsi_scsi_rsp_hdr_t *)rsp_pdu->isp_hdr; 2297 2298 resp->opcode = ISCSI_OP_SCSI_RSP; 2299 resp->flags = ISCSI_FLAG_FINAL; 2300 resp->response = response; 2301 resp->cmd_status = cmd_status; 2302 resp->itt = req->itt; 2303 if ((response == ISCSI_STATUS_CMD_COMPLETED) && 2304 (req->data_length != 0) && 2305 ((req->flags & ISCSI_FLAG_CMD_READ) || 2306 (req->flags & ISCSI_FLAG_CMD_WRITE))) { 2307 resp->flags |= ISCSI_FLAG_CMD_UNDERFLOW; 2308 resp->residual_count = req->data_length; 2309 } 2310 2311 DTRACE_PROBE4(iscsi__scsi__direct__response, 2312 iscsit_conn_t *, ict, 2313 uint8_t, resp->response, 2314 uint8_t, resp->cmd_status, 2315 idm_pdu_t *, rsp_pdu); 2316 2317 iscsit_pdu_tx(rsp_pdu); 2318 } 2319 2320 void 2321 iscsit_send_task_mgmt_resp(idm_pdu_t *tm_resp_pdu, uint8_t tm_status) 2322 { 2323 iscsi_scsi_task_mgt_rsp_hdr_t *tm_resp; 2324 2325 /* 2326 * The target must take note of the last-sent StatSN. 2327 * The StatSN is to be incremented after sending a 2328 * task management response. Digest recovery can only 2329 * work if StatSN is incremented. 2330 */ 2331 tm_resp_pdu->isp_flags |= IDM_PDU_SET_STATSN | IDM_PDU_ADVANCE_STATSN; 2332 tm_resp = (iscsi_scsi_task_mgt_rsp_hdr_t *)tm_resp_pdu->isp_hdr; 2333 tm_resp->response = tm_status; 2334 2335 DTRACE_PROBE3(iscsi__scsi__tm__response, 2336 iscsit_conn_t *, tm_resp_pdu->isp_ic->ic_handle, 2337 uint8_t, tm_resp->response, 2338 idm_pdu_t *, tm_resp_pdu); 2339 iscsit_pdu_tx(tm_resp_pdu); 2340 } 2341 2342 void 2343 iscsit_op_scsi_task_mgmt(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2344 { 2345 idm_pdu_t *tm_resp_pdu; 2346 iscsit_task_t *itask; 2347 iscsit_task_t *tm_itask; 2348 scsi_task_t *task; 2349 iscsi_scsi_task_mgt_hdr_t *iscsi_tm = 2350 (iscsi_scsi_task_mgt_hdr_t *)rx_pdu->isp_hdr; 2351 iscsi_scsi_task_mgt_rsp_hdr_t *iscsi_tm_rsp = 2352 (iscsi_scsi_task_mgt_rsp_hdr_t *)rx_pdu->isp_hdr; 2353 uint32_t rtt, cmdsn, refcmdsn; 2354 uint8_t tm_func; 2355 2356 /* 2357 * Setup response PDU (response field will get filled in later) 2358 */ 2359 tm_resp_pdu = idm_pdu_alloc(sizeof (iscsi_scsi_task_mgt_rsp_hdr_t), 0); 2360 if (tm_resp_pdu == NULL) { 2361 /* Can't respond, just drop it */ 2362 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2363 return; 2364 } 2365 idm_pdu_init(tm_resp_pdu, ict->ict_ic, NULL, NULL); 2366 iscsi_tm_rsp = (iscsi_scsi_task_mgt_rsp_hdr_t *)tm_resp_pdu->isp_hdr; 2367 bzero(iscsi_tm_rsp, sizeof (iscsi_scsi_task_mgt_rsp_hdr_t)); 2368 iscsi_tm_rsp->opcode = ISCSI_OP_SCSI_TASK_MGT_RSP; 2369 iscsi_tm_rsp->flags = ISCSI_FLAG_FINAL; 2370 iscsi_tm_rsp->itt = rx_pdu->isp_hdr->itt; 2371 2372 /* 2373 * Figure out what we're being asked to do. 2374 */ 2375 DTRACE_PROBE4(iscsi__scsi__tm__request, 2376 iscsit_conn_t *, ict, 2377 uint8_t, (iscsi_tm->function & ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK), 2378 uint32_t, iscsi_tm->rtt, 2379 idm_pdu_t *, rx_pdu); 2380 switch (iscsi_tm->function & ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK) { 2381 case ISCSI_TM_FUNC_ABORT_TASK: 2382 /* 2383 * STMF doesn't currently support the "abort task" task 2384 * management command although it does support aborting 2385 * an individual task. We'll get STMF to abort the task 2386 * for us but handle the details of the task management 2387 * command ourselves. 2388 * 2389 * Find the task associated with the referenced task tag. 2390 */ 2391 rtt = iscsi_tm->rtt; 2392 itask = (iscsit_task_t *)idm_task_find_by_handle(ict->ict_ic, 2393 (uintptr_t)rtt); 2394 2395 if (itask == NULL) { 2396 cmdsn = ntohl(iscsi_tm->cmdsn); 2397 refcmdsn = ntohl(iscsi_tm->refcmdsn); 2398 2399 /* 2400 * Task was not found. But the SCSI command could be 2401 * on the rxpdu wait queue. If RefCmdSN is within 2402 * the CmdSN window and less than CmdSN of the TM 2403 * function, return "Function Complete". Otherwise, 2404 * return "Task Does Not Exist". 2405 */ 2406 2407 if (iscsit_cmdsn_in_window(ict, refcmdsn) && 2408 iscsit_sna_lt(refcmdsn, cmdsn)) { 2409 mutex_enter(&ict->ict_sess->ist_sn_mutex); 2410 if (iscsit_remove_pdu_from_queue( 2411 ict->ict_sess, refcmdsn)) { 2412 iscsit_conn_dispatch_rele(ict); 2413 } 2414 mutex_exit(&ict->ict_sess->ist_sn_mutex); 2415 iscsit_send_task_mgmt_resp(tm_resp_pdu, 2416 SCSI_TCP_TM_RESP_COMPLETE); 2417 } else { 2418 iscsit_send_task_mgmt_resp(tm_resp_pdu, 2419 SCSI_TCP_TM_RESP_NO_TASK); 2420 } 2421 } else { 2422 2423 /* 2424 * Tell STMF to abort the task. This will do no harm 2425 * if the task is already complete. 2426 */ 2427 stmf_abort(STMF_QUEUE_TASK_ABORT, itask->it_stmf_task, 2428 STMF_ABORTED, NULL); 2429 2430 /* 2431 * Make sure the task hasn't already completed 2432 */ 2433 mutex_enter(&itask->it_idm_task->idt_mutex); 2434 if ((itask->it_idm_task->idt_state == TASK_COMPLETE) || 2435 (itask->it_idm_task->idt_state == TASK_IDLE)) { 2436 /* 2437 * Task is complete, return "Task Does Not 2438 * Exist" 2439 */ 2440 mutex_exit(&itask->it_idm_task->idt_mutex); 2441 iscsit_send_task_mgmt_resp(tm_resp_pdu, 2442 SCSI_TCP_TM_RESP_NO_TASK); 2443 } else { 2444 /* 2445 * STMF is now aborting the task, return 2446 * "Function Complete" 2447 */ 2448 mutex_exit(&itask->it_idm_task->idt_mutex); 2449 iscsit_send_task_mgmt_resp(tm_resp_pdu, 2450 SCSI_TCP_TM_RESP_COMPLETE); 2451 } 2452 idm_task_rele(itask->it_idm_task); 2453 } 2454 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2455 return; 2456 2457 case ISCSI_TM_FUNC_ABORT_TASK_SET: 2458 tm_func = TM_ABORT_TASK_SET; 2459 break; 2460 2461 case ISCSI_TM_FUNC_CLEAR_ACA: 2462 tm_func = TM_CLEAR_ACA; 2463 break; 2464 2465 case ISCSI_TM_FUNC_CLEAR_TASK_SET: 2466 tm_func = TM_CLEAR_TASK_SET; 2467 break; 2468 2469 case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET: 2470 tm_func = TM_LUN_RESET; 2471 break; 2472 2473 case ISCSI_TM_FUNC_TARGET_WARM_RESET: 2474 tm_func = TM_TARGET_WARM_RESET; 2475 break; 2476 2477 case ISCSI_TM_FUNC_TARGET_COLD_RESET: 2478 tm_func = TM_TARGET_COLD_RESET; 2479 break; 2480 2481 case ISCSI_TM_FUNC_TASK_REASSIGN: 2482 /* 2483 * We do not currently support allegiance reassignment. When 2484 * we start supporting ERL1+, we will need to. 2485 */ 2486 iscsit_send_task_mgmt_resp(tm_resp_pdu, 2487 SCSI_TCP_TM_RESP_NO_ALLG_REASSN); 2488 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2489 return; 2490 2491 default: 2492 iscsit_send_task_mgmt_resp(tm_resp_pdu, 2493 SCSI_TCP_TM_RESP_REJECTED); 2494 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2495 return; 2496 } 2497 2498 tm_itask = iscsit_tm_task_alloc(ict); 2499 if (tm_itask == NULL) { 2500 iscsit_send_task_mgmt_resp(tm_resp_pdu, 2501 SCSI_TCP_TM_RESP_REJECTED); 2502 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2503 return; 2504 } 2505 2506 2507 task = stmf_task_alloc(ict->ict_sess->ist_lport, 2508 ict->ict_sess->ist_stmf_sess, iscsi_tm->lun, 2509 0, STMF_TASK_EXT_NONE); 2510 if (task == NULL) { 2511 /* 2512 * If this happens, either the LU is in reset, couldn't 2513 * get memory, or some other condition in which we simply 2514 * can't complete this request. It would be nice to return 2515 * an error code like "busy" but the closest we have is 2516 * "rejected". 2517 */ 2518 iscsit_send_task_mgmt_resp(tm_resp_pdu, 2519 SCSI_TCP_TM_RESP_REJECTED); 2520 iscsit_tm_task_free(tm_itask); 2521 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2522 return; 2523 } 2524 2525 tm_itask->it_tm_pdu = tm_resp_pdu; 2526 tm_itask->it_stmf_task = task; 2527 task->task_port_private = tm_itask; 2528 task->task_mgmt_function = tm_func; 2529 task->task_additional_flags = TASK_AF_NO_EXPECTED_XFER_LENGTH; 2530 task->task_priority = 0; 2531 task->task_max_nbufs = STMF_BUFS_MAX; 2532 task->task_cmd_seq_no = iscsi_tm->itt; 2533 task->task_expected_xfer_length = 0; 2534 2535 stmf_post_task(task, NULL); 2536 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2537 } 2538 2539 static void 2540 iscsit_pdu_op_noop(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2541 { 2542 iscsi_nop_out_hdr_t *out = (iscsi_nop_out_hdr_t *)rx_pdu->isp_hdr; 2543 iscsi_nop_in_hdr_t *in; 2544 int resp_datalen; 2545 idm_pdu_t *resp; 2546 2547 /* Ignore the response from initiator */ 2548 if ((out->itt == ISCSI_RSVD_TASK_TAG) || 2549 (out->ttt != ISCSI_RSVD_TASK_TAG)) { 2550 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2551 return; 2552 } 2553 2554 /* Allocate a PDU to respond */ 2555 resp_datalen = ntoh24(out->dlength); 2556 resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), resp_datalen); 2557 idm_pdu_init(resp, ict->ict_ic, NULL, NULL); 2558 if (resp_datalen > 0) { 2559 bcopy(rx_pdu->isp_data, resp->isp_data, resp_datalen); 2560 } 2561 2562 /* 2563 * When sending a NOP-In as a response to a NOP-Out from the initiator, 2564 * the target must respond with the same initiator task tag that was 2565 * provided in the NOP-Out request, the target transfer tag must be 2566 * ISCSI_RSVD_TASK_TAG (0xffffffff) and StatSN will contain the next 2567 * status sequence number. The StatSN for the connection is advanced 2568 * after this PDU is sent. 2569 */ 2570 in = (iscsi_nop_in_hdr_t *)resp->isp_hdr; 2571 bzero(in, sizeof (*in)); 2572 in->opcode = ISCSI_OP_NOOP_IN; 2573 in->flags = ISCSI_FLAG_FINAL; 2574 bcopy(out->lun, in->lun, 8); 2575 in->itt = out->itt; 2576 in->ttt = ISCSI_RSVD_TASK_TAG; 2577 hton24(in->dlength, resp_datalen); 2578 resp->isp_flags |= IDM_PDU_SET_STATSN | IDM_PDU_ADVANCE_STATSN; 2579 /* Any other field in resp to be set? */ 2580 iscsit_pdu_tx(resp); 2581 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2582 } 2583 2584 static void 2585 iscsit_pdu_op_login_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2586 { 2587 2588 /* 2589 * Submit PDU to login state machine. State machine will free the 2590 * PDU. 2591 */ 2592 iscsit_login_sm_event(ict, ILE_LOGIN_RCV, rx_pdu); 2593 } 2594 2595 void 2596 iscsit_pdu_op_logout_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2597 { 2598 iscsi_logout_hdr_t *logout_req = 2599 (iscsi_logout_hdr_t *)rx_pdu->isp_hdr; 2600 iscsi_logout_rsp_hdr_t *logout_rsp; 2601 idm_pdu_t *resp; 2602 2603 /* Allocate a PDU to respond */ 2604 resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 2605 idm_pdu_init(resp, ict->ict_ic, NULL, NULL); 2606 /* 2607 * The StatSN is to be sent to the initiator, 2608 * it is not required to increment the number 2609 * as the connection is terminating. 2610 */ 2611 resp->isp_flags |= IDM_PDU_SET_STATSN; 2612 /* 2613 * Logout results in the immediate termination of all tasks except 2614 * if the logout reason is ISCSI_LOGOUT_REASON_RECOVERY. The 2615 * connection state machine will drive this task cleanup automatically 2616 * so we don't need to handle that here. 2617 */ 2618 logout_rsp = (iscsi_logout_rsp_hdr_t *)resp->isp_hdr; 2619 bzero(logout_rsp, sizeof (*logout_rsp)); 2620 logout_rsp->opcode = ISCSI_OP_LOGOUT_RSP; 2621 logout_rsp->flags = ISCSI_FLAG_FINAL; 2622 logout_rsp->itt = logout_req->itt; 2623 if ((logout_req->flags & ISCSI_FLAG_LOGOUT_REASON_MASK) > 2624 ISCSI_LOGOUT_REASON_RECOVERY) { 2625 logout_rsp->response = ISCSI_LOGOUT_RECOVERY_UNSUPPORTED; 2626 } else { 2627 logout_rsp->response = ISCSI_LOGOUT_SUCCESS; 2628 } 2629 2630 iscsit_pdu_tx(resp); 2631 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2632 } 2633 2634 /* 2635 * Calculate the number of outstanding commands we can process 2636 */ 2637 int 2638 iscsit_cmd_window() 2639 { 2640 /* 2641 * Instead of using a pre-defined constant for the command window, 2642 * it should be made confiurable and dynamic. With MC/S, sequence 2643 * numbers will be used up at a much faster rate than with SC/S. 2644 */ 2645 return (ISCSIT_MAX_WINDOW); 2646 } 2647 2648 /* 2649 * Set local registers based on incoming PDU 2650 */ 2651 void 2652 iscsit_set_cmdsn(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2653 { 2654 iscsit_sess_t *ist; 2655 iscsi_scsi_cmd_hdr_t *req; 2656 2657 ist = ict->ict_sess; 2658 2659 req = (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr; 2660 if (req->opcode & ISCSI_OP_IMMEDIATE) { 2661 /* no cmdsn increment for immediate PDUs */ 2662 return; 2663 } 2664 2665 /* Ensure that the ExpCmdSN advances in an orderly manner */ 2666 mutex_enter(&ist->ist_sn_mutex); 2667 ist->ist_expcmdsn = ntohl(req->cmdsn) + 1; 2668 ist->ist_maxcmdsn = ntohl(req->cmdsn) + iscsit_cmd_window(); 2669 mutex_exit(&ist->ist_sn_mutex); 2670 } 2671 2672 /* 2673 * Wrapper funtion, calls iscsi_calc_rspsn and idm_pdu_tx 2674 */ 2675 void 2676 iscsit_pdu_tx(idm_pdu_t *pdu) 2677 { 2678 iscsit_conn_t *ict = pdu->isp_ic->ic_handle; 2679 iscsi_scsi_rsp_hdr_t *rsp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr; 2680 iscsit_sess_t *ist = ict->ict_sess; 2681 2682 /* 2683 * The command sequence numbers are session-wide and must stay 2684 * consistent across the transfer, so protect the cmdsn with a 2685 * mutex lock on the session. The status sequence number will 2686 * be updated just before the transport layer transmits the PDU. 2687 */ 2688 2689 mutex_enter(&ict->ict_sess->ist_sn_mutex); 2690 /* Set ExpCmdSN and MaxCmdSN */ 2691 rsp->maxcmdsn = htonl(ist->ist_maxcmdsn); 2692 rsp->expcmdsn = htonl(ist->ist_expcmdsn); 2693 idm_pdu_tx(pdu); 2694 mutex_exit(&ict->ict_sess->ist_sn_mutex); 2695 } 2696 2697 /* 2698 * Internal functions 2699 */ 2700 2701 void 2702 iscsit_send_async_event(iscsit_conn_t *ict, uint8_t event) 2703 { 2704 idm_pdu_t *abt; 2705 iscsi_async_evt_hdr_t *async_abt; 2706 2707 /* 2708 * Get a PDU to build the abort request. 2709 */ 2710 abt = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 2711 if (abt == NULL) { 2712 idm_conn_event(ict->ict_ic, CE_TRANSPORT_FAIL, NULL); 2713 return; 2714 } 2715 2716 /* 2717 * A asynchronous message is sent by the target to request a logout. 2718 * The StatSN for the connection is advanced after the PDU is sent 2719 * to allow for initiator and target state synchronization. 2720 */ 2721 idm_pdu_init(abt, ict->ict_ic, NULL, NULL); 2722 abt->isp_datalen = 0; 2723 abt->isp_flags |= IDM_PDU_SET_STATSN | IDM_PDU_ADVANCE_STATSN; 2724 2725 async_abt = (iscsi_async_evt_hdr_t *)abt->isp_hdr; 2726 bzero(async_abt, sizeof (*async_abt)); 2727 async_abt->opcode = ISCSI_OP_ASYNC_EVENT; 2728 async_abt->async_event = event; 2729 async_abt->flags = ISCSI_FLAG_FINAL; 2730 async_abt->rsvd4[0] = 0xff; 2731 async_abt->rsvd4[1] = 0xff; 2732 async_abt->rsvd4[2] = 0xff; 2733 async_abt->rsvd4[3] = 0xff; 2734 2735 switch (event) { 2736 case ISCSI_ASYNC_EVENT_REQUEST_LOGOUT: 2737 async_abt->param3 = htons(IDM_LOGOUT_SECONDS); 2738 break; 2739 case ISCSI_ASYNC_EVENT_SCSI_EVENT: 2740 case ISCSI_ASYNC_EVENT_DROPPING_CONNECTION: 2741 case ISCSI_ASYNC_EVENT_DROPPING_ALL_CONNECTIONS: 2742 case ISCSI_ASYNC_EVENT_PARAM_NEGOTIATION: 2743 default: 2744 ASSERT(0); 2745 } 2746 2747 iscsit_pdu_tx(abt); 2748 } 2749 2750 void 2751 iscsit_send_reject(iscsit_conn_t *ict, idm_pdu_t *rejected_pdu, uint8_t reason) 2752 { 2753 idm_pdu_t *reject_pdu; 2754 iscsi_reject_rsp_hdr_t *reject; 2755 2756 /* 2757 * Get a PDU to build the abort request. 2758 */ 2759 reject_pdu = idm_pdu_alloc(sizeof (iscsi_hdr_t), 2760 rejected_pdu->isp_hdrlen); 2761 if (reject_pdu == NULL) { 2762 idm_conn_event(ict->ict_ic, CE_TRANSPORT_FAIL, NULL); 2763 return; 2764 } 2765 idm_pdu_init(reject_pdu, ict->ict_ic, NULL, NULL); 2766 /* StatSN is advanced after a Reject PDU */ 2767 reject_pdu->isp_flags |= IDM_PDU_SET_STATSN | IDM_PDU_ADVANCE_STATSN; 2768 reject_pdu->isp_datalen = rejected_pdu->isp_hdrlen; 2769 bcopy(rejected_pdu->isp_hdr, reject_pdu->isp_data, 2770 rejected_pdu->isp_hdrlen); 2771 2772 reject = (iscsi_reject_rsp_hdr_t *)reject_pdu->isp_hdr; 2773 bzero(reject, sizeof (*reject)); 2774 reject->opcode = ISCSI_OP_REJECT_MSG; 2775 reject->reason = reason; 2776 reject->flags = ISCSI_FLAG_FINAL; 2777 hton24(reject->dlength, rejected_pdu->isp_hdrlen); 2778 reject->must_be_ff[0] = 0xff; 2779 reject->must_be_ff[1] = 0xff; 2780 reject->must_be_ff[2] = 0xff; 2781 reject->must_be_ff[3] = 0xff; 2782 2783 iscsit_pdu_tx(reject_pdu); 2784 } 2785 2786 2787 static iscsit_task_t * 2788 iscsit_task_alloc(iscsit_conn_t *ict) 2789 { 2790 iscsit_task_t *itask; 2791 iscsit_buf_t *immed_ibuf; 2792 2793 /* 2794 * Possible items to pre-alloc if we cache iscsit_task_t's: 2795 * 2796 * Status PDU w/ sense buffer 2797 * stmf_data_buf_t for immediate data 2798 */ 2799 itask = kmem_alloc(sizeof (iscsit_task_t) + sizeof (iscsit_buf_t) + 2800 sizeof (stmf_data_buf_t), KM_NOSLEEP); 2801 if (itask != NULL) { 2802 mutex_init(&itask->it_mutex, NULL, MUTEX_DRIVER, NULL); 2803 itask->it_aborted = itask->it_stmf_abort = 2804 itask->it_tm_task = 0; 2805 2806 immed_ibuf = (iscsit_buf_t *)(itask + 1); 2807 bzero(immed_ibuf, sizeof (*immed_ibuf)); 2808 immed_ibuf->ibuf_is_immed = B_TRUE; 2809 immed_ibuf->ibuf_stmf_buf = (stmf_data_buf_t *)(immed_ibuf + 1); 2810 2811 bzero(immed_ibuf->ibuf_stmf_buf, sizeof (stmf_data_buf_t)); 2812 immed_ibuf->ibuf_stmf_buf->db_port_private = immed_ibuf; 2813 immed_ibuf->ibuf_stmf_buf->db_sglist_length = 1; 2814 immed_ibuf->ibuf_stmf_buf->db_flags = DB_DIRECTION_FROM_RPORT | 2815 DB_DONT_CACHE; 2816 itask->it_immed_data = immed_ibuf; 2817 itask->it_idm_task = idm_task_alloc(ict->ict_ic); 2818 if (itask->it_idm_task != NULL) { 2819 itask->it_idm_task->idt_private = itask; 2820 itask->it_ict = ict; 2821 itask->it_ttt = itask->it_idm_task->idt_tt; 2822 return (itask); 2823 } else { 2824 kmem_free(itask, sizeof (iscsit_task_t) + 2825 sizeof (iscsit_buf_t) + sizeof (stmf_data_buf_t)); 2826 } 2827 } 2828 2829 return (NULL); 2830 } 2831 2832 static void 2833 iscsit_task_free(iscsit_task_t *itask) 2834 { 2835 idm_task_free(itask->it_idm_task); 2836 mutex_destroy(&itask->it_mutex); 2837 kmem_free(itask, sizeof (iscsit_task_t) + 2838 sizeof (iscsit_buf_t) + sizeof (stmf_data_buf_t)); 2839 } 2840 2841 static iscsit_task_t * 2842 iscsit_tm_task_alloc(iscsit_conn_t *ict) 2843 { 2844 iscsit_task_t *itask; 2845 2846 itask = kmem_zalloc(sizeof (iscsit_task_t), KM_NOSLEEP); 2847 if (itask != NULL) { 2848 idm_conn_hold(ict->ict_ic); 2849 mutex_init(&itask->it_mutex, NULL, MUTEX_DRIVER, NULL); 2850 itask->it_aborted = itask->it_stmf_abort = 2851 itask->it_tm_responded = 0; 2852 itask->it_tm_pdu = NULL; 2853 itask->it_tm_task = 1; 2854 itask->it_ict = ict; 2855 } 2856 2857 return (itask); 2858 } 2859 2860 static void 2861 iscsit_tm_task_free(iscsit_task_t *itask) 2862 { 2863 /* 2864 * If we responded then the call to idm_pdu_complete will free the 2865 * PDU. Otherwise we got aborted before the TM function could 2866 * complete and we need to free the PDU explicitly. 2867 */ 2868 if (itask->it_tm_pdu != NULL && !itask->it_tm_responded) 2869 idm_pdu_free(itask->it_tm_pdu); 2870 idm_conn_rele(itask->it_ict->ict_ic); 2871 mutex_destroy(&itask->it_mutex); 2872 kmem_free(itask, sizeof (iscsit_task_t)); 2873 } 2874 2875 static idm_status_t 2876 iscsit_task_start(iscsit_task_t *itask) 2877 { 2878 iscsit_sess_t *ist = itask->it_ict->ict_sess; 2879 avl_index_t where; 2880 2881 /* 2882 * Sanity check the ITT and ensure that this task does not already 2883 * exist. If not then add the task to the session task list. 2884 */ 2885 mutex_enter(&ist->ist_mutex); 2886 mutex_enter(&itask->it_mutex); 2887 itask->it_active = 1; 2888 if (avl_find(&ist->ist_task_list, itask, &where) == NULL) { 2889 /* New task, add to AVL */ 2890 avl_insert(&ist->ist_task_list, itask, where); 2891 mutex_exit(&itask->it_mutex); 2892 mutex_exit(&ist->ist_mutex); 2893 return (IDM_STATUS_SUCCESS); 2894 } 2895 mutex_exit(&itask->it_mutex); 2896 mutex_exit(&ist->ist_mutex); 2897 2898 return (IDM_STATUS_REJECT); 2899 } 2900 2901 static void 2902 iscsit_task_done(iscsit_task_t *itask) 2903 { 2904 iscsit_sess_t *ist = itask->it_ict->ict_sess; 2905 2906 mutex_enter(&ist->ist_mutex); 2907 mutex_enter(&itask->it_mutex); 2908 if (itask->it_active) { 2909 avl_remove(&ist->ist_task_list, itask); 2910 itask->it_active = 0; 2911 } 2912 mutex_exit(&itask->it_mutex); 2913 mutex_exit(&ist->ist_mutex); 2914 } 2915 2916 /* 2917 * iscsit status PDU cache 2918 */ 2919 2920 /*ARGSUSED*/ 2921 static int 2922 iscsit_status_pdu_constructor(void *pdu_void, void *arg, int flags) 2923 { 2924 idm_pdu_t *pdu = pdu_void; 2925 iscsi_scsi_rsp_hdr_t *rsp; 2926 2927 bzero(pdu, sizeof (idm_pdu_t)); 2928 pdu->isp_callback = iscsit_send_good_status_done; 2929 pdu->isp_magic = IDM_PDU_MAGIC; 2930 pdu->isp_hdr = (iscsi_hdr_t *)(pdu + 1); /* Ptr arithmetic */ 2931 pdu->isp_hdrlen = sizeof (iscsi_hdr_t); 2932 2933 /* Setup status response */ 2934 rsp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr; 2935 bzero(rsp, sizeof (*rsp)); 2936 rsp->opcode = ISCSI_OP_SCSI_RSP; 2937 rsp->flags = ISCSI_FLAG_FINAL; 2938 rsp->response = ISCSI_STATUS_CMD_COMPLETED; 2939 2940 return (0); 2941 } 2942 2943 /* 2944 * iscsit private data handler 2945 */ 2946 2947 /*ARGSUSED*/ 2948 static void 2949 iscsit_pp_cb(struct stmf_port_provider *pp, int cmd, void *arg, uint32_t flags) 2950 { 2951 it_config_t *cfg; 2952 nvlist_t *nvl; 2953 iscsit_service_enabled_t old_state; 2954 2955 if ((cmd != STMF_PROVIDER_DATA_UPDATED) || (arg == NULL)) { 2956 return; 2957 } 2958 2959 nvl = (nvlist_t *)arg; 2960 2961 /* Translate nvlist */ 2962 if (it_nv_to_config(nvl, &cfg) != 0) { 2963 cmn_err(CE_WARN, "Configuration is invalid"); 2964 return; 2965 } 2966 2967 /* Check that no iSCSI ioctl is currently running */ 2968 mutex_enter(&iscsit_global.global_state_mutex); 2969 old_state = iscsit_global.global_svc_state; 2970 switch (iscsit_global.global_svc_state) { 2971 case ISE_ENABLED: 2972 case ISE_DISABLED: 2973 iscsit_global.global_svc_state = ISE_BUSY; 2974 break; 2975 case ISE_ENABLING: 2976 /* 2977 * It is OK for the iscsit_pp_cb to be called from inside of 2978 * an iSCSI ioctl only if we are currently executing inside 2979 * of stmf_register_port_provider. 2980 */ 2981 ASSERT((flags & STMF_PCB_PREG_COMPLETE) != 0); 2982 break; 2983 default: 2984 cmn_err(CE_WARN, "iscsit_pp_cb called when global_svc_state" 2985 " is not ENABLED(0x%x) -- ignoring", 2986 iscsit_global.global_svc_state); 2987 mutex_exit(&iscsit_global.global_state_mutex); 2988 it_config_free_cmn(cfg); 2989 return; 2990 } 2991 mutex_exit(&iscsit_global.global_state_mutex); 2992 2993 /* Update config */ 2994 (void) iscsit_config_merge(cfg); 2995 2996 it_config_free_cmn(cfg); 2997 2998 /* Restore old iSCSI driver global state */ 2999 mutex_enter(&iscsit_global.global_state_mutex); 3000 ASSERT(iscsit_global.global_svc_state == ISE_BUSY || 3001 iscsit_global.global_svc_state == ISE_ENABLING); 3002 iscsit_global.global_svc_state = old_state; 3003 mutex_exit(&iscsit_global.global_state_mutex); 3004 } 3005 3006 3007 static it_cfg_status_t 3008 iscsit_config_merge(it_config_t *in_cfg) 3009 { 3010 it_cfg_status_t status; 3011 it_config_t *cfg; 3012 it_config_t tmp_cfg; 3013 list_t tpg_del_list; 3014 3015 if (in_cfg) { 3016 cfg = in_cfg; 3017 } else { 3018 /* Make empty config */ 3019 bzero(&tmp_cfg, sizeof (tmp_cfg)); 3020 cfg = &tmp_cfg; 3021 } 3022 3023 list_create(&tpg_del_list, sizeof (iscsit_tpg_t), 3024 offsetof(iscsit_tpg_t, tpg_delete_ln)); 3025 3026 /* 3027 * Update targets, initiator contexts, target portal groups, 3028 * and iSNS client 3029 */ 3030 ISCSIT_GLOBAL_LOCK(RW_WRITER); 3031 if (((status = iscsit_config_merge_tpg(cfg, &tpg_del_list)) 3032 != 0) || 3033 ((status = iscsit_config_merge_tgt(cfg)) != 0) || 3034 ((status = iscsit_config_merge_ini(cfg)) != 0) || 3035 ((status = isnst_config_merge(cfg)) != 0)) { 3036 ISCSIT_GLOBAL_UNLOCK(); 3037 return (status); 3038 } 3039 3040 /* Update other global config parameters */ 3041 if (iscsit_global.global_props) { 3042 nvlist_free(iscsit_global.global_props); 3043 iscsit_global.global_props = NULL; 3044 } 3045 if (in_cfg) { 3046 (void) nvlist_dup(cfg->config_global_properties, 3047 &iscsit_global.global_props, KM_SLEEP); 3048 } 3049 ISCSIT_GLOBAL_UNLOCK(); 3050 3051 iscsit_config_destroy_tpgs(&tpg_del_list); 3052 3053 list_destroy(&tpg_del_list); 3054 3055 return (ITCFG_SUCCESS); 3056 } 3057 3058 /* 3059 * iscsit_sna_lt[e] 3060 * 3061 * Compare serial numbers using serial number arithmetic as defined in 3062 * RFC 1982. 3063 * 3064 * NOTE: This code is duplicated in the isns server. It ought to be common. 3065 */ 3066 3067 static int 3068 iscsit_sna_lt(uint32_t sn1, uint32_t sn2) 3069 { 3070 return ((sn1 != sn2) && 3071 (((sn1 < sn2) && ((sn2 - sn1) < ISCSIT_SNA32_CHECK)) || 3072 ((sn1 > sn2) && ((sn1 - sn2) > ISCSIT_SNA32_CHECK)))); 3073 } 3074 3075 static int 3076 iscsit_sna_lte(uint32_t sn1, uint32_t sn2) 3077 { 3078 return ((sn1 == sn2) || 3079 (((sn1 < sn2) && ((sn2 - sn1) < ISCSIT_SNA32_CHECK)) || 3080 ((sn1 > sn2) && ((sn1 - sn2) > ISCSIT_SNA32_CHECK)))); 3081 } 3082 3083 3084 static boolean_t 3085 iscsit_cmdsn_in_window(iscsit_conn_t *ict, uint32_t cmdsn) 3086 { 3087 iscsit_sess_t *ist = ict->ict_sess; 3088 int rval = B_TRUE; 3089 3090 ist = ict->ict_sess; 3091 3092 mutex_enter(&ist->ist_sn_mutex); 3093 3094 /* 3095 * If cmdsn is less than ist_expcmdsn - iscsit_cmd_window() or 3096 * greater than ist_expcmdsn, it's not in the window. 3097 */ 3098 3099 if (iscsit_sna_lt(cmdsn, (ist->ist_expcmdsn - iscsit_cmd_window())) || 3100 !iscsit_sna_lte(cmdsn, ist->ist_expcmdsn)) { 3101 rval = B_FALSE; 3102 } 3103 3104 mutex_exit(&ist->ist_sn_mutex); 3105 3106 return (rval); 3107 } 3108 3109 /* 3110 * iscsit_check_cmdsn_and_queue 3111 * 3112 * Independent of the order in which the iSCSI target receives non-immediate 3113 * command PDU across the entire session and any multiple connections within 3114 * the session, the target must deliver the commands to the SCSI layer in 3115 * CmdSN order. So out-of-order non-immediate commands are queued up on a 3116 * session-wide wait queue. Duplicate commands are ignored. 3117 * 3118 */ 3119 static int 3120 iscsit_check_cmdsn_and_queue(idm_pdu_t *rx_pdu) 3121 { 3122 idm_conn_t *ic = rx_pdu->isp_ic; 3123 iscsit_conn_t *ict = ic->ic_handle; 3124 iscsit_sess_t *ist = ict->ict_sess; 3125 iscsi_scsi_cmd_hdr_t *hdr = (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr; 3126 3127 mutex_enter(&ist->ist_sn_mutex); 3128 if (hdr->opcode & ISCSI_OP_IMMEDIATE) { 3129 /* do not queue, handle it immediately */ 3130 DTRACE_PROBE2(immediate__cmd, iscsit_sess_t *, ist, 3131 idm_pdu_t *, rx_pdu); 3132 mutex_exit(&ist->ist_sn_mutex); 3133 return (ISCSIT_CMDSN_EQ_EXPCMDSN); 3134 } 3135 if (iscsit_sna_lt(ist->ist_expcmdsn, ntohl(hdr->cmdsn))) { 3136 /* 3137 * Out-of-order commands (cmdSN higher than ExpCmdSN) 3138 * are staged on a fixed-size circular buffer until 3139 * the missing command is delivered to the SCSI layer. 3140 * Irrespective of the order of insertion into the 3141 * staging queue, the commands are processed out of the 3142 * queue in cmdSN order only. 3143 */ 3144 rx_pdu->isp_queue_time = gethrtime(); 3145 iscsit_add_pdu_to_queue(ist, rx_pdu); 3146 mutex_exit(&ist->ist_sn_mutex); 3147 return (ISCSIT_CMDSN_GT_EXPCMDSN); 3148 } else if (iscsit_sna_lt(ntohl(hdr->cmdsn), ist->ist_expcmdsn)) { 3149 DTRACE_PROBE3(cmdsn__lt__expcmdsn, iscsit_sess_t *, ist, 3150 iscsit_conn_t *, ict, idm_pdu_t *, rx_pdu); 3151 mutex_exit(&ist->ist_sn_mutex); 3152 return (ISCSIT_CMDSN_LT_EXPCMDSN); 3153 } else { 3154 mutex_exit(&ist->ist_sn_mutex); 3155 return (ISCSIT_CMDSN_EQ_EXPCMDSN); 3156 } 3157 } 3158 3159 /* 3160 * iscsit_add_pdu_to_queue() adds PDUs into the array indexed by 3161 * their cmdsn value. The length of the array is kept above the 3162 * maximum window size. The window keeps the cmdsn within a range 3163 * such that there are no collisons. e.g. the assumption is that 3164 * the windowing checks make it impossible to receive PDUs that 3165 * index into the same location in the array. 3166 */ 3167 static void 3168 iscsit_add_pdu_to_queue(iscsit_sess_t *ist, idm_pdu_t *rx_pdu) 3169 { 3170 iscsit_cbuf_t *cbuf = ist->ist_rxpdu_queue; 3171 iscsit_conn_t *ict = rx_pdu->isp_ic->ic_handle; 3172 uint32_t cmdsn = 3173 ((iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr)->cmdsn; 3174 uint32_t index; 3175 3176 ASSERT(MUTEX_HELD(&ist->ist_sn_mutex)); 3177 /* 3178 * If the connection is being torn down, then 3179 * don't add the PDU to the staging queue 3180 */ 3181 mutex_enter(&ict->ict_mutex); 3182 if (ict->ict_lost) { 3183 mutex_exit(&ict->ict_mutex); 3184 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 3185 return; 3186 } 3187 iscsit_conn_dispatch_hold(ict); 3188 mutex_exit(&ict->ict_mutex); 3189 3190 index = ntohl(cmdsn) % ISCSIT_RXPDU_QUEUE_LEN; 3191 /* 3192 * In the normal case, assuming that the Initiator is not 3193 * buggy and that we don't have packet duplication occuring, 3194 * the entry in the array will be NULL. However, we may have 3195 * received a duplicate PDU with cmdsn > expsn , and in that 3196 * case we just ignore this PDU -- the previously received one 3197 * remains queued for processing. We need to be careful not 3198 * to leak this one however. 3199 */ 3200 if (cbuf->cb_buffer[index] != NULL) { 3201 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 3202 } else { 3203 cbuf->cb_buffer[index] = rx_pdu; 3204 cbuf->cb_num_elems++; 3205 } 3206 } 3207 3208 static idm_pdu_t * 3209 iscsit_remove_pdu_from_queue(iscsit_sess_t *ist, uint32_t cmdsn) 3210 { 3211 iscsit_cbuf_t *cbuf = ist->ist_rxpdu_queue; 3212 idm_pdu_t *pdu = NULL; 3213 uint32_t index; 3214 3215 ASSERT(MUTEX_HELD(&ist->ist_sn_mutex)); 3216 index = cmdsn % ISCSIT_RXPDU_QUEUE_LEN; 3217 if ((pdu = cbuf->cb_buffer[index]) != NULL) { 3218 ASSERT(cmdsn == 3219 ntohl(((iscsi_scsi_cmd_hdr_t *)pdu->isp_hdr)->cmdsn)); 3220 cbuf->cb_buffer[index] = NULL; 3221 cbuf->cb_num_elems--; 3222 return (pdu); 3223 } 3224 return (NULL); 3225 } 3226 3227 /* 3228 * iscsit_process_pdu_in_queue() finds the next pdu in sequence 3229 * and posts it to the SCSI layer 3230 */ 3231 static void 3232 iscsit_process_pdu_in_queue(iscsit_sess_t *ist) 3233 { 3234 iscsit_cbuf_t *cbuf = ist->ist_rxpdu_queue; 3235 idm_pdu_t *pdu = NULL; 3236 uint32_t expcmdsn; 3237 3238 for (;;) { 3239 mutex_enter(&ist->ist_sn_mutex); 3240 if (cbuf->cb_num_elems == 0) { 3241 mutex_exit(&ist->ist_sn_mutex); 3242 break; 3243 } 3244 expcmdsn = ist->ist_expcmdsn; 3245 if ((pdu = iscsit_remove_pdu_from_queue(ist, expcmdsn)) 3246 == NULL) { 3247 mutex_exit(&ist->ist_sn_mutex); 3248 break; 3249 } 3250 mutex_exit(&ist->ist_sn_mutex); 3251 iscsit_post_staged_pdu(pdu); 3252 } 3253 } 3254 3255 static void 3256 iscsit_post_staged_pdu(idm_pdu_t *rx_pdu) 3257 { 3258 iscsit_conn_t *ict = rx_pdu->isp_ic->ic_handle; 3259 3260 /* Post the PDU to the SCSI layer */ 3261 switch (IDM_PDU_OPCODE(rx_pdu)) { 3262 case ISCSI_OP_NOOP_OUT: 3263 iscsit_set_cmdsn(ict, rx_pdu); 3264 iscsit_pdu_op_noop(ict, rx_pdu); 3265 break; 3266 case ISCSI_OP_TEXT_CMD: 3267 iscsit_set_cmdsn(ict, rx_pdu); 3268 iscsit_pdu_op_text_cmd(ict, rx_pdu); 3269 break; 3270 case ISCSI_OP_SCSI_TASK_MGT_MSG: 3271 iscsit_set_cmdsn(ict, rx_pdu); 3272 iscsit_op_scsi_task_mgmt(ict, rx_pdu); 3273 break; 3274 case ISCSI_OP_SCSI_CMD: 3275 /* cmdSN will be incremented after creating itask */ 3276 iscsit_post_scsi_cmd(rx_pdu->isp_ic, rx_pdu); 3277 break; 3278 case ISCSI_OP_LOGOUT_CMD: 3279 iscsit_set_cmdsn(ict, rx_pdu); 3280 iscsit_pdu_op_logout_cmd(ict, rx_pdu); 3281 break; 3282 default: 3283 /* No other PDUs should be placed on the queue */ 3284 ASSERT(0); 3285 } 3286 iscsit_conn_dispatch_rele(ict); /* release hold on the conn */ 3287 } 3288 3289 /* ARGSUSED */ 3290 void 3291 iscsit_rxpdu_queue_monitor_start(void) 3292 { 3293 mutex_enter(&iscsit_rxpdu_queue_monitor_mutex); 3294 if (iscsit_rxpdu_queue_monitor_thr_running) { 3295 mutex_exit(&iscsit_rxpdu_queue_monitor_mutex); 3296 return; 3297 } 3298 iscsit_rxpdu_queue_monitor_thr_id = 3299 thread_create(NULL, 0, iscsit_rxpdu_queue_monitor, NULL, 3300 0, &p0, TS_RUN, minclsyspri); 3301 while (!iscsit_rxpdu_queue_monitor_thr_running) { 3302 cv_wait(&iscsit_rxpdu_queue_monitor_cv, 3303 &iscsit_rxpdu_queue_monitor_mutex); 3304 } 3305 mutex_exit(&iscsit_rxpdu_queue_monitor_mutex); 3306 3307 } 3308 3309 /* ARGSUSED */ 3310 void 3311 iscsit_rxpdu_queue_monitor_stop(void) 3312 { 3313 mutex_enter(&iscsit_rxpdu_queue_monitor_mutex); 3314 if (iscsit_rxpdu_queue_monitor_thr_running) { 3315 iscsit_rxpdu_queue_monitor_thr_running = B_FALSE; 3316 cv_signal(&iscsit_rxpdu_queue_monitor_cv); 3317 mutex_exit(&iscsit_rxpdu_queue_monitor_mutex); 3318 3319 thread_join(iscsit_rxpdu_queue_monitor_thr_did); 3320 return; 3321 } 3322 mutex_exit(&iscsit_rxpdu_queue_monitor_mutex); 3323 } 3324 3325 /* 3326 * A separate thread is used to scan the staging queue on all the 3327 * sessions, If a delayed PDU does not arrive within a timeout, the 3328 * target will advance to the staged PDU that is next in sequence 3329 * and exceeded the threshold wait time. It is up to the initiator 3330 * to note that the target has not acknowledged a particular cmdsn 3331 * and take appropriate action. 3332 */ 3333 /* ARGSUSED */ 3334 static void 3335 iscsit_rxpdu_queue_monitor(void *arg) 3336 { 3337 iscsit_tgt_t *tgt; 3338 iscsit_sess_t *ist; 3339 3340 mutex_enter(&iscsit_rxpdu_queue_monitor_mutex); 3341 iscsit_rxpdu_queue_monitor_thr_did = curthread->t_did; 3342 iscsit_rxpdu_queue_monitor_thr_running = B_TRUE; 3343 cv_signal(&iscsit_rxpdu_queue_monitor_cv); 3344 3345 while (iscsit_rxpdu_queue_monitor_thr_running) { 3346 ISCSIT_GLOBAL_LOCK(RW_READER); 3347 for (tgt = avl_first(&iscsit_global.global_target_list); 3348 tgt != NULL; 3349 tgt = AVL_NEXT(&iscsit_global.global_target_list, tgt)) { 3350 mutex_enter(&tgt->target_mutex); 3351 for (ist = avl_first(&tgt->target_sess_list); 3352 ist != NULL; 3353 ist = AVL_NEXT(&tgt->target_sess_list, ist)) { 3354 3355 iscsit_rxpdu_queue_monitor_session(ist); 3356 } 3357 mutex_exit(&tgt->target_mutex); 3358 } 3359 ISCSIT_GLOBAL_UNLOCK(); 3360 if (iscsit_rxpdu_queue_monitor_thr_running == B_FALSE) { 3361 break; 3362 } 3363 (void) cv_reltimedwait(&iscsit_rxpdu_queue_monitor_cv, 3364 &iscsit_rxpdu_queue_monitor_mutex, 3365 ISCSIT_RXPDU_QUEUE_MONITOR_INTERVAL * drv_usectohz(1000000), 3366 TR_CLOCK_TICK); 3367 } 3368 mutex_exit(&iscsit_rxpdu_queue_monitor_mutex); 3369 thread_exit(); 3370 } 3371 3372 static void 3373 iscsit_rxpdu_queue_monitor_session(iscsit_sess_t *ist) 3374 { 3375 iscsit_cbuf_t *cbuf = ist->ist_rxpdu_queue; 3376 idm_pdu_t *next_pdu = NULL; 3377 uint32_t index, next_cmdsn, i; 3378 3379 /* 3380 * Assume that all PDUs in the staging queue have a cmdsn >= expcmdsn. 3381 * Starting with the expcmdsn, iterate over the staged PDUs to find 3382 * the next PDU with a wait time greater than the threshold. If found 3383 * advance the staged PDU to the SCSI layer, skipping over the missing 3384 * PDU(s) to get past the hole in the command sequence. It is up to 3385 * the initiator to note that the target has not acknowledged a cmdsn 3386 * and take appropriate action. 3387 * 3388 * Since the PDU(s) arrive in any random order, it is possible that 3389 * that the actual wait time for a particular PDU is much longer than 3390 * the defined threshold. e.g. Consider a case where commands are sent 3391 * over 4 different connections, and cmdsn = 1004 arrives first, then 3392 * 1003, and 1002 and 1001 are lost due to a connection failure. 3393 * So now 1003 is waiting for 1002 to be delivered, and although the 3394 * wait time of 1004 > wait time of 1003, only 1003 will be considered 3395 * by the monitor thread. 1004 will be automatically processed by 3396 * iscsit_process_pdu_in_queue() once the scan is complete and the 3397 * expcmdsn becomes current. 3398 */ 3399 mutex_enter(&ist->ist_sn_mutex); 3400 cbuf = ist->ist_rxpdu_queue; 3401 if (cbuf->cb_num_elems == 0) { 3402 mutex_exit(&ist->ist_sn_mutex); 3403 return; 3404 } 3405 for (next_pdu = NULL, i = 0; ; i++) { 3406 next_cmdsn = ist->ist_expcmdsn + i; /* start at expcmdsn */ 3407 index = next_cmdsn % ISCSIT_RXPDU_QUEUE_LEN; 3408 if ((next_pdu = cbuf->cb_buffer[index]) != NULL) { 3409 /* 3410 * If the PDU wait time has not exceeded threshold 3411 * stop scanning the staging queue until the timer 3412 * fires again 3413 */ 3414 if ((gethrtime() - next_pdu->isp_queue_time) 3415 < (rxpdu_queue_threshold * NANOSEC)) { 3416 mutex_exit(&ist->ist_sn_mutex); 3417 return; 3418 } 3419 /* 3420 * Remove the next PDU from the queue and post it 3421 * to the SCSI layer, skipping over the missing 3422 * PDU. Stop scanning the staging queue until 3423 * the monitor timer fires again 3424 */ 3425 (void) iscsit_remove_pdu_from_queue(ist, next_cmdsn); 3426 mutex_exit(&ist->ist_sn_mutex); 3427 DTRACE_PROBE3(advanced__to__blocked__cmdsn, 3428 iscsit_sess_t *, ist, idm_pdu_t *, next_pdu, 3429 uint32_t, next_cmdsn); 3430 iscsit_post_staged_pdu(next_pdu); 3431 /* Deliver any subsequent PDUs immediately */ 3432 iscsit_process_pdu_in_queue(ist); 3433 return; 3434 } 3435 /* 3436 * Skipping over i PDUs, e.g. a case where commands 1001 and 3437 * 1002 are lost in the network, skip over both and post 1003 3438 * expcmdsn then becomes 1004 at the end of the scan. 3439 */ 3440 DTRACE_PROBE2(skipping__over__cmdsn, iscsit_sess_t *, ist, 3441 uint32_t, next_cmdsn); 3442 } 3443 /* 3444 * following the assumption, staged cmdsn >= expcmdsn, this statement 3445 * is never reached. 3446 */ 3447 }