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