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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/cpuvar.h> 27 #include <sys/types.h> 28 #include <sys/conf.h> 29 #include <sys/stat.h> 30 #include <sys/file.h> 31 #include <sys/ddi.h> 32 #include <sys/sunddi.h> 33 #include <sys/modctl.h> 34 #include <sys/sysmacros.h> 35 #include <sys/socket.h> 36 #include <sys/strsubr.h> 37 #include <sys/nvpair.h> 38 39 #include <sys/stmf.h> 40 #include <sys/stmf_ioctl.h> 41 #include <sys/portif.h> 42 #include <sys/idm/idm.h> 43 #include <sys/idm/idm_conn_sm.h> 44 #include <iscsit_isns.h> 45 #include <iscsit.h> 46 47 #define ISCSIT_VERSION BUILD_DATE "-1.18dev" 48 #define ISCSIT_NAME_VERSION "COMSTAR ISCSIT v" ISCSIT_VERSION 49 50 /* 51 * DDI entry points. 52 */ 53 static int iscsit_drv_attach(dev_info_t *, ddi_attach_cmd_t); 54 static int iscsit_drv_detach(dev_info_t *, ddi_detach_cmd_t); 55 static int iscsit_drv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 56 static int iscsit_drv_open(dev_t *, int, int, cred_t *); 57 static int iscsit_drv_close(dev_t, int, int, cred_t *); 58 static boolean_t iscsit_drv_busy(void); 59 static int iscsit_drv_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 60 static boolean_t iscsit_cmdsn_in_window(iscsit_conn_t *ict, uint32_t cmdsn); 61 static void iscsit_send_direct_scsi_resp(iscsit_conn_t *ict, idm_pdu_t *rx_pdu, 62 uint8_t response, uint8_t cmd_status); 63 static void iscsit_send_task_mgmt_resp(idm_pdu_t *tm_resp_pdu, 64 uint8_t tm_status); 65 66 extern struct mod_ops mod_miscops; 67 68 69 static struct cb_ops iscsit_cb_ops = { 70 iscsit_drv_open, /* cb_open */ 71 iscsit_drv_close, /* cb_close */ 72 nodev, /* cb_strategy */ 73 nodev, /* cb_print */ 74 nodev, /* cb_dump */ 75 nodev, /* cb_read */ 76 nodev, /* cb_write */ 77 iscsit_drv_ioctl, /* cb_ioctl */ 78 nodev, /* cb_devmap */ 79 nodev, /* cb_mmap */ 80 nodev, /* cb_segmap */ 81 nochpoll, /* cb_chpoll */ 82 ddi_prop_op, /* cb_prop_op */ 83 NULL, /* cb_streamtab */ 84 D_MP, /* cb_flag */ 85 CB_REV, /* cb_rev */ 86 nodev, /* cb_aread */ 87 nodev, /* cb_awrite */ 88 }; 89 90 static struct dev_ops iscsit_dev_ops = { 91 DEVO_REV, /* devo_rev */ 92 0, /* devo_refcnt */ 93 iscsit_drv_getinfo, /* devo_getinfo */ 94 nulldev, /* devo_identify */ 95 nulldev, /* devo_probe */ 96 iscsit_drv_attach, /* devo_attach */ 97 iscsit_drv_detach, /* devo_detach */ 98 nodev, /* devo_reset */ 99 &iscsit_cb_ops, /* devo_cb_ops */ 100 NULL, /* devo_bus_ops */ 101 NULL, /* devo_power */ 102 }; 103 104 static struct modldrv modldrv = { 105 &mod_driverops, 106 "iSCSI Target", 107 &iscsit_dev_ops, 108 }; 109 110 static struct modlinkage modlinkage = { 111 MODREV_1, 112 &modldrv, 113 NULL, 114 }; 115 116 117 iscsit_global_t iscsit_global; 118 119 kmem_cache_t *iscsit_status_pdu_cache; 120 121 boolean_t iscsit_sm_logging = B_FALSE; 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 void 128 iscsit_op_scsi_task_mgmt(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 129 130 static void 131 iscsit_pdu_op_noop(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 132 133 static void 134 iscsit_pdu_op_login_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 135 136 void 137 iscsit_pdu_op_text_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 138 139 static void 140 iscsit_pdu_op_logout_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 141 142 int iscsit_cmd_window(); 143 144 void 145 iscsit_set_cmdsn(iscsit_conn_t *ict, idm_pdu_t *rx_pdu); 146 147 static void 148 iscsit_calc_rspsn(iscsit_conn_t *ict, idm_pdu_t *resp); 149 150 static void 151 iscsit_deferred_dispatch(idm_pdu_t *rx_pdu); 152 153 static void 154 iscsit_deferred(void *rx_pdu_void); 155 156 static idm_status_t 157 iscsit_conn_accept(idm_conn_t *ic); 158 159 static idm_status_t 160 iscsit_ffp_enabled(idm_conn_t *ic); 161 162 static idm_status_t 163 iscsit_ffp_disabled(idm_conn_t *ic, idm_ffp_disable_t disable_class); 164 165 static idm_status_t 166 iscsit_conn_lost(idm_conn_t *ic); 167 168 static idm_status_t 169 iscsit_conn_destroy(idm_conn_t *ic); 170 171 static stmf_data_buf_t * 172 iscsit_dbuf_alloc(scsi_task_t *task, uint32_t size, uint32_t *pminsize, 173 uint32_t flags); 174 175 static void 176 iscsit_dbuf_free(stmf_dbuf_store_t *ds, stmf_data_buf_t *dbuf); 177 178 static void 179 iscsit_buf_xfer_cb(idm_buf_t *idb, idm_status_t status); 180 181 static void 182 iscsit_send_good_status_done(idm_pdu_t *pdu, idm_status_t status); 183 184 static void 185 iscsit_send_status_done(idm_pdu_t *pdu, idm_status_t status); 186 187 static stmf_status_t 188 iscsit_idm_to_stmf(idm_status_t idmrc); 189 190 static iscsit_task_t * 191 iscsit_task_alloc(iscsit_conn_t *ict); 192 193 static void 194 iscsit_task_free(iscsit_task_t *itask); 195 196 static iscsit_task_t * 197 iscsit_tm_task_alloc(iscsit_conn_t *ict); 198 199 static void 200 iscsit_tm_task_free(iscsit_task_t *itask); 201 202 static int 203 iscsit_status_pdu_constructor(void *pdu_void, void *arg, int flags); 204 205 static void 206 iscsit_pp_cb(struct stmf_port_provider *pp, int cmd, void *arg, uint32_t flags); 207 208 static it_cfg_status_t 209 iscsit_config_merge(it_config_t *cfg); 210 211 static idm_status_t 212 iscsit_login_fail(idm_conn_t *ic); 213 214 int 215 _init(void) 216 { 217 int rc; 218 219 rw_init(&iscsit_global.global_rwlock, NULL, RW_DRIVER, NULL); 220 iscsit_global.global_svc_state = ISE_DETACHED; 221 222 if ((rc = mod_install(&modlinkage)) != 0) { 223 rw_destroy(&iscsit_global.global_rwlock); 224 return (rc); 225 } 226 227 return (rc); 228 } 229 230 int 231 _info(struct modinfo *modinfop) 232 { 233 return (mod_info(&modlinkage, modinfop)); 234 } 235 236 int 237 _fini(void) 238 { 239 int rc; 240 241 rc = mod_remove(&modlinkage); 242 243 if (rc == 0) { 244 rw_destroy(&iscsit_global.global_rwlock); 245 } 246 247 return (rc); 248 } 249 250 /* 251 * DDI entry points. 252 */ 253 254 /* ARGSUSED */ 255 static int 256 iscsit_drv_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, 257 void **result) 258 { 259 ulong_t instance = getminor((dev_t)arg); 260 261 switch (cmd) { 262 case DDI_INFO_DEVT2DEVINFO: 263 *result = iscsit_global.global_dip; 264 return (DDI_SUCCESS); 265 266 case DDI_INFO_DEVT2INSTANCE: 267 *result = (void *)instance; 268 return (DDI_SUCCESS); 269 270 default: 271 break; 272 } 273 274 return (DDI_FAILURE); 275 } 276 277 static int 278 iscsit_drv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 279 { 280 if (cmd != DDI_ATTACH) { 281 return (DDI_FAILURE); 282 } 283 284 if (ddi_get_instance(dip) != 0) { 285 /* we only allow instance 0 to attach */ 286 return (DDI_FAILURE); 287 } 288 289 /* create the minor node */ 290 if (ddi_create_minor_node(dip, ISCSIT_MODNAME, S_IFCHR, 0, 291 DDI_PSEUDO, 0) != DDI_SUCCESS) { 292 cmn_err(CE_WARN, "iscsit_drv_attach: " 293 "failed creating minor node"); 294 return (DDI_FAILURE); 295 } 296 297 if (iscsit_init(dip) != IDM_STATUS_SUCCESS) { 298 cmn_err(CE_WARN, "iscsit_drv_attach: " 299 "failed to initialize"); 300 ddi_remove_minor_node(dip, NULL); 301 return (DDI_FAILURE); 302 } 303 304 iscsit_global.global_svc_state = ISE_DISABLED; 305 iscsit_global.global_dip = dip; 306 307 return (DDI_SUCCESS); 308 } 309 310 /*ARGSUSED*/ 311 static int 312 iscsit_drv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 313 { 314 if (cmd != DDI_DETACH) 315 return (DDI_FAILURE); 316 317 ISCSIT_GLOBAL_LOCK(RW_WRITER); 318 if (iscsit_drv_busy()) { 319 ISCSIT_GLOBAL_UNLOCK(); 320 return (EBUSY); 321 } 322 323 iscsit_global.global_dip = NULL; 324 ddi_remove_minor_node(dip, NULL); 325 326 ldi_ident_release(iscsit_global.global_li); 327 iscsit_global.global_svc_state = ISE_DETACHED; 328 329 ISCSIT_GLOBAL_UNLOCK(); 330 331 return (DDI_SUCCESS); 332 } 333 334 /*ARGSUSED*/ 335 static int 336 iscsit_drv_open(dev_t *devp, int flag, int otyp, cred_t *credp) 337 { 338 return (0); 339 } 340 341 /* ARGSUSED */ 342 static int 343 iscsit_drv_close(dev_t dev, int flag, int otyp, cred_t *credp) 344 { 345 return (0); 346 } 347 348 static boolean_t 349 iscsit_drv_busy(void) 350 { 351 switch (iscsit_global.global_svc_state) { 352 case ISE_DISABLED: 353 case ISE_DETACHED: 354 return (B_FALSE); 355 default: 356 return (B_TRUE); 357 } 358 /* NOTREACHED */ 359 } 360 361 /* ARGSUSED */ 362 static int 363 iscsit_drv_ioctl(dev_t drv, int cmd, intptr_t argp, int flag, cred_t *cred, 364 int *retval) 365 { 366 iscsit_ioc_set_config_t setcfg; 367 iscsit_ioc_set_config32_t setcfg32; 368 /* iscsit_ioc_get_config_t getcfg; */ 369 char *cfg_pnvlist; 370 nvlist_t *cfg_nvlist; 371 it_config_t *cfg; 372 idm_status_t idmrc; 373 int rc = 0; 374 375 if (drv_priv(cred) != 0) { 376 return (EPERM); 377 } 378 379 ISCSIT_GLOBAL_LOCK(RW_WRITER); 380 381 /* 382 * Validate ioctl requests against global service state 383 */ 384 switch (iscsit_global.global_svc_state) { 385 case ISE_ENABLED: 386 if (cmd == ISCSIT_IOC_DISABLE_SVC) { 387 iscsit_global.global_svc_state = ISE_DISABLING; 388 } else if (cmd == ISCSIT_IOC_ENABLE_SVC) { 389 /* Already enabled */ 390 ISCSIT_GLOBAL_UNLOCK(); 391 return (0); 392 } else { 393 iscsit_global.global_svc_state = ISE_BUSY; 394 } 395 break; 396 case ISE_DISABLED: 397 if (cmd == ISCSIT_IOC_ENABLE_SVC) { 398 iscsit_global.global_svc_state = ISE_ENABLING; 399 } else if (cmd == ISCSIT_IOC_DISABLE_SVC) { 400 /* Already disabled */ 401 ISCSIT_GLOBAL_UNLOCK(); 402 return (0); 403 } else { 404 rc = EFAULT; 405 } 406 break; 407 case ISE_ENABLING: 408 case ISE_DISABLING: 409 rc = EAGAIN; 410 break; 411 case ISE_DETACHED: 412 default: 413 rc = EFAULT; 414 break; 415 } 416 417 ISCSIT_GLOBAL_UNLOCK(); 418 if (rc != 0) 419 return (rc); 420 421 /* Handle ioctl request (enable/disable have already been handled) */ 422 switch (cmd) { 423 case ISCSIT_IOC_SET_CONFIG: 424 switch (ddi_model_convert_from(flag & FMODELS)) { 425 case DDI_MODEL_ILP32: 426 if (ddi_copyin((void *)argp, &setcfg32, 427 sizeof (iscsit_ioc_set_config32_t), flag) != 0) 428 return (EFAULT); 429 430 setcfg.set_cfg_pnvlist = 431 (char *)((uintptr_t)setcfg32.set_cfg_pnvlist); 432 setcfg.set_cfg_vers = setcfg32.set_cfg_vers; 433 setcfg.set_cfg_pnvlist_len = 434 setcfg32.set_cfg_pnvlist_len; 435 break; 436 case DDI_MODEL_NONE: 437 if (ddi_copyin((void *)argp, &setcfg, 438 sizeof (iscsit_ioc_set_config_t), flag) != 0) 439 return (EFAULT); 440 break; 441 } 442 443 /* Check API version */ 444 if (setcfg.set_cfg_vers != ISCSIT_API_VERS0) { 445 return (EINVAL); 446 } 447 448 /* Config is in packed nvlist format so unpack it */ 449 cfg_pnvlist = kmem_alloc(setcfg.set_cfg_pnvlist_len, 450 KM_SLEEP); 451 ASSERT(cfg_pnvlist != NULL); 452 453 if (ddi_copyin(setcfg.set_cfg_pnvlist, cfg_pnvlist, 454 setcfg.set_cfg_pnvlist_len, flag) != 0) { 455 kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len); 456 return (EFAULT); 457 } 458 459 if (nvlist_unpack(cfg_pnvlist, setcfg.set_cfg_pnvlist_len, 460 &cfg_nvlist, KM_SLEEP) != 0) { 461 kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len); 462 return (EINVAL); 463 } 464 465 /* Translate nvlist */ 466 if (it_nv_to_config(cfg_nvlist, &cfg) != 0) { 467 cmn_err(CE_WARN, "Configuration is invalid"); 468 kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len); 469 nvlist_free(cfg_nvlist); 470 return (EINVAL); 471 } 472 473 /* Update config */ 474 if (iscsit_config_merge(cfg) != 0) { 475 kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len); 476 nvlist_free(cfg_nvlist); 477 return (EIO); 478 } 479 480 it_config_free_cmn(cfg); 481 kmem_free(cfg_pnvlist, setcfg.set_cfg_pnvlist_len); 482 nvlist_free(cfg_nvlist); 483 484 /* 485 * Now that the reconfig is complete set our state back to 486 * enabled. 487 */ 488 ISCSIT_GLOBAL_LOCK(RW_WRITER); 489 iscsit_global.global_svc_state = ISE_ENABLED; 490 ISCSIT_GLOBAL_UNLOCK(); 491 break; 492 case ISCSIT_IOC_ENABLE_SVC: { 493 iscsit_hostinfo_t hostinfo; 494 495 if (ddi_copyin((void *)argp, &hostinfo.length, 496 sizeof (hostinfo.length), flag) != 0) { 497 iscsit_global.global_svc_state = ISE_DISABLED; 498 return (EFAULT); 499 } 500 501 if (hostinfo.length > sizeof (hostinfo.fqhn)) 502 hostinfo.length = sizeof (hostinfo.fqhn); 503 504 if (ddi_copyin((void *)((caddr_t)argp + 505 sizeof (hostinfo.length)), &hostinfo.fqhn, 506 hostinfo.length, flag) != 0) { 507 iscsit_global.global_svc_state = ISE_DISABLED; 508 return (EFAULT); 509 } 510 511 idmrc = iscsit_enable_svc(&hostinfo); 512 ISCSIT_GLOBAL_LOCK(RW_WRITER); 513 if (idmrc == IDM_STATUS_SUCCESS) { 514 iscsit_global.global_svc_state = ISE_ENABLED; 515 } else { 516 rc = EIO; 517 iscsit_global.global_svc_state = ISE_DISABLED; 518 } 519 ISCSIT_GLOBAL_UNLOCK(); 520 break; 521 } 522 case ISCSIT_IOC_DISABLE_SVC: 523 iscsit_disable_svc(); 524 ISCSIT_GLOBAL_LOCK(RW_WRITER); 525 iscsit_global.global_svc_state = ISE_DISABLED; 526 ISCSIT_GLOBAL_UNLOCK(); 527 break; 528 default: 529 rc = EINVAL; 530 } 531 532 /* Don't forget to clear ISE_BUSY state */ 533 ASSERT(iscsit_global.global_svc_state != ISE_BUSY); 534 535 return (rc); 536 } 537 538 static idm_status_t 539 iscsit_init(dev_info_t *dip) 540 { 541 int rc; 542 543 rc = ldi_ident_from_dip(dip, &iscsit_global.global_li); 544 ASSERT(rc == 0); /* Failure indicates invalid argument */ 545 546 iscsit_global.global_svc_state = ISE_DISABLED; 547 548 return (IDM_STATUS_SUCCESS); 549 } 550 551 /* 552 * iscsit_enable_svc 553 * 554 * registers all the configured targets and target portals with STMF 555 */ 556 static idm_status_t 557 iscsit_enable_svc(iscsit_hostinfo_t *hostinfo) 558 { 559 stmf_port_provider_t *pp; 560 stmf_dbuf_store_t *dbuf_store; 561 boolean_t did_iscsit_isns_init; 562 idm_status_t retval = IDM_STATUS_SUCCESS; 563 564 ASSERT(iscsit_global.global_svc_state == ISE_ENABLING); 565 566 /* 567 * Make sure that can tell if we have partially allocated 568 * in case we need to exit and tear down anything allocated. 569 */ 570 iscsit_global.global_tsih_pool = NULL; 571 iscsit_global.global_dbuf_store = NULL; 572 iscsit_status_pdu_cache = NULL; 573 pp = NULL; 574 iscsit_global.global_pp = NULL; 575 iscsit_global.global_default_tpg = NULL; 576 did_iscsit_isns_init = B_FALSE; 577 iscsit_global.global_dispatch_taskq = NULL; 578 579 /* Setup remaining fields in iscsit_global_t */ 580 idm_refcnt_init(&iscsit_global.global_refcnt, 581 &iscsit_global); 582 583 avl_create(&iscsit_global.global_discovery_sessions, 584 iscsit_sess_avl_compare, sizeof (iscsit_sess_t), 585 offsetof(iscsit_sess_t, ist_tgt_ln)); 586 587 avl_create(&iscsit_global.global_target_list, 588 iscsit_tgt_avl_compare, sizeof (iscsit_tgt_t), 589 offsetof(iscsit_tgt_t, target_global_ln)); 590 591 list_create(&iscsit_global.global_deleted_target_list, 592 sizeof (iscsit_tgt_t), 593 offsetof(iscsit_tgt_t, target_global_deleted_ln)); 594 595 avl_create(&iscsit_global.global_tpg_list, 596 iscsit_tpg_avl_compare, sizeof (iscsit_tpg_t), 597 offsetof(iscsit_tpg_t, tpg_global_ln)); 598 599 avl_create(&iscsit_global.global_ini_list, 600 iscsit_ini_avl_compare, sizeof (iscsit_ini_t), 601 offsetof(iscsit_ini_t, ini_global_ln)); 602 603 iscsit_global.global_tsih_pool = vmem_create("iscsit_tsih_pool", 604 (void *)1, ISCSI_MAX_TSIH, 1, NULL, NULL, NULL, 0, 605 VM_SLEEP | VMC_IDENTIFIER); 606 607 /* 608 * Setup STMF dbuf store. Our buffers are bound to a specific 609 * connection so we really can't let STMF cache buffers for us. 610 * Consequently we'll just allocate one global buffer store. 611 */ 612 dbuf_store = stmf_alloc(STMF_STRUCT_DBUF_STORE, 0, 0); 613 if (dbuf_store == NULL) { 614 retval = IDM_STATUS_FAIL; 615 goto tear_down_and_return; 616 } 617 dbuf_store->ds_alloc_data_buf = iscsit_dbuf_alloc; 618 dbuf_store->ds_free_data_buf = iscsit_dbuf_free; 619 dbuf_store->ds_port_private = NULL; 620 iscsit_global.global_dbuf_store = dbuf_store; 621 622 /* Status PDU cache */ 623 iscsit_status_pdu_cache = kmem_cache_create("iscsit_status_pdu_cache", 624 sizeof (idm_pdu_t) + sizeof (iscsi_scsi_rsp_hdr_t), 8, 625 &iscsit_status_pdu_constructor, 626 NULL, NULL, NULL, NULL, KM_SLEEP); 627 628 /* Default TPG and portal */ 629 iscsit_global.global_default_tpg = iscsit_tpg_createdefault(); 630 if (iscsit_global.global_default_tpg == NULL) { 631 retval = IDM_STATUS_FAIL; 632 goto tear_down_and_return; 633 } 634 635 /* initialize isns client */ 636 (void) iscsit_isns_init(hostinfo); 637 did_iscsit_isns_init = B_TRUE; 638 639 /* Register port provider */ 640 pp = stmf_alloc(STMF_STRUCT_PORT_PROVIDER, 0, 0); 641 if (pp == NULL) { 642 retval = IDM_STATUS_FAIL; 643 goto tear_down_and_return; 644 } 645 646 pp->pp_portif_rev = PORTIF_REV_1; 647 pp->pp_instance = 0; 648 pp->pp_name = ISCSIT_MODNAME; 649 pp->pp_cb = iscsit_pp_cb; 650 651 iscsit_global.global_pp = pp; 652 653 654 if (stmf_register_port_provider(pp) != STMF_SUCCESS) { 655 retval = IDM_STATUS_FAIL; 656 goto tear_down_and_return; 657 } 658 659 iscsit_global.global_dispatch_taskq = taskq_create("iscsit_dispatch", 660 1, minclsyspri, 16, 16, TASKQ_PREPOPULATE); 661 662 return (IDM_STATUS_SUCCESS); 663 664 tear_down_and_return: 665 666 if (iscsit_global.global_dispatch_taskq) { 667 taskq_destroy(iscsit_global.global_dispatch_taskq); 668 iscsit_global.global_dispatch_taskq = NULL; 669 } 670 671 if (did_iscsit_isns_init) 672 iscsit_isns_fini(); 673 674 if (iscsit_global.global_default_tpg) { 675 iscsit_tpg_destroydefault(iscsit_global.global_default_tpg); 676 iscsit_global.global_default_tpg = NULL; 677 } 678 679 if (iscsit_global.global_pp) 680 iscsit_global.global_pp = NULL; 681 682 if (pp) 683 stmf_free(pp); 684 685 if (iscsit_status_pdu_cache) { 686 kmem_cache_destroy(iscsit_status_pdu_cache); 687 iscsit_status_pdu_cache = NULL; 688 } 689 690 if (iscsit_global.global_dbuf_store) { 691 stmf_free(iscsit_global.global_dbuf_store); 692 iscsit_global.global_dbuf_store = NULL; 693 } 694 695 if (iscsit_global.global_tsih_pool) { 696 vmem_destroy(iscsit_global.global_tsih_pool); 697 iscsit_global.global_tsih_pool = NULL; 698 } 699 700 avl_destroy(&iscsit_global.global_ini_list); 701 avl_destroy(&iscsit_global.global_tpg_list); 702 list_destroy(&iscsit_global.global_deleted_target_list); 703 avl_destroy(&iscsit_global.global_target_list); 704 avl_destroy(&iscsit_global.global_discovery_sessions); 705 706 idm_refcnt_destroy(&iscsit_global.global_refcnt); 707 708 return (retval); 709 } 710 711 /* 712 * iscsit_disable_svc 713 * 714 * clean up all existing connections and deregister targets from STMF 715 */ 716 static void 717 iscsit_disable_svc(void) 718 { 719 iscsit_sess_t *sess; 720 721 ASSERT(iscsit_global.global_svc_state == ISE_DISABLING); 722 723 /* tear down discovery sessions */ 724 for (sess = avl_first(&iscsit_global.global_discovery_sessions); 725 sess != NULL; 726 sess = AVL_NEXT(&iscsit_global.global_discovery_sessions, sess)) 727 iscsit_sess_close(sess); 728 729 /* 730 * Passing NULL to iscsit_config_merge tells it to go to an empty 731 * config. 732 */ 733 (void) iscsit_config_merge(NULL); 734 735 /* 736 * Wait until there are no more global references 737 */ 738 idm_refcnt_wait_ref(&iscsit_global.global_refcnt); 739 idm_refcnt_destroy(&iscsit_global.global_refcnt); 740 741 /* 742 * Default TPG must be destroyed after global_refcnt is 0. 743 */ 744 iscsit_tpg_destroydefault(iscsit_global.global_default_tpg); 745 746 avl_destroy(&iscsit_global.global_discovery_sessions); 747 list_destroy(&iscsit_global.global_deleted_target_list); 748 avl_destroy(&iscsit_global.global_target_list); 749 avl_destroy(&iscsit_global.global_tpg_list); 750 avl_destroy(&iscsit_global.global_ini_list); 751 752 taskq_destroy(iscsit_global.global_dispatch_taskq); 753 754 iscsit_isns_fini(); 755 756 stmf_free(iscsit_global.global_dbuf_store); 757 iscsit_global.global_dbuf_store = NULL; 758 759 (void) stmf_deregister_port_provider(iscsit_global.global_pp); 760 stmf_free(iscsit_global.global_pp); 761 iscsit_global.global_pp = NULL; 762 763 kmem_cache_destroy(iscsit_status_pdu_cache); 764 iscsit_status_pdu_cache = NULL; 765 766 vmem_destroy(iscsit_global.global_tsih_pool); 767 iscsit_global.global_tsih_pool = NULL; 768 } 769 770 void 771 iscsit_global_hold() 772 { 773 idm_refcnt_hold(&iscsit_global.global_refcnt); 774 } 775 776 void 777 iscsit_global_rele() 778 { 779 idm_refcnt_rele(&iscsit_global.global_refcnt); 780 } 781 782 void 783 iscsit_global_wait_ref() 784 { 785 idm_refcnt_wait_ref(&iscsit_global.global_refcnt); 786 } 787 788 /* 789 * IDM callbacks 790 */ 791 792 /*ARGSUSED*/ 793 void 794 iscsit_rx_pdu(idm_conn_t *ic, idm_pdu_t *rx_pdu) 795 { 796 iscsit_conn_t *ict = ic->ic_handle; 797 switch (IDM_PDU_OPCODE(rx_pdu)) { 798 case ISCSI_OP_SCSI_CMD: 799 ASSERT(0); /* Shouldn't happen */ 800 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 801 break; 802 case ISCSI_OP_SNACK_CMD: 803 /* 804 * We'll need to handle this when we support ERL1/2. For 805 * now we treat it as a protocol error. 806 */ 807 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 808 idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL); 809 break; 810 case ISCSI_OP_SCSI_TASK_MGT_MSG: 811 iscsit_set_cmdsn(ict, rx_pdu); 812 iscsit_op_scsi_task_mgmt(ict, rx_pdu); 813 break; 814 case ISCSI_OP_NOOP_OUT: 815 case ISCSI_OP_LOGIN_CMD: 816 case ISCSI_OP_TEXT_CMD: 817 case ISCSI_OP_LOGOUT_CMD: 818 /* 819 * If/when we switch to userland processing these PDU's 820 * will be handled by iscsitd. 821 */ 822 iscsit_deferred_dispatch(rx_pdu); 823 break; 824 default: 825 /* Protocol error */ 826 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 827 idm_conn_event(ic, CE_TRANSPORT_FAIL, NULL); 828 break; 829 } 830 } 831 832 /*ARGSUSED*/ 833 void 834 iscsit_rx_pdu_error(idm_conn_t *ic, idm_pdu_t *rx_pdu, idm_status_t status) 835 { 836 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 837 } 838 839 void 840 iscsit_task_aborted(idm_task_t *idt, idm_status_t status) 841 { 842 iscsit_task_t *itask = idt->idt_private; 843 844 switch (status) { 845 case IDM_STATUS_SUSPENDED: 846 break; 847 case IDM_STATUS_ABORTED: 848 mutex_enter(&itask->it_mutex); 849 itask->it_aborted = B_TRUE; 850 if (itask->it_stmf_abort) { 851 mutex_exit(&itask->it_mutex); 852 /* 853 * STMF has already asked for this task to be aborted. 854 * Cleanup the task and call STMF to let it know that 855 * the abort is complete. 856 */ 857 idm_task_cleanup(idt); 858 859 /* 860 * STMF specification is wrong... says to return 861 * STMF_ABORTED, the code actually looks for 862 * STMF_ABORT_SUCCESS. 863 */ 864 stmf_task_lport_aborted(itask->it_stmf_task, 865 STMF_ABORT_SUCCESS, STMF_IOF_LPORT_DONE); 866 return; 867 } else { 868 mutex_exit(&itask->it_mutex); 869 /* 870 * Tell STMF to stop processing the task. We will 871 * cleanup the task in the context of iscsit_abort 872 * (lport_abort). 873 */ 874 idm_task_cleanup(idt); 875 stmf_abort(STMF_QUEUE_TASK_ABORT, itask->it_stmf_task, 876 STMF_ABORTED, NULL); 877 return; 878 } 879 /*NOTREACHED*/ 880 default: 881 ASSERT(0); 882 } 883 } 884 885 /*ARGSUSED*/ 886 idm_status_t 887 iscsit_client_notify(idm_conn_t *ic, idm_client_notify_t icn, 888 uintptr_t data) 889 { 890 idm_status_t rc = IDM_STATUS_SUCCESS; 891 892 /* 893 * IDM client notifications will never occur at interrupt level 894 * since they are generated from the connection state machine which 895 * running on taskq threads. 896 * 897 */ 898 switch (icn) { 899 case CN_CONNECT_ACCEPT: 900 rc = iscsit_conn_accept(ic); /* No data */ 901 break; 902 case CN_FFP_ENABLED: 903 rc = iscsit_ffp_enabled(ic); /* No data */ 904 break; 905 case CN_FFP_DISABLED: 906 /* 907 * Data indicates whether this was the result of an 908 * explicit logout request. 909 */ 910 rc = iscsit_ffp_disabled(ic, (idm_ffp_disable_t)data); 911 break; 912 case CN_CONNECT_LOST: 913 rc = iscsit_conn_lost(ic); 914 break; 915 case CN_CONNECT_DESTROY: 916 rc = iscsit_conn_destroy(ic); 917 break; 918 case CN_LOGIN_FAIL: 919 /* 920 * Force the login state machine to completion 921 */ 922 rc = iscsit_login_fail(ic); 923 break; 924 default: 925 rc = IDM_STATUS_REJECT; 926 break; 927 } 928 929 return (rc); 930 } 931 932 933 void 934 iscsit_build_hdr(idm_task_t *idm_task, idm_pdu_t *pdu, uint8_t opcode) 935 { 936 iscsit_task_t *itask = idm_task->idt_private; 937 iscsi_data_rsp_hdr_t *dh = (iscsi_data_rsp_hdr_t *)pdu->isp_hdr; 938 939 /* 940 * We acquired iscsit_sess_t.ist_sn_rwlock in iscsit_xfer_scsi_data 941 * in reader mode so we expect to be locked here 942 */ 943 944 /* 945 * Lun is only required if the opcode == ISCSI_OP_SCSI_DATA_RSP 946 * and the 'A' bit is to be set 947 */ 948 dh->opcode = opcode; 949 dh->itt = itask->it_itt; 950 dh->ttt = itask->it_ttt; 951 /* Statsn is only set during phase collapse */ 952 dh->expcmdsn = htonl(itask->it_ict->ict_sess->ist_expcmdsn); 953 dh->maxcmdsn = htonl(itask->it_ict->ict_sess->ist_maxcmdsn); 954 955 /* 956 * IDM must set: 957 * 958 * data.flags and rtt.flags 959 * data.dlength 960 * data.datasn 961 * data.offset 962 * residual_count and cmd_status (if we ever implement phase collapse) 963 * rtt.rttsn 964 * rtt.data_offset 965 * rtt.data_length 966 */ 967 } 968 969 static idm_status_t 970 iscsit_conn_accept(idm_conn_t *ic) 971 { 972 iscsit_conn_t *ict; 973 974 /* 975 * Allocate an associated iscsit structure to represent this 976 * connection. We shouldn't really create a session until we 977 * get the first login PDU. 978 */ 979 ict = kmem_zalloc(sizeof (*ict), KM_SLEEP); 980 981 ict->ict_ic = ic; 982 ict->ict_statsn = 1; 983 ic->ic_handle = ict; 984 mutex_init(&ict->ict_mutex, NULL, MUTEX_DRIVER, NULL); 985 idm_refcnt_init(&ict->ict_refcnt, ict); 986 987 /* 988 * Initialize login state machine 989 */ 990 if (iscsit_login_sm_init(ict) != IDM_STATUS_SUCCESS) { 991 return (IDM_STATUS_FAIL); 992 } 993 994 return (IDM_STATUS_SUCCESS); 995 } 996 997 idm_status_t 998 iscsit_conn_reinstate(iscsit_conn_t *reinstate_ict, iscsit_conn_t *new_ict) 999 { 1000 idm_status_t result; 1001 1002 /* 1003 * Note in new connection state that this connection is 1004 * reinstating an existing connection. 1005 */ 1006 new_ict->ict_reinstating = B_TRUE; 1007 new_ict->ict_reinstate_conn = reinstate_ict; 1008 new_ict->ict_statsn = reinstate_ict->ict_statsn; 1009 1010 /* 1011 * Now generate connection state machine event to existing connection 1012 * so that it starts the cleanup process. 1013 */ 1014 result = idm_conn_reinstate_event(reinstate_ict->ict_ic, 1015 new_ict->ict_ic); 1016 1017 return (result); 1018 } 1019 1020 void 1021 iscsit_conn_hold(iscsit_conn_t *ict) 1022 { 1023 idm_refcnt_hold(&ict->ict_refcnt); 1024 } 1025 1026 void 1027 iscsit_conn_rele(iscsit_conn_t *ict) 1028 { 1029 idm_refcnt_rele(&ict->ict_refcnt); 1030 } 1031 1032 void 1033 iscsit_conn_dispatch_hold(iscsit_conn_t *ict) 1034 { 1035 idm_refcnt_hold(&ict->ict_dispatch_refcnt); 1036 } 1037 1038 void 1039 iscsit_conn_dispatch_rele(iscsit_conn_t *ict) 1040 { 1041 idm_refcnt_rele(&ict->ict_dispatch_refcnt); 1042 } 1043 1044 static idm_status_t 1045 iscsit_login_fail(idm_conn_t *ic) 1046 { 1047 iscsit_conn_t *ict = ic->ic_handle; 1048 1049 /* Generate login state machine event */ 1050 iscsit_login_sm_event(ict, ILE_LOGIN_CONN_ERROR, NULL); 1051 1052 return (IDM_STATUS_SUCCESS); 1053 } 1054 1055 static idm_status_t 1056 iscsit_ffp_enabled(idm_conn_t *ic) 1057 { 1058 iscsit_conn_t *ict = ic->ic_handle; 1059 1060 /* Generate session state machine event */ 1061 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_LOGGED_IN, ict); 1062 1063 return (IDM_STATUS_SUCCESS); 1064 } 1065 1066 static idm_status_t 1067 iscsit_ffp_disabled(idm_conn_t *ic, idm_ffp_disable_t disable_class) 1068 { 1069 iscsit_conn_t *ict = ic->ic_handle; 1070 1071 /* Generate session state machine event */ 1072 switch (disable_class) { 1073 case FD_CONN_FAIL: 1074 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FFP_FAIL, ict); 1075 break; 1076 case FD_CONN_LOGOUT: 1077 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FFP_DISABLE, ict); 1078 break; 1079 case FD_SESS_LOGOUT: 1080 iscsit_sess_sm_event(ict->ict_sess, SE_SESSION_CLOSE, ict); 1081 break; 1082 default: 1083 ASSERT(0); 1084 } 1085 1086 return (IDM_STATUS_SUCCESS); 1087 } 1088 1089 static idm_status_t 1090 iscsit_conn_lost(idm_conn_t *ic) 1091 { 1092 iscsit_conn_t *ict = ic->ic_handle; 1093 1094 mutex_enter(&ict->ict_mutex); 1095 ict->ict_lost = B_TRUE; 1096 mutex_exit(&ict->ict_mutex); 1097 1098 /* 1099 * Make sure there aren't any PDU's transitioning from the receive 1100 * handler to the dispatch taskq. 1101 */ 1102 idm_refcnt_wait_ref(&ict->ict_dispatch_refcnt); 1103 1104 return (IDM_STATUS_SUCCESS); 1105 } 1106 1107 static idm_status_t 1108 iscsit_conn_destroy(idm_conn_t *ic) 1109 { 1110 iscsit_conn_t *ict = ic->ic_handle; 1111 1112 mutex_enter(&ict->ict_mutex); 1113 ict->ict_destroyed = B_TRUE; 1114 mutex_exit(&ict->ict_mutex); 1115 1116 /* Generate session state machine event */ 1117 if (ict->ict_sess != NULL) { 1118 /* 1119 * Session state machine will call iscsit_conn_destroy_done() 1120 * when it has removed references to this connection. 1121 */ 1122 iscsit_sess_sm_event(ict->ict_sess, SE_CONN_FAIL, ict); 1123 } 1124 1125 ict->ict_ic = NULL; 1126 1127 idm_refcnt_wait_ref(&ict->ict_refcnt); 1128 1129 mutex_destroy(&ict->ict_mutex); 1130 idm_refcnt_destroy(&ict->ict_refcnt); 1131 kmem_free(ict, sizeof (*ict)); 1132 1133 return (IDM_STATUS_SUCCESS); 1134 } 1135 1136 /* 1137 * STMF-related functions 1138 * 1139 * iSCSI to STMF mapping 1140 * 1141 * Session == ? 1142 * Connection == bound to local port but not itself a local port 1143 * Target 1144 * Target portal (group?) == local port (really but we're not going to do this) 1145 * iscsit needs to map connections to local ports (whatever we decide 1146 * they are) 1147 * Target == ? 1148 */ 1149 1150 /*ARGSUSED*/ 1151 static stmf_data_buf_t * 1152 iscsit_dbuf_alloc(scsi_task_t *task, uint32_t size, uint32_t *pminsize, 1153 uint32_t flags) 1154 { 1155 iscsit_task_t *itask = task->task_port_private; 1156 idm_buf_t *idm_buffer; 1157 iscsit_buf_t *ibuf; 1158 stmf_data_buf_t *result; 1159 1160 /* 1161 * Once the iSER picture is better understood it might make sense 1162 * to pre-allocate some registered buffers, similar to what 1163 * fct/qlt are doing. In the meantime hopefully stmf can allocate 1164 * these things quickly. 1165 * 1166 * We can't support a transfer larger than MaxBurstLength bytes. 1167 */ 1168 if (size > itask->it_ict->ict_op.op_max_burst_length) { 1169 *pminsize = itask->it_ict->ict_op.op_max_burst_length; 1170 return (NULL); 1171 } 1172 1173 /* Alloc buffer */ 1174 idm_buffer = idm_buf_alloc(itask->it_ict->ict_ic, NULL, size); 1175 if (idm_buffer != NULL) { 1176 result = stmf_alloc(STMF_STRUCT_DATA_BUF, 1177 sizeof (iscsit_buf_t), 0); 1178 if (result != NULL) { 1179 /* Fill in stmf_data_buf_t */ 1180 ibuf = result->db_port_private; 1181 ibuf->ibuf_idm_buf = idm_buffer; 1182 ibuf->ibuf_stmf_buf = result; 1183 ibuf->ibuf_is_immed = B_FALSE; 1184 result->db_flags = DB_DONT_CACHE; 1185 result->db_buf_size = size; 1186 result->db_data_size = size; 1187 result->db_sglist_length = 1; 1188 result->db_sglist[0].seg_addr = idm_buffer->idb_buf; 1189 result->db_sglist[0].seg_length = 1190 idm_buffer->idb_buflen; 1191 return (result); 1192 } 1193 1194 /* Couldn't get the stmf_data_buf_t so free the buffer */ 1195 idm_buf_free(idm_buffer); 1196 } 1197 1198 return (NULL); 1199 } 1200 1201 /*ARGSUSED*/ 1202 static void 1203 iscsit_dbuf_free(stmf_dbuf_store_t *ds, stmf_data_buf_t *dbuf) 1204 { 1205 iscsit_buf_t *ibuf = dbuf->db_port_private; 1206 1207 if (ibuf->ibuf_is_immed) { 1208 /* 1209 * The iscsit_buf_t structure itself will be freed with its 1210 * associated task. Here we just need to free the PDU that 1211 * held the immediate data. 1212 */ 1213 idm_pdu_complete(ibuf->ibuf_immed_data_pdu, IDM_STATUS_SUCCESS); 1214 ibuf->ibuf_immed_data_pdu = 0; 1215 } else { 1216 idm_buf_free(ibuf->ibuf_idm_buf); 1217 stmf_free(dbuf); 1218 } 1219 } 1220 1221 /*ARGSUSED*/ 1222 stmf_status_t 1223 iscsit_xfer_scsi_data(scsi_task_t *task, stmf_data_buf_t *dbuf, 1224 uint32_t ioflags) 1225 { 1226 iscsit_task_t *iscsit_task = task->task_port_private; 1227 iscsit_buf_t *ibuf = dbuf->db_port_private; 1228 int idm_rc; 1229 1230 /* 1231 * If it's not immediate data then start the transfer 1232 */ 1233 ASSERT(ibuf->ibuf_is_immed == B_FALSE); 1234 if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) { 1235 1236 /* 1237 * IDM will call iscsit_build_hdr so lock now to serialize 1238 * access to the SN values. We need to lock here to enforce 1239 * lock ordering 1240 */ 1241 rw_enter(&iscsit_task->it_ict->ict_sess->ist_sn_rwlock, 1242 RW_READER); 1243 idm_rc = idm_buf_tx_to_ini(iscsit_task->it_idm_task, 1244 ibuf->ibuf_idm_buf, dbuf->db_relative_offset, 1245 dbuf->db_data_size, &iscsit_buf_xfer_cb, dbuf); 1246 rw_exit(&iscsit_task->it_ict->ict_sess->ist_sn_rwlock); 1247 1248 return (iscsit_idm_to_stmf(idm_rc)); 1249 } else if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) { 1250 /* Grab the SN lock (see comment above) */ 1251 rw_enter(&iscsit_task->it_ict->ict_sess->ist_sn_rwlock, 1252 RW_READER); 1253 idm_rc = idm_buf_rx_from_ini(iscsit_task->it_idm_task, 1254 ibuf->ibuf_idm_buf, dbuf->db_relative_offset, 1255 dbuf->db_data_size, &iscsit_buf_xfer_cb, dbuf); 1256 rw_exit(&iscsit_task->it_ict->ict_sess->ist_sn_rwlock); 1257 1258 return (iscsit_idm_to_stmf(idm_rc)); 1259 } 1260 1261 /* What are we supposed to do if there is no direction? */ 1262 return (STMF_INVALID_ARG); 1263 } 1264 1265 static void 1266 iscsit_buf_xfer_cb(idm_buf_t *idb, idm_status_t status) 1267 { 1268 iscsit_task_t *itask = idb->idb_task_binding->idt_private; 1269 stmf_data_buf_t *dbuf = idb->idb_cb_arg; 1270 1271 dbuf->db_xfer_status = iscsit_idm_to_stmf(status); 1272 1273 /* 1274 * COMSTAR currently requires port providers to support 1275 * the DB_SEND_STATUS_GOOD flag even if phase collapse is 1276 * not supported. So we will roll our own... pretend we are 1277 * COMSTAR and ask for a status PDU. 1278 */ 1279 if ((dbuf->db_flags & DB_SEND_STATUS_GOOD) && 1280 status == IDM_STATUS_SUCCESS) { 1281 /* 1282 * If iscsit_send_scsi_status succeeds then the TX PDU 1283 * callback will call stmf_send_status_done and set 1284 * STMF_IOF_LPORT_DONE. Consequently we don't need 1285 * to call stmf_data_xfer_done in that case. We 1286 * still need to call it if we get a failure. 1287 * 1288 * To elaborate on this some more, upon successful return 1289 * from iscsit_send_scsi_status it's possible that itask 1290 * and idb have been freed and are no longer valid. 1291 */ 1292 if (iscsit_send_scsi_status(itask->it_stmf_task, 0) 1293 != IDM_STATUS_SUCCESS) { 1294 /* Failed to send status */ 1295 dbuf->db_xfer_status = STMF_FAILURE; 1296 stmf_data_xfer_done(itask->it_stmf_task, dbuf, 1297 STMF_IOF_LPORT_DONE); 1298 } 1299 } else { 1300 stmf_data_xfer_done(itask->it_stmf_task, dbuf, 0); 1301 } 1302 } 1303 1304 /*ARGSUSED*/ 1305 stmf_status_t 1306 iscsit_send_scsi_status(scsi_task_t *task, uint32_t ioflags) 1307 { 1308 iscsit_task_t *itask = task->task_port_private; 1309 iscsi_scsi_rsp_hdr_t *rsp; 1310 idm_pdu_t *pdu; 1311 int resp_datalen; 1312 1313 /* 1314 * If this task is aborted then we don't need to respond. 1315 */ 1316 if (itask->it_stmf_abort) { 1317 stmf_send_status_done(task, STMF_SUCCESS, 1318 STMF_IOF_LPORT_DONE); 1319 return (STMF_SUCCESS); 1320 } 1321 1322 /* 1323 * If this is a task management status, handle it elsewhere. 1324 */ 1325 if (task->task_mgmt_function != TM_NONE) { 1326 /* 1327 * Don't wait for the PDU completion to tell STMF 1328 * the task is done -- it doesn't really matter and 1329 * it makes life complicated if STMF later asks us to 1330 * abort the request and we don't know whether the 1331 * status has been sent or not. 1332 */ 1333 itask->it_tm_responded = B_TRUE; 1334 iscsit_send_task_mgmt_resp(itask->it_tm_pdu, 1335 (task->task_completion_status == STMF_SUCCESS) ? 1336 SCSI_TCP_TM_RESP_COMPLETE : SCSI_TCP_TM_RESP_FUNC_NOT_SUPP); 1337 stmf_send_status_done(task, STMF_SUCCESS, 1338 STMF_IOF_LPORT_DONE); 1339 return (STMF_SUCCESS); 1340 } 1341 1342 mutex_enter(&itask->it_idm_task->idt_mutex); 1343 if ((itask->it_idm_task->idt_state == TASK_ACTIVE) && 1344 (task->task_completion_status == STMF_SUCCESS) && 1345 (task->task_sense_length == 0) && 1346 (task->task_resid == 0)) { 1347 itask->it_idm_task->idt_state = TASK_COMPLETE; 1348 /* PDU callback releases task hold */ 1349 idm_task_hold(itask->it_idm_task); 1350 mutex_exit(&itask->it_idm_task->idt_mutex); 1351 /* 1352 * Fast path. Cached status PDU's are already 1353 * initialized. We just need to fill in 1354 * connection and task information. 1355 */ 1356 pdu = kmem_cache_alloc(iscsit_status_pdu_cache, KM_SLEEP); 1357 pdu->isp_ic = itask->it_ict->ict_ic; 1358 pdu->isp_private = itask; 1359 1360 rsp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr; 1361 rsp->itt = itask->it_itt; 1362 rsp->cmd_status = task->task_scsi_status; 1363 iscsit_pdu_tx(pdu); 1364 return (STMF_SUCCESS); 1365 } else { 1366 if (itask->it_idm_task->idt_state != TASK_ACTIVE) { 1367 mutex_exit(&itask->it_idm_task->idt_mutex); 1368 return (IDM_STATUS_FAIL); 1369 } 1370 itask->it_idm_task->idt_state = TASK_COMPLETE; 1371 /* PDU callback releases task hold */ 1372 idm_task_hold(itask->it_idm_task); 1373 mutex_exit(&itask->it_idm_task->idt_mutex); 1374 1375 resp_datalen = (task->task_sense_length == 0) ? 0 : 1376 (task->task_sense_length + sizeof (uint16_t)); 1377 1378 pdu = idm_pdu_alloc(sizeof (iscsi_hdr_t), resp_datalen); 1379 idm_pdu_init(pdu, itask->it_ict->ict_ic, itask, 1380 iscsit_send_status_done); 1381 1382 rsp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr; 1383 bzero(rsp, sizeof (*rsp)); 1384 rsp->opcode = ISCSI_OP_SCSI_RSP; 1385 1386 rsp->flags = ISCSI_FLAG_FINAL; 1387 if (task->task_status_ctrl & TASK_SCTRL_OVER) { 1388 rsp->flags |= ISCSI_FLAG_CMD_OVERFLOW; 1389 } else if (task->task_status_ctrl & TASK_SCTRL_UNDER) { 1390 rsp->flags |= ISCSI_FLAG_CMD_UNDERFLOW; 1391 } 1392 1393 rsp->bi_residual_count = 0; 1394 rsp->residual_count = htonl(task->task_resid); 1395 rsp->itt = itask->it_itt; 1396 rsp->response = ISCSI_STATUS_CMD_COMPLETED; 1397 rsp->cmd_status = task->task_scsi_status; 1398 if (task->task_sense_length != 0) { 1399 /* 1400 * Add a byte to provide the sense length in 1401 * the response 1402 */ 1403 *(uint16_t *)((void *)pdu->isp_data) = 1404 htons(task->task_sense_length); 1405 bcopy(task->task_sense_data, 1406 (uint8_t *)pdu->isp_data + 1407 sizeof (uint16_t), 1408 task->task_sense_length); 1409 hton24(rsp->dlength, resp_datalen); 1410 } 1411 1412 iscsit_pdu_tx(pdu); 1413 1414 return (STMF_SUCCESS); 1415 } 1416 } 1417 1418 /*ARGSUSED*/ 1419 static void 1420 iscsit_send_good_status_done(idm_pdu_t *pdu, idm_status_t status) 1421 { 1422 iscsit_task_t *itask; 1423 1424 itask = pdu->isp_private; 1425 idm_task_rele(itask->it_idm_task); 1426 stmf_send_status_done(itask->it_stmf_task, 1427 iscsit_idm_to_stmf(pdu->isp_status), STMF_IOF_LPORT_DONE); 1428 kmem_cache_free(iscsit_status_pdu_cache, pdu); 1429 } 1430 1431 /*ARGSUSED*/ 1432 static void 1433 iscsit_send_status_done(idm_pdu_t *pdu, idm_status_t status) 1434 { 1435 iscsit_task_t *itask; 1436 1437 itask = pdu->isp_private; 1438 idm_task_rele(itask->it_idm_task); 1439 stmf_send_status_done(itask->it_stmf_task, 1440 iscsit_idm_to_stmf(pdu->isp_status), STMF_IOF_LPORT_DONE); 1441 idm_pdu_free(pdu); 1442 } 1443 1444 1445 void 1446 iscsit_lport_task_free(scsi_task_t *task) 1447 { 1448 iscsit_task_t *itask = task->task_port_private; 1449 1450 /* We only call idm_task_start for regular tasks, not task management */ 1451 if (task->task_mgmt_function == TM_NONE) { 1452 idm_task_done(itask->it_idm_task); 1453 iscsit_task_free(itask); 1454 return; 1455 } else { 1456 iscsit_tm_task_free(itask); 1457 } 1458 } 1459 1460 /*ARGSUSED*/ 1461 stmf_status_t 1462 iscsit_abort(stmf_local_port_t *lport, int abort_cmd, void *arg, uint32_t flags) 1463 { 1464 scsi_task_t *st = (scsi_task_t *)arg; 1465 iscsit_task_t *iscsit_task; 1466 idm_task_t *idt; 1467 1468 /* 1469 * If this is a task management request then there's really not much to 1470 * do. 1471 */ 1472 if (st->task_mgmt_function != TM_NONE) { 1473 return (STMF_ABORT_SUCCESS); 1474 } 1475 1476 /* 1477 * Regular task, start cleaning up 1478 */ 1479 iscsit_task = st->task_port_private; 1480 idt = iscsit_task->it_idm_task; 1481 mutex_enter(&iscsit_task->it_mutex); 1482 iscsit_task->it_stmf_abort = B_TRUE; 1483 if (iscsit_task->it_aborted) { 1484 mutex_exit(&iscsit_task->it_mutex); 1485 /* 1486 * STMF specification is wrong... says to return 1487 * STMF_ABORTED, the code actually looks for 1488 * STMF_ABORT_SUCCESS. 1489 */ 1490 return (STMF_ABORT_SUCCESS); 1491 } else { 1492 mutex_exit(&iscsit_task->it_mutex); 1493 /* 1494 * Call IDM to abort the task. Due to a variety of 1495 * circumstances the task may already be in the process of 1496 * aborting. 1497 * We'll let IDM worry about rationalizing all that except 1498 * for one particular instance. If the state of the task 1499 * is TASK_COMPLETE, we need to indicate to the framework 1500 * that we are in fact done. This typically happens with 1501 * framework-initiated task management type requests 1502 * (e.g. abort task). 1503 */ 1504 if (idt->idt_state == TASK_COMPLETE) { 1505 idm_refcnt_wait_ref(&idt->idt_refcnt); 1506 return (STMF_ABORT_SUCCESS); 1507 } else { 1508 idm_task_abort(idt->idt_ic, idt, AT_TASK_MGMT_ABORT); 1509 return (STMF_SUCCESS); 1510 } 1511 } 1512 1513 /*NOTREACHED*/ 1514 } 1515 1516 /*ARGSUSED*/ 1517 void 1518 iscsit_ctl(stmf_local_port_t *lport, int cmd, void *arg) 1519 { 1520 iscsit_tgt_t *iscsit_tgt; 1521 1522 ASSERT((cmd == STMF_CMD_LPORT_ONLINE) || 1523 (cmd == STMF_ACK_LPORT_ONLINE_COMPLETE) || 1524 (cmd == STMF_CMD_LPORT_OFFLINE) || 1525 (cmd == STMF_ACK_LPORT_OFFLINE_COMPLETE)); 1526 1527 iscsit_tgt = (iscsit_tgt_t *)lport->lport_port_private; 1528 1529 switch (cmd) { 1530 case STMF_CMD_LPORT_ONLINE: 1531 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_ONLINE_REQ); 1532 break; 1533 case STMF_CMD_LPORT_OFFLINE: 1534 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_OFFLINE_REQ); 1535 break; 1536 case STMF_ACK_LPORT_ONLINE_COMPLETE: 1537 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_ONLINE_COMPLETE_ACK); 1538 break; 1539 case STMF_ACK_LPORT_OFFLINE_COMPLETE: 1540 iscsit_tgt_sm_event(iscsit_tgt, TE_STMF_OFFLINE_COMPLETE_ACK); 1541 break; 1542 1543 default: 1544 break; 1545 } 1546 } 1547 1548 static stmf_status_t 1549 iscsit_idm_to_stmf(idm_status_t idmrc) 1550 { 1551 switch (idmrc) { 1552 case IDM_STATUS_SUCCESS: 1553 return (STMF_SUCCESS); 1554 default: 1555 return (STMF_FAILURE); 1556 } 1557 /*NOTREACHED*/ 1558 } 1559 1560 1561 /* 1562 * ISCSI protocol 1563 */ 1564 1565 void 1566 iscsit_op_scsi_cmd(idm_conn_t *ic, idm_pdu_t *rx_pdu) 1567 { 1568 iscsit_conn_t *ict; 1569 iscsit_task_t *itask; 1570 scsi_task_t *task; 1571 iscsit_buf_t *ibuf; 1572 iscsi_scsi_cmd_hdr_t *iscsi_scsi = 1573 (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr; 1574 iscsi_addl_hdr_t *ahs_hdr; 1575 uint16_t addl_cdb_len = 0; 1576 1577 ict = ic->ic_handle; 1578 1579 itask = iscsit_task_alloc(ict); 1580 if (itask == NULL) { 1581 iscsit_send_direct_scsi_resp(ict, rx_pdu, 1582 ISCSI_STATUS_CMD_COMPLETED, STATUS_BUSY); 1583 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1584 return; 1585 } 1586 1587 /* Finish processing request */ 1588 iscsit_set_cmdsn(ict, rx_pdu); 1589 1590 /* 1591 * Note CmdSN and ITT in task. IDM will have already validated this 1592 * request against the connection state so we don't need to check 1593 * that (the connection may have changed state in the meantime but 1594 * we will catch that when we try to send a response) 1595 */ 1596 itask->it_cmdsn = ntohl(iscsi_scsi->cmdsn); 1597 itask->it_itt = iscsi_scsi->itt; 1598 1599 /* 1600 * Check for extended CDB AHS 1601 */ 1602 if (iscsi_scsi->hlength > 0) { 1603 ahs_hdr = (iscsi_addl_hdr_t *)iscsi_scsi; 1604 addl_cdb_len = ((ahs_hdr->ahs_hlen_hi << 8) | 1605 ahs_hdr->ahs_hlen_lo) - 1; /* Adjust for reserved byte */ 1606 if (((addl_cdb_len + 4) / sizeof (uint32_t)) > 1607 iscsi_scsi->hlength) { 1608 /* Mangled header info, drop it */ 1609 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1610 return; 1611 } 1612 } 1613 1614 ict = rx_pdu->isp_ic->ic_handle; /* IDM client private */ 1615 1616 itask->it_stmf_task = stmf_task_alloc( 1617 itask->it_ict->ict_sess->ist_lport, 1618 itask->it_ict->ict_sess->ist_stmf_sess, iscsi_scsi->lun, 1619 16 + addl_cdb_len, 0); 1620 if (itask->it_stmf_task == NULL) { 1621 /* 1622 * Either stmf really couldn't get memory for a task or, 1623 * more likely, the LU is currently in reset. Either way 1624 * we have no choice but to fail the request. 1625 */ 1626 iscsit_task_free(itask); 1627 iscsit_send_direct_scsi_resp(ict, rx_pdu, 1628 ISCSI_STATUS_CMD_COMPLETED, STATUS_BUSY); 1629 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 1630 return; 1631 } 1632 1633 task = itask->it_stmf_task; 1634 task->task_port_private = itask; 1635 1636 bcopy(iscsi_scsi->lun, task->task_lun_no, sizeof (task->task_lun_no)); 1637 1638 /* 1639 * iSCSI and Comstar use the same values. Should we rely on this 1640 * or translate them bit-wise? 1641 */ 1642 1643 task->task_flags = 1644 (((iscsi_scsi->flags & ISCSI_FLAG_CMD_READ) ? TF_READ_DATA : 0) | 1645 ((iscsi_scsi->flags & ISCSI_FLAG_CMD_WRITE) ? TF_WRITE_DATA : 0) | 1646 ((rx_pdu->isp_datalen == 0) ? 0 : TF_INITIAL_BURST)); 1647 1648 switch (iscsi_scsi->flags & ISCSI_FLAG_CMD_ATTR_MASK) { 1649 case ISCSI_ATTR_UNTAGGED: 1650 break; 1651 case ISCSI_ATTR_SIMPLE: 1652 task->task_additional_flags |= TF_ATTR_SIMPLE_QUEUE; 1653 break; 1654 case ISCSI_ATTR_ORDERED: 1655 task->task_additional_flags |= TF_ATTR_ORDERED_QUEUE; 1656 break; 1657 case ISCSI_ATTR_HEAD_OF_QUEUE: 1658 task->task_additional_flags |= TF_ATTR_HEAD_OF_QUEUE; 1659 break; 1660 case ISCSI_ATTR_ACA: 1661 task->task_additional_flags |= TF_ATTR_ACA; 1662 break; 1663 default: 1664 /* Protocol error but just take it, treat as untagged */ 1665 break; 1666 } 1667 1668 1669 task->task_additional_flags = 0; 1670 task->task_priority = 0; 1671 task->task_mgmt_function = TM_NONE; 1672 1673 /* 1674 * This "task_max_nbufs" doesn't map well to BIDI. We probably need 1675 * parameter for each direction. "MaxOutstandingR2T" may very well 1676 * be set to one which could prevent us from doing simultaneous 1677 * transfers in each direction. 1678 */ 1679 task->task_max_nbufs = (iscsi_scsi->flags & ISCSI_FLAG_CMD_WRITE) ? 1680 ict->ict_op.op_max_outstanding_r2t : STMF_BUFS_MAX; 1681 task->task_cmd_seq_no = ntohl(iscsi_scsi->itt); 1682 task->task_expected_xfer_length = ntohl(iscsi_scsi->data_length); 1683 1684 /* Copy CDB */ 1685 bcopy(iscsi_scsi->scb, task->task_cdb, 16); 1686 if (addl_cdb_len > 0) { 1687 bcopy(ahs_hdr->ahs_extscb, task->task_cdb + 16, addl_cdb_len); 1688 } 1689 1690 /* 1691 * Copy the transport header into the task handle from the PDU 1692 * handle. The transport header describes this task's remote tagged 1693 * buffer. 1694 */ 1695 if (rx_pdu->isp_transport_hdrlen != 0) { 1696 bcopy(rx_pdu->isp_transport_hdr, 1697 itask->it_idm_task->idt_transport_hdr, 1698 rx_pdu->isp_transport_hdrlen); 1699 } 1700 1701 /* 1702 * Tell IDM about our new active task 1703 */ 1704 idm_task_start(itask->it_idm_task, (uintptr_t)itask->it_itt); 1705 1706 /* 1707 * If we have any immediate data then setup the immediate buffer 1708 * context that comes with the task 1709 */ 1710 if (rx_pdu->isp_datalen) { 1711 ibuf = itask->it_immed_data; 1712 ibuf->ibuf_immed_data_pdu = rx_pdu; 1713 ibuf->ibuf_stmf_buf->db_data_size = rx_pdu->isp_datalen; 1714 ibuf->ibuf_stmf_buf->db_buf_size = rx_pdu->isp_datalen; 1715 ibuf->ibuf_stmf_buf->db_relative_offset = 0; 1716 ibuf->ibuf_stmf_buf->db_sglist[0].seg_length = 1717 rx_pdu->isp_datalen; 1718 ibuf->ibuf_stmf_buf->db_sglist[0].seg_addr = rx_pdu->isp_data; 1719 1720 stmf_post_task(task, ibuf->ibuf_stmf_buf); 1721 } else { 1722 stmf_post_task(task, NULL); 1723 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1724 } 1725 } 1726 1727 /*ARGSUSED*/ 1728 void 1729 iscsit_deferred_dispatch(idm_pdu_t *rx_pdu) 1730 { 1731 iscsit_conn_t *ict = rx_pdu->isp_ic->ic_handle; 1732 1733 /* 1734 * If the connection has been lost then ignore new PDU's 1735 */ 1736 mutex_enter(&ict->ict_mutex); 1737 if (ict->ict_lost) { 1738 mutex_exit(&ict->ict_mutex); 1739 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 1740 return; 1741 } 1742 1743 /* 1744 * Grab a hold on the connection to prevent it from going away 1745 * between now and when the taskq function is called. 1746 */ 1747 iscsit_conn_dispatch_hold(ict); 1748 mutex_exit(&ict->ict_mutex); 1749 1750 if (taskq_dispatch(iscsit_global.global_dispatch_taskq, 1751 iscsit_deferred, rx_pdu, DDI_NOSLEEP) == NULL) { 1752 /* 1753 * In the unlikely scenario that we couldn't get the resources 1754 * to dispatch the PDU then just drop it. 1755 */ 1756 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 1757 idm_conn_event(ict->ict_ic, CE_TRANSPORT_FAIL, NULL); 1758 iscsit_conn_dispatch_rele(ict); 1759 } 1760 } 1761 1762 static void 1763 iscsit_deferred(void *rx_pdu_void) 1764 { 1765 idm_pdu_t *rx_pdu = rx_pdu_void; 1766 idm_conn_t *ic = rx_pdu->isp_ic; 1767 iscsit_conn_t *ict = ic->ic_handle; 1768 1769 switch (IDM_PDU_OPCODE(rx_pdu)) { 1770 case ISCSI_OP_NOOP_OUT: 1771 iscsit_set_cmdsn(ict, rx_pdu); 1772 iscsit_pdu_op_noop(ict, rx_pdu); 1773 break; 1774 case ISCSI_OP_LOGIN_CMD: 1775 iscsit_pdu_op_login_cmd(ict, rx_pdu); 1776 break; 1777 case ISCSI_OP_TEXT_CMD: 1778 iscsit_set_cmdsn(ict, rx_pdu); 1779 iscsit_pdu_op_text_cmd(ict, rx_pdu); 1780 break; 1781 case ISCSI_OP_LOGOUT_CMD: 1782 iscsit_set_cmdsn(ict, rx_pdu); 1783 iscsit_pdu_op_logout_cmd(ict, rx_pdu); 1784 break; 1785 default: 1786 /* Protocol error. IDM should have caught this */ 1787 idm_pdu_complete(rx_pdu, IDM_STATUS_FAIL); 1788 ASSERT(0); 1789 break; 1790 } 1791 1792 iscsit_conn_dispatch_rele(ict); 1793 } 1794 1795 static void 1796 iscsit_send_direct_scsi_resp(iscsit_conn_t *ict, idm_pdu_t *rx_pdu, 1797 uint8_t response, uint8_t cmd_status) 1798 { 1799 idm_pdu_t *rsp_pdu; 1800 idm_conn_t *ic; 1801 iscsi_scsi_rsp_hdr_t *resp; 1802 1803 ic = ict->ict_ic; 1804 1805 rsp_pdu = idm_pdu_alloc(sizeof (iscsi_scsi_rsp_hdr_t), 0); 1806 idm_pdu_init(rsp_pdu, ic, NULL, NULL); 1807 resp = (iscsi_scsi_rsp_hdr_t *)rsp_pdu->isp_hdr; 1808 1809 resp->opcode = ISCSI_OP_SCSI_RSP; 1810 resp->flags = ISCSI_FLAG_FINAL; 1811 resp->response = response; 1812 resp->cmd_status = cmd_status; 1813 resp->itt = rx_pdu->isp_hdr->itt; 1814 1815 iscsit_pdu_tx(rsp_pdu); 1816 } 1817 1818 void 1819 iscsit_send_task_mgmt_resp(idm_pdu_t *tm_resp_pdu, uint8_t tm_status) 1820 { 1821 iscsi_scsi_task_mgt_rsp_hdr_t *tm_resp; 1822 1823 tm_resp = (iscsi_scsi_task_mgt_rsp_hdr_t *)tm_resp_pdu->isp_hdr; 1824 tm_resp->response = tm_status; 1825 iscsit_pdu_tx(tm_resp_pdu); 1826 } 1827 1828 void 1829 iscsit_op_scsi_task_mgmt(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 1830 { 1831 idm_pdu_t *tm_resp_pdu; 1832 iscsit_task_t *itask; 1833 iscsit_task_t *tm_itask; 1834 scsi_task_t *task; 1835 iscsi_scsi_task_mgt_hdr_t *iscsi_tm = 1836 (iscsi_scsi_task_mgt_hdr_t *)rx_pdu->isp_hdr; 1837 iscsi_scsi_task_mgt_rsp_hdr_t *iscsi_tm_rsp = 1838 (iscsi_scsi_task_mgt_rsp_hdr_t *)rx_pdu->isp_hdr; 1839 uint32_t rtt, cmdsn, refcmdsn; 1840 uint8_t tm_func; 1841 1842 /* 1843 * Setup response PDU (response field will get filled in later) 1844 */ 1845 tm_resp_pdu = idm_pdu_alloc(sizeof (iscsi_scsi_task_mgt_rsp_hdr_t), 0); 1846 if (tm_resp_pdu == NULL) { 1847 /* Can't respond, just drop it */ 1848 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1849 return; 1850 } 1851 idm_pdu_init(tm_resp_pdu, ict->ict_ic, NULL, NULL); 1852 iscsi_tm_rsp = (iscsi_scsi_task_mgt_rsp_hdr_t *)tm_resp_pdu->isp_hdr; 1853 bzero(iscsi_tm_rsp, sizeof (iscsi_scsi_task_mgt_rsp_hdr_t)); 1854 iscsi_tm_rsp->opcode = ISCSI_OP_SCSI_TASK_MGT_RSP; 1855 iscsi_tm_rsp->flags = ISCSI_FLAG_FINAL; 1856 iscsi_tm_rsp->itt = rx_pdu->isp_hdr->itt; 1857 1858 /* 1859 * Figure out what we're being asked to do. 1860 */ 1861 switch (iscsi_tm->function & ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK) { 1862 case ISCSI_TM_FUNC_ABORT_TASK: 1863 /* 1864 * STMF doesn't currently support the "abort task" task 1865 * management command although it does support aborting 1866 * an individual task. We'll get STMF to abort the task 1867 * for us but handle the details of the task management 1868 * command ourselves. 1869 * 1870 * Find the task associated with the referenced task tag. 1871 */ 1872 rtt = iscsi_tm->rtt; 1873 itask = (iscsit_task_t *)idm_task_find_by_handle(ict->ict_ic, 1874 (uintptr_t)rtt); 1875 1876 if (itask == NULL) { 1877 cmdsn = ntohl(iscsi_tm->cmdsn); 1878 refcmdsn = ntohl(iscsi_tm->refcmdsn); 1879 1880 /* 1881 * Task was not found. If RefCmdSN is within the CmdSN 1882 * window and less than CmdSN of the TM function, return 1883 * "Function Complete". Otherwise, return 1884 * "Task Does Not Exist". 1885 */ 1886 1887 if (iscsit_cmdsn_in_window(ict, refcmdsn) && 1888 (refcmdsn < cmdsn)) { 1889 iscsit_send_task_mgmt_resp(tm_resp_pdu, 1890 SCSI_TCP_TM_RESP_COMPLETE); 1891 } else { 1892 iscsit_send_task_mgmt_resp(tm_resp_pdu, 1893 SCSI_TCP_TM_RESP_NO_TASK); 1894 } 1895 } else { 1896 1897 /* 1898 * Tell STMF to abort the task. This will do no harm 1899 * if the task is already complete. 1900 */ 1901 stmf_abort(STMF_QUEUE_TASK_ABORT, itask->it_stmf_task, 1902 STMF_ABORTED, NULL); 1903 1904 /* 1905 * Make sure the task hasn't already completed 1906 */ 1907 mutex_enter(&itask->it_idm_task->idt_mutex); 1908 if ((itask->it_idm_task->idt_state == TASK_COMPLETE) || 1909 (itask->it_idm_task->idt_state == TASK_IDLE)) { 1910 /* 1911 * Task is complete, return "Task Does Not 1912 * Exist" 1913 */ 1914 mutex_exit(&itask->it_idm_task->idt_mutex); 1915 iscsit_send_task_mgmt_resp(tm_resp_pdu, 1916 SCSI_TCP_TM_RESP_NO_TASK); 1917 } else { 1918 /* 1919 * STMF is now aborting the task, return 1920 * "Function Complete" 1921 */ 1922 mutex_exit(&itask->it_idm_task->idt_mutex); 1923 iscsit_send_task_mgmt_resp(tm_resp_pdu, 1924 SCSI_TCP_TM_RESP_COMPLETE); 1925 } 1926 idm_task_rele(itask->it_idm_task); 1927 } 1928 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1929 return; 1930 1931 case ISCSI_TM_FUNC_ABORT_TASK_SET: 1932 tm_func = TM_ABORT_TASK_SET; 1933 break; 1934 1935 case ISCSI_TM_FUNC_CLEAR_ACA: 1936 tm_func = TM_CLEAR_ACA; 1937 break; 1938 1939 case ISCSI_TM_FUNC_CLEAR_TASK_SET: 1940 tm_func = TM_CLEAR_TASK_SET; 1941 break; 1942 1943 case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET: 1944 tm_func = TM_LUN_RESET; 1945 break; 1946 1947 case ISCSI_TM_FUNC_TARGET_WARM_RESET: 1948 tm_func = TM_TARGET_WARM_RESET; 1949 break; 1950 1951 case ISCSI_TM_FUNC_TARGET_COLD_RESET: 1952 tm_func = TM_TARGET_COLD_RESET; 1953 break; 1954 1955 case ISCSI_TM_FUNC_TASK_REASSIGN: 1956 /* 1957 * We do not currently support allegiance reassignment. When 1958 * we start supporting ERL1+, we will need to. 1959 */ 1960 iscsit_send_task_mgmt_resp(tm_resp_pdu, 1961 SCSI_TCP_TM_RESP_NO_ALLG_REASSN); 1962 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1963 return; 1964 1965 default: 1966 iscsit_send_task_mgmt_resp(tm_resp_pdu, 1967 SCSI_TCP_TM_RESP_REJECTED); 1968 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1969 return; 1970 } 1971 1972 tm_itask = iscsit_tm_task_alloc(ict); 1973 if (tm_itask == NULL) { 1974 iscsit_send_task_mgmt_resp(tm_resp_pdu, 1975 SCSI_TCP_TM_RESP_REJECTED); 1976 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1977 return; 1978 } 1979 1980 1981 task = stmf_task_alloc(ict->ict_sess->ist_lport, 1982 ict->ict_sess->ist_stmf_sess, iscsi_tm->lun, 1983 0, STMF_TASK_EXT_NONE); 1984 if (task == NULL) { 1985 /* 1986 * If this happens, either the LU is in reset, couldn't 1987 * get memory, or some other condition in which we simply 1988 * can't complete this request. It would be nice to return 1989 * an error code like "busy" but the closest we have is 1990 * "rejected". 1991 */ 1992 iscsit_send_task_mgmt_resp(tm_resp_pdu, 1993 SCSI_TCP_TM_RESP_REJECTED); 1994 iscsit_tm_task_free(tm_itask); 1995 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 1996 return; 1997 } 1998 1999 tm_itask->it_tm_pdu = tm_resp_pdu; 2000 tm_itask->it_stmf_task = task; 2001 task->task_port_private = tm_itask; 2002 task->task_mgmt_function = tm_func; 2003 task->task_additional_flags = TASK_AF_NO_EXPECTED_XFER_LENGTH; 2004 task->task_priority = 0; 2005 task->task_max_nbufs = STMF_BUFS_MAX; 2006 task->task_cmd_seq_no = iscsi_tm->itt; 2007 task->task_expected_xfer_length = 0; 2008 2009 stmf_post_task(task, NULL); 2010 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2011 } 2012 2013 static void 2014 iscsit_pdu_op_noop(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2015 { 2016 iscsi_nop_out_hdr_t *out = (iscsi_nop_out_hdr_t *)rx_pdu->isp_hdr; 2017 iscsi_nop_in_hdr_t *in; 2018 int resp_datalen; 2019 idm_pdu_t *resp; 2020 2021 /* Get iSCSI session handle */ 2022 /* Ignore the response from initiator */ 2023 if (out->ttt != ISCSI_RSVD_TASK_TAG) 2024 return; 2025 2026 /* Allocate a PDU to respond */ 2027 resp_datalen = ntoh24(out->dlength); 2028 resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), resp_datalen); 2029 idm_pdu_init(resp, ict->ict_ic, NULL, NULL); 2030 if (resp_datalen > 0) { 2031 bcopy(rx_pdu->isp_data, resp->isp_data, resp_datalen); 2032 } 2033 2034 in = (iscsi_nop_in_hdr_t *)resp->isp_hdr; 2035 bzero(in, sizeof (*in)); 2036 in->opcode = ISCSI_OP_NOOP_IN; 2037 in->flags = ISCSI_FLAG_FINAL; 2038 bcopy(out->lun, in->lun, 8); 2039 in->itt = out->itt; 2040 in->ttt = ISCSI_RSVD_TASK_TAG; 2041 hton24(in->dlength, resp_datalen); 2042 2043 /* Any other field in resp to be set? */ 2044 iscsit_pdu_tx(resp); 2045 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2046 } 2047 2048 static void 2049 iscsit_pdu_op_login_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2050 { 2051 2052 /* 2053 * Submit PDU to login state machine. State machine will free the 2054 * PDU. 2055 */ 2056 iscsit_login_sm_event(ict, ILE_LOGIN_RCV, rx_pdu); 2057 } 2058 2059 void 2060 iscsit_pdu_op_logout_cmd(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2061 { 2062 iscsi_logout_hdr_t *logout_req = 2063 (iscsi_logout_hdr_t *)rx_pdu->isp_hdr; 2064 iscsi_logout_rsp_hdr_t *logout_rsp; 2065 idm_pdu_t *resp; 2066 2067 /* Allocate a PDU to respond */ 2068 resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 2069 idm_pdu_init(resp, ict->ict_ic, NULL, NULL); 2070 2071 /* 2072 * Logout results in the immediate termination of all tasks except 2073 * if the logout reason is ISCSI_LOGOUT_REASON_RECOVERY. The 2074 * connection state machine will drive this task cleanup automatically 2075 * so we don't need to handle that here. 2076 */ 2077 logout_rsp = (iscsi_logout_rsp_hdr_t *)resp->isp_hdr; 2078 bzero(logout_rsp, sizeof (*logout_rsp)); 2079 logout_rsp->opcode = ISCSI_OP_LOGOUT_RSP; 2080 logout_rsp->flags = ISCSI_FLAG_FINAL; 2081 logout_rsp->itt = logout_req->itt; 2082 if ((logout_req->flags & ISCSI_FLAG_LOGOUT_REASON_MASK) > 2083 ISCSI_LOGOUT_REASON_RECOVERY) { 2084 logout_rsp->response = ISCSI_LOGOUT_RECOVERY_UNSUPPORTED; 2085 } else { 2086 logout_rsp->response = ISCSI_LOGOUT_SUCCESS; 2087 } 2088 2089 iscsit_pdu_tx(resp); 2090 idm_pdu_complete(rx_pdu, IDM_STATUS_SUCCESS); 2091 } 2092 2093 /* 2094 * Calculate the number of outstanding commands we can process 2095 */ 2096 int 2097 iscsit_cmd_window() 2098 { 2099 /* Will be better later */ 2100 return (1024); 2101 } 2102 2103 /* 2104 * Set local registers based on incoming PDU 2105 */ 2106 void 2107 iscsit_set_cmdsn(iscsit_conn_t *ict, idm_pdu_t *rx_pdu) 2108 { 2109 iscsit_sess_t *ist; 2110 iscsi_scsi_cmd_hdr_t *req; 2111 2112 ist = ict->ict_sess; 2113 2114 req = (iscsi_scsi_cmd_hdr_t *)rx_pdu->isp_hdr; 2115 2116 rw_enter(&ist->ist_sn_rwlock, RW_WRITER); 2117 ist->ist_expcmdsn = ntohl(req->cmdsn) + 1; 2118 ist->ist_maxcmdsn = ntohl(req->cmdsn) + iscsit_cmd_window(); 2119 rw_exit(&ist->ist_sn_rwlock); 2120 } 2121 2122 /* 2123 * Update local StatSN and set SNs in response 2124 */ 2125 static void 2126 iscsit_calc_rspsn(iscsit_conn_t *ict, idm_pdu_t *resp) 2127 { 2128 iscsit_sess_t *ist; 2129 iscsi_scsi_rsp_hdr_t *rsp; 2130 2131 /* Get iSCSI session handle */ 2132 ist = ict->ict_sess; 2133 2134 rsp = (iscsi_scsi_rsp_hdr_t *)resp->isp_hdr; 2135 2136 /* Update StatSN */ 2137 rsp->statsn = htonl(ict->ict_statsn); 2138 switch (IDM_PDU_OPCODE(resp)) { 2139 case ISCSI_OP_RTT_RSP: 2140 /* Do nothing */ 2141 break; 2142 case ISCSI_OP_NOOP_IN: 2143 /* 2144 * Refer to section 10.19.1, RFC3720. 2145 * Advance only if target is responding initiator 2146 */ 2147 if (((iscsi_nop_in_hdr_t *)rsp)->ttt == ISCSI_RSVD_TASK_TAG) 2148 ict->ict_statsn++; 2149 break; 2150 case ISCSI_OP_SCSI_DATA_RSP: 2151 if (rsp->flags & ISCSI_FLAG_DATA_STATUS) 2152 ict->ict_statsn++; 2153 else 2154 rsp->statsn = 0; 2155 break; 2156 default: 2157 ict->ict_statsn++; 2158 break; 2159 } 2160 2161 /* Set ExpCmdSN and MaxCmdSN */ 2162 rsp->maxcmdsn = htonl(ist->ist_maxcmdsn); 2163 rsp->expcmdsn = htonl(ist->ist_expcmdsn); 2164 } 2165 2166 /* 2167 * Wrapper funtion, calls iscsi_calc_rspsn and idm_pdu_tx 2168 */ 2169 void 2170 iscsit_pdu_tx(idm_pdu_t *pdu) 2171 { 2172 iscsit_conn_t *ict = pdu->isp_ic->ic_handle; 2173 2174 /* 2175 * Protect ict->ict_statsn, ist->ist_maxcmdsn, and ist->ist_expcmdsn 2176 * (which are used by iscsit_calc_rspsn) with the session mutex 2177 * (ist->ist_sn_mutex). 2178 */ 2179 rw_enter(&ict->ict_sess->ist_sn_rwlock, RW_WRITER); 2180 iscsit_calc_rspsn(ict, pdu); 2181 idm_pdu_tx(pdu); 2182 rw_exit(&ict->ict_sess->ist_sn_rwlock); 2183 } 2184 2185 /* 2186 * Internal functions 2187 */ 2188 2189 void 2190 iscsit_send_async_event(iscsit_conn_t *ict, uint8_t event) 2191 { 2192 idm_pdu_t *abt; 2193 iscsi_async_evt_hdr_t *async_abt; 2194 2195 /* 2196 * Get a PDU to build the abort request. 2197 */ 2198 abt = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 2199 if (abt == NULL) { 2200 idm_conn_event(ict->ict_ic, CE_TRANSPORT_FAIL, NULL); 2201 return; 2202 } 2203 idm_pdu_init(abt, ict->ict_ic, NULL, NULL); 2204 2205 ASSERT(abt != NULL); 2206 abt->isp_datalen = 0; 2207 2208 async_abt = (iscsi_async_evt_hdr_t *)abt->isp_hdr; 2209 bzero(async_abt, sizeof (*async_abt)); 2210 async_abt->opcode = ISCSI_OP_ASYNC_EVENT; 2211 async_abt->async_event = event; 2212 async_abt->flags = ISCSI_FLAG_FINAL; 2213 async_abt->rsvd4[0] = 0xff; 2214 async_abt->rsvd4[1] = 0xff; 2215 async_abt->rsvd4[2] = 0xff; 2216 async_abt->rsvd4[3] = 0xff; 2217 2218 switch (event) { 2219 case ISCSI_ASYNC_EVENT_REQUEST_LOGOUT: 2220 async_abt->param3 = htons(IDM_LOGOUT_SECONDS); 2221 break; 2222 case ISCSI_ASYNC_EVENT_SCSI_EVENT: 2223 case ISCSI_ASYNC_EVENT_DROPPING_CONNECTION: 2224 case ISCSI_ASYNC_EVENT_DROPPING_ALL_CONNECTIONS: 2225 case ISCSI_ASYNC_EVENT_PARAM_NEGOTIATION: 2226 default: 2227 ASSERT(0); 2228 } 2229 2230 iscsit_pdu_tx(abt); 2231 } 2232 2233 2234 static iscsit_task_t * 2235 iscsit_task_alloc(iscsit_conn_t *ict) 2236 { 2237 iscsit_task_t *itask; 2238 iscsit_buf_t *immed_ibuf; 2239 2240 /* 2241 * Possible items to pre-alloc if we cache iscsit_task_t's: 2242 * 2243 * Status PDU w/ sense buffer 2244 * stmf_data_buf_t for immediate data 2245 */ 2246 itask = kmem_alloc(sizeof (iscsit_task_t) + sizeof (iscsit_buf_t) + 2247 sizeof (stmf_data_buf_t), KM_NOSLEEP); 2248 if (itask != NULL) { 2249 mutex_init(&itask->it_mutex, NULL, MUTEX_DRIVER, NULL); 2250 itask->it_aborted = itask->it_stmf_abort = 2251 itask->it_tm_task = 0; 2252 2253 immed_ibuf = (iscsit_buf_t *)(itask + 1); 2254 bzero(immed_ibuf, sizeof (*immed_ibuf)); 2255 immed_ibuf->ibuf_is_immed = B_TRUE; 2256 immed_ibuf->ibuf_stmf_buf = (stmf_data_buf_t *)(immed_ibuf + 1); 2257 2258 bzero(immed_ibuf->ibuf_stmf_buf, sizeof (stmf_data_buf_t)); 2259 immed_ibuf->ibuf_stmf_buf->db_port_private = immed_ibuf; 2260 immed_ibuf->ibuf_stmf_buf->db_sglist_length = 1; 2261 immed_ibuf->ibuf_stmf_buf->db_flags = DB_DIRECTION_FROM_RPORT | 2262 DB_DONT_CACHE; 2263 itask->it_immed_data = immed_ibuf; 2264 itask->it_idm_task = idm_task_alloc(ict->ict_ic); 2265 if (itask->it_idm_task != NULL) { 2266 itask->it_idm_task->idt_private = itask; 2267 itask->it_ict = ict; 2268 itask->it_ttt = itask->it_idm_task->idt_tt; 2269 return (itask); 2270 } else { 2271 kmem_free(itask, sizeof (iscsit_task_t) + 2272 sizeof (iscsit_buf_t) + sizeof (stmf_data_buf_t)); 2273 } 2274 } 2275 2276 return (NULL); 2277 } 2278 2279 static void 2280 iscsit_task_free(iscsit_task_t *itask) 2281 { 2282 idm_task_free(itask->it_idm_task); 2283 mutex_destroy(&itask->it_mutex); 2284 kmem_free(itask, sizeof (iscsit_task_t) + 2285 sizeof (iscsit_buf_t) + sizeof (stmf_data_buf_t)); 2286 } 2287 2288 static iscsit_task_t * 2289 iscsit_tm_task_alloc(iscsit_conn_t *ict) 2290 { 2291 iscsit_task_t *itask; 2292 2293 itask = kmem_zalloc(sizeof (iscsit_task_t), KM_NOSLEEP); 2294 if (itask != NULL) { 2295 idm_conn_hold(ict->ict_ic); 2296 mutex_init(&itask->it_mutex, NULL, MUTEX_DRIVER, NULL); 2297 itask->it_aborted = itask->it_stmf_abort = 2298 itask->it_tm_responded = 0; 2299 itask->it_tm_pdu = NULL; 2300 itask->it_tm_task = 1; 2301 itask->it_ict = ict; 2302 } 2303 2304 return (itask); 2305 } 2306 2307 static void 2308 iscsit_tm_task_free(iscsit_task_t *itask) 2309 { 2310 /* 2311 * If we responded then the call to idm_pdu_complete will free the 2312 * PDU. Otherwise we got aborted before the TM function could 2313 * complete and we need to free the PDU explicitly. 2314 */ 2315 if (itask->it_tm_pdu != NULL && !itask->it_tm_responded) 2316 idm_pdu_free(itask->it_tm_pdu); 2317 idm_conn_rele(itask->it_ict->ict_ic); 2318 mutex_destroy(&itask->it_mutex); 2319 kmem_free(itask, sizeof (iscsit_task_t)); 2320 } 2321 2322 /* 2323 * iscsit status PDU cache 2324 */ 2325 2326 /*ARGSUSED*/ 2327 static int 2328 iscsit_status_pdu_constructor(void *pdu_void, void *arg, int flags) 2329 { 2330 idm_pdu_t *pdu = pdu_void; 2331 iscsi_scsi_rsp_hdr_t *rsp; 2332 2333 bzero(pdu, sizeof (idm_pdu_t)); 2334 pdu->isp_callback = iscsit_send_good_status_done; 2335 pdu->isp_magic = IDM_PDU_MAGIC; 2336 pdu->isp_hdr = (iscsi_hdr_t *)(pdu + 1); /* Ptr arithmetic */ 2337 pdu->isp_hdrlen = sizeof (iscsi_hdr_t); 2338 2339 /* Setup status response */ 2340 rsp = (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr; 2341 bzero(rsp, sizeof (*rsp)); 2342 rsp->opcode = ISCSI_OP_SCSI_RSP; 2343 rsp->flags = ISCSI_FLAG_FINAL; 2344 rsp->response = ISCSI_STATUS_CMD_COMPLETED; 2345 2346 return (0); 2347 } 2348 2349 /* 2350 * iscsit private data handler 2351 */ 2352 2353 /*ARGSUSED*/ 2354 static void 2355 iscsit_pp_cb(struct stmf_port_provider *pp, int cmd, void *arg, uint32_t flags) 2356 { 2357 it_config_t *cfg; 2358 nvlist_t *nvl; 2359 2360 if ((cmd != STMF_PROVIDER_DATA_UPDATED) || (arg == NULL)) { 2361 return; 2362 } 2363 2364 nvl = (nvlist_t *)arg; 2365 2366 /* Translate nvlist */ 2367 if (it_nv_to_config(nvl, &cfg) != 0) { 2368 cmn_err(CE_WARN, "Configuration is invalid"); 2369 return; 2370 } 2371 2372 /* Update config */ 2373 (void) iscsit_config_merge(cfg); 2374 2375 it_config_free_cmn(cfg); 2376 } 2377 2378 2379 static it_cfg_status_t 2380 iscsit_config_merge(it_config_t *in_cfg) 2381 { 2382 it_cfg_status_t status; 2383 it_config_t *cfg; 2384 it_config_t tmp_cfg; 2385 list_t tpg_del_list; 2386 2387 if (in_cfg) { 2388 cfg = in_cfg; 2389 } else { 2390 /* Make empty config */ 2391 bzero(&tmp_cfg, sizeof (tmp_cfg)); 2392 cfg = &tmp_cfg; 2393 } 2394 2395 list_create(&tpg_del_list, sizeof (iscsit_tpg_t), 2396 offsetof(iscsit_tpg_t, tpg_delete_ln)); 2397 2398 /* 2399 * Update targets, initiator contexts, target portal groups, 2400 * and iSNS client 2401 */ 2402 ISCSIT_GLOBAL_LOCK(RW_WRITER); 2403 if (((status = iscsit_config_merge_tpg(cfg, &tpg_del_list)) 2404 != 0) || 2405 ((status = iscsit_config_merge_tgt(cfg)) != 0) || 2406 ((status = iscsit_config_merge_ini(cfg)) != 0) || 2407 ((status = isnst_config_merge(cfg)) != 0)) { 2408 ISCSIT_GLOBAL_UNLOCK(); 2409 return (status); 2410 } 2411 2412 /* Update other global config parameters */ 2413 if (iscsit_global.global_props) { 2414 nvlist_free(iscsit_global.global_props); 2415 iscsit_global.global_props = NULL; 2416 } 2417 if (in_cfg) { 2418 (void) nvlist_dup(cfg->config_global_properties, 2419 &iscsit_global.global_props, KM_SLEEP); 2420 } 2421 ISCSIT_GLOBAL_UNLOCK(); 2422 2423 iscsit_config_destroy_tpgs(&tpg_del_list); 2424 2425 list_destroy(&tpg_del_list); 2426 2427 return (ITCFG_SUCCESS); 2428 } 2429 2430 /* 2431 * iscsit_sna_lt[e] 2432 * 2433 * Compare serial numbers using serial number arithmetic as defined in 2434 * RFC 1982. 2435 * 2436 * NOTE: This code is duplicated in the isns server as well as iscsitgtd. It 2437 * ought to be common. 2438 */ 2439 2440 static int 2441 iscsit_sna_lt(uint32_t sn1, uint32_t sn2) 2442 { 2443 return ((sn1 != sn2) && 2444 (((sn1 < sn2) && ((sn2 - sn1) < ISCSIT_SNA32_CHECK)) || 2445 ((sn1 > sn2) && ((sn1 - sn2) > ISCSIT_SNA32_CHECK)))); 2446 } 2447 2448 static int 2449 iscsit_sna_lte(uint32_t sn1, uint32_t sn2) 2450 { 2451 return ((sn1 == sn2) || 2452 (((sn1 < sn2) && ((sn2 - sn1) < ISCSIT_SNA32_CHECK)) || 2453 ((sn1 > sn2) && ((sn1 - sn2) > ISCSIT_SNA32_CHECK)))); 2454 } 2455 2456 2457 static boolean_t 2458 iscsit_cmdsn_in_window(iscsit_conn_t *ict, uint32_t cmdsn) 2459 { 2460 iscsit_sess_t *ist = ict->ict_sess; 2461 int rval = B_TRUE; 2462 2463 ist = ict->ict_sess; 2464 2465 rw_enter(&ist->ist_sn_rwlock, RW_READER); 2466 2467 /* 2468 * If cmdsn is less than ist_expcmdsn - iscsit_cmd_window() or 2469 * greater than ist_expcmdsn, it's not in the window. 2470 */ 2471 2472 if (iscsit_sna_lt(cmdsn, (ist->ist_expcmdsn - iscsit_cmd_window())) || 2473 !iscsit_sna_lte(cmdsn, ist->ist_expcmdsn)) { 2474 rval = B_FALSE; 2475 } 2476 2477 rw_exit(&ist->ist_sn_rwlock); 2478 2479 return (rval); 2480 } 2481