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 /*
  25  * Copyright 2012, Nexenta Systems, Inc. All rights reserved.
  26  * Copyright (c) 2013 by Delphix. All rights reserved.
  27  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  28  */
  29 
  30 #include <sys/conf.h>
  31 #include <sys/file.h>
  32 #include <sys/ddi.h>
  33 #include <sys/sunddi.h>
  34 #include <sys/modctl.h>
  35 #include <sys/scsi/scsi.h>
  36 #include <sys/scsi/generic/persist.h>
  37 #include <sys/scsi/impl/scsi_reset_notify.h>
  38 #include <sys/disp.h>
  39 #include <sys/byteorder.h>
  40 #include <sys/atomic.h>
  41 #include <sys/ethernet.h>
  42 #include <sys/sdt.h>
  43 #include <sys/nvpair.h>
  44 #include <sys/zone.h>
  45 #include <sys/id_space.h>
 
 
 107 static void stmf_svc_kill_obj_requests(void *obj);
 108 static void stmf_svc_timeout(struct stmf_svc_clocks *);
 109 void stmf_check_freetask();
 110 void stmf_abort_target_reset(scsi_task_t *task);
 111 stmf_status_t stmf_lun_reset_poll(stmf_lu_t *lu, struct scsi_task *task,
 112                                                         int target_reset);
 113 void stmf_target_reset_poll(struct scsi_task *task);
 114 void stmf_handle_lun_reset(scsi_task_t *task);
 115 void stmf_handle_target_reset(scsi_task_t *task);
 116 void stmf_xd_to_dbuf(stmf_data_buf_t *dbuf, int set_rel_off);
 117 int stmf_load_ppd_ioctl(stmf_ppioctl_data_t *ppi, uint64_t *ppi_token,
 118     uint32_t *err_ret);
 119 int stmf_delete_ppd_ioctl(stmf_ppioctl_data_t *ppi);
 120 int stmf_get_ppd_ioctl(stmf_ppioctl_data_t *ppi, stmf_ppioctl_data_t *ppi_out,
 121     uint32_t *err_ret);
 122 void stmf_delete_ppd(stmf_pp_data_t *ppd);
 123 void stmf_delete_all_ppds();
 124 void stmf_trace_clear();
 125 void stmf_worker_init();
 126 stmf_status_t stmf_worker_fini();
 127 void stmf_worker_mgmt();
 128 void stmf_worker_task(void *arg);
 129 static void stmf_task_lu_free(scsi_task_t *task, stmf_i_scsi_session_t *iss);
 130 static stmf_status_t stmf_ic_lu_reg(stmf_ic_reg_dereg_lun_msg_t *msg,
 131     uint32_t type);
 132 static stmf_status_t stmf_ic_lu_dereg(stmf_ic_reg_dereg_lun_msg_t *msg);
 133 static stmf_status_t stmf_ic_rx_scsi_status(stmf_ic_scsi_status_msg_t *msg);
 134 static stmf_status_t stmf_ic_rx_status(stmf_ic_status_msg_t *msg);
 135 static stmf_status_t stmf_ic_rx_scsi_data(stmf_ic_scsi_data_msg_t *msg);
 136 void stmf_task_lu_killall(stmf_lu_t *lu, scsi_task_t *tm_task, stmf_status_t s);
 137 
 138 /* pppt modhandle */
 139 ddi_modhandle_t pppt_mod;
 140 
 141 /* pppt modload imported functions */
 142 stmf_ic_reg_port_msg_alloc_func_t ic_reg_port_msg_alloc;
 143 stmf_ic_dereg_port_msg_alloc_func_t ic_dereg_port_msg_alloc;
 144 stmf_ic_reg_lun_msg_alloc_func_t ic_reg_lun_msg_alloc;
 145 stmf_ic_dereg_lun_msg_alloc_func_t ic_dereg_lun_msg_alloc;
 146 stmf_ic_lun_active_msg_alloc_func_t ic_lun_active_msg_alloc;
 147 stmf_ic_scsi_cmd_msg_alloc_func_t ic_scsi_cmd_msg_alloc;
 148 stmf_ic_scsi_data_xfer_done_msg_alloc_func_t ic_scsi_data_xfer_done_msg_alloc;
 149 stmf_ic_session_create_msg_alloc_func_t ic_session_reg_msg_alloc;
 150 stmf_ic_session_destroy_msg_alloc_func_t ic_session_dereg_msg_alloc;
 151 stmf_ic_tx_msg_func_t ic_tx_msg;
 152 stmf_ic_msg_free_func_t ic_msg_free;
 153 
 154 static void stmf_itl_task_start(stmf_i_scsi_task_t *itask);
 155 static void stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask);
 156 static void stmf_itl_task_done(stmf_i_scsi_task_t *itask);
 157 
 158 static void stmf_lport_xfer_start(stmf_i_scsi_task_t *itask,
 159     stmf_data_buf_t *dbuf);
 160 static void stmf_lport_xfer_done(stmf_i_scsi_task_t *itask,
 161     stmf_data_buf_t *dbuf);
 162 
 163 static void stmf_update_kstat_lu_q(scsi_task_t *, void());
 164 static void stmf_update_kstat_lport_q(scsi_task_t *, void());
 165 static void stmf_update_kstat_lu_io(scsi_task_t *, stmf_data_buf_t *);
 166 static void stmf_update_kstat_lport_io(scsi_task_t *, stmf_data_buf_t *);
 167 
 168 static int stmf_irport_compare(const void *void_irport1,
 169     const void *void_irport2);
 170 static stmf_i_remote_port_t *stmf_irport_create(scsi_devid_desc_t *rport_devid);
 171 static void stmf_irport_destroy(stmf_i_remote_port_t *irport);
 172 static stmf_i_remote_port_t *stmf_irport_register(
 173     scsi_devid_desc_t *rport_devid);
 174 static stmf_i_remote_port_t *stmf_irport_lookup_locked(
 175     scsi_devid_desc_t *rport_devid);
 176 static void stmf_irport_deregister(stmf_i_remote_port_t *irport);
 177 
 178 extern struct mod_ops mod_driverops;
 179 
 180 /* =====[ Tunables ]===== */
 181 /* Internal tracing */
 182 volatile int    stmf_trace_on = 1;
 183 volatile int    stmf_trace_buf_size = (1 * 1024 * 1024);
 184 /*
 185  * The reason default task timeout is 75 is because we want the
 186  * host to timeout 1st and mostly host timeout is 60 seconds.
 187  */
 188 volatile int    stmf_default_task_timeout = 75;
 189 /*
 190  * Setting this to one means, you are responsible for config load and keeping
 191  * things in sync with persistent database.
 192  */
 193 volatile int    stmf_allow_modunload = 0;
 194 
 195 volatile int stmf_max_nworkers = 256;
 196 volatile int stmf_min_nworkers = 4;
 197 volatile int stmf_worker_scale_down_delay = 20;
 198 
 199 /* === [ Debugging and fault injection ] === */
 200 #ifdef  DEBUG
 201 volatile uint32_t stmf_drop_task_counter = 0;
 202 volatile uint32_t stmf_drop_buf_counter = 0;
 203 
 204 #endif
 205 
 206 stmf_state_t            stmf_state;
 207 static stmf_lu_t        *dlun0;
 208 
 209 static uint8_t stmf_first_zero[] =
 210         { 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0xff };
 211 static uint8_t stmf_first_one[] =
 212         { 0xff, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
 213 
 214 static kmutex_t trace_buf_lock;
 215 static int      trace_buf_size;
 216 static int      trace_buf_curndx;
 217 caddr_t stmf_trace_buf;
 218 
 219 static enum {
 220         STMF_WORKERS_DISABLED = 0,
 221         STMF_WORKERS_ENABLING,
 222         STMF_WORKERS_ENABLED
 223 } stmf_workers_state = STMF_WORKERS_DISABLED;
 224 static int stmf_i_max_nworkers;
 225 static int stmf_i_min_nworkers;
 226 static int stmf_nworkers_cur;           /* # of workers currently running */
 227 static int stmf_nworkers_needed;        /* # of workers need to be running */
 228 static int stmf_worker_sel_counter = 0;
 229 static uint32_t stmf_cur_ntasks = 0;
 230 static clock_t stmf_wm_last = 0;
 231 /*
 232  * This is equal to stmf_nworkers_cur while we are increasing # workers and
 233  * stmf_nworkers_needed while we are decreasing the worker count.
 234  */
 235 static int stmf_nworkers_accepting_cmds;
 236 static stmf_worker_t *stmf_workers = NULL;
 237 static clock_t stmf_worker_mgmt_delay = 2;
 238 static clock_t stmf_worker_scale_down_timer = 0;
 239 static int stmf_worker_scale_down_qd = 0;
 240 
 241 static struct cb_ops stmf_cb_ops = {
 242         stmf_open,                      /* open */
 243         stmf_close,                     /* close */
 244         nodev,                          /* strategy */
 245         nodev,                          /* print */
 246         nodev,                          /* dump */
 247         nodev,                          /* read */
 248         nodev,                          /* write */
 249         stmf_ioctl,                     /* ioctl */
 250         nodev,                          /* devmap */
 251         nodev,                          /* mmap */
 252         nodev,                          /* segmap */
 253         nochpoll,                       /* chpoll */
 254         ddi_prop_op,                    /* cb_prop_op */
 255         0,                              /* streamtab */
 256         D_NEW | D_MP,                   /* cb_flag */
 257         CB_REV,                         /* rev */
 258         nodev,                          /* aread */
 259         nodev                           /* awrite */
 260 };
 261 
 262 static struct dev_ops stmf_ops = {
 263         DEVO_REV,
 264         0,
 265         stmf_getinfo,
 266         nulldev,                /* identify */
 267         nulldev,                /* probe */
 268         stmf_attach,
 269         stmf_detach,
 270         nodev,                  /* reset */
 271         &stmf_cb_ops,
 272         NULL,                   /* bus_ops */
 273         NULL                    /* power */
 274 };
 275 
 276 #define STMF_NAME               "COMSTAR STMF"
 277 #define STMF_MODULE_NAME        "stmf"
 278 
 279 static struct modldrv modldrv = {
 280         &mod_driverops,
 281         STMF_NAME,
 282         &stmf_ops
 283 };
 284 
 285 static struct modlinkage modlinkage = {
 286         MODREV_1,
 287         &modldrv,
 288         NULL
 289 };
 290 
 291 int
 292 _init(void)
 293 {
 294         int ret;
 295 
 296         ret = mod_install(&modlinkage);
 297         if (ret)
 298                 return (ret);
 299         stmf_trace_buf = kmem_zalloc(stmf_trace_buf_size, KM_SLEEP);
 300         trace_buf_size = stmf_trace_buf_size;
 301         trace_buf_curndx = 0;
 302         mutex_init(&trace_buf_lock, NULL, MUTEX_DRIVER, 0);
 303         bzero(&stmf_state, sizeof (stmf_state_t));
 304         /* STMF service is off by default */
 305         stmf_state.stmf_service_running = 0;
 306         /* default lu/lport states are online */
 307         stmf_state.stmf_default_lu_state = STMF_STATE_ONLINE;
 308         stmf_state.stmf_default_lport_state = STMF_STATE_ONLINE;
 309         mutex_init(&stmf_state.stmf_lock, NULL, MUTEX_DRIVER, NULL);
 310         cv_init(&stmf_state.stmf_cv, NULL, CV_DRIVER, NULL);
 311         stmf_session_counter = (uint64_t)ddi_get_lbolt();
 312         avl_create(&stmf_state.stmf_irportlist,
 313             stmf_irport_compare, sizeof (stmf_i_remote_port_t),
 314             offsetof(stmf_i_remote_port_t, irport_ln));
 315         stmf_state.stmf_ilport_inst_space =
 316             id_space_create("lport-instances", 0, MAX_ILPORT);
 317         stmf_state.stmf_irport_inst_space =
 318             id_space_create("rport-instances", 0, MAX_IRPORT);
 319         stmf_view_init();
 320         stmf_svc_init();
 321         stmf_dlun_init();
 322         return (ret);
 
 353         ret = mod_remove(&modlinkage);
 354         if (ret) {
 355                 stmf_svc_init();
 356                 stmf_dlun_init();
 357                 stmf_worker_init();
 358                 return (ret);
 359         }
 360 
 361         stmf_view_clear_config();
 362 
 363         while ((irport = avl_destroy_nodes(&stmf_state.stmf_irportlist,
 364             &avl_dest_cookie)) != NULL)
 365                 stmf_irport_destroy(irport);
 366         avl_destroy(&stmf_state.stmf_irportlist);
 367         id_space_destroy(stmf_state.stmf_ilport_inst_space);
 368         id_space_destroy(stmf_state.stmf_irport_inst_space);
 369 
 370         kmem_free(stmf_trace_buf, stmf_trace_buf_size);
 371         mutex_destroy(&trace_buf_lock);
 372         mutex_destroy(&stmf_state.stmf_lock);
 373         cv_destroy(&stmf_state.stmf_cv);
 374         return (ret);
 375 }
 376 
 377 int
 378 _info(struct modinfo *modinfop)
 379 {
 380         return (mod_info(&modlinkage, modinfop));
 381 }
 382 
 383 /* ARGSUSED */
 384 static int
 385 stmf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
 386 {
 387         switch (cmd) {
 388         case DDI_INFO_DEVT2DEVINFO:
 389                 *result = stmf_state.stmf_dip;
 390                 break;
 391         case DDI_INFO_DEVT2INSTANCE:
 392                 *result =
 
1638 find_task_from_msgid(uint8_t *lu_id, stmf_ic_msgid_t task_msgid)
1639 {
1640         stmf_i_lu_t *ilu;
1641         stmf_i_scsi_task_t *itask;
1642 
1643         mutex_enter(&stmf_state.stmf_lock);
1644         for (ilu = stmf_state.stmf_ilulist; ilu != NULL; ilu = ilu->ilu_next) {
1645                 if (bcmp(lu_id, ilu->ilu_lu->lu_id->ident, 16) == 0) {
1646                         break;
1647                 }
1648         }
1649 
1650         if (ilu == NULL) {
1651                 mutex_exit(&stmf_state.stmf_lock);
1652                 return (NULL);
1653         }
1654 
1655         mutex_enter(&ilu->ilu_task_lock);
1656         for (itask = ilu->ilu_tasks; itask != NULL;
1657             itask = itask->itask_lu_next) {
1658                 if (itask->itask_flags & (ITASK_IN_FREE_LIST |
1659                     ITASK_BEING_ABORTED)) {
1660                         continue;
1661                 }
1662                 if (itask->itask_proxy_msg_id == task_msgid) {
1663                         break;
1664                 }
1665         }
1666         mutex_exit(&ilu->ilu_task_lock);
1667         mutex_exit(&stmf_state.stmf_lock);
1668 
1669         if (itask != NULL) {
1670                 return (itask->itask_task);
1671         } else {
1672                 /* task not found. Likely already aborted. */
1673                 return (NULL);
1674         }
1675 }
1676 
1677 /*
1678  * message received from pppt/ic
1679  */
1680 stmf_status_t
1681 stmf_msg_rx(stmf_ic_msg_t *msg)
 
1886         }
1887 
1888         if (ilport->ilport_proxy_registered == 0) {
1889                 return (STMF_FAILURE);
1890         }
1891 
1892         mutex_enter(&stmf_state.stmf_lock);
1893         itask->itask_proxy_msg_id = stmf_proxy_msg_id++;
1894         mutex_exit(&stmf_state.stmf_lock);
1895         itask->itask_proxy_dbuf = dbuf;
1896 
1897         /*
1898          * stmf will now take over the task handling for this task
1899          * but it still needs to be treated differently from other
1900          * default handled tasks, hence the ITASK_PROXY_TASK.
1901          * If this is a task management function, we're really just
1902          * duping the command to the peer. Set the TM bit so that
1903          * we can recognize this on return since we won't be completing
1904          * the proxied task in that case.
1905          */
1906         if (task->task_mgmt_function) {
1907                 itask->itask_proxy_msg_id |= MSG_ID_TM_BIT;
1908         } else {
1909                 uint32_t new, old;
1910                 do {
1911                         new = old = itask->itask_flags;
1912                         if (new & ITASK_BEING_ABORTED)
1913                                 return (STMF_FAILURE);
1914                         new |= ITASK_DEFAULT_HANDLING | ITASK_PROXY_TASK;
1915                 } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
1916         }
1917         if (dbuf) {
1918                 ic_cmd_msg = ic_scsi_cmd_msg_alloc(itask->itask_proxy_msg_id,
1919                     task, dbuf->db_data_size, dbuf->db_sglist[0].seg_addr,
1920                     itask->itask_proxy_msg_id);
1921         } else {
1922                 ic_cmd_msg = ic_scsi_cmd_msg_alloc(itask->itask_proxy_msg_id,
1923                     task, 0, NULL, itask->itask_proxy_msg_id);
1924         }
1925         if (ic_cmd_msg) {
1926                 ic_ret = ic_tx_msg(ic_cmd_msg);
1927                 if (ic_ret == STMF_IC_MSG_SUCCESS) {
1928                         ret = STMF_SUCCESS;
1929                 }
1930         }
1931         return (ret);
1932 }
1933 
1934 
1935 stmf_status_t
1936 pppt_modload()
1937 {
1938         int error;
1939 
1940         if (pppt_mod == NULL && ((pppt_mod =
1941             ddi_modopen("drv/pppt", KRTLD_MODE_FIRST, &error)) == NULL)) {
1942                 cmn_err(CE_WARN, "Unable to load pppt");
1943                 return (STMF_FAILURE);
1944         }
 
2508         /*
2509          * User is requesting that the token be checked.
2510          * If there was another set after the user's get
2511          * it's an error
2512          */
2513         if (ppi->ppi_token_valid) {
2514                 if (ppi->ppi_token != ppd->ppd_token) {
2515                         *err_ret = STMF_IOCERR_PPD_UPDATED;
2516                         mutex_exit(&stmf_state.stmf_lock);
2517                         return (EINVAL);
2518                 }
2519         }
2520 
2521         if ((ret = nvlist_unpack((char *)ppi->ppi_data,
2522             (size_t)ppi->ppi_data_size, &nv, KM_NOSLEEP)) != 0) {
2523                 mutex_exit(&stmf_state.stmf_lock);
2524                 return (ret);
2525         }
2526 
2527         /* Free any existing lists and add this one to the ppd */
2528         nvlist_free(ppd->ppd_nv);
2529         ppd->ppd_nv = nv;
2530 
2531         /* set the token for writes */
2532         ppd->ppd_token++;
2533         /* return token to caller */
2534         if (ppi_token) {
2535                 *ppi_token = ppd->ppd_token;
2536         }
2537 
2538         /* If there is a provider registered, do the notifications */
2539         if (ppd->ppd_provider) {
2540                 uint32_t cb_flags = 0;
2541 
2542                 if (stmf_state.stmf_config_state == STMF_CONFIG_INIT)
2543                         cb_flags |= STMF_PCB_STMF_ONLINING;
2544                 if (ppi->ppi_lu_provider) {
2545                         ilp = (stmf_i_lu_provider_t *)ppd->ppd_provider;
2546                         if (ilp->ilp_lp->lp_cb == NULL)
2547                                 goto bail_out;
 
2580                 if (ppd->ppd_lu_provider) {
2581                         ((stmf_i_lu_provider_t *)
2582                             ppd->ppd_provider)->ilp_ppd = NULL;
2583                 } else {
2584                         ((stmf_i_port_provider_t *)
2585                             ppd->ppd_provider)->ipp_ppd = NULL;
2586                 }
2587                 ppd->ppd_provider = NULL;
2588         }
2589 
2590         for (pppd = &stmf_state.stmf_ppdlist; *pppd != NULL;
2591             pppd = &((*pppd)->ppd_next)) {
2592                 if (*pppd == ppd)
2593                         break;
2594         }
2595 
2596         if (*pppd == NULL)
2597                 return;
2598 
2599         *pppd = ppd->ppd_next;
2600         nvlist_free(ppd->ppd_nv);
2601 
2602         kmem_free(ppd, ppd->ppd_alloc_size);
2603 }
2604 
2605 int
2606 stmf_delete_ppd_ioctl(stmf_ppioctl_data_t *ppi)
2607 {
2608         stmf_pp_data_t *ppd;
2609         int ret = ENOENT;
2610 
2611         if ((ppi->ppi_lu_provider + ppi->ppi_port_provider) != 1) {
2612                 return (EINVAL);
2613         }
2614 
2615         mutex_enter(&stmf_state.stmf_lock);
2616 
2617         for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = ppd->ppd_next) {
2618                 if (ppi->ppi_lu_provider) {
2619                         if (!ppd->ppd_lu_provider)
 
2689 }
2690 
2691 void
2692 stmf_delete_all_ppds()
2693 {
2694         stmf_pp_data_t *ppd, *nppd;
2695 
2696         ASSERT(mutex_owned(&stmf_state.stmf_lock));
2697         for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = nppd) {
2698                 nppd = ppd->ppd_next;
2699                 stmf_delete_ppd(ppd);
2700         }
2701 }
2702 
2703 /*
2704  * 16 is the max string length of a protocol_ident, increase
2705  * the size if needed.
2706  */
2707 #define STMF_KSTAT_LU_SZ        (STMF_GUID_INPUT + 1 + 256)
2708 #define STMF_KSTAT_TGT_SZ       (256 * 2 + 16)
2709 
2710 /*
2711  * This array matches the Protocol Identifier in stmf_ioctl.h
2712  */
2713 #define MAX_PROTO_STR_LEN       32
2714 
2715 char *protocol_ident[PROTOCOL_ANY] = {
2716         "Fibre Channel",
2717         "Parallel SCSI",
2718         "SSA",
2719         "IEEE_1394",
2720         "SRP",
2721         "iSCSI",
2722         "SAS",
2723         "ADT",
2724         "ATAPI",
2725         "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"
2726 };
2727 
2728 /*
 
2766 }
2767 
2768 static void
2769 stmf_update_kstat_lport_io(scsi_task_t *task, stmf_data_buf_t *dbuf)
2770 {
2771         stmf_i_local_port_t     *ilp;
2772         kstat_io_t              *kip;
2773 
2774         ilp = (stmf_i_local_port_t *)task->task_lport->lport_stmf_private;
2775         if (ilp != NULL && ilp->ilport_kstat_io != NULL) {
2776                 kip = KSTAT_IO_PTR(ilp->ilport_kstat_io);
2777                 if (kip != NULL) {
2778                         mutex_enter(ilp->ilport_kstat_io->ks_lock);
2779                         STMF_UPDATE_KSTAT_IO(kip, dbuf);
2780                         mutex_exit(ilp->ilport_kstat_io->ks_lock);
2781                 }
2782         }
2783 }
2784 
2785 static void
2786 stmf_update_kstat_lu_io(scsi_task_t *task, stmf_data_buf_t *dbuf)
2787 {
2788         stmf_i_lu_t             *ilu;
2789         kstat_io_t              *kip;
2790 
2791         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
2792         if (ilu != NULL && ilu->ilu_kstat_io != NULL) {
2793                 kip = KSTAT_IO_PTR(ilu->ilu_kstat_io);
2794                 if (kip != NULL) {
2795                         mutex_enter(ilu->ilu_kstat_io->ks_lock);
2796                         STMF_UPDATE_KSTAT_IO(kip, dbuf);
2797                         mutex_exit(ilu->ilu_kstat_io->ks_lock);
2798                 }
2799         }
2800 }
2801 
2802 static void
2803 stmf_create_kstat_lu(stmf_i_lu_t *ilu)
2804 {
2805         char                            ks_nm[KSTAT_STRLEN];
 
3426         alloc_len = sizeof (*irport) + sizeof (scsi_devid_desc_t) +
3427             rport_devid->ident_length - 1;
3428         irport = kmem_zalloc(alloc_len, KM_NOSLEEP);
3429         if (irport == NULL) {
3430                 return (NULL);
3431         }
3432 
3433         irport->irport_instance =
3434             id_alloc_nosleep(stmf_state.stmf_irport_inst_space);
3435         if (irport->irport_instance == -1) {
3436                 kmem_free(irport, alloc_len);
3437                 return (NULL);
3438         }
3439 
3440         irport->irport_id =
3441             (struct scsi_devid_desc *)(irport + 1); /* Ptr. Arith. */
3442         bcopy(rport_devid, irport->irport_id,
3443             sizeof (scsi_devid_desc_t) + rport_devid->ident_length - 1);
3444         irport->irport_refcnt = 1;
3445         mutex_init(&irport->irport_mutex, NULL, MUTEX_DEFAULT, NULL);
3446 
3447         return (irport);
3448 }
3449 
3450 static void
3451 stmf_irport_destroy(stmf_i_remote_port_t *irport)
3452 {
3453         id_free(stmf_state.stmf_irport_inst_space, irport->irport_instance);
3454         mutex_destroy(&irport->irport_mutex);
3455         kmem_free(irport, sizeof (*irport) + sizeof (scsi_devid_desc_t) +
3456             irport->irport_id->ident_length - 1);
3457 }
3458 
3459 static stmf_i_remote_port_t *
3460 stmf_irport_register(scsi_devid_desc_t *rport_devid)
3461 {
3462         stmf_i_remote_port_t    *irport;
3463 
3464         mutex_enter(&stmf_state.stmf_lock);
3465 
3466         /*
3467          * Lookup will bump the refcnt if there's an existing rport
3468          * context for this identifier.
3469          */
3470         if ((irport = stmf_irport_lookup_locked(rport_devid)) != NULL) {
3471                 mutex_exit(&stmf_state.stmf_lock);
3472                 return (irport);
3473         }
3474 
3475         irport = stmf_irport_create(rport_devid);
3476         if (irport == NULL) {
3477                 mutex_exit(&stmf_state.stmf_lock);
3478                 return (NULL);
3479         }
3480 
3481         avl_add(&stmf_state.stmf_irportlist, irport);
3482         mutex_exit(&stmf_state.stmf_lock);
3483 
3484         return (irport);
3485 }
3486 
3487 static stmf_i_remote_port_t *
3488 stmf_irport_lookup_locked(scsi_devid_desc_t *rport_devid)
3489 {
3490         stmf_i_remote_port_t    *irport;
3491         stmf_i_remote_port_t    tmp_irport;
3492 
3493         ASSERT(mutex_owned(&stmf_state.stmf_lock));
3494         tmp_irport.irport_id = rport_devid;
3495         irport = avl_find(&stmf_state.stmf_irportlist, &tmp_irport, NULL);
3496         if (irport != NULL) {
3497                 mutex_enter(&irport->irport_mutex);
3498                 irport->irport_refcnt++;
3499                 mutex_exit(&irport->irport_mutex);
3500         }
 
3584 
3585         mutex_enter(&stmf_state.stmf_lock);
3586         rw_enter(&ilport->ilport_lock, RW_WRITER);
3587         (void) stmf_session_create_lun_map(ilport, iss);
3588         ilport->ilport_nsessions++;
3589         iss->iss_next = ilport->ilport_ss_list;
3590         ilport->ilport_ss_list = iss;
3591         rw_exit(&ilport->ilport_lock);
3592         mutex_exit(&stmf_state.stmf_lock);
3593 
3594         iss->iss_creation_time = ddi_get_time();
3595         ss->ss_session_id = atomic_inc_64_nv(&stmf_session_counter);
3596         iss->iss_flags &= ~ISS_BEING_CREATED;
3597         /* XXX should we remove ISS_LUN_INVENTORY_CHANGED on new session? */
3598         iss->iss_flags &= ~ISS_LUN_INVENTORY_CHANGED;
3599         DTRACE_PROBE2(session__online, stmf_local_port_t *, lport,
3600             stmf_scsi_session_t *, ss);
3601         return (STMF_SUCCESS);
3602 }
3603 
3604 void
3605 stmf_deregister_scsi_session(stmf_local_port_t *lport, stmf_scsi_session_t *ss)
3606 {
3607         stmf_i_local_port_t *ilport = (stmf_i_local_port_t *)
3608             lport->lport_stmf_private;
3609         stmf_i_scsi_session_t *iss, **ppss;
3610         int found = 0;
3611         stmf_ic_msg_t *ic_session_dereg;
3612         stmf_status_t ic_ret = STMF_FAILURE;
3613 
3614         DTRACE_PROBE2(session__offline, stmf_local_port_t *, lport,
3615             stmf_scsi_session_t *, ss);
3616 
3617         iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
3618         if (ss->ss_rport_alias) {
3619                 ss->ss_rport_alias = NULL;
3620         }
3621 
3622 try_dereg_ss_again:
3623         mutex_enter(&stmf_state.stmf_lock);
3624         atomic_and_32(&iss->iss_flags,
3625             ~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
3626         if (iss->iss_flags & ISS_EVENT_ACTIVE) {
3627                 mutex_exit(&stmf_state.stmf_lock);
3628                 delay(1);
3629                 goto try_dereg_ss_again;
3630         }
3631 
3632         /* dereg proxy session if not standby port */
 
3642                         }
3643                 }
3644         }
3645 
3646         rw_enter(&ilport->ilport_lock, RW_WRITER);
3647         for (ppss = &ilport->ilport_ss_list; *ppss != NULL;
3648             ppss = &((*ppss)->iss_next)) {
3649                 if (iss == (*ppss)) {
3650                         *ppss = (*ppss)->iss_next;
3651                         found = 1;
3652                         break;
3653                 }
3654         }
3655         if (!found) {
3656                 cmn_err(CE_PANIC, "Deregister session called for non existent"
3657                     " session");
3658         }
3659         ilport->ilport_nsessions--;
3660 
3661         stmf_irport_deregister(iss->iss_irport);
3662         (void) stmf_session_destroy_lun_map(ilport, iss);
3663         rw_exit(&ilport->ilport_lock);
3664         mutex_exit(&stmf_state.stmf_lock);
3665 
3666         if (iss->iss_flags & ISS_NULL_TPTID) {
3667                 stmf_remote_port_free(ss->ss_rport);
3668         }
3669 }
3670 
3671 stmf_i_scsi_session_t *
3672 stmf_session_id_to_issptr(uint64_t session_id, int stay_locked)
3673 {
3674         stmf_i_local_port_t *ilport;
3675         stmf_i_scsi_session_t *iss;
3676 
3677         mutex_enter(&stmf_state.stmf_lock);
3678         for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
3679             ilport = ilport->ilport_next) {
3680                 rw_enter(&ilport->ilport_lock, RW_WRITER);
3681                 for (iss = ilport->ilport_ss_list; iss != NULL;
3682                     iss = iss->iss_next) {
3683                         if (iss->iss_ss->ss_session_id == session_id) {
3684                                 if (!stay_locked)
3685                                         rw_exit(&ilport->ilport_lock);
3686                                 mutex_exit(&stmf_state.stmf_lock);
3687                                 return (iss);
3688                         }
3689                 }
3690                 rw_exit(&ilport->ilport_lock);
 
3846                                                 goto dai_scan_done;
3847                                         }
3848                                 }
3849                         } /* lun table for a session */
3850                 } /* sessions */
3851                 rw_exit(&ilport->ilport_lock);
3852         } /* ports */
3853 
3854 dai_scan_done:
3855         mutex_exit(&stmf_state.stmf_lock);
3856 
3857         for (i = 0; i < nu; i++) {
3858                 stmf_do_itl_dereg(lu, itl_list[i],
3859                     STMF_ITL_REASON_DEREG_REQUEST);
3860         }
3861         kmem_free(itl_list, nmaps * sizeof (stmf_itl_data_t *));
3862 
3863         return (STMF_SUCCESS);
3864 }
3865 
3866 stmf_status_t
3867 stmf_get_itl_handle(stmf_lu_t *lu, uint8_t *lun, stmf_scsi_session_t *ss,
3868     uint64_t session_id, void **itl_handle_retp)
3869 {
3870         stmf_i_scsi_session_t *iss;
3871         stmf_lun_map_ent_t *ent;
3872         stmf_lun_map_t *lm;
3873         stmf_status_t ret;
3874         int i;
3875         uint16_t n;
3876 
3877         if (ss == NULL) {
3878                 iss = stmf_session_id_to_issptr(session_id, 1);
3879                 if (iss == NULL)
3880                         return (STMF_NOT_FOUND);
3881         } else {
3882                 iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
3883                 rw_enter(iss->iss_lockp, RW_WRITER);
3884         }
3885 
3886         ent = NULL;
3887         if (lun == NULL) {
3888                 lm = iss->iss_sm;
3889                 for (i = 0; i < lm->lm_nentries; i++) {
3890                         if (lm->lm_plus[i] == NULL)
3891                                 continue;
3892                         ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
3893                         if (ent->ent_lu == lu)
3894                                 break;
3895                 }
3896         } else {
3897                 n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
3898                 ent = (stmf_lun_map_ent_t *)
3899                     stmf_get_ent_from_map(iss->iss_sm, n);
3900                 if (lu && (ent->ent_lu != lu))
3901                         ent = NULL;
3902         }
3903         if (ent && ent->ent_itl_datap) {
3904                 *itl_handle_retp = ent->ent_itl_datap->itl_handle;
3905                 ret = STMF_SUCCESS;
3906         } else {
3907                 ret = STMF_NOT_FOUND;
3908         }
3909 
3910         rw_exit(iss->iss_lockp);
3911         return (ret);
3912 }
3913 
3914 stmf_data_buf_t *
3915 stmf_alloc_dbuf(scsi_task_t *task, uint32_t size, uint32_t *pminsize,
3916     uint32_t flags)
3917 {
3918         stmf_i_scsi_task_t *itask =
3919             (stmf_i_scsi_task_t *)task->task_stmf_private;
3920         stmf_local_port_t *lport = task->task_lport;
3921         stmf_data_buf_t *dbuf;
3922         uint8_t ndx;
3923 
3924         ndx = stmf_first_zero[itask->itask_allocated_buf_map];
3925         if (ndx == 0xff)
3926                 return (NULL);
3927         dbuf = itask->itask_dbufs[ndx] = lport->lport_ds->ds_alloc_data_buf(
3928             task, size, pminsize, flags);
3929         if (dbuf) {
3930                 task->task_cur_nbufs++;
3931                 itask->itask_allocated_buf_map |= (1 << ndx);
3932                 dbuf->db_flags &= ~DB_LPORT_XFER_ACTIVE;
3933                 dbuf->db_handle = ndx;
 
4027 
4028         /*
4029          * We allocate 7 extra bytes for CDB to provide a cdb pointer which
4030          * is guaranteed to be 8 byte aligned. Some LU providers like OSD
4031          * depend upon this alignment.
4032          */
4033         if (cdb_length_in >= 16)
4034                 cdb_length = cdb_length_in + 7;
4035         else
4036                 cdb_length = 16 + 7;
4037         iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4038         luNbr = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
4039         rw_enter(iss->iss_lockp, RW_READER);
4040         lun_map_ent =
4041             (stmf_lun_map_ent_t *)stmf_get_ent_from_map(iss->iss_sm, luNbr);
4042         if (!lun_map_ent) {
4043                 lu = dlun0;
4044         } else {
4045                 lu = lun_map_ent->ent_lu;
4046         }
4047         ilu = lu->lu_stmf_private;
4048         if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4049                 rw_exit(iss->iss_lockp);
4050                 return (NULL);
4051         }
4052         ASSERT(lu == dlun0 || (ilu->ilu_state != STMF_STATE_OFFLINING &&
4053             ilu->ilu_state != STMF_STATE_OFFLINE));
4054         do {
4055                 if (ilu->ilu_free_tasks == NULL) {
4056                         new_task = 1;
4057                         break;
4058                 }
4059                 mutex_enter(&ilu->ilu_task_lock);
4060                 for (ppitask = &ilu->ilu_free_tasks; (*ppitask != NULL) &&
4061                     ((*ppitask)->itask_cdb_buf_size < cdb_length);
4062                     ppitask = &((*ppitask)->itask_lu_free_next))
4063                         ;
4064                 if (*ppitask) {
4065                         itask = *ppitask;
4066                         *ppitask = (*ppitask)->itask_lu_free_next;
4067                         ilu->ilu_ntasks_free--;
4068                         if (ilu->ilu_ntasks_free < ilu->ilu_ntasks_min_free)
4069                                 ilu->ilu_ntasks_min_free = ilu->ilu_ntasks_free;
4070                 } else {
4071                         new_task = 1;
4072                 }
4073                 mutex_exit(&ilu->ilu_task_lock);
 
4081                  * selection process above.
4082                  */
4083                 uint8_t *save_cdb;
4084                 uintptr_t t_start, t_end;
4085 
4086                 task = itask->itask_task;
4087                 save_cdb = task->task_cdb;   /* save */
4088                 t_start = (uintptr_t)&task->task_flags;
4089                 t_end = (uintptr_t)&task->task_extended_cmd;
4090                 bzero((void *)t_start, (size_t)(t_end - t_start));
4091                 task->task_cdb = save_cdb;   /* restore */
4092                 itask->itask_ncmds = 0;
4093         } else {
4094                 task = (scsi_task_t *)stmf_alloc(STMF_STRUCT_SCSI_TASK,
4095                     cdb_length, AF_FORCE_NOSLEEP);
4096                 if (task == NULL) {
4097                         rw_exit(iss->iss_lockp);
4098                         return (NULL);
4099                 }
4100                 task->task_lu = lu;
4101                 l = task->task_lun_no;
4102                 l[0] = lun[0];
4103                 l[1] = lun[1];
4104                 l[2] = lun[2];
4105                 l[3] = lun[3];
4106                 l[4] = lun[4];
4107                 l[5] = lun[5];
4108                 l[6] = lun[6];
4109                 l[7] = lun[7];
4110                 task->task_cdb = (uint8_t *)task->task_port_private;
4111                 if ((ulong_t)(task->task_cdb) & 7ul) {
4112                         task->task_cdb = (uint8_t *)(((ulong_t)
4113                             (task->task_cdb) + 7ul) & ~(7ul));
4114                 }
4115                 itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
4116                 itask->itask_cdb_buf_size = cdb_length;
4117                 mutex_init(&itask->itask_audit_mutex, NULL, MUTEX_DRIVER, NULL);
4118         }
4119         task->task_session = ss;
4120         task->task_lport = lport;
4121         task->task_cdb_length = cdb_length_in;
4122         itask->itask_flags = ITASK_IN_TRANSITION;
4123         itask->itask_waitq_time = 0;
4124         itask->itask_lu_read_time = itask->itask_lu_write_time = 0;
4125         itask->itask_lport_read_time = itask->itask_lport_write_time = 0;
4126         itask->itask_read_xfer = itask->itask_write_xfer = 0;
4127         itask->itask_audit_index = 0;
4128 
4129         if (new_task) {
4130                 if (lu->lu_task_alloc(task) != STMF_SUCCESS) {
4131                         rw_exit(iss->iss_lockp);
4132                         stmf_free(task);
4133                         return (NULL);
4134                 }
4135                 mutex_enter(&ilu->ilu_task_lock);
4136                 if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4137                         mutex_exit(&ilu->ilu_task_lock);
4138                         rw_exit(iss->iss_lockp);
4139                         stmf_free(task);
4140                         return (NULL);
4141                 }
4142                 itask->itask_lu_next = ilu->ilu_tasks;
4143                 if (ilu->ilu_tasks)
4144                         ilu->ilu_tasks->itask_lu_prev = itask;
4145                 ilu->ilu_tasks = itask;
4146                 /* kmem_zalloc automatically makes itask->itask_lu_prev NULL */
4147                 ilu->ilu_ntasks++;
4148                 mutex_exit(&ilu->ilu_task_lock);
4149         }
4150 
4151         itask->itask_ilu_task_cntr = ilu->ilu_cur_task_cntr;
4152         atomic_inc_32(itask->itask_ilu_task_cntr);
4153         itask->itask_start_time = ddi_get_lbolt();
4154 
4155         if ((lun_map_ent != NULL) && ((itask->itask_itl_datap =
4156             lun_map_ent->ent_itl_datap) != NULL)) {
4157                 atomic_inc_32(&itask->itask_itl_datap->itl_counter);
4158                 task->task_lu_itl_handle = itask->itask_itl_datap->itl_handle;
4159         } else {
4160                 itask->itask_itl_datap = NULL;
4161                 task->task_lu_itl_handle = NULL;
4162         }
4163 
4164         rw_exit(iss->iss_lockp);
4165         return (task);
4166 }
4167 
4168 static void
4169 stmf_task_lu_free(scsi_task_t *task, stmf_i_scsi_session_t *iss)
4170 {
4171         stmf_i_scsi_task_t *itask =
4172             (stmf_i_scsi_task_t *)task->task_stmf_private;
4173         stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
4174 
4175         ASSERT(rw_lock_held(iss->iss_lockp));
4176         itask->itask_flags = ITASK_IN_FREE_LIST;
4177         itask->itask_proxy_msg_id = 0;
4178         mutex_enter(&ilu->ilu_task_lock);
4179         itask->itask_lu_free_next = ilu->ilu_free_tasks;
4180         ilu->ilu_free_tasks = itask;
4181         ilu->ilu_ntasks_free++;
4182         if (ilu->ilu_ntasks == ilu->ilu_ntasks_free)
4183                 cv_signal(&ilu->ilu_offline_pending_cv);
4184         mutex_exit(&ilu->ilu_task_lock);
4185         atomic_dec_32(itask->itask_ilu_task_cntr);
4186 }
4187 
4188 void
4189 stmf_task_lu_check_freelist(stmf_i_lu_t *ilu)
4190 {
4191         uint32_t        num_to_release, ndx;
4192         stmf_i_scsi_task_t *itask;
4193         stmf_lu_t       *lu = ilu->ilu_lu;
4194 
4195         ASSERT(ilu->ilu_ntasks_min_free <= ilu->ilu_ntasks_free);
4196 
4197         /* free half of the minimal free of the free tasks */
4198         num_to_release = (ilu->ilu_ntasks_min_free + 1) / 2;
4199         if (!num_to_release) {
4200                 return;
4201         }
4202         for (ndx = 0; ndx < num_to_release; ndx++) {
4203                 mutex_enter(&ilu->ilu_task_lock);
4204                 itask = ilu->ilu_free_tasks;
4205                 if (itask == NULL) {
 
4242                 if (!ilu->ilu_ntasks_min_free) {
4243                         ilu->ilu_ntasks_min_free = ilu->ilu_ntasks_free;
4244                         continue;
4245                 }
4246                 ilu->ilu_flags |= ILU_STALL_DEREGISTER;
4247                 mutex_exit(&stmf_state.stmf_lock);
4248                 stmf_task_lu_check_freelist(ilu);
4249                 /*
4250                  * we do not care about the accuracy of
4251                  * ilu_ntasks_min_free, so we don't lock here
4252                  */
4253                 ilu->ilu_ntasks_min_free = ilu->ilu_ntasks_free;
4254                 mutex_enter(&stmf_state.stmf_lock);
4255                 ilu->ilu_flags &= ~ILU_STALL_DEREGISTER;
4256                 cv_broadcast(&stmf_state.stmf_cv);
4257                 if (ddi_get_lbolt() >= endtime)
4258                         break;
4259         }
4260 }
4261 
4262 void
4263 stmf_do_ilu_timeouts(stmf_i_lu_t *ilu)
4264 {
4265         clock_t l = ddi_get_lbolt();
4266         clock_t ps = drv_usectohz(1000000);
4267         stmf_i_scsi_task_t *itask;
4268         scsi_task_t *task;
4269         uint32_t to;
4270 
4271         mutex_enter(&ilu->ilu_task_lock);
4272         for (itask = ilu->ilu_tasks; itask != NULL;
4273             itask = itask->itask_lu_next) {
4274                 if (itask->itask_flags & (ITASK_IN_FREE_LIST |
4275                     ITASK_BEING_ABORTED)) {
4276                         continue;
4277                 }
4278                 task = itask->itask_task;
4279                 if (task->task_timeout == 0)
4280                         to = stmf_default_task_timeout;
4281                 else
4282                         to = task->task_timeout;
4283                 if ((itask->itask_start_time + (to * ps)) > l)
4284                         continue;
4285                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
4286                     STMF_TIMEOUT, NULL);
4287         }
4288         mutex_exit(&ilu->ilu_task_lock);
4289 }
4290 
4291 /*
4292  * Called with stmf_lock held
4293  */
4294 void
4295 stmf_check_ilu_timing()
4296 {
4297         stmf_i_lu_t *ilu;
4298         clock_t endtime = ddi_get_lbolt() + drv_usectohz(10000);
4299 
4300         /* stmf_svc_ilu_timing may get changed after stmf_lock is released */
4301         while ((ilu = stmf_state.stmf_svc_ilu_timing) != NULL) {
4302                 stmf_state.stmf_svc_ilu_timing = ilu->ilu_next;
4303                 if (ilu->ilu_cur_task_cntr == (&ilu->ilu_task_cntr1)) {
4304                         if (ilu->ilu_task_cntr2 == 0) {
 
4319                 mutex_exit(&stmf_state.stmf_lock);
4320                 stmf_do_ilu_timeouts(ilu);
4321                 mutex_enter(&stmf_state.stmf_lock);
4322                 ilu->ilu_flags &= ~ILU_STALL_DEREGISTER;
4323                 cv_broadcast(&stmf_state.stmf_cv);
4324                 if (ddi_get_lbolt() >= endtime)
4325                         break;
4326         }
4327 }
4328 
4329 /*
4330  * Kills all tasks on a lu except tm_task
4331  */
4332 void
4333 stmf_task_lu_killall(stmf_lu_t *lu, scsi_task_t *tm_task, stmf_status_t s)
4334 {
4335         stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4336         stmf_i_scsi_task_t *itask;
4337 
4338         mutex_enter(&ilu->ilu_task_lock);
4339 
4340         for (itask = ilu->ilu_tasks; itask != NULL;
4341             itask = itask->itask_lu_next) {
4342                 if (itask->itask_flags & ITASK_IN_FREE_LIST)
4343                         continue;
4344                 if (itask->itask_task == tm_task)
4345                         continue;
4346                 stmf_abort(STMF_QUEUE_TASK_ABORT, itask->itask_task, s, NULL);
4347         }
4348         mutex_exit(&ilu->ilu_task_lock);
4349 }
4350 
4351 void
4352 stmf_free_task_bufs(stmf_i_scsi_task_t *itask, stmf_local_port_t *lport)
4353 {
4354         int i;
4355         uint8_t map;
4356 
4357         if ((map = itask->itask_allocated_buf_map) == 0)
4358                 return;
4359         for (i = 0; i < 4; i++) {
4360                 if (map & 1) {
4361                         stmf_data_buf_t *dbuf;
4362 
4363                         dbuf = itask->itask_dbufs[i];
 
4379                         } else {
4380                                 ASSERT(dbuf->db_lu_private == NULL);
4381                                 dbuf->db_lu_private = NULL;
4382                                 lport->lport_ds->ds_free_data_buf(
4383                                     lport->lport_ds, dbuf);
4384                         }
4385                 }
4386                 map >>= 1;
4387         }
4388         itask->itask_allocated_buf_map = 0;
4389 }
4390 
4391 void
4392 stmf_task_free(scsi_task_t *task)
4393 {
4394         stmf_local_port_t *lport = task->task_lport;
4395         stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
4396             task->task_stmf_private;
4397         stmf_i_scsi_session_t *iss = (stmf_i_scsi_session_t *)
4398             task->task_session->ss_stmf_private;
4399 
4400         stmf_task_audit(itask, TE_TASK_FREE, CMD_OR_IOF_NA, NULL);
4401 
4402         stmf_free_task_bufs(itask, lport);
4403         stmf_itl_task_done(itask);
4404         DTRACE_PROBE2(stmf__task__end, scsi_task_t *, task,
4405             hrtime_t,
4406             itask->itask_done_timestamp - itask->itask_start_timestamp);
4407         if (itask->itask_itl_datap) {
4408                 if (atomic_dec_32_nv(&itask->itask_itl_datap->itl_counter) ==
4409                     0) {
4410                         stmf_release_itl_handle(task->task_lu,
4411                             itask->itask_itl_datap);
4412                 }
4413         }
4414 
4415         rw_enter(iss->iss_lockp, RW_READER);
4416         lport->lport_task_free(task);
4417         if (itask->itask_worker) {
4418                 atomic_dec_32(&stmf_cur_ntasks);
4419                 atomic_dec_32(&itask->itask_worker->worker_ref_count);
4420         }
4421         /*
4422          * After calling stmf_task_lu_free, the task pointer can no longer
4423          * be trusted.
4424          */
4425         stmf_task_lu_free(task, iss);
4426         rw_exit(iss->iss_lockp);
4427 }
4428 
4429 void
4430 stmf_post_task(scsi_task_t *task, stmf_data_buf_t *dbuf)
4431 {
4432         stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
4433             task->task_stmf_private;
4434         stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
4435         int nv;
4436         uint32_t old, new;
4437         uint32_t ct;
4438         stmf_worker_t *w, *w1;
4439         uint8_t tm;
4440 
4441         if (task->task_max_nbufs > 4)
4442                 task->task_max_nbufs = 4;
4443         task->task_cur_nbufs = 0;
4444         /* Latest value of currently running tasks */
4445         ct = atomic_inc_32_nv(&stmf_cur_ntasks);
4446 
4447         /* Select the next worker using round robin */
4448         nv = (int)atomic_inc_32_nv((uint32_t *)&stmf_worker_sel_counter);
4449         if (nv >= stmf_nworkers_accepting_cmds) {
4450                 int s = nv;
4451                 do {
4452                         nv -= stmf_nworkers_accepting_cmds;
4453                 } while (nv >= stmf_nworkers_accepting_cmds);
4454                 if (nv < 0)
4455                         nv = 0;
4456                 /* Its ok if this cas fails */
4457                 (void) atomic_cas_32((uint32_t *)&stmf_worker_sel_counter,
4458                     s, nv);
4459         }
4460         w = &stmf_workers[nv];
4461 
4462         /*
4463          * A worker can be pinned by interrupt. So select the next one
4464          * if it has lower load.
4465          */
4466         if ((nv + 1) >= stmf_nworkers_accepting_cmds) {
4467                 w1 = stmf_workers;
4468         } else {
4469                 w1 = &stmf_workers[nv + 1];
4470         }
4471         if (w1->worker_queue_depth < w->worker_queue_depth)
4472                 w = w1;
4473 
4474         mutex_enter(&w->worker_lock);
4475         if (((w->worker_flags & STMF_WORKER_STARTED) == 0) ||
4476             (w->worker_flags & STMF_WORKER_TERMINATE)) {
4477                 /*
4478                  * Maybe we are in the middle of a change. Just go to
4479                  * the 1st worker.
4480                  */
4481                 mutex_exit(&w->worker_lock);
4482                 w = stmf_workers;
4483                 mutex_enter(&w->worker_lock);
4484         }
4485         itask->itask_worker = w;
4486         /*
4487          * Track max system load inside the worker as we already have the
4488          * worker lock (no point implementing another lock). The service
4489          * thread will do the comparisons and figure out the max overall
4490          * system load.
4491          */
4492         if (w->worker_max_sys_qdepth_pu < ct)
4493                 w->worker_max_sys_qdepth_pu = ct;
4494 
4495         do {
4496                 old = new = itask->itask_flags;
4497                 new |= ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE;
4498                 if (task->task_mgmt_function) {
4499                         tm = task->task_mgmt_function;
4500                         if ((tm == TM_TARGET_RESET) ||
4501                             (tm == TM_TARGET_COLD_RESET) ||
4502                             (tm == TM_TARGET_WARM_RESET)) {
4503                                 new |= ITASK_DEFAULT_HANDLING;
4504                         }
4505                 } else if (task->task_cdb[0] == SCMD_REPORT_LUNS) {
4506                         new |= ITASK_DEFAULT_HANDLING;
4507                 }
4508                 new &= ~ITASK_IN_TRANSITION;
4509         } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
4510 
4511         stmf_itl_task_start(itask);
4512 
4513         itask->itask_worker_next = NULL;
4514         if (w->worker_task_tail) {
4515                 w->worker_task_tail->itask_worker_next = itask;
4516         } else {
4517                 w->worker_task_head = itask;
4518         }
4519         w->worker_task_tail = itask;
4520         if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
4521                 w->worker_max_qdepth_pu = w->worker_queue_depth;
4522         }
4523         /* Measure task waitq time */
4524         itask->itask_waitq_enter_timestamp = gethrtime();
4525         atomic_inc_32(&w->worker_ref_count);
4526         itask->itask_cmd_stack[0] = ITASK_CMD_NEW_TASK;
4527         itask->itask_ncmds = 1;
4528         stmf_task_audit(itask, TE_TASK_START, CMD_OR_IOF_NA, dbuf);
4529         if (dbuf) {
4530                 itask->itask_allocated_buf_map = 1;
4531                 itask->itask_dbufs[0] = dbuf;
4532                 dbuf->db_handle = 0;
4533         } else {
4534                 itask->itask_allocated_buf_map = 0;
4535                 itask->itask_dbufs[0] = NULL;
4536         }
4537 
4538         if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0) {
4539                 w->worker_signal_timestamp = gethrtime();
4540                 DTRACE_PROBE2(worker__signal, stmf_worker_t *, w,
4541                     scsi_task_t *, task);
4542                 cv_signal(&w->worker_cv);
4543         }
4544         mutex_exit(&w->worker_lock);
4545 
4546         /*
4547          * This can only happen if during stmf_task_alloc(), ILU_RESET_ACTIVE
4548          * was set between checking of ILU_RESET_ACTIVE and clearing of the
4549          * ITASK_IN_FREE_LIST flag. Take care of these "sneaked-in" tasks here.
4550          */
4551         if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4552                 stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ABORTED, NULL);
4553         }
4554 }
4555 
4556 static void
4557 stmf_task_audit(stmf_i_scsi_task_t *itask,
4558     task_audit_event_t te, uint32_t cmd_or_iof, stmf_data_buf_t *dbuf)
4559 {
4560         stmf_task_audit_rec_t *ar;
4561 
4562         mutex_enter(&itask->itask_audit_mutex);
4563         ar = &itask->itask_audit_records[itask->itask_audit_index++];
4564         itask->itask_audit_index &= (ITASK_TASK_AUDIT_DEPTH - 1);
 
4580  * we will only call that entry point if ITASK_KNOWN_TO_LU was set.
4581  *
4582  * Same logic applies for the port.
4583  *
4584  * Also ITASK_BEING_ABORTED will not be allowed to set if both KNOWN_TO_LU
4585  * and KNOWN_TO_TGT_PORT are reset.
4586  *
4587  * +++++++++++++++++++++++++++++++++++++++++++++++
4588  */
4589 
4590 stmf_status_t
4591 stmf_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t ioflags)
4592 {
4593         stmf_status_t ret = STMF_SUCCESS;
4594 
4595         stmf_i_scsi_task_t *itask =
4596             (stmf_i_scsi_task_t *)task->task_stmf_private;
4597 
4598         stmf_task_audit(itask, TE_XFER_START, ioflags, dbuf);
4599 
4600         if (ioflags & STMF_IOF_LU_DONE) {
4601                 uint32_t new, old;
4602                 do {
4603                         new = old = itask->itask_flags;
4604                         if (new & ITASK_BEING_ABORTED)
4605                                 return (STMF_ABORTED);
4606                         new &= ~ITASK_KNOWN_TO_LU;
4607                 } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
4608         }
4609         if (itask->itask_flags & ITASK_BEING_ABORTED)
4610                 return (STMF_ABORTED);
4611 #ifdef  DEBUG
4612         if (!(ioflags & STMF_IOF_STATS_ONLY) && stmf_drop_buf_counter > 0) {
4613                 if (atomic_dec_32_nv(&stmf_drop_buf_counter) == 1)
4614                         return (STMF_SUCCESS);
4615         }
4616 #endif
4617 
4618         stmf_update_kstat_lu_io(task, dbuf);
4619         stmf_update_kstat_lport_io(task, dbuf);
4620         stmf_lport_xfer_start(itask, dbuf);
4621         if (ioflags & STMF_IOF_STATS_ONLY) {
4622                 stmf_lport_xfer_done(itask, dbuf);
4623                 return (STMF_SUCCESS);
4624         }
4625 
4626         dbuf->db_flags |= DB_LPORT_XFER_ACTIVE;
4627         ret = task->task_lport->lport_xfer_data(task, dbuf, ioflags);
4628 
4629         /*
4630          * Port provider may have already called the buffer callback in
4631          * which case dbuf->db_xfer_start_timestamp will be 0.
4632          */
4633         if (ret != STMF_SUCCESS) {
4634                 dbuf->db_flags &= ~DB_LPORT_XFER_ACTIVE;
4635                 if (dbuf->db_xfer_start_timestamp != 0)
4636                         stmf_lport_xfer_done(itask, dbuf);
4637         }
4638 
4639         return (ret);
4640 }
4641 
4642 void
4643 stmf_data_xfer_done(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t iof)
4644 {
4645         stmf_i_scsi_task_t *itask =
4646             (stmf_i_scsi_task_t *)task->task_stmf_private;
4647         stmf_i_local_port_t *ilport;
4648         stmf_worker_t *w = itask->itask_worker;
4649         uint32_t new, old;
4650         uint8_t update_queue_flags, free_it, queue_it;
4651 
4652         stmf_lport_xfer_done(itask, dbuf);
4653 
4654         stmf_task_audit(itask, TE_XFER_DONE, iof, dbuf);
4655 
4656         /* Guard against unexpected completions from the lport */
4657         if (dbuf->db_flags & DB_LPORT_XFER_ACTIVE) {
4658                 dbuf->db_flags &= ~DB_LPORT_XFER_ACTIVE;
4659         } else {
4660                 /*
4661                  * This should never happen.
4662                  */
4663                 ilport = task->task_lport->lport_stmf_private;
4664                 ilport->ilport_unexpected_comp++;
4665                 cmn_err(CE_PANIC, "Unexpected xfer completion task %p dbuf %p",
4666                     (void *)task, (void *)dbuf);
4667                 return;
4668         }
4669 
4670         mutex_enter(&w->worker_lock);
4671         do {
4672                 new = old = itask->itask_flags;
4673                 if (old & ITASK_BEING_ABORTED) {
4674                         mutex_exit(&w->worker_lock);
4675                         return;
4676                 }
4677                 free_it = 0;
4678                 if (iof & STMF_IOF_LPORT_DONE) {
4679                         new &= ~ITASK_KNOWN_TO_TGT_PORT;
4680                         task->task_completion_status = dbuf->db_xfer_status;
4681                         free_it = 1;
4682                 }
4683                 /*
4684                  * If the task is known to LU then queue it. But if
4685                  * it is already queued (multiple completions) then
4686                  * just update the buffer information by grabbing the
4687                  * worker lock. If the task is not known to LU,
4688                  * completed/aborted, then see if we need to
4689                  * free this task.
4690                  */
4691                 if (old & ITASK_KNOWN_TO_LU) {
4692                         free_it = 0;
4693                         update_queue_flags = 1;
4694                         if (old & ITASK_IN_WORKER_QUEUE) {
4695                                 queue_it = 0;
4696                         } else {
4697                                 queue_it = 1;
4698                                 new |= ITASK_IN_WORKER_QUEUE;
4699                         }
4700                 } else {
4701                         update_queue_flags = 0;
4702                         queue_it = 0;
4703                 }
4704         } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
4705 
4706         if (update_queue_flags) {
4707                 uint8_t cmd = (dbuf->db_handle << 5) | ITASK_CMD_DATA_XFER_DONE;
4708 
4709                 ASSERT(itask->itask_ncmds < ITASK_MAX_NCMDS);
4710                 itask->itask_cmd_stack[itask->itask_ncmds++] = cmd;
4711                 if (queue_it) {
4712                         itask->itask_worker_next = NULL;
4713                         if (w->worker_task_tail) {
4714                                 w->worker_task_tail->itask_worker_next = itask;
4715                         } else {
4716                                 w->worker_task_head = itask;
4717                         }
4718                         w->worker_task_tail = itask;
4719                         /* Measure task waitq time */
4720                         itask->itask_waitq_enter_timestamp = gethrtime();
4721                         if (++(w->worker_queue_depth) >
4722                             w->worker_max_qdepth_pu) {
4723                                 w->worker_max_qdepth_pu = w->worker_queue_depth;
4724                         }
4725                         if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0)
4726                                 cv_signal(&w->worker_cv);
4727                 }
4728         }
4729         mutex_exit(&w->worker_lock);
4730 
4731         if (free_it) {
4732                 if ((itask->itask_flags & (ITASK_KNOWN_TO_LU |
4733                     ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
4734                     ITASK_BEING_ABORTED)) == 0) {
4735                         stmf_task_free(task);
4736                 }
4737         }
4738 }
4739 
4740 stmf_status_t
4741 stmf_send_scsi_status(scsi_task_t *task, uint32_t ioflags)
4742 {
4743         DTRACE_PROBE1(scsi__send__status, scsi_task_t *, task);
4744 
4745         stmf_i_scsi_task_t *itask =
4746             (stmf_i_scsi_task_t *)task->task_stmf_private;
4747 
4748         stmf_task_audit(itask, TE_SEND_STATUS, ioflags, NULL);
4749 
4750         if (ioflags & STMF_IOF_LU_DONE) {
4751                 uint32_t new, old;
4752                 do {
4753                         new = old = itask->itask_flags;
4754                         if (new & ITASK_BEING_ABORTED)
4755                                 return (STMF_ABORTED);
4756                         new &= ~ITASK_KNOWN_TO_LU;
4757                 } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
4758         }
4759 
4760         if (!(itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT)) {
4761                 return (STMF_SUCCESS);
4762         }
4763 
4764         if (itask->itask_flags & ITASK_BEING_ABORTED)
4765                 return (STMF_ABORTED);
4766 
4767         if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
4768                 task->task_status_ctrl = 0;
4769                 task->task_resid = 0;
4770         } else if (task->task_cmd_xfer_length >
4771             task->task_expected_xfer_length) {
4772                 task->task_status_ctrl = TASK_SCTRL_OVER;
4773                 task->task_resid = task->task_cmd_xfer_length -
4774                     task->task_expected_xfer_length;
4775         } else if (task->task_nbytes_transferred <
4776             task->task_expected_xfer_length) {
4777                 task->task_status_ctrl = TASK_SCTRL_UNDER;
4778                 task->task_resid = task->task_expected_xfer_length -
4779                     task->task_nbytes_transferred;
4780         } else {
4781                 task->task_status_ctrl = 0;
4782                 task->task_resid = 0;
4783         }
4784         return (task->task_lport->lport_send_status(task, ioflags));
4785 }
4786 
4787 void
4788 stmf_send_status_done(scsi_task_t *task, stmf_status_t s, uint32_t iof)
4789 {
4790         stmf_i_scsi_task_t *itask =
4791             (stmf_i_scsi_task_t *)task->task_stmf_private;
4792         stmf_worker_t *w = itask->itask_worker;
4793         uint32_t new, old;
4794         uint8_t free_it, queue_it;
4795 
4796         stmf_task_audit(itask, TE_SEND_STATUS_DONE, iof, NULL);
4797 
4798         mutex_enter(&w->worker_lock);
4799         do {
4800                 new = old = itask->itask_flags;
4801                 if (old & ITASK_BEING_ABORTED) {
4802                         mutex_exit(&w->worker_lock);
4803                         return;
4804                 }
4805                 free_it = 0;
4806                 if (iof & STMF_IOF_LPORT_DONE) {
4807                         new &= ~ITASK_KNOWN_TO_TGT_PORT;
4808                         free_it = 1;
4809                 }
4810                 /*
4811                  * If the task is known to LU then queue it. But if
4812                  * it is already queued (multiple completions) then
4813                  * just update the buffer information by grabbing the
4814                  * worker lock. If the task is not known to LU,
4815                  * completed/aborted, then see if we need to
4816                  * free this task.
4817                  */
4818                 if (old & ITASK_KNOWN_TO_LU) {
4819                         free_it = 0;
4820                         queue_it = 1;
4821                         if (old & ITASK_IN_WORKER_QUEUE) {
4822                                 cmn_err(CE_PANIC, "status completion received"
4823                                     " when task is already in worker queue "
4824                                     " task = %p", (void *)task);
4825                         }
4826                         new |= ITASK_IN_WORKER_QUEUE;
4827                 } else {
4828                         queue_it = 0;
4829                 }
4830         } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
4831         task->task_completion_status = s;
4832 
4833 
4834         if (queue_it) {
4835                 ASSERT(itask->itask_ncmds < ITASK_MAX_NCMDS);
4836                 itask->itask_cmd_stack[itask->itask_ncmds++] =
4837                     ITASK_CMD_STATUS_DONE;
4838                 itask->itask_worker_next = NULL;
4839                 if (w->worker_task_tail) {
4840                         w->worker_task_tail->itask_worker_next = itask;
4841                 } else {
4842                         w->worker_task_head = itask;
4843                 }
4844                 w->worker_task_tail = itask;
4845                 /* Measure task waitq time */
4846                 itask->itask_waitq_enter_timestamp = gethrtime();
4847                 if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
4848                         w->worker_max_qdepth_pu = w->worker_queue_depth;
4849                 }
4850                 if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0)
4851                         cv_signal(&w->worker_cv);
4852         }
4853         mutex_exit(&w->worker_lock);
4854 
4855         if (free_it) {
4856                 if ((itask->itask_flags & (ITASK_KNOWN_TO_LU |
4857                     ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
4858                     ITASK_BEING_ABORTED)) == 0) {
4859                         stmf_task_free(task);
4860                 } else {
4861                         cmn_err(CE_PANIC, "LU is done with the task but LPORT "
4862                             " is not done, itask %p itask_flags %x",
4863                             (void *)itask, itask->itask_flags);
4864                 }
4865         }
4866 }
4867 
4868 void
4869 stmf_task_lu_done(scsi_task_t *task)
4870 {
4871         stmf_i_scsi_task_t *itask =
4872             (stmf_i_scsi_task_t *)task->task_stmf_private;
4873         stmf_worker_t *w = itask->itask_worker;
4874         uint32_t new, old;
4875 
4876         mutex_enter(&w->worker_lock);
4877         do {
4878                 new = old = itask->itask_flags;
4879                 if (old & ITASK_BEING_ABORTED) {
4880                         mutex_exit(&w->worker_lock);
4881                         return;
4882                 }
4883                 if (old & ITASK_IN_WORKER_QUEUE) {
4884                         cmn_err(CE_PANIC, "task_lu_done received"
4885                             " when task is in worker queue "
4886                             " task = %p", (void *)task);
4887                 }
4888                 new &= ~ITASK_KNOWN_TO_LU;
4889         } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
4890 
4891         mutex_exit(&w->worker_lock);
4892 
4893         if ((itask->itask_flags & (ITASK_KNOWN_TO_LU |
4894             ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
4895             ITASK_BEING_ABORTED)) == 0) {
4896                 stmf_task_free(task);
4897         } else {
4898                 cmn_err(CE_PANIC, "stmf_lu_done should be the last stage but "
4899                     " the task is still not done, task = %p", (void *)task);
4900         }
4901 }
4902 
4903 void
4904 stmf_queue_task_for_abort(scsi_task_t *task, stmf_status_t s)
4905 {
4906         stmf_i_scsi_task_t *itask =
4907             (stmf_i_scsi_task_t *)task->task_stmf_private;
4908         stmf_worker_t *w;
4909         uint32_t old, new;
4910 
4911         stmf_task_audit(itask, TE_TASK_ABORT, CMD_OR_IOF_NA, NULL);
4912 
4913         do {
4914                 old = new = itask->itask_flags;
4915                 if ((old & ITASK_BEING_ABORTED) ||
4916                     ((old & (ITASK_KNOWN_TO_TGT_PORT |
4917                     ITASK_KNOWN_TO_LU)) == 0)) {
4918                         return;
4919                 }
4920                 new |= ITASK_BEING_ABORTED;
4921         } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
4922         task->task_completion_status = s;
4923         itask->itask_start_time = ddi_get_lbolt();
4924 
4925         if (((w = itask->itask_worker) == NULL) ||
4926             (itask->itask_flags & ITASK_IN_TRANSITION)) {
4927                 return;
4928         }
4929 
4930         /* Queue it and get out */
4931         mutex_enter(&w->worker_lock);
4932         if (itask->itask_flags & ITASK_IN_WORKER_QUEUE) {
4933                 mutex_exit(&w->worker_lock);
4934                 return;
4935         }
4936         atomic_or_32(&itask->itask_flags, ITASK_IN_WORKER_QUEUE);
4937         itask->itask_worker_next = NULL;
4938         if (w->worker_task_tail) {
4939                 w->worker_task_tail->itask_worker_next = itask;
4940         } else {
4941                 w->worker_task_head = itask;
4942         }
4943         w->worker_task_tail = itask;
4944         if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
4945                 w->worker_max_qdepth_pu = w->worker_queue_depth;
4946         }
4947         if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0)
4948                 cv_signal(&w->worker_cv);
4949         mutex_exit(&w->worker_lock);
4950 }
4951 
4952 void
4953 stmf_abort(int abort_cmd, scsi_task_t *task, stmf_status_t s, void *arg)
4954 {
4955         stmf_i_scsi_task_t *itask = NULL;
4956         uint32_t old, new, f, rf;
4957 
4958         DTRACE_PROBE2(scsi__task__abort, scsi_task_t *, task,
4959             stmf_status_t, s);
4960 
4961         switch (abort_cmd) {
4962         case STMF_QUEUE_ABORT_LU:
4963                 stmf_task_lu_killall((stmf_lu_t *)arg, task, s);
4964                 return;
4965         case STMF_QUEUE_TASK_ABORT:
4966                 stmf_queue_task_for_abort(task, s);
4967                 return;
4968         case STMF_REQUEUE_TASK_ABORT_LPORT:
4969                 rf = ITASK_TGT_PORT_ABORT_CALLED;
4970                 f = ITASK_KNOWN_TO_TGT_PORT;
4971                 break;
4972         case STMF_REQUEUE_TASK_ABORT_LU:
4973                 rf = ITASK_LU_ABORT_CALLED;
4974                 f = ITASK_KNOWN_TO_LU;
4975                 break;
4976         default:
4977                 return;
4978         }
4979         itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
4980         f |= ITASK_BEING_ABORTED | rf;
4981         do {
4982                 old = new = itask->itask_flags;
4983                 if ((old & f) != f) {
4984                         return;
4985                 }
4986                 new &= ~rf;
4987         } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
4988 }
4989 
4990 void
4991 stmf_task_lu_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof)
4992 {
4993         char                     info[STMF_CHANGE_INFO_LEN];
4994         stmf_i_scsi_task_t      *itask = TASK_TO_ITASK(task);
4995         unsigned long long      st;
4996 
4997         stmf_task_audit(itask, TE_TASK_LU_ABORTED, iof, NULL);
4998 
4999         st = s; /* gcc fix */
5000         if ((s != STMF_ABORT_SUCCESS) && (s != STMF_NOT_FOUND)) {
5001                 (void) snprintf(info, sizeof (info),
5002                     "task %p, lu failed to abort ret=%llx", (void *)task, st);
5003         } else if ((iof & STMF_IOF_LU_DONE) == 0) {
5004                 (void) snprintf(info, sizeof (info),
5005                     "Task aborted but LU is not finished, task ="
5006                     "%p, s=%llx, iof=%x", (void *)task, st, iof);
5007         } else {
5008                 /*
5009                  * LU abort successfully
5010                  */
5011                 atomic_and_32(&itask->itask_flags, ~ITASK_KNOWN_TO_LU);
5012                 return;
5013         }
5014 
5015         stmf_abort_task_offline(task, 1, info);
5016 }
5017 
5018 void
5019 stmf_task_lport_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof)
5020 {
5021         char                    info[STMF_CHANGE_INFO_LEN];
5022         stmf_i_scsi_task_t      *itask = TASK_TO_ITASK(task);
5023         unsigned long long      st;
5024         uint32_t                old, new;
5025 
5026         stmf_task_audit(itask, TE_TASK_LPORT_ABORTED, iof, NULL);
5027 
5028         st = s;
5029         if ((s != STMF_ABORT_SUCCESS) && (s != STMF_NOT_FOUND)) {
5030                 (void) snprintf(info, sizeof (info),
5031                     "task %p, tgt port failed to abort ret=%llx", (void *)task,
5032                     st);
5033         } else if ((iof & STMF_IOF_LPORT_DONE) == 0) {
5034                 (void) snprintf(info, sizeof (info),
5035                     "Task aborted but tgt port is not finished, "
5036                     "task=%p, s=%llx, iof=%x", (void *)task, st, iof);
5037         } else {
5038                 /*
5039                  * LPORT abort successfully
5040                  */
5041                 do {
5042                         old = new = itask->itask_flags;
5043                         if (!(old & ITASK_KNOWN_TO_TGT_PORT))
5044                                 return;
5045                         new &= ~ITASK_KNOWN_TO_TGT_PORT;
5046                 } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
5047                 return;
5048         }
5049 
5050         stmf_abort_task_offline(task, 0, info);
5051 }
5052 
5053 stmf_status_t
5054 stmf_task_poll_lu(scsi_task_t *task, uint32_t timeout)
5055 {
5056         stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
5057             task->task_stmf_private;
5058         stmf_worker_t *w = itask->itask_worker;
5059         int i;
5060 
5061         ASSERT(itask->itask_flags & ITASK_KNOWN_TO_LU);
5062         mutex_enter(&w->worker_lock);
5063         if (itask->itask_ncmds >= ITASK_MAX_NCMDS) {
5064                 mutex_exit(&w->worker_lock);
5065                 return (STMF_BUSY);
5066         }
5067         for (i = 0; i < itask->itask_ncmds; i++) {
5068                 if (itask->itask_cmd_stack[i] == ITASK_CMD_POLL_LU) {
5069                         mutex_exit(&w->worker_lock);
5070                         return (STMF_SUCCESS);
5071                 }
5072         }
5073         itask->itask_cmd_stack[itask->itask_ncmds++] = ITASK_CMD_POLL_LU;
5074         if (timeout == ITASK_DEFAULT_POLL_TIMEOUT) {
5075                 itask->itask_poll_timeout = ddi_get_lbolt() + 1;
5076         } else {
5077                 clock_t t = drv_usectohz(timeout * 1000);
5078                 if (t == 0)
5079                         t = 1;
5080                 itask->itask_poll_timeout = ddi_get_lbolt() + t;
5081         }
5082         if ((itask->itask_flags & ITASK_IN_WORKER_QUEUE) == 0) {
5083                 itask->itask_worker_next = NULL;
5084                 if (w->worker_task_tail) {
5085                         w->worker_task_tail->itask_worker_next = itask;
5086                 } else {
5087                         w->worker_task_head = itask;
5088                 }
5089                 w->worker_task_tail = itask;
5090                 if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
5091                         w->worker_max_qdepth_pu = w->worker_queue_depth;
5092                 }
5093                 atomic_or_32(&itask->itask_flags, ITASK_IN_WORKER_QUEUE);
5094                 if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0)
5095                         cv_signal(&w->worker_cv);
5096         }
5097         mutex_exit(&w->worker_lock);
5098         return (STMF_SUCCESS);
5099 }
5100 
5101 stmf_status_t
5102 stmf_task_poll_lport(scsi_task_t *task, uint32_t timeout)
5103 {
5104         stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
5105             task->task_stmf_private;
5106         stmf_worker_t *w = itask->itask_worker;
5107         int i;
5108 
5109         ASSERT(itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT);
5110         mutex_enter(&w->worker_lock);
5111         if (itask->itask_ncmds >= ITASK_MAX_NCMDS) {
5112                 mutex_exit(&w->worker_lock);
5113                 return (STMF_BUSY);
5114         }
5115         for (i = 0; i < itask->itask_ncmds; i++) {
5116                 if (itask->itask_cmd_stack[i] == ITASK_CMD_POLL_LPORT) {
5117                         mutex_exit(&w->worker_lock);
5118                         return (STMF_SUCCESS);
5119                 }
5120         }
5121         itask->itask_cmd_stack[itask->itask_ncmds++] = ITASK_CMD_POLL_LPORT;
5122         if (timeout == ITASK_DEFAULT_POLL_TIMEOUT) {
5123                 itask->itask_poll_timeout = ddi_get_lbolt() + 1;
5124         } else {
5125                 clock_t t = drv_usectohz(timeout * 1000);
5126                 if (t == 0)
5127                         t = 1;
5128                 itask->itask_poll_timeout = ddi_get_lbolt() + t;
5129         }
5130         if ((itask->itask_flags & ITASK_IN_WORKER_QUEUE) == 0) {
5131                 itask->itask_worker_next = NULL;
5132                 if (w->worker_task_tail) {
5133                         w->worker_task_tail->itask_worker_next = itask;
5134                 } else {
5135                         w->worker_task_head = itask;
5136                 }
5137                 w->worker_task_tail = itask;
5138                 if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
5139                         w->worker_max_qdepth_pu = w->worker_queue_depth;
5140                 }
5141                 if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0)
5142                         cv_signal(&w->worker_cv);
5143         }
5144         mutex_exit(&w->worker_lock);
5145         return (STMF_SUCCESS);
5146 }
5147 
5148 void
5149 stmf_do_task_abort(scsi_task_t *task)
5150 {
5151         stmf_i_scsi_task_t      *itask = TASK_TO_ITASK(task);
5152         stmf_lu_t               *lu;
5153         stmf_local_port_t       *lport;
5154         unsigned long long       ret;
5155         uint32_t                 old, new;
5156         uint8_t                  call_lu_abort, call_port_abort;
5157         char                     info[STMF_CHANGE_INFO_LEN];
5158 
5159         lu = task->task_lu;
5160         lport = task->task_lport;
5161         do {
5162                 old = new = itask->itask_flags;
5163                 if ((old & (ITASK_KNOWN_TO_LU | ITASK_LU_ABORT_CALLED)) ==
5164                     ITASK_KNOWN_TO_LU) {
5165                         new |= ITASK_LU_ABORT_CALLED;
5166                         call_lu_abort = 1;
5167                 } else {
5168                         call_lu_abort = 0;
5169                 }
5170         } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
5171 
5172         if (call_lu_abort) {
5173                 if ((itask->itask_flags & ITASK_DEFAULT_HANDLING) == 0) {
5174                         ret = lu->lu_abort(lu, STMF_LU_ABORT_TASK, task, 0);
5175                 } else {
5176                         ret = dlun0->lu_abort(lu, STMF_LU_ABORT_TASK, task, 0);
5177                 }
5178                 if ((ret == STMF_ABORT_SUCCESS) || (ret == STMF_NOT_FOUND)) {
5179                         stmf_task_lu_aborted(task, ret, STMF_IOF_LU_DONE);
5180                 } else if (ret == STMF_BUSY) {
5181                         atomic_and_32(&itask->itask_flags,
5182                             ~ITASK_LU_ABORT_CALLED);
5183                 } else if (ret != STMF_SUCCESS) {
5184                         (void) snprintf(info, sizeof (info),
5185                             "Abort failed by LU %p, ret %llx", (void *)lu, ret);
5186                         stmf_abort_task_offline(task, 1, info);
5187                 }
5188         } else if (itask->itask_flags & ITASK_KNOWN_TO_LU) {
5189                 if (ddi_get_lbolt() > (itask->itask_start_time +
5190                     STMF_SEC2TICK(lu->lu_abort_timeout?
5191                     lu->lu_abort_timeout : ITASK_DEFAULT_ABORT_TIMEOUT))) {
5192                         (void) snprintf(info, sizeof (info),
5193                             "lu abort timed out");
5194                         stmf_abort_task_offline(itask->itask_task, 1, info);
5195                 }
5196         }
5197 
5198         do {
5199                 old = new = itask->itask_flags;
5200                 if ((old & (ITASK_KNOWN_TO_TGT_PORT |
5201                     ITASK_TGT_PORT_ABORT_CALLED)) == ITASK_KNOWN_TO_TGT_PORT) {
5202                         new |= ITASK_TGT_PORT_ABORT_CALLED;
5203                         call_port_abort = 1;
5204                 } else {
5205                         call_port_abort = 0;
5206                 }
5207         } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
5208         if (call_port_abort) {
5209                 ret = lport->lport_abort(lport, STMF_LPORT_ABORT_TASK, task, 0);
5210                 if ((ret == STMF_ABORT_SUCCESS) || (ret == STMF_NOT_FOUND)) {
5211                         stmf_task_lport_aborted(task, ret, STMF_IOF_LPORT_DONE);
5212                 } else if (ret == STMF_BUSY) {
5213                         atomic_and_32(&itask->itask_flags,
5214                             ~ITASK_TGT_PORT_ABORT_CALLED);
5215                 } else if (ret != STMF_SUCCESS) {
5216                         (void) snprintf(info, sizeof (info),
5217                             "Abort failed by tgt port %p ret %llx",
5218                             (void *)lport, ret);
5219                         stmf_abort_task_offline(task, 0, info);
5220                 }
5221         } else if (itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT) {
5222                 if (ddi_get_lbolt() > (itask->itask_start_time +
5223                     STMF_SEC2TICK(lport->lport_abort_timeout?
5224                     lport->lport_abort_timeout :
5225                     ITASK_DEFAULT_ABORT_TIMEOUT))) {
5226                         (void) snprintf(info, sizeof (info),
5227                             "lport abort timed out");
5228                         stmf_abort_task_offline(itask->itask_task, 0, info);
5229                 }
5230         }
5231 }
5232 
5233 stmf_status_t
5234 stmf_ctl(int cmd, void *obj, void *arg)
5235 {
5236         stmf_status_t                   ret;
5237         stmf_i_lu_t                     *ilu;
5238         stmf_i_local_port_t             *ilport;
5239         stmf_state_change_info_t        *ssci = (stmf_state_change_info_t *)arg;
5240 
5241         mutex_enter(&stmf_state.stmf_lock);
5242         ret = STMF_INVALID_ARG;
5243         if (cmd & STMF_CMD_LU_OP) {
5244                 ilu = stmf_lookup_lu((stmf_lu_t *)obj);
5245                 if (ilu == NULL) {
5246                         goto stmf_ctl_lock_exit;
5247                 }
5248                 DTRACE_PROBE3(lu__state__change,
5249                     stmf_lu_t *, ilu->ilu_lu,
5250                     int, cmd, stmf_state_change_info_t *, ssci);
 
5542         sdid->association = ID_IS_TARGET_PORT;
5543         sdid->ident_length = 20;
5544         /* Convert wwn value to "wwn.XXXXXXXXXXXXXXXX" format */
5545         (void) snprintf(wwn_str, sizeof (wwn_str),
5546             "wwn.%02X%02X%02X%02X%02X%02X%02X%02X",
5547             wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
5548         bcopy(wwn_str, (char *)sdid->ident, 20);
5549 }
5550 
5551 
5552 stmf_xfer_data_t *
5553 stmf_prepare_tpgs_data(uint8_t ilu_alua)
5554 {
5555         stmf_xfer_data_t *xd;
5556         stmf_i_local_port_t *ilport;
5557         uint8_t *p;
5558         uint32_t sz, asz, nports = 0, nports_standby = 0;
5559 
5560         mutex_enter(&stmf_state.stmf_lock);
5561         /* check if any ports are standby and create second group */
5562         for (ilport = stmf_state.stmf_ilportlist; ilport;
5563             ilport = ilport->ilport_next) {
5564                 if (ilport->ilport_standby == 1) {
5565                         nports_standby++;
5566                 } else {
5567                         nports++;
5568                 }
5569         }
5570 
5571         /* The spec only allows for 255 ports to be reported per group */
5572         nports = min(nports, 255);
5573         nports_standby = min(nports_standby, 255);
5574         sz = (nports * 4) + 12;
5575         if (nports_standby && ilu_alua) {
5576                 sz += (nports_standby * 4) + 8;
5577         }
5578         asz = sz + sizeof (*xd) - 4;
5579         xd = (stmf_xfer_data_t *)kmem_zalloc(asz, KM_NOSLEEP);
5580         if (xd == NULL) {
5581                 mutex_exit(&stmf_state.stmf_lock);
5582                 return (NULL);
5583         }
5584         xd->alloc_size = asz;
5585         xd->size_left = sz;
5586 
5587         p = xd->buf;
5588 
5589         *((uint32_t *)p) = BE_32(sz - 4);
5590         p += 4;
5591         p[0] = 0x80;    /* PREF */
5592         p[1] = 5;       /* AO_SUP, S_SUP */
5593         if (stmf_state.stmf_alua_node == 1) {
5594                 p[3] = 1;       /* Group 1 */
5595         } else {
5596                 p[3] = 0;       /* Group 0 */
5597         }
5598         p[7] = nports & 0xff;
5599         p += 8;
5600         for (ilport = stmf_state.stmf_ilportlist; ilport;
5601             ilport = ilport->ilport_next) {
5602                 if (ilport->ilport_standby == 1) {
5603                         continue;
5604                 }
5605                 ((uint16_t *)p)[1] = BE_16(ilport->ilport_rtpid);
5606                 p += 4;
5607         }
5608         if (nports_standby && ilu_alua) {
5609                 p[0] = 0x02;    /* Non PREF, Standby */
5610                 p[1] = 5;       /* AO_SUP, S_SUP */
5611                 if (stmf_state.stmf_alua_node == 1) {
5612                         p[3] = 0;       /* Group 0 */
5613                 } else {
5614                         p[3] = 1;       /* Group 1 */
5615                 }
5616                 p[7] = nports_standby & 0xff;
5617                 p += 8;
5618                 for (ilport = stmf_state.stmf_ilportlist; ilport;
5619                     ilport = ilport->ilport_next) {
5620                         if (ilport->ilport_standby == 0) {
5621                                 continue;
5622                         }
5623                         ((uint16_t *)p)[1] = BE_16(ilport->ilport_rtpid);
5624                         p += 4;
5625                 }
5626         }
5627 
5628         mutex_exit(&stmf_state.stmf_lock);
5629 
5630         return (xd);
5631 }
5632 
5633 struct scsi_devid_desc *
5634 stmf_scsilib_get_devid_desc(uint16_t rtpid)
5635 {
5636         scsi_devid_desc_t *devid = NULL;
5637         stmf_i_local_port_t *ilport;
5638 
5639         mutex_enter(&stmf_state.stmf_lock);
5640 
5641         for (ilport = stmf_state.stmf_ilportlist; ilport;
5642             ilport = ilport->ilport_next) {
5643                 if (ilport->ilport_rtpid == rtpid) {
5644                         scsi_devid_desc_t *id = ilport->ilport_lport->lport_id;
 
5845                         break;
5846                 }
5847         }
5848 
5849         page[2] = (m >> 8) & 0xff;
5850         page[3] = m & 0xff;
5851 
5852         return (n);
5853 }
5854 
5855 void
5856 stmf_scsilib_handle_report_tpgs(scsi_task_t *task, stmf_data_buf_t *dbuf)
5857 {
5858         stmf_i_scsi_task_t *itask =
5859             (stmf_i_scsi_task_t *)task->task_stmf_private;
5860         stmf_i_lu_t *ilu =
5861             (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
5862         stmf_xfer_data_t *xd;
5863         uint32_t sz, minsz;
5864 
5865         itask->itask_flags |= ITASK_DEFAULT_HANDLING;
5866         task->task_cmd_xfer_length =
5867             ((((uint32_t)task->task_cdb[6]) << 24) |
5868             (((uint32_t)task->task_cdb[7]) << 16) |
5869             (((uint32_t)task->task_cdb[8]) << 8) |
5870             ((uint32_t)task->task_cdb[9]));
5871 
5872         if (task->task_additional_flags &
5873             TASK_AF_NO_EXPECTED_XFER_LENGTH) {
5874                 task->task_expected_xfer_length =
5875                     task->task_cmd_xfer_length;
5876         }
5877 
5878         if (task->task_cmd_xfer_length == 0) {
5879                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
5880                 return;
5881         }
5882         if (task->task_cmd_xfer_length < 4) {
5883                 stmf_scsilib_send_status(task, STATUS_CHECK,
5884                     STMF_SAA_INVALID_FIELD_IN_CDB);
5885                 return;
5886         }
5887 
5888         sz = min(task->task_expected_xfer_length,
5889             task->task_cmd_xfer_length);
5890 
5891         xd = stmf_prepare_tpgs_data(ilu->ilu_alua);
5892 
5893         if (xd == NULL) {
5894                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
5895                     STMF_ALLOC_FAILURE, NULL);
5896                 return;
 
5962         /*
5963          * To sync with target reset, grab this lock. The LU is not going
5964          * anywhere as there is atleast one task pending (this task).
5965          */
5966         mutex_enter(&stmf_state.stmf_lock);
5967 
5968         if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
5969                 mutex_exit(&stmf_state.stmf_lock);
5970                 stmf_scsilib_send_status(task, STATUS_CHECK,
5971                     STMF_SAA_OPERATION_IN_PROGRESS);
5972                 return;
5973         }
5974         atomic_or_32(&ilu->ilu_flags, ILU_RESET_ACTIVE);
5975         mutex_exit(&stmf_state.stmf_lock);
5976 
5977         /*
5978          * Mark this task as the one causing LU reset so that we know who
5979          * was responsible for setting the ILU_RESET_ACTIVE. In case this
5980          * task itself gets aborted, we will clear ILU_RESET_ACTIVE.
5981          */
5982         itask->itask_flags |= ITASK_DEFAULT_HANDLING | ITASK_CAUSING_LU_RESET;
5983 
5984         /* Initiatiate abort on all commands on this LU except this one */
5985         stmf_abort(STMF_QUEUE_ABORT_LU, task, STMF_ABORTED, task->task_lu);
5986 
5987         /* Start polling on this task */
5988         if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
5989             != STMF_SUCCESS) {
5990                 stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ALLOC_FAILURE,
5991                     NULL);
5992                 return;
5993         }
5994 }
5995 
5996 void
5997 stmf_handle_target_reset(scsi_task_t *task)
5998 {
5999         stmf_i_scsi_task_t *itask;
6000         stmf_i_lu_t *ilu;
6001         stmf_i_scsi_session_t *iss;
6002         stmf_lun_map_t *lm;
 
6038                 ilu = (stmf_i_lu_t *)(lm_ent->ent_lu->lu_stmf_private);
6039                 if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
6040                         atomic_and_32(&iss->iss_flags, ~ISS_RESET_ACTIVE);
6041                         rw_exit(iss->iss_lockp);
6042                         mutex_exit(&stmf_state.stmf_lock);
6043                         stmf_scsilib_send_status(task, STATUS_CHECK,
6044                             STMF_SAA_OPERATION_IN_PROGRESS);
6045                         return;
6046                 }
6047         }
6048         if (lf == 0) {
6049                 /* No luns in this session */
6050                 atomic_and_32(&iss->iss_flags, ~ISS_RESET_ACTIVE);
6051                 rw_exit(iss->iss_lockp);
6052                 mutex_exit(&stmf_state.stmf_lock);
6053                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
6054                 return;
6055         }
6056 
6057         /* ok, start the damage */
6058         itask->itask_flags |= ITASK_DEFAULT_HANDLING |
6059             ITASK_CAUSING_TARGET_RESET;
6060         for (i = 0; i < lm->lm_nentries; i++) {
6061                 if (lm->lm_plus[i] == NULL)
6062                         continue;
6063                 lm_ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
6064                 ilu = (stmf_i_lu_t *)(lm_ent->ent_lu->lu_stmf_private);
6065                 atomic_or_32(&ilu->ilu_flags, ILU_RESET_ACTIVE);
6066         }
6067 
6068         for (i = 0; i < lm->lm_nentries; i++) {
6069                 if (lm->lm_plus[i] == NULL)
6070                         continue;
6071                 lm_ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
6072                 stmf_abort(STMF_QUEUE_ABORT_LU, task, STMF_ABORTED,
6073                     lm_ent->ent_lu);
6074         }
6075 
6076         rw_exit(iss->iss_lockp);
6077         mutex_exit(&stmf_state.stmf_lock);
6078 
6079         /* Start polling on this task */
 
6097             (task->task_cdb[0] == SCMD_INQUIRY)) {
6098                 rw_exit(iss->iss_lockp);
6099                 return (0);
6100         }
6101         atomic_and_32(&iss->iss_flags,
6102             ~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
6103         rw_exit(iss->iss_lockp);
6104 
6105         if (task->task_cdb[0] == SCMD_REPORT_LUNS) {
6106                 return (0);
6107         }
6108         stmf_scsilib_send_status(task, STATUS_CHECK,
6109             STMF_SAA_REPORT_LUN_DATA_HAS_CHANGED);
6110         return (1);
6111 }
6112 
6113 void
6114 stmf_worker_init()
6115 {
6116         uint32_t i;
6117 
6118         /* Make local copy of global tunables */
6119         stmf_i_max_nworkers = stmf_max_nworkers;
6120         stmf_i_min_nworkers = stmf_min_nworkers;
6121 
6122         ASSERT(stmf_workers == NULL);
6123         if (stmf_i_min_nworkers < 4) {
6124                 stmf_i_min_nworkers = 4;
6125         }
6126         if (stmf_i_max_nworkers < stmf_i_min_nworkers) {
6127                 stmf_i_max_nworkers = stmf_i_min_nworkers;
6128         }
6129         stmf_workers = (stmf_worker_t *)kmem_zalloc(
6130             sizeof (stmf_worker_t) * stmf_i_max_nworkers, KM_SLEEP);
6131         for (i = 0; i < stmf_i_max_nworkers; i++) {
6132                 stmf_worker_t *w = &stmf_workers[i];
6133                 mutex_init(&w->worker_lock, NULL, MUTEX_DRIVER, NULL);
6134                 cv_init(&w->worker_cv, NULL, CV_DRIVER, NULL);
6135         }
6136         stmf_worker_mgmt_delay = drv_usectohz(20 * 1000);
6137         stmf_workers_state = STMF_WORKERS_ENABLED;
6138 
6139         /* Workers will be started by stmf_worker_mgmt() */
6140 
6141         /* Lets wait for atleast one worker to start */
6142         while (stmf_nworkers_cur == 0)
6143                 delay(drv_usectohz(20 * 1000));
6144         stmf_worker_mgmt_delay = drv_usectohz(3 * 1000 * 1000);
6145 }
6146 
6147 stmf_status_t
6148 stmf_worker_fini()
6149 {
6150         int i;
6151         clock_t sb;
6152 
6153         if (stmf_workers_state == STMF_WORKERS_DISABLED)
6154                 return (STMF_SUCCESS);
6155         ASSERT(stmf_workers);
6156         stmf_workers_state = STMF_WORKERS_DISABLED;
6157         stmf_worker_mgmt_delay = drv_usectohz(20 * 1000);
6158         cv_signal(&stmf_state.stmf_cv);
6159 
6160         sb = ddi_get_lbolt() + drv_usectohz(10 * 1000 * 1000);
6161         /* Wait for all the threads to die */
6162         while (stmf_nworkers_cur != 0) {
6163                 if (ddi_get_lbolt() > sb) {
6164                         stmf_workers_state = STMF_WORKERS_ENABLED;
6165                         return (STMF_BUSY);
6166                 }
6167                 delay(drv_usectohz(100 * 1000));
6168         }
6169         for (i = 0; i < stmf_i_max_nworkers; i++) {
6170                 stmf_worker_t *w = &stmf_workers[i];
6171                 mutex_destroy(&w->worker_lock);
6172                 cv_destroy(&w->worker_cv);
6173         }
6174         kmem_free(stmf_workers, sizeof (stmf_worker_t) * stmf_i_max_nworkers);
6175         stmf_workers = NULL;
6176 
6177         return (STMF_SUCCESS);
6178 }
6179 
6180 void
6181 stmf_worker_task(void *arg)
6182 {
6183         stmf_worker_t *w;
6184         stmf_i_scsi_session_t *iss;
6185         scsi_task_t *task;
6186         stmf_i_scsi_task_t *itask;
6187         stmf_data_buf_t *dbuf;
6188         stmf_lu_t *lu;
6189         clock_t wait_timer = 0;
6190         clock_t wait_ticks, wait_delta = 0;
6191         uint32_t old, new;
6192         uint8_t curcmd;
6193         uint8_t abort_free;
6194         uint8_t wait_queue;
6195         uint8_t dec_qdepth;
6196 
6197         w = (stmf_worker_t *)arg;
6198         wait_ticks = drv_usectohz(10000);
6199 
6200         DTRACE_PROBE1(worker__create, stmf_worker_t, w);
6201         mutex_enter(&w->worker_lock);
6202         w->worker_flags |= STMF_WORKER_STARTED | STMF_WORKER_ACTIVE;
6203 stmf_worker_loop:;
6204         if ((w->worker_ref_count == 0) &&
6205             (w->worker_flags & STMF_WORKER_TERMINATE)) {
6206                 w->worker_flags &= ~(STMF_WORKER_STARTED |
6207                     STMF_WORKER_ACTIVE | STMF_WORKER_TERMINATE);
6208                 w->worker_tid = NULL;
6209                 mutex_exit(&w->worker_lock);
6210                 DTRACE_PROBE1(worker__destroy, stmf_worker_t, w);
6211                 thread_exit();
6212         }
6213         /* CONSTCOND */
6214         while (1) {
6215                 dec_qdepth = 0;
6216                 if (wait_timer && (ddi_get_lbolt() >= wait_timer)) {
6217                         wait_timer = 0;
6218                         wait_delta = 0;
6219                         if (w->worker_wait_head) {
6220                                 ASSERT(w->worker_wait_tail);
6221                                 if (w->worker_task_head == NULL)
6222                                         w->worker_task_head =
6223                                             w->worker_wait_head;
6224                                 else
6225                                         w->worker_task_tail->itask_worker_next =
6226                                             w->worker_wait_head;
6227                                 w->worker_task_tail = w->worker_wait_tail;
6228                                 w->worker_wait_head = w->worker_wait_tail =
6229                                     NULL;
6230                         }
6231                 }
6232                 if ((itask = w->worker_task_head) == NULL) {
6233                         break;
6234                 }
6235                 task = itask->itask_task;
6236                 DTRACE_PROBE2(worker__active, stmf_worker_t, w,
6237                     scsi_task_t *, task);
6238                 w->worker_task_head = itask->itask_worker_next;
6239                 if (w->worker_task_head == NULL)
6240                         w->worker_task_tail = NULL;
6241 
6242                 wait_queue = 0;
6243                 abort_free = 0;
6244                 if (itask->itask_ncmds > 0) {
6245                         curcmd = itask->itask_cmd_stack[itask->itask_ncmds - 1];
6246                 } else {
6247                         ASSERT(itask->itask_flags & ITASK_BEING_ABORTED);
6248                 }
6249                 do {
6250                         old = itask->itask_flags;
6251                         if (old & ITASK_BEING_ABORTED) {
6252                                 itask->itask_ncmds = 1;
6253                                 curcmd = itask->itask_cmd_stack[0] =
6254                                     ITASK_CMD_ABORT;
6255                                 goto out_itask_flag_loop;
6256                         } else if ((curcmd & ITASK_CMD_MASK) ==
6257                             ITASK_CMD_NEW_TASK) {
6258                                 /*
6259                                  * set ITASK_KSTAT_IN_RUNQ, this flag
6260                                  * will not reset until task completed
6261                                  */
6262                                 new = old | ITASK_KNOWN_TO_LU |
6263                                     ITASK_KSTAT_IN_RUNQ;
6264                         } else {
6265                                 goto out_itask_flag_loop;
6266                         }
6267                 } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
6268 
6269 out_itask_flag_loop:
6270 
6271                 /*
6272                  * Decide if this task needs to go to a queue and/or if
6273                  * we can decrement the itask_cmd_stack.
6274                  */
6275                 if (curcmd == ITASK_CMD_ABORT) {
6276                         if (itask->itask_flags & (ITASK_KNOWN_TO_LU |
6277                             ITASK_KNOWN_TO_TGT_PORT)) {
6278                                 wait_queue = 1;
6279                         } else {
6280                                 abort_free = 1;
6281                         }
6282                 } else if ((curcmd & ITASK_CMD_POLL) &&
6283                     (itask->itask_poll_timeout > ddi_get_lbolt())) {
6284                         wait_queue = 1;
6285                 }
6286 
6287                 if (wait_queue) {
 
6306                         w->worker_task_tail = itask;
6307                 } else {
6308                         atomic_and_32(&itask->itask_flags,
6309                             ~ITASK_IN_WORKER_QUEUE);
6310                         /*
6311                          * This is where the queue depth should go down by
6312                          * one but we delay that on purpose to account for
6313                          * the call into the provider. The actual decrement
6314                          * happens after the worker has done its job.
6315                          */
6316                         dec_qdepth = 1;
6317                         itask->itask_waitq_time +=
6318                             gethrtime() - itask->itask_waitq_enter_timestamp;
6319                 }
6320 
6321                 /* We made it here means we are going to call LU */
6322                 if ((itask->itask_flags & ITASK_DEFAULT_HANDLING) == 0)
6323                         lu = task->task_lu;
6324                 else
6325                         lu = dlun0;
6326                 dbuf = itask->itask_dbufs[ITASK_CMD_BUF_NDX(curcmd)];
6327                 mutex_exit(&w->worker_lock);
6328                 curcmd &= ITASK_CMD_MASK;
6329                 stmf_task_audit(itask, TE_PROCESS_CMD, curcmd, dbuf);
6330                 switch (curcmd) {
6331                 case ITASK_CMD_NEW_TASK:
6332                         iss = (stmf_i_scsi_session_t *)
6333                             task->task_session->ss_stmf_private;
6334                         stmf_itl_lu_new_task(itask);
6335                         if (iss->iss_flags & ISS_LUN_INVENTORY_CHANGED) {
6336                                 if (stmf_handle_cmd_during_ic(itask))
6337                                         break;
6338                         }
6339 #ifdef  DEBUG
6340                         if (stmf_drop_task_counter > 0) {
6341                                 if (atomic_dec_32_nv(&stmf_drop_task_counter)
6342                                     == 1)
6343                                         break;
6344                         }
6345 #endif
6346                         DTRACE_PROBE1(scsi__task__start, scsi_task_t *, task);
6347                         lu->lu_new_task(task, dbuf);
6348                         break;
6349                 case ITASK_CMD_DATA_XFER_DONE:
6350                         lu->lu_dbuf_xfer_done(task, dbuf);
6351                         break;
6352                 case ITASK_CMD_STATUS_DONE:
6353                         lu->lu_send_status_done(task);
6354                         break;
6355                 case ITASK_CMD_ABORT:
6356                         if (abort_free) {
6357                                 stmf_task_free(task);
6358                         } else {
6359                                 stmf_do_task_abort(task);
6360                         }
6361                         break;
6362                 case ITASK_CMD_POLL_LU:
6363                         if (!wait_queue) {
6364                                 lu->lu_task_poll(task);
6365                         }
6366                         break;
6367                 case ITASK_CMD_POLL_LPORT:
6368                         if (!wait_queue)
6369                                 task->task_lport->lport_task_poll(task);
6370                         break;
6371                 case ITASK_CMD_SEND_STATUS:
6372                 /* case ITASK_CMD_XFER_DATA: */
6373                         break;
6374                 }
6375                 mutex_enter(&w->worker_lock);
6376                 if (dec_qdepth) {
6377                         w->worker_queue_depth--;
6378                 }
6379         }
6380         if ((w->worker_flags & STMF_WORKER_TERMINATE) && (wait_timer == 0)) {
6381                 if (w->worker_ref_count == 0)
6382                         goto stmf_worker_loop;
6383                 else {
6384                         wait_timer = ddi_get_lbolt() + 1;
6385                         wait_delta = 1;
6386                 }
6387         }
6388         w->worker_flags &= ~STMF_WORKER_ACTIVE;
6389         if (wait_timer) {
6390                 DTRACE_PROBE1(worker__timed__sleep, stmf_worker_t, w);
6391                 (void) cv_reltimedwait(&w->worker_cv, &w->worker_lock,
6392                     wait_delta, TR_CLOCK_TICK);
6393         } else {
6394                 DTRACE_PROBE1(worker__sleep, stmf_worker_t, w);
6395                 cv_wait(&w->worker_cv, &w->worker_lock);
6396         }
6397         DTRACE_PROBE1(worker__wakeup, stmf_worker_t, w);
6398         w->worker_flags |= STMF_WORKER_ACTIVE;
6399         goto stmf_worker_loop;
6400 }
6401 
6402 void
6403 stmf_worker_mgmt()
6404 {
6405         int i;
6406         int workers_needed;
6407         uint32_t qd;
6408         clock_t tps, d = 0;
6409         uint32_t cur_max_ntasks = 0;
6410         stmf_worker_t *w;
6411 
6412         /* Check if we are trying to increase the # of threads */
6413         for (i = stmf_nworkers_cur; i < stmf_nworkers_needed; i++) {
6414                 if (stmf_workers[i].worker_flags & STMF_WORKER_STARTED) {
6415                         stmf_nworkers_cur++;
6416                         stmf_nworkers_accepting_cmds++;
6417                 } else {
6418                         /* Wait for transition to complete */
6419                         return;
6420                 }
6421         }
6422         /* Check if we are trying to decrease the # of workers */
6423         for (i = (stmf_nworkers_cur - 1); i >= stmf_nworkers_needed; i--) {
6424                 if ((stmf_workers[i].worker_flags & STMF_WORKER_STARTED) == 0) {
6425                         stmf_nworkers_cur--;
6426                         /*
6427                          * stmf_nworkers_accepting_cmds has already been
6428                          * updated by the request to reduce the # of workers.
6429                          */
6430                 } else {
6431                         /* Wait for transition to complete */
6432                         return;
6433                 }
6434         }
6435         /* Check if we are being asked to quit */
6436         if (stmf_workers_state != STMF_WORKERS_ENABLED) {
6437                 if (stmf_nworkers_cur) {
6438                         workers_needed = 0;
6439                         goto worker_mgmt_trigger_change;
6440                 }
6441                 return;
6442         }
6443         /* Check if we are starting */
6444         if (stmf_nworkers_cur < stmf_i_min_nworkers) {
6445                 workers_needed = stmf_i_min_nworkers;
6446                 goto worker_mgmt_trigger_change;
6447         }
6448 
6449         tps = drv_usectohz(1 * 1000 * 1000);
6450         if ((stmf_wm_last != 0) &&
6451             ((d = ddi_get_lbolt() - stmf_wm_last) > tps)) {
6452                 qd = 0;
6453                 for (i = 0; i < stmf_nworkers_accepting_cmds; i++) {
6454                         qd += stmf_workers[i].worker_max_qdepth_pu;
6455                         stmf_workers[i].worker_max_qdepth_pu = 0;
6456                         if (stmf_workers[i].worker_max_sys_qdepth_pu >
6457                             cur_max_ntasks) {
6458                                 cur_max_ntasks =
6459                                     stmf_workers[i].worker_max_sys_qdepth_pu;
6460                         }
6461                         stmf_workers[i].worker_max_sys_qdepth_pu = 0;
6462                 }
6463         }
6464         stmf_wm_last = ddi_get_lbolt();
6465         if (d <= tps) {
6466                 /* still ramping up */
6467                 return;
6468         }
6469         /* max qdepth cannot be more than max tasks */
6470         if (qd > cur_max_ntasks)
6471                 qd = cur_max_ntasks;
6472 
6473         /* See if we have more workers */
6474         if (qd < stmf_nworkers_accepting_cmds) {
6475                 /*
6476                  * Since we dont reduce the worker count right away, monitor
6477                  * the highest load during the scale_down_delay.
6478                  */
6479                 if (qd > stmf_worker_scale_down_qd)
6480                         stmf_worker_scale_down_qd = qd;
6481                 if (stmf_worker_scale_down_timer == 0) {
6482                         stmf_worker_scale_down_timer = ddi_get_lbolt() +
6483                             drv_usectohz(stmf_worker_scale_down_delay *
6484                             1000 * 1000);
6485                         return;
6486                 }
6487                 if (ddi_get_lbolt() < stmf_worker_scale_down_timer) {
6488                         return;
6489                 }
6490                 /* Its time to reduce the workers */
6491                 if (stmf_worker_scale_down_qd < stmf_i_min_nworkers)
6492                         stmf_worker_scale_down_qd = stmf_i_min_nworkers;
6493                 if (stmf_worker_scale_down_qd > stmf_i_max_nworkers)
6494                         stmf_worker_scale_down_qd = stmf_i_max_nworkers;
6495                 if (stmf_worker_scale_down_qd == stmf_nworkers_cur)
6496                         return;
6497                 workers_needed = stmf_worker_scale_down_qd;
6498                 stmf_worker_scale_down_qd = 0;
6499                 goto worker_mgmt_trigger_change;
6500         }
6501         stmf_worker_scale_down_qd = 0;
6502         stmf_worker_scale_down_timer = 0;
6503         if (qd > stmf_i_max_nworkers)
6504                 qd = stmf_i_max_nworkers;
6505         if (qd < stmf_i_min_nworkers)
6506                 qd = stmf_i_min_nworkers;
6507         if (qd == stmf_nworkers_cur)
6508                 return;
6509         workers_needed = qd;
6510         goto worker_mgmt_trigger_change;
6511 
6512         /* NOTREACHED */
6513         return;
6514 
6515 worker_mgmt_trigger_change:
6516         ASSERT(workers_needed != stmf_nworkers_cur);
6517         if (workers_needed > stmf_nworkers_cur) {
6518                 stmf_nworkers_needed = workers_needed;
6519                 for (i = stmf_nworkers_cur; i < workers_needed; i++) {
6520                         w = &stmf_workers[i];
6521                         w->worker_tid = thread_create(NULL, 0, stmf_worker_task,
6522                             (void *)&stmf_workers[i], 0, &p0, TS_RUN,
6523                             minclsyspri);
6524                 }
6525                 return;
6526         }
6527         /* At this point we know that we are decreasing the # of workers */
6528         stmf_nworkers_accepting_cmds = workers_needed;
6529         stmf_nworkers_needed = workers_needed;
6530         /* Signal the workers that its time to quit */
6531         for (i = (stmf_nworkers_cur - 1); i >= stmf_nworkers_needed; i--) {
6532                 w = &stmf_workers[i];
6533                 ASSERT(w && (w->worker_flags & STMF_WORKER_STARTED));
6534                 mutex_enter(&w->worker_lock);
6535                 w->worker_flags |= STMF_WORKER_TERMINATE;
6536                 if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0)
6537                         cv_signal(&w->worker_cv);
6538                 mutex_exit(&w->worker_lock);
6539         }
6540 }
6541 
6542 /*
6543  * Fills out a dbuf from stmf_xfer_data_t (contained in the db_lu_private).
6544  * If all the data has been filled out, frees the xd and makes
6545  * db_lu_private NULL.
6546  */
6547 void
6548 stmf_xd_to_dbuf(stmf_data_buf_t *dbuf, int set_rel_off)
6549 {
6550         stmf_xfer_data_t *xd;
6551         uint8_t *p;
6552         int i;
6553         uint32_t s;
6554 
6555         xd = (stmf_xfer_data_t *)dbuf->db_lu_private;
6556         dbuf->db_data_size = 0;
6557         if (set_rel_off)
6558                 dbuf->db_relative_offset = xd->size_done;
6559         for (i = 0; i < dbuf->db_sglist_length; i++) {
6560                 s = min(xd->size_left, dbuf->db_sglist[i].seg_length);
6561                 p = &xd->buf[xd->size_done];
 
6638                         stmf_abort(STMF_QUEUE_TASK_ABORT, task,
6639                             STMF_ALLOC_FAILURE, NULL);
6640                         return;
6641                 }
6642                 dbuf->db_lu_private = NULL;
6643 
6644                 p = dbuf->db_sglist[0].seg_addr;
6645 
6646                 /*
6647                  * Standard inquiry handling only.
6648                  */
6649 
6650                 bzero(p, inq_page_length + 5);
6651 
6652                 p[0] = DPQ_SUPPORTED | DTYPE_UNKNOWN;
6653                 p[2] = 5;
6654                 p[3] = 0x12;
6655                 p[4] = inq_page_length;
6656                 p[6] = 0x80;
6657 
6658                 (void) strncpy((char *)p+8, "SUN     ", 8);
6659                 (void) strncpy((char *)p+16, "COMSTAR          ", 16);
6660                 (void) strncpy((char *)p+32, "1.0 ", 4);
6661 
6662                 dbuf->db_data_size = sz;
6663                 dbuf->db_relative_offset = 0;
6664                 dbuf->db_flags = DB_DIRECTION_TO_RPORT;
6665                 (void) stmf_xfer_data(task, dbuf, 0);
6666 
6667                 return;
6668 
6669         case SCMD_REPORT_LUNS:
6670                 task->task_cmd_xfer_length =
6671                     ((((uint32_t)task->task_cdb[6]) << 24) |
6672                     (((uint32_t)task->task_cdb[7]) << 16) |
6673                     (((uint32_t)task->task_cdb[8]) << 8) |
6674                     ((uint32_t)task->task_cdb[9]));
6675 
6676                 if (task->task_additional_flags &
6677                     TASK_AF_NO_EXPECTED_XFER_LENGTH) {
6678                         task->task_expected_xfer_length =
6679                             task->task_cmd_xfer_length;
6680                 }
 
6850         case TM_CLEAR_TASK_SET:
6851         case TM_LUN_RESET:
6852                 (void) stmf_lun_reset_poll(task->task_lu, task, 0);
6853                 return;
6854         case TM_TARGET_RESET:
6855         case TM_TARGET_COLD_RESET:
6856         case TM_TARGET_WARM_RESET:
6857                 stmf_target_reset_poll(task);
6858                 return;
6859         }
6860 }
6861 
6862 /* ARGSUSED */
6863 void
6864 stmf_dlun0_ctl(struct stmf_lu *lu, int cmd, void *arg)
6865 {
6866         /* This function will never be called */
6867         cmn_err(CE_WARN, "stmf_dlun0_ctl called with cmd %x", cmd);
6868 }
6869 
6870 void
6871 stmf_dlun_init()
6872 {
6873         stmf_i_lu_t *ilu;
6874 
6875         dlun0 = stmf_alloc(STMF_STRUCT_STMF_LU, 0, 0);
6876         dlun0->lu_task_alloc = stmf_dlun0_task_alloc;
6877         dlun0->lu_new_task = stmf_dlun0_new_task;
6878         dlun0->lu_dbuf_xfer_done = stmf_dlun0_dbuf_done;
6879         dlun0->lu_send_status_done = stmf_dlun0_status_done;
6880         dlun0->lu_task_free = stmf_dlun0_task_free;
6881         dlun0->lu_abort = stmf_dlun0_abort;
6882         dlun0->lu_task_poll = stmf_dlun0_task_poll;
6883         dlun0->lu_ctl = stmf_dlun0_ctl;
6884 
6885         ilu = (stmf_i_lu_t *)dlun0->lu_stmf_private;
6886         ilu->ilu_cur_task_cntr = &ilu->ilu_task_cntr1;
6887 }
6888 
6889 stmf_status_t
6890 stmf_dlun_fini()
6891 {
6892         stmf_i_lu_t *ilu;
6893 
6894         ilu = (stmf_i_lu_t *)dlun0->lu_stmf_private;
6895 
6896         ASSERT(ilu->ilu_ntasks == ilu->ilu_ntasks_free);
6897         if (ilu->ilu_ntasks) {
6898                 stmf_i_scsi_task_t *itask, *nitask;
6899 
6900                 nitask = ilu->ilu_tasks;
6901                 do {
6902                         itask = nitask;
 
7127 {
7128         if (STMF_EVENT_ENABLED(ilport->ilport_event_hdl, eventid) &&
7129             (ilport->ilport_lport->lport_event_handler != NULL)) {
7130                 ilport->ilport_lport->lport_event_handler(
7131                     ilport->ilport_lport, eventid, arg, flags);
7132         }
7133 }
7134 
7135 /*
7136  * With the possibility of having multiple itl sessions pointing to the
7137  * same itl_kstat_info, the ilu_kstat_lock mutex is used to synchronize
7138  * the kstat update of the ilu_kstat_io, itl_kstat_taskq and itl_kstat_lu_xfer
7139  * statistics.
7140  */
7141 void
7142 stmf_itl_task_start(stmf_i_scsi_task_t *itask)
7143 {
7144         stmf_itl_data_t *itl = itask->itask_itl_datap;
7145         scsi_task_t     *task = itask->itask_task;
7146         stmf_i_lu_t     *ilu;
7147 
7148         if (itl == NULL || task->task_lu == dlun0)
7149                 return;
7150         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7151         itask->itask_start_timestamp = gethrtime();
7152         if (ilu->ilu_kstat_io != NULL) {
7153                 mutex_enter(ilu->ilu_kstat_io->ks_lock);
7154                 stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter);
7155                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7156         }
7157 
7158         stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_enter);
7159 }
7160 
7161 void
7162 stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask)
7163 {
7164         stmf_itl_data_t *itl = itask->itask_itl_datap;
7165         scsi_task_t     *task = itask->itask_task;
7166         stmf_i_lu_t     *ilu;
7167 
7168         if (itl == NULL || task->task_lu == dlun0)
7169                 return;
7170         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7171         if (ilu->ilu_kstat_io != NULL) {
7172                 mutex_enter(ilu->ilu_kstat_io->ks_lock);
7173                 stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq);
7174                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7175         }
7176 
7177         stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_to_runq);
7178 }
7179 
7180 void
7181 stmf_itl_task_done(stmf_i_scsi_task_t *itask)
7182 {
7183         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7184         scsi_task_t             *task = itask->itask_task;
7185         stmf_i_lu_t     *ilu;
7186 
7187         itask->itask_done_timestamp = gethrtime();
7188 
7189         if (itl == NULL || task->task_lu == dlun0)
7190                 return;
7191         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7192 
7193         if (ilu->ilu_kstat_io == NULL)
7194                 return;
7195 
7196         mutex_enter(ilu->ilu_kstat_io->ks_lock);
7197 
7198         if (itask->itask_flags & ITASK_KSTAT_IN_RUNQ) {
7199                 stmf_update_kstat_lu_q(task, kstat_runq_exit);
7200                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7201                 stmf_update_kstat_lport_q(task, kstat_runq_exit);
7202         } else {
7203                 stmf_update_kstat_lu_q(task, kstat_waitq_exit);
7204                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7205                 stmf_update_kstat_lport_q(task, kstat_waitq_exit);
7206         }
7207 }
7208 
7209 static void
7210 stmf_lport_xfer_start(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7211 {
7212         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7213 
7214         if (itl == NULL)
7215                 return;
7216 
7217         DTRACE_PROBE2(scsi__xfer__start, scsi_task_t *, itask->itask_task,
7218             stmf_data_buf_t *, dbuf);
7219 
7220         dbuf->db_xfer_start_timestamp = gethrtime();
7221 }
7222 
7223 static void
7224 stmf_lport_xfer_done(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7225 {
7226         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7227         hrtime_t                elapsed_time;
7228         uint64_t                xfer_size;
7229 
7230         if (itl == NULL)
7231                 return;
7232 
7233         xfer_size = (dbuf->db_xfer_status == STMF_SUCCESS) ?
7234             dbuf->db_data_size : 0;
7235 
7236         elapsed_time = gethrtime() - dbuf->db_xfer_start_timestamp;
7237         if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
7238                 atomic_add_64((uint64_t *)&itask->itask_lport_read_time,
7239                     elapsed_time);
7240                 atomic_add_64((uint64_t *)&itask->itask_read_xfer,
7241                     xfer_size);
7242         } else {
7243                 atomic_add_64((uint64_t *)&itask->itask_lport_write_time,
7244                     elapsed_time);
7245                 atomic_add_64((uint64_t *)&itask->itask_write_xfer,
7246                     xfer_size);
7247         }
7248 
7249         DTRACE_PROBE3(scsi__xfer__end, scsi_task_t *, itask->itask_task,
7250             stmf_data_buf_t *, dbuf, hrtime_t, elapsed_time);
7251 
7252         dbuf->db_xfer_start_timestamp = 0;
7253 }
7254 
7255 void
7256 stmf_svc_init()
7257 {
7258         if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
7259                 return;
7260         stmf_state.stmf_svc_tailp = &stmf_state.stmf_svc_active;
7261         stmf_state.stmf_svc_taskq = ddi_taskq_create(0, "STMF_SVC_TASKQ", 1,
7262             TASKQ_DEFAULTPRI, 0);
7263         (void) ddi_taskq_dispatch(stmf_state.stmf_svc_taskq,
7264             stmf_svc, 0, DDI_SLEEP);
7265 }
7266 
7267 stmf_status_t
7268 stmf_svc_fini()
7269 {
7270         uint32_t i;
7271 
7272         mutex_enter(&stmf_state.stmf_lock);
7273         if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED) {
7274                 stmf_state.stmf_svc_flags |= STMF_SVC_TERMINATE;
7275                 cv_signal(&stmf_state.stmf_cv);
7276         }
7277         mutex_exit(&stmf_state.stmf_lock);
7278 
7279         /* Wait for 5 seconds */
7280         for (i = 0; i < 500; i++) {
7281                 if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
7282                         delay(drv_usectohz(10000));
7283                 else
7284                         break;
7285         }
7286         if (i == 500)
7287                 return (STMF_BUSY);
7288 
7289         ddi_taskq_destroy(stmf_state.stmf_svc_taskq);
7290 
7291         return (STMF_SUCCESS);
7292 }
7293 
7294 struct stmf_svc_clocks {
7295         clock_t drain_start, drain_next;
7296         clock_t timing_start, timing_next;
7297         clock_t worker_delay;
7298 };
7299 
7300 /* ARGSUSED */
7301 void
7302 stmf_svc(void *arg)
7303 {
7304         stmf_svc_req_t *req;
7305         stmf_lu_t *lu;
7306         stmf_i_lu_t *ilu;
7307         stmf_local_port_t *lport;
7308         struct stmf_svc_clocks clks = { 0 };
7309 
7310         mutex_enter(&stmf_state.stmf_lock);
7311         stmf_state.stmf_svc_flags |= STMF_SVC_STARTED | STMF_SVC_ACTIVE;
7312 
7313         while (!(stmf_state.stmf_svc_flags & STMF_SVC_TERMINATE)) {
7314                 if (stmf_state.stmf_svc_active == NULL) {
7315                         stmf_svc_timeout(&clks);
7316                         continue;
7317                 }
7318 
7319                 /*
7320                  * Pop the front request from the active list.  After this,
7321                  * the request will no longer be referenced by global state,
7322                  * so it should be safe to access it without holding the
7323                  * stmf state lock.
7324                  */
7325                 req = stmf_state.stmf_svc_active;
7326                 stmf_state.stmf_svc_active = req->svc_next;
7327 
7328                 if (stmf_state.stmf_svc_active == NULL)
7329                         stmf_state.stmf_svc_tailp = &stmf_state.stmf_svc_active;
7330 
7331                 switch (req->svc_cmd) {
7332                 case STMF_CMD_LPORT_ONLINE:
7333                         /* Fallthrough */
7334                 case STMF_CMD_LPORT_OFFLINE:
7335                         mutex_exit(&stmf_state.stmf_lock);
7336                         lport = (stmf_local_port_t *)req->svc_obj;
7337                         lport->lport_ctl(lport, req->svc_cmd, &req->svc_info);
7338                         break;
7339                 case STMF_CMD_LU_ONLINE:
7340                         mutex_exit(&stmf_state.stmf_lock);
7341                         lu = (stmf_lu_t *)req->svc_obj;
7342                         lu->lu_ctl(lu, req->svc_cmd, &req->svc_info);
7343                         break;
7344                 case STMF_CMD_LU_OFFLINE:
7345                         /* Remove all mappings of this LU */
7346                         stmf_session_lu_unmapall((stmf_lu_t *)req->svc_obj);
7347                         /* Kill all the pending I/Os for this LU */
7348                         mutex_exit(&stmf_state.stmf_lock);
7349                         stmf_task_lu_killall((stmf_lu_t *)req->svc_obj, NULL,
7350                             STMF_ABORTED);
 
7381         if (stmf_state.stmf_nlus &&
7382             ((!clks->timing_next) || (ddi_get_lbolt() >= clks->timing_next))) {
7383                 if (!stmf_state.stmf_svc_ilu_timing) {
7384                         /* we are starting a new round */
7385                         stmf_state.stmf_svc_ilu_timing =
7386                             stmf_state.stmf_ilulist;
7387                         clks->timing_start = ddi_get_lbolt();
7388                 }
7389 
7390                 stmf_check_ilu_timing();
7391                 if (!stmf_state.stmf_svc_ilu_timing) {
7392                         /* we finished a complete round */
7393                         clks->timing_next =
7394                             clks->timing_start + drv_usectohz(5*1000*1000);
7395                 } else {
7396                         /* we still have some ilu items to check */
7397                         clks->timing_next =
7398                             ddi_get_lbolt() + drv_usectohz(1*1000*1000);
7399                 }
7400 
7401                 if (stmf_state.stmf_svc_active)
7402                         return;
7403         }
7404 
7405         /* Check if there are free tasks to clear */
7406         if (stmf_state.stmf_nlus &&
7407             ((!clks->drain_next) || (ddi_get_lbolt() >= clks->drain_next))) {
7408                 if (!stmf_state.stmf_svc_ilu_draining) {
7409                         /* we are starting a new round */
7410                         stmf_state.stmf_svc_ilu_draining =
7411                             stmf_state.stmf_ilulist;
7412                         clks->drain_start = ddi_get_lbolt();
7413                 }
7414 
7415                 stmf_check_freetask();
7416                 if (!stmf_state.stmf_svc_ilu_draining) {
7417                         /* we finished a complete round */
7418                         clks->drain_next =
7419                             clks->drain_start + drv_usectohz(10*1000*1000);
7420                 } else {
7421                         /* we still have some ilu items to check */
7422                         clks->drain_next =
7423                             ddi_get_lbolt() + drv_usectohz(1*1000*1000);
7424                 }
7425 
7426                 if (stmf_state.stmf_svc_active)
7427                         return;
7428         }
7429 
7430         /* Check if we need to run worker_mgmt */
7431         if (ddi_get_lbolt() > clks->worker_delay) {
7432                 stmf_worker_mgmt();
7433                 clks->worker_delay = ddi_get_lbolt() +
7434                     stmf_worker_mgmt_delay;
7435         }
7436 
7437         /* Check if any active session got its 1st LUN */
7438         if (stmf_state.stmf_process_initial_luns) {
7439                 int stmf_level = 0;
7440                 int port_level;
7441 
7442                 for (ilport = stmf_state.stmf_ilportlist; ilport;
7443                     ilport = next_ilport) {
7444                         int ilport_lock_held;
7445                         next_ilport = ilport->ilport_next;
7446 
7447                         if ((ilport->ilport_flags &
7448                             ILPORT_SS_GOT_INITIAL_LUNS) == 0)
7449                                 continue;
7450 
7451                         port_level = 0;
7452                         rw_enter(&ilport->ilport_lock, RW_READER);
7453                         ilport_lock_held = 1;
7454 
7455                         for (iss = ilport->ilport_ss_list; iss;
7456                             iss = iss->iss_next) {
 
7543         stmf_svc_req_t *req;
7544         int s;
7545 
7546         ASSERT(!mutex_owned(&stmf_state.stmf_lock));
7547         s = sizeof (stmf_svc_req_t);
7548         if (info->st_additional_info) {
7549                 s += strlen(info->st_additional_info) + 1;
7550         }
7551         req = kmem_zalloc(s, KM_SLEEP);
7552 
7553         req->svc_cmd = cmd;
7554         req->svc_obj = obj;
7555         req->svc_info.st_rflags = info->st_rflags;
7556         if (info->st_additional_info) {
7557                 req->svc_info.st_additional_info = (char *)(GET_BYTE_OFFSET(req,
7558                     sizeof (stmf_svc_req_t)));
7559                 (void) strcpy(req->svc_info.st_additional_info,
7560                     info->st_additional_info);
7561         }
7562         req->svc_req_alloc_size = s;
7563         req->svc_next = NULL;
7564 
7565         mutex_enter(&stmf_state.stmf_lock);
7566         *stmf_state.stmf_svc_tailp = req;
7567         stmf_state.stmf_svc_tailp = &req->svc_next;
7568         if ((stmf_state.stmf_svc_flags & STMF_SVC_ACTIVE) == 0) {
7569                 cv_signal(&stmf_state.stmf_cv);
7570         }
7571         mutex_exit(&stmf_state.stmf_lock);
7572 }
7573 
7574 static void
7575 stmf_svc_kill_obj_requests(void *obj)
7576 {
7577         stmf_svc_req_t *prev_req = NULL;
7578         stmf_svc_req_t *next_req;
7579         stmf_svc_req_t *req;
7580 
7581         ASSERT(mutex_owned(&stmf_state.stmf_lock));
7582 
7583         for (req = stmf_state.stmf_svc_active; req != NULL; req = next_req) {
7584                 next_req = req->svc_next;
7585 
7586                 if (req->svc_obj == obj) {
7587                         if (prev_req != NULL)
7588                                 prev_req->svc_next = next_req;
7589                         else
7590                                 stmf_state.stmf_svc_active = next_req;
7591 
7592                         if (next_req == NULL)
7593                                 stmf_state.stmf_svc_tailp = (prev_req != NULL) ?
7594                                     &prev_req->svc_next :
7595                                     &stmf_state.stmf_svc_active;
7596 
7597                         kmem_free(req, req->svc_req_alloc_size);
7598                 } else {
7599                         prev_req = req;
7600                 }
7601         }
7602 }
7603 
7604 void
7605 stmf_trace(caddr_t ident, const char *fmt, ...)
7606 {
7607         va_list args;
7608         char tbuf[160];
7609         int len;
7610 
7611         if (!stmf_trace_on)
7612                 return;
7613         len = snprintf(tbuf, 158, "%s:%07lu: ", ident ? ident : "",
7614             ddi_get_lbolt());
7615         va_start(args, fmt);
7616         len += vsnprintf(tbuf + len, 158 - len, fmt, args);
7617         va_end(args);
7618 
7619         if (len > 158) {
 
7625         mutex_enter(&trace_buf_lock);
7626         bcopy(tbuf, &stmf_trace_buf[trace_buf_curndx], len+1);
7627         trace_buf_curndx += len;
7628         if (trace_buf_curndx > (trace_buf_size - 320))
7629                 trace_buf_curndx = 0;
7630         mutex_exit(&trace_buf_lock);
7631 }
7632 
7633 void
7634 stmf_trace_clear()
7635 {
7636         if (!stmf_trace_on)
7637                 return;
7638         mutex_enter(&trace_buf_lock);
7639         trace_buf_curndx = 0;
7640         if (trace_buf_size > 0)
7641                 stmf_trace_buf[0] = 0;
7642         mutex_exit(&trace_buf_lock);
7643 }
7644 
7645 static void
7646 stmf_abort_task_offline(scsi_task_t *task, int offline_lu, char *info)
7647 {
7648         stmf_state_change_info_t        change_info;
7649         void                            *ctl_private;
7650         uint32_t                        ctl_cmd;
7651         int                             msg = 0;
7652 
7653         stmf_trace("FROM STMF", "abort_task_offline called for %s: %s",
7654             offline_lu ? "LU" : "LPORT", info ? info : "no additional info");
7655         change_info.st_additional_info = info;
7656         if (offline_lu) {
7657                 change_info.st_rflags = STMF_RFLAG_RESET |
7658                     STMF_RFLAG_LU_ABORT;
7659                 ctl_private = task->task_lu;
7660                 if (((stmf_i_lu_t *)
7661                     task->task_lu->lu_stmf_private)->ilu_state ==
7662                     STMF_STATE_ONLINE) {
7663                         msg = 1;
7664                 }
7665                 ctl_cmd = STMF_CMD_LU_OFFLINE;
7666         } else {
7667                 change_info.st_rflags = STMF_RFLAG_RESET |
7668                     STMF_RFLAG_LPORT_ABORT;
7669                 ctl_private = task->task_lport;
7670                 if (((stmf_i_local_port_t *)
7671                     task->task_lport->lport_stmf_private)->ilport_state ==
7672                     STMF_STATE_ONLINE) {
7673                         msg = 1;
7674                 }
7675                 ctl_cmd = STMF_CMD_LPORT_OFFLINE;
7676         }
7677 
7678         if (msg) {
7679                 stmf_trace(0, "Calling stmf_ctl to offline %s : %s",
7680                     offline_lu ? "LU" : "LPORT", info ? info :
7681                     "<no additional info>");
7682         }
7683         (void) stmf_ctl(ctl_cmd, ctl_private, &change_info);
7684 }
7685 
7686 static char
7687 stmf_ctoi(char c)
7688 {
7689         if ((c >= '0') && (c <= '9'))
7690                 c -= '0';
7691         else if ((c >= 'A') && (c <= 'F'))
7692                 c = c - 'A' + 10;
7693         else if ((c >= 'a') && (c <= 'f'))
7694                 c = c - 'a' + 10;
7695         else
7696                 c = -1;
7697         return (c);
7698 }
7699 
7700 /* Convert from Hex value in ASCII format to the equivalent bytes */
7701 static boolean_t
7702 stmf_base16_str_to_binary(char *c, int dplen, uint8_t *dp)
7703 {
 
7720 
7721 boolean_t
7722 stmf_scsilib_tptid_validate(scsi_transport_id_t *tptid, uint32_t total_sz,
7723                                 uint16_t *tptid_sz)
7724 {
7725         uint16_t tpd_len = SCSI_TPTID_SIZE;
7726 
7727         if (tptid_sz)
7728                 *tptid_sz = 0;
7729         if (total_sz < sizeof (scsi_transport_id_t))
7730                 return (B_FALSE);
7731 
7732         switch (tptid->protocol_id) {
7733 
7734         case PROTOCOL_FIBRE_CHANNEL:
7735                 /* FC Transport ID validation checks. SPC3 rev23, Table 284 */
7736                 if (total_sz < tpd_len || tptid->format_code != 0)
7737                         return (B_FALSE);
7738                 break;
7739 
7740         case PROTOCOL_iSCSI:
7741                 {
7742                 iscsi_transport_id_t    *iscsiid;
7743                 uint16_t                adn_len, name_len;
7744 
7745                 /* Check for valid format code, SPC3 rev 23 Table 288 */
7746                 if ((total_sz < tpd_len) ||
7747                     (tptid->format_code != 0 && tptid->format_code != 1))
7748                         return (B_FALSE);
7749 
7750                 iscsiid = (iscsi_transport_id_t *)tptid;
7751                 adn_len = READ_SCSI16(iscsiid->add_len, uint16_t);
7752                 tpd_len = sizeof (iscsi_transport_id_t) + adn_len - 1;
7753 
7754                 /*
7755                  * iSCSI Transport ID validation checks.
7756                  * As per SPC3 rev 23 Section 7.5.4.6 and Table 289 & Table 290
7757                  */
7758                 if (adn_len < 20 || (adn_len % 4 != 0))
7759                         return (B_FALSE);
7760 
 
7765                 /* If the format_code is 1 check for ISID seperator */
7766                 if ((tptid->format_code == 1) && (strstr(iscsiid->iscsi_name,
7767                     SCSI_TPTID_ISCSI_ISID_SEPERATOR) == NULL))
7768                         return (B_FALSE);
7769 
7770                 }
7771                 break;
7772 
7773         case PROTOCOL_SRP:
7774                 /* SRP Transport ID validation checks. SPC3 rev23, Table 287 */
7775                 if (total_sz < tpd_len || tptid->format_code != 0)
7776                         return (B_FALSE);
7777                 break;
7778 
7779         case PROTOCOL_PARALLEL_SCSI:
7780         case PROTOCOL_SSA:
7781         case PROTOCOL_IEEE_1394:
7782         case PROTOCOL_SAS:
7783         case PROTOCOL_ADT:
7784         case PROTOCOL_ATAPI:
7785         default:
7786                 {
7787                 stmf_dflt_scsi_tptid_t *dflttpd;
7788 
7789                 tpd_len = sizeof (stmf_dflt_scsi_tptid_t);
7790                 if (total_sz < tpd_len)
7791                         return (B_FALSE);
7792                 dflttpd = (stmf_dflt_scsi_tptid_t *)tptid;
7793                 tpd_len = tpd_len + SCSI_READ16(&dflttpd->ident_len) - 1;
7794                 if (total_sz < tpd_len)
7795                         return (B_FALSE);
7796                 }
7797                 break;
7798         }
7799         if (tptid_sz)
7800                 *tptid_sz = tpd_len;
7801         return (B_TRUE);
7802 }
7803 
7804 boolean_t
7805 stmf_scsilib_tptid_compare(scsi_transport_id_t *tpd1,
7806                                 scsi_transport_id_t *tpd2)
7807 {
7808         if ((tpd1->protocol_id != tpd2->protocol_id) ||
7809             (tpd1->format_code != tpd2->format_code))
7810                 return (B_FALSE);
7811 
7812         switch (tpd1->protocol_id) {
7813 
7814         case PROTOCOL_iSCSI:
7815                 {
7816                 iscsi_transport_id_t *iscsitpd1, *iscsitpd2;
7817                 uint16_t len;
7818 
7819                 iscsitpd1 = (iscsi_transport_id_t *)tpd1;
7820                 iscsitpd2 = (iscsi_transport_id_t *)tpd2;
7821                 len = SCSI_READ16(&iscsitpd1->add_len);
7822                 if ((memcmp(iscsitpd1->add_len, iscsitpd2->add_len, 2) != 0) ||
7823                     (memcmp(iscsitpd1->iscsi_name, iscsitpd2->iscsi_name, len)
7824                     != 0))
7825                         return (B_FALSE);
7826                 }
7827                 break;
7828 
7829         case PROTOCOL_SRP:
7830                 {
7831                 scsi_srp_transport_id_t *srptpd1, *srptpd2;
7832 
7833                 srptpd1 = (scsi_srp_transport_id_t *)tpd1;
7834                 srptpd2 = (scsi_srp_transport_id_t *)tpd2;
7835                 if (memcmp(srptpd1->srp_name, srptpd2->srp_name,
7836                     sizeof (srptpd1->srp_name)) != 0)
7837                         return (B_FALSE);
7838                 }
7839                 break;
7840 
7841         case PROTOCOL_FIBRE_CHANNEL:
7842                 {
7843                 scsi_fc_transport_id_t *fctpd1, *fctpd2;
7844 
7845                 fctpd1 = (scsi_fc_transport_id_t *)tpd1;
7846                 fctpd2 = (scsi_fc_transport_id_t *)tpd2;
7847                 if (memcmp(fctpd1->port_name, fctpd2->port_name,
7848                     sizeof (fctpd1->port_name)) != 0)
7849                         return (B_FALSE);
7850                 }
7851                 break;
7852 
7853         case PROTOCOL_PARALLEL_SCSI:
7854         case PROTOCOL_SSA:
7855         case PROTOCOL_IEEE_1394:
7856         case PROTOCOL_SAS:
7857         case PROTOCOL_ADT:
7858         case PROTOCOL_ATAPI:
7859         default:
7860                 {
7861                 stmf_dflt_scsi_tptid_t *dflt1, *dflt2;
7862                 uint16_t len;
7863 
7864                 dflt1 = (stmf_dflt_scsi_tptid_t *)tpd1;
7865                 dflt2 = (stmf_dflt_scsi_tptid_t *)tpd2;
7866                 len = SCSI_READ16(&dflt1->ident_len);
7867                 if ((memcmp(dflt1->ident_len, dflt2->ident_len, 2) != 0) ||
7868                     (memcmp(dflt1->ident, dflt2->ident, len) != 0))
7869                         return (B_FALSE);
7870                 }
7871                 break;
7872         }
7873         return (B_TRUE);
7874 }
7875 
7876 /*
7877  * Changes devid_desc to corresponding TransportID format
7878  * Returns :- pointer to stmf_remote_port_t
7879  * Note    :- Allocates continous memory for stmf_remote_port_t and TransportID,
 
7950                 ident_len = devid->ident_length;
7951                 sz = ALIGNED_TO_8BYTE_BOUNDARY(sizeof (stmf_dflt_scsi_tptid_t) +
7952                     ident_len - 1);
7953                 rpt = stmf_remote_port_alloc(sz);
7954                 rpt->rport_tptid->format_code = 0;
7955                 rpt->rport_tptid->protocol_id = devid->protocol_id;
7956                 dflt_tpd = (stmf_dflt_scsi_tptid_t *)rpt->rport_tptid;
7957                 SCSI_WRITE16(dflt_tpd->ident_len, ident_len);
7958                 (void) memcpy(dflt_tpd->ident, devid->ident, ident_len);
7959                 break;
7960         }
7961         return (rpt);
7962 
7963 devid_to_remote_port_fail:
7964         stmf_remote_port_free(rpt);
7965         return (NULL);
7966 
7967 }
7968 
7969 stmf_remote_port_t *
7970 stmf_remote_port_alloc(uint16_t tptid_sz) {
7971         stmf_remote_port_t *rpt;
7972         rpt = (stmf_remote_port_t *)kmem_zalloc(
7973             sizeof (stmf_remote_port_t) + tptid_sz, KM_SLEEP);
7974         rpt->rport_tptid_sz = tptid_sz;
7975         rpt->rport_tptid = (scsi_transport_id_t *)(rpt + 1);
7976         return (rpt);
7977 }
7978 
7979 void
7980 stmf_remote_port_free(stmf_remote_port_t *rpt)
7981 {
7982         /*
7983          * Note: stmf_scsilib_devid_to_remote_port() function allocates
7984          *      remote port structures for all transports in the same way, So
7985          *      it is safe to deallocate it in a protocol independent manner.
7986          *      If any of the allocation method changes, corresponding changes
7987          *      need to be made here too.
7988          */
7989         kmem_free(rpt, sizeof (stmf_remote_port_t) + rpt->rport_tptid_sz);
7990 }
 | 
   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright 2019 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2013 by Delphix. All rights reserved.
  28  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  29  */
  30 
  31 #include <sys/conf.h>
  32 #include <sys/file.h>
  33 #include <sys/ddi.h>
  34 #include <sys/sunddi.h>
  35 #include <sys/modctl.h>
  36 #include <sys/scsi/scsi.h>
  37 #include <sys/scsi/generic/persist.h>
  38 #include <sys/scsi/impl/scsi_reset_notify.h>
  39 #include <sys/disp.h>
  40 #include <sys/byteorder.h>
  41 #include <sys/atomic.h>
  42 #include <sys/ethernet.h>
  43 #include <sys/sdt.h>
  44 #include <sys/nvpair.h>
  45 #include <sys/zone.h>
  46 #include <sys/id_space.h>
 
 
 108 static void stmf_svc_kill_obj_requests(void *obj);
 109 static void stmf_svc_timeout(struct stmf_svc_clocks *);
 110 void stmf_check_freetask();
 111 void stmf_abort_target_reset(scsi_task_t *task);
 112 stmf_status_t stmf_lun_reset_poll(stmf_lu_t *lu, struct scsi_task *task,
 113                                                         int target_reset);
 114 void stmf_target_reset_poll(struct scsi_task *task);
 115 void stmf_handle_lun_reset(scsi_task_t *task);
 116 void stmf_handle_target_reset(scsi_task_t *task);
 117 void stmf_xd_to_dbuf(stmf_data_buf_t *dbuf, int set_rel_off);
 118 int stmf_load_ppd_ioctl(stmf_ppioctl_data_t *ppi, uint64_t *ppi_token,
 119     uint32_t *err_ret);
 120 int stmf_delete_ppd_ioctl(stmf_ppioctl_data_t *ppi);
 121 int stmf_get_ppd_ioctl(stmf_ppioctl_data_t *ppi, stmf_ppioctl_data_t *ppi_out,
 122     uint32_t *err_ret);
 123 void stmf_delete_ppd(stmf_pp_data_t *ppd);
 124 void stmf_delete_all_ppds();
 125 void stmf_trace_clear();
 126 void stmf_worker_init();
 127 stmf_status_t stmf_worker_fini();
 128 void stmf_worker_task(void *arg);
 129 static void stmf_task_lu_free(scsi_task_t *task, stmf_i_scsi_session_t *iss);
 130 static stmf_status_t stmf_ic_lu_reg(stmf_ic_reg_dereg_lun_msg_t *msg,
 131     uint32_t type);
 132 static stmf_status_t stmf_ic_lu_dereg(stmf_ic_reg_dereg_lun_msg_t *msg);
 133 static stmf_status_t stmf_ic_rx_scsi_status(stmf_ic_scsi_status_msg_t *msg);
 134 static stmf_status_t stmf_ic_rx_status(stmf_ic_status_msg_t *msg);
 135 static stmf_status_t stmf_ic_rx_scsi_data(stmf_ic_scsi_data_msg_t *msg);
 136 void stmf_task_lu_killall(stmf_lu_t *lu, scsi_task_t *tm_task, stmf_status_t s);
 137 
 138 /* pppt modhandle */
 139 ddi_modhandle_t pppt_mod;
 140 
 141 /* pppt modload imported functions */
 142 stmf_ic_reg_port_msg_alloc_func_t ic_reg_port_msg_alloc;
 143 stmf_ic_dereg_port_msg_alloc_func_t ic_dereg_port_msg_alloc;
 144 stmf_ic_reg_lun_msg_alloc_func_t ic_reg_lun_msg_alloc;
 145 stmf_ic_dereg_lun_msg_alloc_func_t ic_dereg_lun_msg_alloc;
 146 stmf_ic_lun_active_msg_alloc_func_t ic_lun_active_msg_alloc;
 147 stmf_ic_scsi_cmd_msg_alloc_func_t ic_scsi_cmd_msg_alloc;
 148 stmf_ic_scsi_data_xfer_done_msg_alloc_func_t ic_scsi_data_xfer_done_msg_alloc;
 149 stmf_ic_session_create_msg_alloc_func_t ic_session_reg_msg_alloc;
 150 stmf_ic_session_destroy_msg_alloc_func_t ic_session_dereg_msg_alloc;
 151 stmf_ic_tx_msg_func_t ic_tx_msg;
 152 stmf_ic_msg_free_func_t ic_msg_free;
 153 
 154 static void stmf_itl_task_start(stmf_i_scsi_task_t *itask);
 155 static void stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask);
 156 static void stmf_itl_task_done(stmf_i_scsi_task_t *itask);
 157 
 158 static void stmf_lport_xfer_start(stmf_i_scsi_task_t *itask,
 159     stmf_data_buf_t *dbuf);
 160 static void stmf_lport_xfer_done(stmf_i_scsi_task_t *itask,
 161     stmf_data_buf_t *dbuf);
 162 
 163 static void stmf_update_kstat_lu_q(scsi_task_t *, void());
 164 static void stmf_update_kstat_lport_q(scsi_task_t *, void());
 165 static void stmf_update_kstat_lu_io(scsi_task_t *, stmf_data_buf_t *);
 166 static void stmf_update_kstat_lport_io(scsi_task_t *, stmf_data_buf_t *);
 167 static hrtime_t stmf_update_rport_timestamps(hrtime_t *start_tstamp,
 168     hrtime_t *done_tstamp, stmf_i_scsi_task_t *itask);
 169 
 170 static int stmf_irport_compare(const void *void_irport1,
 171     const void *void_irport2);
 172 static void stmf_create_kstat_rport(stmf_i_remote_port_t *irport);
 173 static void stmf_destroy_kstat_rport(stmf_i_remote_port_t *irport);
 174 static int stmf_kstat_rport_update(kstat_t *ksp, int rw);
 175 static stmf_i_remote_port_t *stmf_irport_create(scsi_devid_desc_t *rport_devid);
 176 static void stmf_irport_destroy(stmf_i_remote_port_t *irport);
 177 static stmf_i_remote_port_t *stmf_irport_register(
 178     scsi_devid_desc_t *rport_devid);
 179 static stmf_i_remote_port_t *stmf_irport_lookup_locked(
 180     scsi_devid_desc_t *rport_devid);
 181 static void stmf_irport_deregister(stmf_i_remote_port_t *irport);
 182 
 183 extern struct mod_ops mod_driverops;
 184 
 185 /* =====[ Tunables ]===== */
 186 /* Internal tracing */
 187 volatile int    stmf_trace_on = 0;
 188 volatile int    stmf_trace_buf_size = (1 * 1024 * 1024);
 189 /*
 190  * The reason default task timeout is 75 is because we want the
 191  * host to timeout 1st and mostly host timeout is 60 seconds.
 192  */
 193 volatile int    stmf_default_task_timeout = 75;
 194 /*
 195  * Setting this to one means, you are responsible for config load and keeping
 196  * things in sync with persistent database.
 197  */
 198 volatile int    stmf_allow_modunload = 0;
 199 
 200 volatile int stmf_nworkers = 512;
 201 volatile int stmf_worker_warn = 0;
 202 
 203 /* === [ Debugging and fault injection ] === */
 204 #ifdef  DEBUG
 205 volatile int stmf_drop_task_counter = 0;
 206 volatile int stmf_drop_buf_counter = 0;
 207 
 208 #endif
 209 
 210 stmf_state_t            stmf_state;
 211 static stmf_lu_t        *dlun0;
 212 
 213 static uint8_t stmf_first_zero[] =
 214         { 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0xff };
 215 static uint8_t stmf_first_one[] =
 216         { 0xff, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
 217 
 218 static kmutex_t trace_buf_lock;
 219 static int      trace_buf_size;
 220 static int      trace_buf_curndx;
 221 caddr_t stmf_trace_buf;
 222 
 223 static enum {
 224         STMF_WORKERS_DISABLED = 0,
 225         STMF_WORKERS_ENABLING,
 226         STMF_WORKERS_ENABLED
 227 } stmf_workers_state = STMF_WORKERS_DISABLED;
 228 static kmutex_t stmf_worker_sel_mx;
 229 volatile uint32_t stmf_nworkers_cur = 0; /* # of workers currently running */
 230 static int stmf_worker_sel_counter = 0;
 231 static uint32_t stmf_cur_ntasks = 0;
 232 static clock_t stmf_wm_next = 0;
 233 static int stmf_nworkers_accepting_cmds;
 234 static stmf_worker_t *stmf_workers = NULL;
 235 static clock_t stmf_worker_scale_down_timer = 0;
 236 static int stmf_worker_scale_down_qd = 0;
 237 
 238 static struct cb_ops stmf_cb_ops = {
 239         stmf_open,                      /* open */
 240         stmf_close,                     /* close */
 241         nodev,                          /* strategy */
 242         nodev,                          /* print */
 243         nodev,                          /* dump */
 244         nodev,                          /* read */
 245         nodev,                          /* write */
 246         stmf_ioctl,                     /* ioctl */
 247         nodev,                          /* devmap */
 248         nodev,                          /* mmap */
 249         nodev,                          /* segmap */
 250         nochpoll,                       /* chpoll */
 251         ddi_prop_op,                    /* cb_prop_op */
 252         0,                              /* streamtab */
 253         D_NEW | D_MP,                   /* cb_flag */
 254         CB_REV,                         /* rev */
 255         nodev,                          /* aread */
 256         nodev                           /* awrite */
 257 };
 258 
 259 static struct dev_ops stmf_ops = {
 260         DEVO_REV,
 261         0,
 262         stmf_getinfo,
 263         nulldev,                /* identify */
 264         nulldev,                /* probe */
 265         stmf_attach,
 266         stmf_detach,
 267         nodev,                  /* reset */
 268         &stmf_cb_ops,
 269         NULL,                   /* bus_ops */
 270         NULL                    /* power */
 271 };
 272 
 273 
 274 #define STMF_MODULE_NAME        "stmf"
 275 
 276 #ifdef  DEBUG
 277 #define STMF_NAME               "COMSTAR STMF D " __DATE__ " " __TIME__
 278 #else
 279 #define STMF_NAME               "COMSTAR STMF"
 280 #endif
 281 
 282 static struct modldrv modldrv = {
 283         &mod_driverops,
 284         STMF_NAME,
 285         &stmf_ops
 286 };
 287 
 288 static struct modlinkage modlinkage = {
 289         MODREV_1,
 290         &modldrv,
 291         NULL
 292 };
 293 
 294 int
 295 _init(void)
 296 {
 297         int ret;
 298 
 299         ret = mod_install(&modlinkage);
 300         if (ret)
 301                 return (ret);
 302         stmf_trace_buf = kmem_zalloc(stmf_trace_buf_size, KM_SLEEP);
 303         trace_buf_size = stmf_trace_buf_size;
 304         trace_buf_curndx = 0;
 305         mutex_init(&trace_buf_lock, NULL, MUTEX_DRIVER, 0);
 306         mutex_init(&stmf_worker_sel_mx, NULL, MUTEX_ADAPTIVE, 0);
 307         bzero(&stmf_state, sizeof (stmf_state_t));
 308         /* STMF service is off by default */
 309         stmf_state.stmf_service_running = 0;
 310         /* default lu/lport states are online */
 311         stmf_state.stmf_default_lu_state = STMF_STATE_ONLINE;
 312         stmf_state.stmf_default_lport_state = STMF_STATE_ONLINE;
 313         mutex_init(&stmf_state.stmf_lock, NULL, MUTEX_DRIVER, NULL);
 314         cv_init(&stmf_state.stmf_cv, NULL, CV_DRIVER, NULL);
 315         stmf_session_counter = (uint64_t)ddi_get_lbolt();
 316         avl_create(&stmf_state.stmf_irportlist,
 317             stmf_irport_compare, sizeof (stmf_i_remote_port_t),
 318             offsetof(stmf_i_remote_port_t, irport_ln));
 319         stmf_state.stmf_ilport_inst_space =
 320             id_space_create("lport-instances", 0, MAX_ILPORT);
 321         stmf_state.stmf_irport_inst_space =
 322             id_space_create("rport-instances", 0, MAX_IRPORT);
 323         stmf_view_init();
 324         stmf_svc_init();
 325         stmf_dlun_init();
 326         return (ret);
 
 357         ret = mod_remove(&modlinkage);
 358         if (ret) {
 359                 stmf_svc_init();
 360                 stmf_dlun_init();
 361                 stmf_worker_init();
 362                 return (ret);
 363         }
 364 
 365         stmf_view_clear_config();
 366 
 367         while ((irport = avl_destroy_nodes(&stmf_state.stmf_irportlist,
 368             &avl_dest_cookie)) != NULL)
 369                 stmf_irport_destroy(irport);
 370         avl_destroy(&stmf_state.stmf_irportlist);
 371         id_space_destroy(stmf_state.stmf_ilport_inst_space);
 372         id_space_destroy(stmf_state.stmf_irport_inst_space);
 373 
 374         kmem_free(stmf_trace_buf, stmf_trace_buf_size);
 375         mutex_destroy(&trace_buf_lock);
 376         mutex_destroy(&stmf_state.stmf_lock);
 377         mutex_destroy(&stmf_worker_sel_mx);
 378         cv_destroy(&stmf_state.stmf_cv);
 379         return (ret);
 380 }
 381 
 382 int
 383 _info(struct modinfo *modinfop)
 384 {
 385         return (mod_info(&modlinkage, modinfop));
 386 }
 387 
 388 /* ARGSUSED */
 389 static int
 390 stmf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
 391 {
 392         switch (cmd) {
 393         case DDI_INFO_DEVT2DEVINFO:
 394                 *result = stmf_state.stmf_dip;
 395                 break;
 396         case DDI_INFO_DEVT2INSTANCE:
 397                 *result =
 
1643 find_task_from_msgid(uint8_t *lu_id, stmf_ic_msgid_t task_msgid)
1644 {
1645         stmf_i_lu_t *ilu;
1646         stmf_i_scsi_task_t *itask;
1647 
1648         mutex_enter(&stmf_state.stmf_lock);
1649         for (ilu = stmf_state.stmf_ilulist; ilu != NULL; ilu = ilu->ilu_next) {
1650                 if (bcmp(lu_id, ilu->ilu_lu->lu_id->ident, 16) == 0) {
1651                         break;
1652                 }
1653         }
1654 
1655         if (ilu == NULL) {
1656                 mutex_exit(&stmf_state.stmf_lock);
1657                 return (NULL);
1658         }
1659 
1660         mutex_enter(&ilu->ilu_task_lock);
1661         for (itask = ilu->ilu_tasks; itask != NULL;
1662             itask = itask->itask_lu_next) {
1663                 mutex_enter(&itask->itask_mutex);
1664                 if (itask->itask_flags & (ITASK_IN_FREE_LIST |
1665                     ITASK_BEING_ABORTED)) {
1666                         mutex_exit(&itask->itask_mutex);
1667                         continue;
1668                 }
1669                 mutex_exit(&itask->itask_mutex);
1670                 if (itask->itask_proxy_msg_id == task_msgid) {
1671                         break;
1672                 }
1673         }
1674         mutex_exit(&ilu->ilu_task_lock);
1675         mutex_exit(&stmf_state.stmf_lock);
1676 
1677         if (itask != NULL) {
1678                 return (itask->itask_task);
1679         } else {
1680                 /* task not found. Likely already aborted. */
1681                 return (NULL);
1682         }
1683 }
1684 
1685 /*
1686  * message received from pppt/ic
1687  */
1688 stmf_status_t
1689 stmf_msg_rx(stmf_ic_msg_t *msg)
 
1894         }
1895 
1896         if (ilport->ilport_proxy_registered == 0) {
1897                 return (STMF_FAILURE);
1898         }
1899 
1900         mutex_enter(&stmf_state.stmf_lock);
1901         itask->itask_proxy_msg_id = stmf_proxy_msg_id++;
1902         mutex_exit(&stmf_state.stmf_lock);
1903         itask->itask_proxy_dbuf = dbuf;
1904 
1905         /*
1906          * stmf will now take over the task handling for this task
1907          * but it still needs to be treated differently from other
1908          * default handled tasks, hence the ITASK_PROXY_TASK.
1909          * If this is a task management function, we're really just
1910          * duping the command to the peer. Set the TM bit so that
1911          * we can recognize this on return since we won't be completing
1912          * the proxied task in that case.
1913          */
1914         mutex_enter(&itask->itask_mutex);
1915         if (task->task_mgmt_function) {
1916                 itask->itask_proxy_msg_id |= MSG_ID_TM_BIT;
1917         } else {
1918                 if (itask->itask_flags & ITASK_BEING_ABORTED) {
1919                         mutex_exit(&itask->itask_mutex);
1920                         return (STMF_FAILURE);
1921                 }
1922                 itask->itask_flags |= ITASK_DEFAULT_HANDLING | ITASK_PROXY_TASK;
1923         }
1924         if (dbuf) {
1925                 ic_cmd_msg = ic_scsi_cmd_msg_alloc(itask->itask_proxy_msg_id,
1926                     task, dbuf->db_data_size, dbuf->db_sglist[0].seg_addr,
1927                     itask->itask_proxy_msg_id);
1928         } else {
1929                 ic_cmd_msg = ic_scsi_cmd_msg_alloc(itask->itask_proxy_msg_id,
1930                     task, 0, NULL, itask->itask_proxy_msg_id);
1931         }
1932         mutex_exit(&itask->itask_mutex);
1933         if (ic_cmd_msg) {
1934                 ic_ret = ic_tx_msg(ic_cmd_msg);
1935                 if (ic_ret == STMF_IC_MSG_SUCCESS) {
1936                         ret = STMF_SUCCESS;
1937                 }
1938         }
1939         return (ret);
1940 }
1941 
1942 
1943 stmf_status_t
1944 pppt_modload()
1945 {
1946         int error;
1947 
1948         if (pppt_mod == NULL && ((pppt_mod =
1949             ddi_modopen("drv/pppt", KRTLD_MODE_FIRST, &error)) == NULL)) {
1950                 cmn_err(CE_WARN, "Unable to load pppt");
1951                 return (STMF_FAILURE);
1952         }
 
2516         /*
2517          * User is requesting that the token be checked.
2518          * If there was another set after the user's get
2519          * it's an error
2520          */
2521         if (ppi->ppi_token_valid) {
2522                 if (ppi->ppi_token != ppd->ppd_token) {
2523                         *err_ret = STMF_IOCERR_PPD_UPDATED;
2524                         mutex_exit(&stmf_state.stmf_lock);
2525                         return (EINVAL);
2526                 }
2527         }
2528 
2529         if ((ret = nvlist_unpack((char *)ppi->ppi_data,
2530             (size_t)ppi->ppi_data_size, &nv, KM_NOSLEEP)) != 0) {
2531                 mutex_exit(&stmf_state.stmf_lock);
2532                 return (ret);
2533         }
2534 
2535         /* Free any existing lists and add this one to the ppd */
2536         if (ppd->ppd_nv)
2537                 nvlist_free(ppd->ppd_nv);
2538         ppd->ppd_nv = nv;
2539 
2540         /* set the token for writes */
2541         ppd->ppd_token++;
2542         /* return token to caller */
2543         if (ppi_token) {
2544                 *ppi_token = ppd->ppd_token;
2545         }
2546 
2547         /* If there is a provider registered, do the notifications */
2548         if (ppd->ppd_provider) {
2549                 uint32_t cb_flags = 0;
2550 
2551                 if (stmf_state.stmf_config_state == STMF_CONFIG_INIT)
2552                         cb_flags |= STMF_PCB_STMF_ONLINING;
2553                 if (ppi->ppi_lu_provider) {
2554                         ilp = (stmf_i_lu_provider_t *)ppd->ppd_provider;
2555                         if (ilp->ilp_lp->lp_cb == NULL)
2556                                 goto bail_out;
 
2589                 if (ppd->ppd_lu_provider) {
2590                         ((stmf_i_lu_provider_t *)
2591                             ppd->ppd_provider)->ilp_ppd = NULL;
2592                 } else {
2593                         ((stmf_i_port_provider_t *)
2594                             ppd->ppd_provider)->ipp_ppd = NULL;
2595                 }
2596                 ppd->ppd_provider = NULL;
2597         }
2598 
2599         for (pppd = &stmf_state.stmf_ppdlist; *pppd != NULL;
2600             pppd = &((*pppd)->ppd_next)) {
2601                 if (*pppd == ppd)
2602                         break;
2603         }
2604 
2605         if (*pppd == NULL)
2606                 return;
2607 
2608         *pppd = ppd->ppd_next;
2609         if (ppd->ppd_nv)
2610                 nvlist_free(ppd->ppd_nv);
2611 
2612         kmem_free(ppd, ppd->ppd_alloc_size);
2613 }
2614 
2615 int
2616 stmf_delete_ppd_ioctl(stmf_ppioctl_data_t *ppi)
2617 {
2618         stmf_pp_data_t *ppd;
2619         int ret = ENOENT;
2620 
2621         if ((ppi->ppi_lu_provider + ppi->ppi_port_provider) != 1) {
2622                 return (EINVAL);
2623         }
2624 
2625         mutex_enter(&stmf_state.stmf_lock);
2626 
2627         for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = ppd->ppd_next) {
2628                 if (ppi->ppi_lu_provider) {
2629                         if (!ppd->ppd_lu_provider)
 
2699 }
2700 
2701 void
2702 stmf_delete_all_ppds()
2703 {
2704         stmf_pp_data_t *ppd, *nppd;
2705 
2706         ASSERT(mutex_owned(&stmf_state.stmf_lock));
2707         for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = nppd) {
2708                 nppd = ppd->ppd_next;
2709                 stmf_delete_ppd(ppd);
2710         }
2711 }
2712 
2713 /*
2714  * 16 is the max string length of a protocol_ident, increase
2715  * the size if needed.
2716  */
2717 #define STMF_KSTAT_LU_SZ        (STMF_GUID_INPUT + 1 + 256)
2718 #define STMF_KSTAT_TGT_SZ       (256 * 2 + 16)
2719 #define STMF_KSTAT_RPORT_DATAMAX        (sizeof (stmf_kstat_rport_info_t) / \
2720                                             sizeof (kstat_named_t))
2721 
2722 /*
2723  * This array matches the Protocol Identifier in stmf_ioctl.h
2724  */
2725 #define MAX_PROTO_STR_LEN       32
2726 
2727 char *protocol_ident[PROTOCOL_ANY] = {
2728         "Fibre Channel",
2729         "Parallel SCSI",
2730         "SSA",
2731         "IEEE_1394",
2732         "SRP",
2733         "iSCSI",
2734         "SAS",
2735         "ADT",
2736         "ATAPI",
2737         "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"
2738 };
2739 
2740 /*
 
2778 }
2779 
2780 static void
2781 stmf_update_kstat_lport_io(scsi_task_t *task, stmf_data_buf_t *dbuf)
2782 {
2783         stmf_i_local_port_t     *ilp;
2784         kstat_io_t              *kip;
2785 
2786         ilp = (stmf_i_local_port_t *)task->task_lport->lport_stmf_private;
2787         if (ilp != NULL && ilp->ilport_kstat_io != NULL) {
2788                 kip = KSTAT_IO_PTR(ilp->ilport_kstat_io);
2789                 if (kip != NULL) {
2790                         mutex_enter(ilp->ilport_kstat_io->ks_lock);
2791                         STMF_UPDATE_KSTAT_IO(kip, dbuf);
2792                         mutex_exit(ilp->ilport_kstat_io->ks_lock);
2793                 }
2794         }
2795 }
2796 
2797 static void
2798 stmf_update_kstat_rport_io(scsi_task_t *task, stmf_data_buf_t *dbuf)
2799 {
2800         stmf_i_scsi_session_t   *iss;
2801         stmf_i_remote_port_t    *irport;
2802         kstat_io_t              *kip;
2803 
2804         iss = task->task_session->ss_stmf_private;
2805         irport = iss->iss_irport;
2806         if (irport->irport_kstat_io != NULL) {
2807                 kip = KSTAT_IO_PTR(irport->irport_kstat_io);
2808                 mutex_enter(irport->irport_kstat_io->ks_lock);
2809                 STMF_UPDATE_KSTAT_IO(kip, dbuf);
2810                 mutex_exit(irport->irport_kstat_io->ks_lock);
2811         }
2812 }
2813 
2814 static void
2815 stmf_update_kstat_rport_estat(scsi_task_t *task)
2816 {
2817         stmf_i_scsi_task_t              *itask;
2818         stmf_i_scsi_session_t           *iss;
2819         stmf_i_remote_port_t            *irport;
2820         stmf_kstat_rport_estat_t        *ks_estat;
2821         hrtime_t                        lat = 0;
2822         uint32_t                        n = 0;
2823 
2824         itask = task->task_stmf_private;
2825         iss = task->task_session->ss_stmf_private;
2826         irport = iss->iss_irport;
2827 
2828         if (irport->irport_kstat_estat == NULL)
2829                 return;
2830 
2831         ks_estat = (stmf_kstat_rport_estat_t *)KSTAT_NAMED_PTR(
2832             irport->irport_kstat_estat);
2833 
2834         mutex_enter(irport->irport_kstat_estat->ks_lock);
2835 
2836         if (task->task_flags & TF_READ_DATA)
2837                 n = atomic_dec_32_nv(&irport->irport_nread_tasks);
2838         else if (task->task_flags & TF_WRITE_DATA)
2839                 n = atomic_dec_32_nv(&irport->irport_nwrite_tasks);
2840 
2841         if (itask->itask_read_xfer > 0) {
2842                 ks_estat->i_nread_tasks.value.ui64++;
2843                 lat = stmf_update_rport_timestamps(
2844                     &irport->irport_rdstart_timestamp,
2845                     &irport->irport_rddone_timestamp, itask);
2846                 if (n == 0)
2847                         ks_estat->i_rport_read_latency.value.ui64 += lat;
2848         } else if ((itask->itask_write_xfer > 0) ||
2849             (task->task_flags & TF_INITIAL_BURST)) {
2850                 ks_estat->i_nwrite_tasks.value.ui64++;
2851                 lat = stmf_update_rport_timestamps(
2852                     &irport->irport_wrstart_timestamp,
2853                     &irport->irport_wrdone_timestamp, itask);
2854                 if (n == 0)
2855                         ks_estat->i_rport_write_latency.value.ui64 += lat;
2856         }
2857 
2858         if (n == 0) {
2859                 if (task->task_flags & TF_READ_DATA) {
2860                         irport->irport_rdstart_timestamp = LLONG_MAX;
2861                         irport->irport_rddone_timestamp = 0;
2862                 } else if (task->task_flags & TF_WRITE_DATA) {
2863                         irport->irport_wrstart_timestamp = LLONG_MAX;
2864                         irport->irport_wrdone_timestamp = 0;
2865                 }
2866         }
2867 
2868         mutex_exit(irport->irport_kstat_estat->ks_lock);
2869 }
2870 
2871 static hrtime_t
2872 stmf_update_rport_timestamps(hrtime_t *start_tstamp, hrtime_t *done_tstamp,
2873     stmf_i_scsi_task_t *itask)
2874 {
2875         *start_tstamp = MIN(*start_tstamp, itask->itask_start_timestamp);
2876         if ((*done_tstamp == 0) &&
2877             (itask->itask_xfer_done_timestamp == 0)) {
2878                 *done_tstamp = *start_tstamp;
2879         } else {
2880                 *done_tstamp = MAX(*done_tstamp,
2881                     itask->itask_xfer_done_timestamp);
2882         }
2883 
2884         return (*done_tstamp - *start_tstamp);
2885 }
2886 
2887 static void
2888 stmf_update_kstat_lu_io(scsi_task_t *task, stmf_data_buf_t *dbuf)
2889 {
2890         stmf_i_lu_t             *ilu;
2891         kstat_io_t              *kip;
2892 
2893         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
2894         if (ilu != NULL && ilu->ilu_kstat_io != NULL) {
2895                 kip = KSTAT_IO_PTR(ilu->ilu_kstat_io);
2896                 if (kip != NULL) {
2897                         mutex_enter(ilu->ilu_kstat_io->ks_lock);
2898                         STMF_UPDATE_KSTAT_IO(kip, dbuf);
2899                         mutex_exit(ilu->ilu_kstat_io->ks_lock);
2900                 }
2901         }
2902 }
2903 
2904 static void
2905 stmf_create_kstat_lu(stmf_i_lu_t *ilu)
2906 {
2907         char                            ks_nm[KSTAT_STRLEN];
 
3528         alloc_len = sizeof (*irport) + sizeof (scsi_devid_desc_t) +
3529             rport_devid->ident_length - 1;
3530         irport = kmem_zalloc(alloc_len, KM_NOSLEEP);
3531         if (irport == NULL) {
3532                 return (NULL);
3533         }
3534 
3535         irport->irport_instance =
3536             id_alloc_nosleep(stmf_state.stmf_irport_inst_space);
3537         if (irport->irport_instance == -1) {
3538                 kmem_free(irport, alloc_len);
3539                 return (NULL);
3540         }
3541 
3542         irport->irport_id =
3543             (struct scsi_devid_desc *)(irport + 1); /* Ptr. Arith. */
3544         bcopy(rport_devid, irport->irport_id,
3545             sizeof (scsi_devid_desc_t) + rport_devid->ident_length - 1);
3546         irport->irport_refcnt = 1;
3547         mutex_init(&irport->irport_mutex, NULL, MUTEX_DEFAULT, NULL);
3548         irport->irport_rdstart_timestamp = LLONG_MAX;
3549         irport->irport_wrstart_timestamp = LLONG_MAX;
3550 
3551         return (irport);
3552 }
3553 
3554 static void
3555 stmf_irport_destroy(stmf_i_remote_port_t *irport)
3556 {
3557         stmf_destroy_kstat_rport(irport);
3558         id_free(stmf_state.stmf_irport_inst_space, irport->irport_instance);
3559         mutex_destroy(&irport->irport_mutex);
3560         kmem_free(irport, sizeof (*irport) + sizeof (scsi_devid_desc_t) +
3561             irport->irport_id->ident_length - 1);
3562 }
3563 
3564 static void
3565 stmf_create_kstat_rport(stmf_i_remote_port_t *irport)
3566 {
3567         scsi_devid_desc_t *id = irport->irport_id;
3568         char ks_nm[KSTAT_STRLEN];
3569         stmf_kstat_rport_info_t *ks_info;
3570         stmf_kstat_rport_estat_t *ks_estat;
3571         char *ident = NULL;
3572 
3573         ks_info = kmem_zalloc(sizeof (*ks_info), KM_NOSLEEP);
3574         if (ks_info == NULL)
3575                 goto err_out;
3576 
3577         (void) snprintf(ks_nm, KSTAT_STRLEN, "stmf_rport_%"PRIxPTR"",
3578             (uintptr_t)irport);
3579         irport->irport_kstat_info = kstat_create(STMF_MODULE_NAME, 0,
3580             ks_nm, "misc", KSTAT_TYPE_NAMED,
3581             STMF_KSTAT_RPORT_DATAMAX - STMF_RPORT_INFO_LIMIT,
3582             KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_VAR_SIZE);
3583         if (irport->irport_kstat_info == NULL) {
3584                 kmem_free(ks_info, sizeof (*ks_info));
3585                 goto err_out;
3586         }
3587 
3588         irport->irport_kstat_info->ks_data = ks_info;
3589         irport->irport_kstat_info->ks_private = irport;
3590         irport->irport_kstat_info->ks_update = stmf_kstat_rport_update;
3591         ident = kmem_alloc(id->ident_length + 1, KM_NOSLEEP);
3592         if (ident == NULL) {
3593                 kstat_delete(irport->irport_kstat_info);
3594                 irport->irport_kstat_info = NULL;
3595                 kmem_free(ks_info, sizeof (*ks_info));
3596                 goto err_out;
3597         }
3598 
3599         (void) memcpy(ident, id->ident, id->ident_length);
3600         ident[id->ident_length] = '\0';
3601         kstat_named_init(&ks_info->i_rport_name, "name", KSTAT_DATA_STRING);
3602         kstat_named_init(&ks_info->i_protocol, "protocol",
3603             KSTAT_DATA_STRING);
3604 
3605         kstat_named_setstr(&ks_info->i_rport_name, ident);
3606         kstat_named_setstr(&ks_info->i_protocol,
3607             protocol_ident[irport->irport_id->protocol_id]);
3608         irport->irport_kstat_info->ks_lock = &irport->irport_mutex;
3609         irport->irport_info_dirty = B_TRUE;
3610         kstat_install(irport->irport_kstat_info);
3611 
3612         (void) snprintf(ks_nm, KSTAT_STRLEN, "stmf_rport_io_%"PRIxPTR"",
3613             (uintptr_t)irport);
3614         irport->irport_kstat_io = kstat_create(STMF_MODULE_NAME, 0, ks_nm,
3615             "io", KSTAT_TYPE_IO, 1, 0);
3616         if (irport->irport_kstat_io == NULL)
3617                 goto err_out;
3618 
3619         irport->irport_kstat_io->ks_lock = &irport->irport_mutex;
3620         kstat_install(irport->irport_kstat_io);
3621 
3622         (void) snprintf(ks_nm, KSTAT_STRLEN, "stmf_rport_st_%"PRIxPTR"",
3623             (uintptr_t)irport);
3624         irport->irport_kstat_estat = kstat_create(STMF_MODULE_NAME, 0, ks_nm,
3625             "misc", KSTAT_TYPE_NAMED,
3626             sizeof (*ks_estat) / sizeof (kstat_named_t), 0);
3627         if (irport->irport_kstat_estat == NULL)
3628                 goto err_out;
3629 
3630         ks_estat = (stmf_kstat_rport_estat_t *)KSTAT_NAMED_PTR(
3631             irport->irport_kstat_estat);
3632         kstat_named_init(&ks_estat->i_rport_read_latency,
3633             "rlatency", KSTAT_DATA_UINT64);
3634         kstat_named_init(&ks_estat->i_rport_write_latency,
3635             "wlatency", KSTAT_DATA_UINT64);
3636         kstat_named_init(&ks_estat->i_nread_tasks, "rntasks",
3637             KSTAT_DATA_UINT64);
3638         kstat_named_init(&ks_estat->i_nwrite_tasks, "wntasks",
3639             KSTAT_DATA_UINT64);
3640         irport->irport_kstat_estat->ks_lock = &irport->irport_mutex;
3641         kstat_install(irport->irport_kstat_estat);
3642 
3643         return;
3644 
3645 err_out:
3646         (void) memcpy(ks_nm, id->ident, MAX(KSTAT_STRLEN - 1,
3647             id->ident_length));
3648         ks_nm[id->ident_length] = '\0';
3649         cmn_err(CE_WARN, "STMF: remote port kstat creation failed: %s", ks_nm);
3650 }
3651 
3652 static void
3653 stmf_destroy_kstat_rport(stmf_i_remote_port_t *irport)
3654 {
3655         if (irport->irport_kstat_io != NULL) {
3656                 kstat_delete(irport->irport_kstat_io);
3657         }
3658         if (irport->irport_kstat_info != NULL) {
3659                 stmf_kstat_rport_info_t *ks_info;
3660                 kstat_named_t *knp;
3661                 void *ptr;
3662                 int i;
3663 
3664                 ks_info = (stmf_kstat_rport_info_t *)KSTAT_NAMED_PTR(
3665                     irport->irport_kstat_info);
3666                 kstat_delete(irport->irport_kstat_info);
3667                 ptr = KSTAT_NAMED_STR_PTR(&ks_info->i_rport_name);
3668                 kmem_free(ptr, KSTAT_NAMED_STR_BUFLEN(&ks_info->i_rport_name));
3669 
3670                 for (i = 0, knp = ks_info->i_rport_uinfo;
3671                     i < STMF_RPORT_INFO_LIMIT; i++, knp++) {
3672                         ptr = KSTAT_NAMED_STR_PTR(knp);
3673                         if (ptr != NULL)
3674                         kmem_free(ptr, KSTAT_NAMED_STR_BUFLEN(knp));
3675                 }
3676                 kmem_free(ks_info, sizeof (*ks_info));
3677         }
3678 }
3679 
3680 static stmf_i_remote_port_t *
3681 stmf_irport_register(scsi_devid_desc_t *rport_devid)
3682 {
3683         stmf_i_remote_port_t    *irport;
3684 
3685         mutex_enter(&stmf_state.stmf_lock);
3686 
3687         /*
3688          * Lookup will bump the refcnt if there's an existing rport
3689          * context for this identifier.
3690          */
3691         if ((irport = stmf_irport_lookup_locked(rport_devid)) != NULL) {
3692                 mutex_exit(&stmf_state.stmf_lock);
3693                 return (irport);
3694         }
3695 
3696         irport = stmf_irport_create(rport_devid);
3697         if (irport == NULL) {
3698                 mutex_exit(&stmf_state.stmf_lock);
3699                 return (NULL);
3700         }
3701 
3702         stmf_create_kstat_rport(irport);
3703         avl_add(&stmf_state.stmf_irportlist, irport);
3704         mutex_exit(&stmf_state.stmf_lock);
3705 
3706         return (irport);
3707 }
3708 
3709 static stmf_i_remote_port_t *
3710 stmf_irport_lookup_locked(scsi_devid_desc_t *rport_devid)
3711 {
3712         stmf_i_remote_port_t    *irport;
3713         stmf_i_remote_port_t    tmp_irport;
3714 
3715         ASSERT(mutex_owned(&stmf_state.stmf_lock));
3716         tmp_irport.irport_id = rport_devid;
3717         irport = avl_find(&stmf_state.stmf_irportlist, &tmp_irport, NULL);
3718         if (irport != NULL) {
3719                 mutex_enter(&irport->irport_mutex);
3720                 irport->irport_refcnt++;
3721                 mutex_exit(&irport->irport_mutex);
3722         }
 
3806 
3807         mutex_enter(&stmf_state.stmf_lock);
3808         rw_enter(&ilport->ilport_lock, RW_WRITER);
3809         (void) stmf_session_create_lun_map(ilport, iss);
3810         ilport->ilport_nsessions++;
3811         iss->iss_next = ilport->ilport_ss_list;
3812         ilport->ilport_ss_list = iss;
3813         rw_exit(&ilport->ilport_lock);
3814         mutex_exit(&stmf_state.stmf_lock);
3815 
3816         iss->iss_creation_time = ddi_get_time();
3817         ss->ss_session_id = atomic_inc_64_nv(&stmf_session_counter);
3818         iss->iss_flags &= ~ISS_BEING_CREATED;
3819         /* XXX should we remove ISS_LUN_INVENTORY_CHANGED on new session? */
3820         iss->iss_flags &= ~ISS_LUN_INVENTORY_CHANGED;
3821         DTRACE_PROBE2(session__online, stmf_local_port_t *, lport,
3822             stmf_scsi_session_t *, ss);
3823         return (STMF_SUCCESS);
3824 }
3825 
3826 stmf_status_t
3827 stmf_add_rport_info(stmf_scsi_session_t *ss,
3828     const char *prop_name, const char *prop_value)
3829 {
3830         stmf_i_scsi_session_t *iss = ss->ss_stmf_private;
3831         stmf_i_remote_port_t *irport = iss->iss_irport;
3832         kstat_named_t *knp;
3833         char *s;
3834         int i;
3835 
3836         s = strdup(prop_value);
3837 
3838         mutex_enter(irport->irport_kstat_info->ks_lock);
3839         /* Make sure the caller doesn't try to add already existing property */
3840         knp = KSTAT_NAMED_PTR(irport->irport_kstat_info);
3841         for (i = 0; i < STMF_KSTAT_RPORT_DATAMAX; i++, knp++) {
3842                 if (KSTAT_NAMED_STR_PTR(knp) == NULL)
3843                         break;
3844 
3845                 ASSERT(strcmp(knp->name, prop_name) != 0);
3846         }
3847 
3848         if (i == STMF_KSTAT_RPORT_DATAMAX) {
3849                 mutex_exit(irport->irport_kstat_info->ks_lock);
3850                 kmem_free(s, strlen(s) + 1);
3851                 return (STMF_FAILURE);
3852         }
3853 
3854         irport->irport_info_dirty = B_TRUE;
3855         kstat_named_init(knp, prop_name, KSTAT_DATA_STRING);
3856         kstat_named_setstr(knp, s);
3857         mutex_exit(irport->irport_kstat_info->ks_lock);
3858 
3859         return (STMF_SUCCESS);
3860 }
3861 
3862 void
3863 stmf_remove_rport_info(stmf_scsi_session_t *ss,
3864     const char *prop_name)
3865 {
3866         stmf_i_scsi_session_t *iss = ss->ss_stmf_private;
3867         stmf_i_remote_port_t *irport = iss->iss_irport;
3868         kstat_named_t *knp;
3869         char *s;
3870         int i;
3871         uint32_t len;
3872 
3873         mutex_enter(irport->irport_kstat_info->ks_lock);
3874         knp = KSTAT_NAMED_PTR(irport->irport_kstat_info);
3875         for (i = 0; i < STMF_KSTAT_RPORT_DATAMAX; i++, knp++) {
3876                 if ((knp->name != NULL) && (strcmp(knp->name, prop_name) == 0))
3877                         break;
3878         }
3879 
3880         if (i == STMF_KSTAT_RPORT_DATAMAX) {
3881                 mutex_exit(irport->irport_kstat_info->ks_lock);
3882                 return;
3883         }
3884 
3885         s = KSTAT_NAMED_STR_PTR(knp);
3886         len = KSTAT_NAMED_STR_BUFLEN(knp);
3887 
3888         for (; i < STMF_KSTAT_RPORT_DATAMAX - 1; i++, knp++) {
3889                 kstat_named_init(knp, knp[1].name, KSTAT_DATA_STRING);
3890                 kstat_named_setstr(knp, KSTAT_NAMED_STR_PTR(&knp[1]));
3891         }
3892         kstat_named_init(knp, "", KSTAT_DATA_STRING);
3893 
3894         irport->irport_info_dirty = B_TRUE;
3895         mutex_exit(irport->irport_kstat_info->ks_lock);
3896         kmem_free(s, len);
3897 }
3898 
3899 static int
3900 stmf_kstat_rport_update(kstat_t *ksp, int rw)
3901 {
3902         stmf_i_remote_port_t *irport = ksp->ks_private;
3903         kstat_named_t *knp;
3904         uint_t ndata = 0;
3905         size_t dsize = 0;
3906         int i;
3907 
3908         if (rw == KSTAT_WRITE)
3909                 return (EACCES);
3910 
3911         if (!irport->irport_info_dirty)
3912                 return (0);
3913 
3914         knp = KSTAT_NAMED_PTR(ksp);
3915         for (i = 0; i < STMF_KSTAT_RPORT_DATAMAX; i++, knp++) {
3916                 if (KSTAT_NAMED_STR_PTR(knp) == NULL)
3917                         break;
3918                 ndata++;
3919                 dsize += KSTAT_NAMED_STR_BUFLEN(knp);
3920         }
3921 
3922         ksp->ks_ndata = ndata;
3923         ksp->ks_data_size = sizeof (kstat_named_t) * ndata + dsize;
3924         irport->irport_info_dirty = B_FALSE;
3925 
3926         return (0);
3927 }
3928 
3929 void
3930 stmf_deregister_scsi_session(stmf_local_port_t *lport, stmf_scsi_session_t *ss)
3931 {
3932         stmf_i_local_port_t *ilport = (stmf_i_local_port_t *)
3933             lport->lport_stmf_private;
3934         stmf_i_scsi_session_t *iss, **ppss;
3935         int found = 0;
3936         stmf_ic_msg_t *ic_session_dereg;
3937         stmf_status_t ic_ret = STMF_FAILURE;
3938         stmf_lun_map_t *sm;
3939         stmf_i_lu_t *ilu;
3940         uint16_t n;
3941         stmf_lun_map_ent_t *ent;
3942 
3943         DTRACE_PROBE2(session__offline, stmf_local_port_t *, lport,
3944             stmf_scsi_session_t *, ss);
3945 
3946         iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
3947         if (ss->ss_rport_alias) {
3948                 ss->ss_rport_alias = NULL;
3949         }
3950 
3951 try_dereg_ss_again:
3952         mutex_enter(&stmf_state.stmf_lock);
3953         atomic_and_32(&iss->iss_flags,
3954             ~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
3955         if (iss->iss_flags & ISS_EVENT_ACTIVE) {
3956                 mutex_exit(&stmf_state.stmf_lock);
3957                 delay(1);
3958                 goto try_dereg_ss_again;
3959         }
3960 
3961         /* dereg proxy session if not standby port */
 
3971                         }
3972                 }
3973         }
3974 
3975         rw_enter(&ilport->ilport_lock, RW_WRITER);
3976         for (ppss = &ilport->ilport_ss_list; *ppss != NULL;
3977             ppss = &((*ppss)->iss_next)) {
3978                 if (iss == (*ppss)) {
3979                         *ppss = (*ppss)->iss_next;
3980                         found = 1;
3981                         break;
3982                 }
3983         }
3984         if (!found) {
3985                 cmn_err(CE_PANIC, "Deregister session called for non existent"
3986                     " session");
3987         }
3988         ilport->ilport_nsessions--;
3989 
3990         stmf_irport_deregister(iss->iss_irport);
3991         /*
3992          * to avoid conflict with updating session's map,
3993          * which only grab stmf_lock
3994          */
3995         sm = iss->iss_sm;
3996         iss->iss_sm = NULL;
3997         iss->iss_hg = NULL;
3998 
3999         rw_exit(&ilport->ilport_lock);
4000 
4001         if (sm->lm_nentries) {
4002                 for (n = 0; n < sm->lm_nentries; n++) {
4003                         if ((ent = (stmf_lun_map_ent_t *)sm->lm_plus[n])
4004                             != NULL) {
4005                                 if (ent->ent_itl_datap) {
4006                                         stmf_do_itl_dereg(ent->ent_lu,
4007                                             ent->ent_itl_datap,
4008                                             STMF_ITL_REASON_IT_NEXUS_LOSS);
4009                                 }
4010                                 ilu = (stmf_i_lu_t *)
4011                                     ent->ent_lu->lu_stmf_private;
4012                                 atomic_dec_32(&ilu->ilu_ref_cnt);
4013                                 kmem_free(sm->lm_plus[n],
4014                                     sizeof (stmf_lun_map_ent_t));
4015                         }
4016                 }
4017                 kmem_free(sm->lm_plus,
4018                     sizeof (stmf_lun_map_ent_t *) * sm->lm_nentries);
4019         }
4020         kmem_free(sm, sizeof (*sm));
4021 
4022         if (iss->iss_flags & ISS_NULL_TPTID) {
4023                 stmf_remote_port_free(ss->ss_rport);
4024         }
4025 
4026         mutex_exit(&stmf_state.stmf_lock);
4027 }
4028 
4029 
4030 
4031 stmf_i_scsi_session_t *
4032 stmf_session_id_to_issptr(uint64_t session_id, int stay_locked)
4033 {
4034         stmf_i_local_port_t *ilport;
4035         stmf_i_scsi_session_t *iss;
4036 
4037         mutex_enter(&stmf_state.stmf_lock);
4038         for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
4039             ilport = ilport->ilport_next) {
4040                 rw_enter(&ilport->ilport_lock, RW_WRITER);
4041                 for (iss = ilport->ilport_ss_list; iss != NULL;
4042                     iss = iss->iss_next) {
4043                         if (iss->iss_ss->ss_session_id == session_id) {
4044                                 if (!stay_locked)
4045                                         rw_exit(&ilport->ilport_lock);
4046                                 mutex_exit(&stmf_state.stmf_lock);
4047                                 return (iss);
4048                         }
4049                 }
4050                 rw_exit(&ilport->ilport_lock);
 
4206                                                 goto dai_scan_done;
4207                                         }
4208                                 }
4209                         } /* lun table for a session */
4210                 } /* sessions */
4211                 rw_exit(&ilport->ilport_lock);
4212         } /* ports */
4213 
4214 dai_scan_done:
4215         mutex_exit(&stmf_state.stmf_lock);
4216 
4217         for (i = 0; i < nu; i++) {
4218                 stmf_do_itl_dereg(lu, itl_list[i],
4219                     STMF_ITL_REASON_DEREG_REQUEST);
4220         }
4221         kmem_free(itl_list, nmaps * sizeof (stmf_itl_data_t *));
4222 
4223         return (STMF_SUCCESS);
4224 }
4225 
4226 stmf_data_buf_t *
4227 stmf_alloc_dbuf(scsi_task_t *task, uint32_t size, uint32_t *pminsize,
4228     uint32_t flags)
4229 {
4230         stmf_i_scsi_task_t *itask =
4231             (stmf_i_scsi_task_t *)task->task_stmf_private;
4232         stmf_local_port_t *lport = task->task_lport;
4233         stmf_data_buf_t *dbuf;
4234         uint8_t ndx;
4235 
4236         ndx = stmf_first_zero[itask->itask_allocated_buf_map];
4237         if (ndx == 0xff)
4238                 return (NULL);
4239         dbuf = itask->itask_dbufs[ndx] = lport->lport_ds->ds_alloc_data_buf(
4240             task, size, pminsize, flags);
4241         if (dbuf) {
4242                 task->task_cur_nbufs++;
4243                 itask->itask_allocated_buf_map |= (1 << ndx);
4244                 dbuf->db_flags &= ~DB_LPORT_XFER_ACTIVE;
4245                 dbuf->db_handle = ndx;
 
4339 
4340         /*
4341          * We allocate 7 extra bytes for CDB to provide a cdb pointer which
4342          * is guaranteed to be 8 byte aligned. Some LU providers like OSD
4343          * depend upon this alignment.
4344          */
4345         if (cdb_length_in >= 16)
4346                 cdb_length = cdb_length_in + 7;
4347         else
4348                 cdb_length = 16 + 7;
4349         iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4350         luNbr = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
4351         rw_enter(iss->iss_lockp, RW_READER);
4352         lun_map_ent =
4353             (stmf_lun_map_ent_t *)stmf_get_ent_from_map(iss->iss_sm, luNbr);
4354         if (!lun_map_ent) {
4355                 lu = dlun0;
4356         } else {
4357                 lu = lun_map_ent->ent_lu;
4358         }
4359 
4360         ilu = lu->lu_stmf_private;
4361         if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4362                 rw_exit(iss->iss_lockp);
4363                 return (NULL);
4364         }
4365 
4366         /*
4367          * if the LUN is being offlined or is offline then only command
4368          * that are to query the LUN are allowed.  These are handled in
4369          * stmf via the dlun0 vector.  It is possible that a race condition
4370          * will cause other commands to arrive while the lun is in the
4371          * process of being offlined.  Check for those and just let the
4372          * protocol stack handle the error.
4373          */
4374         if ((ilu->ilu_state == STMF_STATE_OFFLINING) ||
4375             (ilu->ilu_state == STMF_STATE_OFFLINE)) {
4376                 if (lu != dlun0) {
4377                         rw_exit(iss->iss_lockp);
4378                         return (NULL);
4379                 }
4380         }
4381 
4382         do {
4383                 if (ilu->ilu_free_tasks == NULL) {
4384                         new_task = 1;
4385                         break;
4386                 }
4387                 mutex_enter(&ilu->ilu_task_lock);
4388                 for (ppitask = &ilu->ilu_free_tasks; (*ppitask != NULL) &&
4389                     ((*ppitask)->itask_cdb_buf_size < cdb_length);
4390                     ppitask = &((*ppitask)->itask_lu_free_next))
4391                         ;
4392                 if (*ppitask) {
4393                         itask = *ppitask;
4394                         *ppitask = (*ppitask)->itask_lu_free_next;
4395                         ilu->ilu_ntasks_free--;
4396                         if (ilu->ilu_ntasks_free < ilu->ilu_ntasks_min_free)
4397                                 ilu->ilu_ntasks_min_free = ilu->ilu_ntasks_free;
4398                 } else {
4399                         new_task = 1;
4400                 }
4401                 mutex_exit(&ilu->ilu_task_lock);
 
4409                  * selection process above.
4410                  */
4411                 uint8_t *save_cdb;
4412                 uintptr_t t_start, t_end;
4413 
4414                 task = itask->itask_task;
4415                 save_cdb = task->task_cdb;   /* save */
4416                 t_start = (uintptr_t)&task->task_flags;
4417                 t_end = (uintptr_t)&task->task_extended_cmd;
4418                 bzero((void *)t_start, (size_t)(t_end - t_start));
4419                 task->task_cdb = save_cdb;   /* restore */
4420                 itask->itask_ncmds = 0;
4421         } else {
4422                 task = (scsi_task_t *)stmf_alloc(STMF_STRUCT_SCSI_TASK,
4423                     cdb_length, AF_FORCE_NOSLEEP);
4424                 if (task == NULL) {
4425                         rw_exit(iss->iss_lockp);
4426                         return (NULL);
4427                 }
4428                 task->task_lu = lu;
4429                 task->task_cdb = (uint8_t *)task->task_port_private;
4430                 if ((ulong_t)(task->task_cdb) & 7ul) {
4431                         task->task_cdb = (uint8_t *)(((ulong_t)
4432                             (task->task_cdb) + 7ul) & ~(7ul));
4433                 }
4434                 itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
4435                 itask->itask_cdb_buf_size = cdb_length;
4436                 mutex_init(&itask->itask_audit_mutex, NULL, MUTEX_DRIVER, NULL);
4437                 mutex_init(&itask->itask_mutex, NULL, MUTEX_DRIVER, NULL);
4438         }
4439 
4440         /*
4441          * Since a LUN can be mapped as different LUN ids to different initiator
4442          * groups, we need to set LUN id for a new task and reset LUN id for
4443          * a reused task.
4444          */
4445         l = task->task_lun_no;
4446         l[0] = lun[0];
4447         l[1] = lun[1];
4448         l[2] = lun[2];
4449         l[3] = lun[3];
4450         l[4] = lun[4];
4451         l[5] = lun[5];
4452         l[6] = lun[6];
4453         l[7] = lun[7];
4454 
4455         mutex_enter(&itask->itask_mutex);
4456         task->task_session = ss;
4457         task->task_lport = lport;
4458         task->task_cdb_length = cdb_length_in;
4459         itask->itask_flags = ITASK_IN_TRANSITION;
4460         itask->itask_waitq_time = 0;
4461         itask->itask_lu_read_time = itask->itask_lu_write_time = 0;
4462         itask->itask_lport_read_time = itask->itask_lport_write_time = 0;
4463         itask->itask_read_xfer = itask->itask_write_xfer = 0;
4464         itask->itask_audit_index = 0;
4465         bzero(&itask->itask_audit_records[0],
4466             sizeof (stmf_task_audit_rec_t) * ITASK_TASK_AUDIT_DEPTH);
4467         mutex_exit(&itask->itask_mutex);
4468 
4469         if (new_task) {
4470                 if (lu->lu_task_alloc(task) != STMF_SUCCESS) {
4471                         rw_exit(iss->iss_lockp);
4472                         stmf_free(task);
4473                         return (NULL);
4474                 }
4475                 mutex_enter(&ilu->ilu_task_lock);
4476                 if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4477                         mutex_exit(&ilu->ilu_task_lock);
4478                         rw_exit(iss->iss_lockp);
4479                         stmf_free(task);
4480                         return (NULL);
4481                 }
4482                 itask->itask_lu_next = ilu->ilu_tasks;
4483                 if (ilu->ilu_tasks)
4484                         ilu->ilu_tasks->itask_lu_prev = itask;
4485                 ilu->ilu_tasks = itask;
4486                 /* kmem_zalloc automatically makes itask->itask_lu_prev NULL */
4487                 ilu->ilu_ntasks++;
4488                 mutex_exit(&ilu->ilu_task_lock);
4489         }
4490 
4491         itask->itask_ilu_task_cntr = ilu->ilu_cur_task_cntr;
4492         atomic_inc_32(itask->itask_ilu_task_cntr);
4493         itask->itask_start_time = ddi_get_lbolt();
4494 
4495         if ((lun_map_ent != NULL) && ((itask->itask_itl_datap =
4496             lun_map_ent->ent_itl_datap) != NULL)) {
4497                 atomic_inc_32(&itask->itask_itl_datap->itl_counter);
4498                 task->task_lu_itl_handle = itask->itask_itl_datap->itl_handle;
4499         } else {
4500                 itask->itask_itl_datap = NULL;
4501                 task->task_lu_itl_handle = NULL;
4502         }
4503 
4504         rw_exit(iss->iss_lockp);
4505         return (task);
4506 }
4507 
4508 /* ARGSUSED */
4509 static void
4510 stmf_task_lu_free(scsi_task_t *task, stmf_i_scsi_session_t *iss)
4511 {
4512         stmf_i_scsi_task_t *itask =
4513             (stmf_i_scsi_task_t *)task->task_stmf_private;
4514         stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
4515 
4516         ASSERT(rw_lock_held(iss->iss_lockp));
4517         ASSERT((itask->itask_flags & ITASK_IN_FREE_LIST) == 0);
4518         ASSERT((itask->itask_flags & ITASK_IN_WORKER_QUEUE) == 0);
4519         ASSERT((itask->itask_flags & ITASK_IN_TRANSITION) == 0);
4520         ASSERT((itask->itask_flags & ITASK_KNOWN_TO_LU) == 0);
4521         ASSERT(mutex_owned(&itask->itask_mutex));
4522 
4523         itask->itask_flags = ITASK_IN_FREE_LIST;
4524         itask->itask_ncmds = 0;
4525         itask->itask_proxy_msg_id = 0;
4526         atomic_dec_32(itask->itask_ilu_task_cntr);
4527         itask->itask_worker_next = NULL;
4528         mutex_exit(&itask->itask_mutex);
4529 
4530         mutex_enter(&ilu->ilu_task_lock);
4531         itask->itask_lu_free_next = ilu->ilu_free_tasks;
4532         ilu->ilu_free_tasks = itask;
4533         ilu->ilu_ntasks_free++;
4534         if (ilu->ilu_ntasks == ilu->ilu_ntasks_free)
4535                 cv_signal(&ilu->ilu_offline_pending_cv);
4536         mutex_exit(&ilu->ilu_task_lock);
4537 }
4538 
4539 void
4540 stmf_task_lu_check_freelist(stmf_i_lu_t *ilu)
4541 {
4542         uint32_t        num_to_release, ndx;
4543         stmf_i_scsi_task_t *itask;
4544         stmf_lu_t       *lu = ilu->ilu_lu;
4545 
4546         ASSERT(ilu->ilu_ntasks_min_free <= ilu->ilu_ntasks_free);
4547 
4548         /* free half of the minimal free of the free tasks */
4549         num_to_release = (ilu->ilu_ntasks_min_free + 1) / 2;
4550         if (!num_to_release) {
4551                 return;
4552         }
4553         for (ndx = 0; ndx < num_to_release; ndx++) {
4554                 mutex_enter(&ilu->ilu_task_lock);
4555                 itask = ilu->ilu_free_tasks;
4556                 if (itask == NULL) {
 
4593                 if (!ilu->ilu_ntasks_min_free) {
4594                         ilu->ilu_ntasks_min_free = ilu->ilu_ntasks_free;
4595                         continue;
4596                 }
4597                 ilu->ilu_flags |= ILU_STALL_DEREGISTER;
4598                 mutex_exit(&stmf_state.stmf_lock);
4599                 stmf_task_lu_check_freelist(ilu);
4600                 /*
4601                  * we do not care about the accuracy of
4602                  * ilu_ntasks_min_free, so we don't lock here
4603                  */
4604                 ilu->ilu_ntasks_min_free = ilu->ilu_ntasks_free;
4605                 mutex_enter(&stmf_state.stmf_lock);
4606                 ilu->ilu_flags &= ~ILU_STALL_DEREGISTER;
4607                 cv_broadcast(&stmf_state.stmf_cv);
4608                 if (ddi_get_lbolt() >= endtime)
4609                         break;
4610         }
4611 }
4612 
4613 /*
4614  * Since this method is looking to find tasks that are stuck, lost, or senile
4615  * it should be more willing to give up scaning during this time period. This
4616  * is why mutex_tryenter is now used instead of the standard mutex_enter.
4617  * There has been at least one case were the following occurred.
4618  *
4619  * 1) The iscsit_deferred() method is trying to register a session and
4620  *    needs the global lock which is held.
4621  * 2) Another thread which holds the global lock is trying to deregister a
4622  *    session and needs the session lock.
4623  * 3) A third thread is allocating a stmf task that has grabbed the session
4624  *    lock and is trying to grab the lun task lock.
4625  * 4) There's a timeout thread that has the lun task lock and is trying to grab
4626  *    a specific task lock.
4627  * 5) The thread that has the task lock is waiting for the ref count to go to
4628  *    zero.
4629  * 6) There's a task that would drop the count to zero, but it's in the task
4630  *    queue waiting to run and is stuck because of #1 is currently block.
4631  *
4632  * This method is number 4 in the above chain of events. Had this code
4633  * originally used mutex_tryenter the chain would have been broken and the
4634  * system wouldn't have hung. So, now this method uses mutex_tryenter and
4635  * you know why it does so.
4636  */
4637 /* ---- Only one thread calls stmf_do_ilu_timeouts so no lock required ---- */
4638 typedef struct stmf_bailout_cnt {
4639         int     no_ilu_lock;
4640         int     no_task_lock;
4641         int     tasks_checked;
4642 } stmf_bailout_cnt_t;
4643 
4644 stmf_bailout_cnt_t stmf_bailout;
4645 
4646 static void
4647 stmf_do_ilu_timeouts(stmf_i_lu_t *ilu)
4648 {
4649         clock_t l = ddi_get_lbolt();
4650         clock_t ps = drv_usectohz(1000000);
4651         stmf_i_scsi_task_t *itask;
4652         scsi_task_t *task;
4653         uint32_t to;
4654 
4655         if (mutex_tryenter(&ilu->ilu_task_lock) == 0) {
4656                 stmf_bailout.no_ilu_lock++;
4657                 return;
4658         }
4659 
4660         for (itask = ilu->ilu_tasks; itask != NULL;
4661             itask = itask->itask_lu_next) {
4662                 if (mutex_tryenter(&itask->itask_mutex) == 0) {
4663                         stmf_bailout.no_task_lock++;
4664                         continue;
4665                 }
4666                 stmf_bailout.tasks_checked++;
4667                 if (itask->itask_flags & (ITASK_IN_FREE_LIST |
4668                     ITASK_BEING_ABORTED)) {
4669                         mutex_exit(&itask->itask_mutex);
4670                         continue;
4671                 }
4672                 task = itask->itask_task;
4673                 if (task->task_timeout == 0)
4674                         to = stmf_default_task_timeout;
4675                 else
4676                         to = task->task_timeout;
4677 
4678                 if ((itask->itask_start_time + (to * ps)) > l) {
4679                         mutex_exit(&itask->itask_mutex);
4680                         continue;
4681                 }
4682                 mutex_exit(&itask->itask_mutex);
4683                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
4684                     STMF_TIMEOUT, NULL);
4685         }
4686         mutex_exit(&ilu->ilu_task_lock);
4687 }
4688 
4689 /*
4690  * Called with stmf_lock held
4691  */
4692 void
4693 stmf_check_ilu_timing()
4694 {
4695         stmf_i_lu_t *ilu;
4696         clock_t endtime = ddi_get_lbolt() + drv_usectohz(10000);
4697 
4698         /* stmf_svc_ilu_timing may get changed after stmf_lock is released */
4699         while ((ilu = stmf_state.stmf_svc_ilu_timing) != NULL) {
4700                 stmf_state.stmf_svc_ilu_timing = ilu->ilu_next;
4701                 if (ilu->ilu_cur_task_cntr == (&ilu->ilu_task_cntr1)) {
4702                         if (ilu->ilu_task_cntr2 == 0) {
 
4717                 mutex_exit(&stmf_state.stmf_lock);
4718                 stmf_do_ilu_timeouts(ilu);
4719                 mutex_enter(&stmf_state.stmf_lock);
4720                 ilu->ilu_flags &= ~ILU_STALL_DEREGISTER;
4721                 cv_broadcast(&stmf_state.stmf_cv);
4722                 if (ddi_get_lbolt() >= endtime)
4723                         break;
4724         }
4725 }
4726 
4727 /*
4728  * Kills all tasks on a lu except tm_task
4729  */
4730 void
4731 stmf_task_lu_killall(stmf_lu_t *lu, scsi_task_t *tm_task, stmf_status_t s)
4732 {
4733         stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4734         stmf_i_scsi_task_t *itask;
4735 
4736         mutex_enter(&ilu->ilu_task_lock);
4737         for (itask = ilu->ilu_tasks; itask != NULL;
4738             itask = itask->itask_lu_next) {
4739                 mutex_enter(&itask->itask_mutex);
4740                 if (itask->itask_flags & ITASK_IN_FREE_LIST) {
4741                         mutex_exit(&itask->itask_mutex);
4742                         continue;
4743                 }
4744                 mutex_exit(&itask->itask_mutex);
4745                 if (itask->itask_task == tm_task)
4746                         continue;
4747                 stmf_abort(STMF_QUEUE_TASK_ABORT, itask->itask_task, s, NULL);
4748         }
4749         mutex_exit(&ilu->ilu_task_lock);
4750 }
4751 
4752 void
4753 stmf_free_task_bufs(stmf_i_scsi_task_t *itask, stmf_local_port_t *lport)
4754 {
4755         int i;
4756         uint8_t map;
4757 
4758         if ((map = itask->itask_allocated_buf_map) == 0)
4759                 return;
4760         for (i = 0; i < 4; i++) {
4761                 if (map & 1) {
4762                         stmf_data_buf_t *dbuf;
4763 
4764                         dbuf = itask->itask_dbufs[i];
 
4780                         } else {
4781                                 ASSERT(dbuf->db_lu_private == NULL);
4782                                 dbuf->db_lu_private = NULL;
4783                                 lport->lport_ds->ds_free_data_buf(
4784                                     lport->lport_ds, dbuf);
4785                         }
4786                 }
4787                 map >>= 1;
4788         }
4789         itask->itask_allocated_buf_map = 0;
4790 }
4791 
4792 void
4793 stmf_task_free(scsi_task_t *task)
4794 {
4795         stmf_local_port_t *lport = task->task_lport;
4796         stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
4797             task->task_stmf_private;
4798         stmf_i_scsi_session_t *iss = (stmf_i_scsi_session_t *)
4799             task->task_session->ss_stmf_private;
4800         stmf_lu_t *lu = task->task_lu;
4801 
4802         stmf_task_audit(itask, TE_TASK_FREE, CMD_OR_IOF_NA, NULL);
4803         ASSERT(mutex_owned(&itask->itask_mutex));
4804         if ((lu != NULL) && (lu->lu_task_done != NULL))
4805                 lu->lu_task_done(task);
4806         stmf_free_task_bufs(itask, lport);
4807         stmf_itl_task_done(itask);
4808         DTRACE_PROBE2(stmf__task__end, scsi_task_t *, task,
4809             hrtime_t,
4810             itask->itask_done_timestamp - itask->itask_start_timestamp);
4811         if (itask->itask_itl_datap) {
4812                 if (atomic_dec_32_nv(&itask->itask_itl_datap->itl_counter) ==
4813                     0) {
4814                         stmf_release_itl_handle(task->task_lu,
4815                             itask->itask_itl_datap);
4816                 }
4817         }
4818 
4819         /*
4820          * To prevent a deadlock condition must release the itask_mutex,
4821          * grab a reader lock on iss_lockp and then reacquire the itask_mutex.
4822          */
4823         mutex_exit(&itask->itask_mutex);
4824         rw_enter(iss->iss_lockp, RW_READER);
4825         mutex_enter(&itask->itask_mutex);
4826 
4827         lport->lport_task_free(task);
4828         if (itask->itask_worker) {
4829                 atomic_dec_32(&stmf_cur_ntasks);
4830                 atomic_dec_32(&itask->itask_worker->worker_ref_count);
4831         }
4832         /*
4833          * After calling stmf_task_lu_free, the task pointer can no longer
4834          * be trusted.
4835          */
4836         stmf_task_lu_free(task, iss);
4837         rw_exit(iss->iss_lockp);
4838 }
4839 
4840 void
4841 stmf_post_task(scsi_task_t *task, stmf_data_buf_t *dbuf)
4842 {
4843         stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
4844             task->task_stmf_private;
4845         stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
4846         int nv;
4847         uint32_t new;
4848         uint32_t ct;
4849         stmf_worker_t *w;
4850         uint8_t tm;
4851 
4852         if (task->task_max_nbufs > 4)
4853                 task->task_max_nbufs = 4;
4854         task->task_cur_nbufs = 0;
4855         /* Latest value of currently running tasks */
4856         ct = atomic_inc_32_nv(&stmf_cur_ntasks);
4857 
4858         /* Select the next worker using round robin */
4859         mutex_enter(&stmf_worker_sel_mx);
4860         stmf_worker_sel_counter++;
4861         if (stmf_worker_sel_counter >= stmf_nworkers)
4862                 stmf_worker_sel_counter = 0;
4863         nv = stmf_worker_sel_counter;
4864 
4865         /* if the selected worker is not idle then bump to the next worker */
4866         if (stmf_workers[nv].worker_queue_depth > 0) {
4867                 stmf_worker_sel_counter++;
4868                 if (stmf_worker_sel_counter >= stmf_nworkers)
4869                         stmf_worker_sel_counter = 0;
4870                 nv = stmf_worker_sel_counter;
4871         }
4872         mutex_exit(&stmf_worker_sel_mx);
4873 
4874         w = &stmf_workers[nv];
4875 
4876         mutex_enter(&itask->itask_mutex);
4877         mutex_enter(&w->worker_lock);
4878 
4879         itask->itask_worker = w;
4880 
4881         /*
4882          * Track max system load inside the worker as we already have the
4883          * worker lock (no point implementing another lock). The service
4884          * thread will do the comparisons and figure out the max overall
4885          * system load.
4886          */
4887         if (w->worker_max_sys_qdepth_pu < ct)
4888                 w->worker_max_sys_qdepth_pu = ct;
4889 
4890         new = itask->itask_flags;
4891         new |= ITASK_KNOWN_TO_TGT_PORT;
4892         if (task->task_mgmt_function) {
4893                 tm = task->task_mgmt_function;
4894                 if ((tm == TM_TARGET_RESET) ||
4895                     (tm == TM_TARGET_COLD_RESET) ||
4896                     (tm == TM_TARGET_WARM_RESET)) {
4897                         new |= ITASK_DEFAULT_HANDLING;
4898                 }
4899         } else if (task->task_cdb[0] == SCMD_REPORT_LUNS) {
4900                 new |= ITASK_DEFAULT_HANDLING;
4901         }
4902         new &= ~ITASK_IN_TRANSITION;
4903         itask->itask_flags = new;
4904 
4905         stmf_itl_task_start(itask);
4906 
4907         itask->itask_cmd_stack[0] = ITASK_CMD_NEW_TASK;
4908         itask->itask_ncmds = 1;
4909 
4910         if ((task->task_flags & TF_INITIAL_BURST) &&
4911             !(curthread->t_flag & T_INTR_THREAD)) {
4912                 stmf_update_kstat_lu_io(task, dbuf);
4913                 stmf_update_kstat_lport_io(task, dbuf);
4914                 stmf_update_kstat_rport_io(task, dbuf);
4915         }
4916 
4917         stmf_task_audit(itask, TE_TASK_START, CMD_OR_IOF_NA, dbuf);
4918         if (dbuf) {
4919                 itask->itask_allocated_buf_map = 1;
4920                 itask->itask_dbufs[0] = dbuf;
4921                 dbuf->db_handle = 0;
4922         } else {
4923                 itask->itask_allocated_buf_map = 0;
4924                 itask->itask_dbufs[0] = NULL;
4925         }
4926 
4927         STMF_ENQUEUE_ITASK(w, itask);
4928 
4929         mutex_exit(&w->worker_lock);
4930         mutex_exit(&itask->itask_mutex);
4931 
4932         /*
4933          * This can only happen if during stmf_task_alloc(), ILU_RESET_ACTIVE
4934          * was set between checking of ILU_RESET_ACTIVE and clearing of the
4935          * ITASK_IN_FREE_LIST flag. Take care of these "sneaked-in" tasks here.
4936          */
4937         if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4938                 stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ABORTED, NULL);
4939         }
4940 }
4941 
4942 static void
4943 stmf_task_audit(stmf_i_scsi_task_t *itask,
4944     task_audit_event_t te, uint32_t cmd_or_iof, stmf_data_buf_t *dbuf)
4945 {
4946         stmf_task_audit_rec_t *ar;
4947 
4948         mutex_enter(&itask->itask_audit_mutex);
4949         ar = &itask->itask_audit_records[itask->itask_audit_index++];
4950         itask->itask_audit_index &= (ITASK_TASK_AUDIT_DEPTH - 1);
 
4966  * we will only call that entry point if ITASK_KNOWN_TO_LU was set.
4967  *
4968  * Same logic applies for the port.
4969  *
4970  * Also ITASK_BEING_ABORTED will not be allowed to set if both KNOWN_TO_LU
4971  * and KNOWN_TO_TGT_PORT are reset.
4972  *
4973  * +++++++++++++++++++++++++++++++++++++++++++++++
4974  */
4975 
4976 stmf_status_t
4977 stmf_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t ioflags)
4978 {
4979         stmf_status_t ret = STMF_SUCCESS;
4980 
4981         stmf_i_scsi_task_t *itask =
4982             (stmf_i_scsi_task_t *)task->task_stmf_private;
4983 
4984         stmf_task_audit(itask, TE_XFER_START, ioflags, dbuf);
4985 
4986         mutex_enter(&itask->itask_mutex);
4987         if (ioflags & STMF_IOF_LU_DONE) {
4988                 if (itask->itask_flags & ITASK_BEING_ABORTED) {
4989                         mutex_exit(&itask->itask_mutex);
4990                         return (STMF_ABORTED);
4991                 }
4992                 itask->itask_flags &= ~ITASK_KNOWN_TO_LU;
4993         }
4994         if ((itask->itask_flags & ITASK_BEING_ABORTED) != 0) {
4995                 mutex_exit(&itask->itask_mutex);
4996                 return (STMF_ABORTED);
4997         }
4998         mutex_exit(&itask->itask_mutex);
4999 
5000 #ifdef  DEBUG
5001         if (!(ioflags & STMF_IOF_STATS_ONLY) && stmf_drop_buf_counter > 0) {
5002                 if (atomic_dec_32_nv((uint32_t *)&stmf_drop_buf_counter) == 1)
5003                         return (STMF_SUCCESS);
5004         }
5005 #endif
5006 
5007         stmf_update_kstat_lu_io(task, dbuf);
5008         stmf_update_kstat_lport_io(task, dbuf);
5009         stmf_update_kstat_rport_io(task, dbuf);
5010         stmf_lport_xfer_start(itask, dbuf);
5011         if (ioflags & STMF_IOF_STATS_ONLY) {
5012                 stmf_lport_xfer_done(itask, dbuf);
5013                 return (STMF_SUCCESS);
5014         }
5015 
5016         dbuf->db_flags |= DB_LPORT_XFER_ACTIVE;
5017         ret = task->task_lport->lport_xfer_data(task, dbuf, ioflags);
5018 
5019         /*
5020          * Port provider may have already called the buffer callback in
5021          * which case dbuf->db_xfer_start_timestamp will be 0.
5022          */
5023         if (ret != STMF_SUCCESS) {
5024                 dbuf->db_flags &= ~DB_LPORT_XFER_ACTIVE;
5025                 if (dbuf->db_xfer_start_timestamp != 0)
5026                         stmf_lport_xfer_done(itask, dbuf);
5027         }
5028 
5029         return (ret);
5030 }
5031 
5032 void
5033 stmf_data_xfer_done(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t iof)
5034 {
5035         stmf_i_scsi_task_t *itask =
5036             (stmf_i_scsi_task_t *)task->task_stmf_private;
5037         stmf_i_local_port_t *ilport;
5038         stmf_worker_t *w = itask->itask_worker;
5039         uint32_t new;
5040         uint8_t update_queue_flags, free_it, queue_it;
5041 
5042         stmf_lport_xfer_done(itask, dbuf);
5043 
5044         stmf_task_audit(itask, TE_XFER_DONE, iof, dbuf);
5045 
5046         /* Guard against unexpected completions from the lport */
5047         if (dbuf->db_flags & DB_LPORT_XFER_ACTIVE) {
5048                 dbuf->db_flags &= ~DB_LPORT_XFER_ACTIVE;
5049         } else {
5050                 /*
5051                  * This should never happen.
5052                  */
5053                 ilport = task->task_lport->lport_stmf_private;
5054                 ilport->ilport_unexpected_comp++;
5055                 cmn_err(CE_PANIC, "Unexpected xfer completion task %p dbuf %p",
5056                     (void *)task, (void *)dbuf);
5057                 return;
5058         }
5059 
5060         mutex_enter(&itask->itask_mutex);
5061         mutex_enter(&w->worker_lock);
5062         new = itask->itask_flags;
5063         if (itask->itask_flags & ITASK_BEING_ABORTED) {
5064                 mutex_exit(&w->worker_lock);
5065                 mutex_exit(&itask->itask_mutex);
5066                 return;
5067         }
5068         free_it = 0;
5069         if (iof & STMF_IOF_LPORT_DONE) {
5070                 new &= ~ITASK_KNOWN_TO_TGT_PORT;
5071                 task->task_completion_status = dbuf->db_xfer_status;
5072                 free_it = 1;
5073         }
5074         /*
5075          * If the task is known to LU then queue it. But if
5076          * it is already queued (multiple completions) then
5077          * just update the buffer information by grabbing the
5078          * worker lock. If the task is not known to LU,
5079          * completed/aborted, then see if we need to
5080          * free this task.
5081          */
5082         if (itask->itask_flags & ITASK_KNOWN_TO_LU) {
5083                 free_it = 0;
5084                 update_queue_flags = 1;
5085                 if (itask->itask_flags & ITASK_IN_WORKER_QUEUE) {
5086                         queue_it = 0;
5087                 } else {
5088                         queue_it = 1;
5089                 }
5090         } else {
5091                 update_queue_flags = 0;
5092                 queue_it = 0;
5093         }
5094         itask->itask_flags = new;
5095 
5096         if (update_queue_flags) {
5097                 uint8_t cmd = (dbuf->db_handle << 5) | ITASK_CMD_DATA_XFER_DONE;
5098 
5099                 ASSERT((itask->itask_flags & ITASK_IN_FREE_LIST) == 0);
5100                 ASSERT(itask->itask_ncmds < ITASK_MAX_NCMDS);
5101 
5102                 itask->itask_cmd_stack[itask->itask_ncmds++] = cmd;
5103                 if (queue_it) {
5104                         STMF_ENQUEUE_ITASK(w, itask);
5105                 }
5106                 mutex_exit(&w->worker_lock);
5107                 mutex_exit(&itask->itask_mutex);
5108                 return;
5109         }
5110 
5111         mutex_exit(&w->worker_lock);
5112         if (free_it) {
5113                 if ((itask->itask_flags & (ITASK_KNOWN_TO_LU |
5114                     ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
5115                     ITASK_BEING_ABORTED)) == 0) {
5116                         stmf_task_free(task);
5117                         return;
5118                 }
5119         }
5120         mutex_exit(&itask->itask_mutex);
5121 }
5122 
5123 stmf_status_t
5124 stmf_send_scsi_status(scsi_task_t *task, uint32_t ioflags)
5125 {
5126         DTRACE_PROBE1(scsi__send__status, scsi_task_t *, task);
5127 
5128         stmf_i_scsi_task_t *itask =
5129             (stmf_i_scsi_task_t *)task->task_stmf_private;
5130 
5131         stmf_task_audit(itask, TE_SEND_STATUS, ioflags, NULL);
5132 
5133         mutex_enter(&itask->itask_mutex);
5134         if (ioflags & STMF_IOF_LU_DONE) {
5135                 if (itask->itask_flags & ITASK_BEING_ABORTED) {
5136                         mutex_exit(&itask->itask_mutex);
5137                         return (STMF_ABORTED);
5138                 }
5139                 itask->itask_flags &= ~ITASK_KNOWN_TO_LU;
5140         }
5141 
5142         if (!(itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT)) {
5143                 mutex_exit(&itask->itask_mutex);
5144                 return (STMF_SUCCESS);
5145         }
5146 
5147         if (itask->itask_flags & ITASK_BEING_ABORTED) {
5148                 mutex_exit(&itask->itask_mutex);
5149                 return (STMF_ABORTED);
5150         }
5151         mutex_exit(&itask->itask_mutex);
5152 
5153         if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
5154                 task->task_status_ctrl = 0;
5155                 task->task_resid = 0;
5156         } else if (task->task_cmd_xfer_length >
5157             task->task_expected_xfer_length) {
5158                 task->task_status_ctrl = TASK_SCTRL_OVER;
5159                 task->task_resid = task->task_cmd_xfer_length -
5160                     task->task_expected_xfer_length;
5161         } else if (task->task_nbytes_transferred <
5162             task->task_expected_xfer_length) {
5163                 task->task_status_ctrl = TASK_SCTRL_UNDER;
5164                 task->task_resid = task->task_expected_xfer_length -
5165                     task->task_nbytes_transferred;
5166         } else {
5167                 task->task_status_ctrl = 0;
5168                 task->task_resid = 0;
5169         }
5170         return (task->task_lport->lport_send_status(task, ioflags));
5171 }
5172 
5173 void
5174 stmf_send_status_done(scsi_task_t *task, stmf_status_t s, uint32_t iof)
5175 {
5176         stmf_i_scsi_task_t *itask =
5177             (stmf_i_scsi_task_t *)task->task_stmf_private;
5178         stmf_worker_t *w = itask->itask_worker;
5179         uint32_t new;
5180         uint8_t free_it, queue_it;
5181 
5182         stmf_task_audit(itask, TE_SEND_STATUS_DONE, iof, NULL);
5183 
5184         mutex_enter(&itask->itask_mutex);
5185         mutex_enter(&w->worker_lock);
5186         new = itask->itask_flags;
5187         if (itask->itask_flags & ITASK_BEING_ABORTED) {
5188                 mutex_exit(&w->worker_lock);
5189                 mutex_exit(&itask->itask_mutex);
5190                 return;
5191         }
5192         free_it = 0;
5193         if (iof & STMF_IOF_LPORT_DONE) {
5194                 new &= ~ITASK_KNOWN_TO_TGT_PORT;
5195                 free_it = 1;
5196         }
5197         /*
5198          * If the task is known to LU then queue it. But if
5199          * it is already queued (multiple completions) then
5200          * just update the buffer information by grabbing the
5201          * worker lock. If the task is not known to LU,
5202          * completed/aborted, then see if we need to
5203          * free this task.
5204          */
5205         if (itask->itask_flags & ITASK_KNOWN_TO_LU) {
5206                 free_it = 0;
5207                 queue_it = 1;
5208                 if (itask->itask_flags & ITASK_IN_WORKER_QUEUE) {
5209                         cmn_err(CE_PANIC, "status completion received"
5210                             " when task is already in worker queue "
5211                             " task = %p", (void *)task);
5212                 }
5213         } else {
5214                 queue_it = 0;
5215         }
5216         itask->itask_flags = new;
5217         task->task_completion_status = s;
5218 
5219         if (queue_it) {
5220                 ASSERT(itask->itask_ncmds < ITASK_MAX_NCMDS);
5221                 itask->itask_cmd_stack[itask->itask_ncmds++] =
5222                     ITASK_CMD_STATUS_DONE;
5223 
5224                 STMF_ENQUEUE_ITASK(w, itask);
5225                 mutex_exit(&w->worker_lock);
5226                 mutex_exit(&itask->itask_mutex);
5227                 return;
5228         }
5229 
5230         mutex_exit(&w->worker_lock);
5231 
5232         if (free_it) {
5233                 if ((itask->itask_flags & (ITASK_KNOWN_TO_LU |
5234                     ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
5235                     ITASK_BEING_ABORTED)) == 0) {
5236                         stmf_task_free(task);
5237                         return;
5238                 } else {
5239                         cmn_err(CE_PANIC, "LU is done with the task but LPORT "
5240                             " is not done, itask %p itask_flags %x",
5241                             (void *)itask, itask->itask_flags);
5242                 }
5243         }
5244         mutex_exit(&itask->itask_mutex);
5245 }
5246 
5247 void
5248 stmf_task_lu_done(scsi_task_t *task)
5249 {
5250         stmf_i_scsi_task_t *itask =
5251             (stmf_i_scsi_task_t *)task->task_stmf_private;
5252         stmf_worker_t *w = itask->itask_worker;
5253 
5254         mutex_enter(&itask->itask_mutex);
5255         mutex_enter(&w->worker_lock);
5256         if (itask->itask_flags & ITASK_BEING_ABORTED) {
5257                 mutex_exit(&w->worker_lock);
5258                 mutex_exit(&itask->itask_mutex);
5259                 return;
5260         }
5261         if (itask->itask_flags & ITASK_IN_WORKER_QUEUE) {
5262                 cmn_err(CE_PANIC, "task_lu_done received"
5263                     " when task is in worker queue "
5264                     " task = %p", (void *)task);
5265         }
5266         itask->itask_flags &= ~ITASK_KNOWN_TO_LU;
5267 
5268         mutex_exit(&w->worker_lock);
5269         if ((itask->itask_flags & (ITASK_KNOWN_TO_LU |
5270             ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
5271             ITASK_BEING_ABORTED)) == 0) {
5272                 stmf_task_free(task);
5273                 return;
5274         } else {
5275                 cmn_err(CE_PANIC, "stmf_lu_done should be the last stage but "
5276                     " the task is still not done, task = %p", (void *)task);
5277         }
5278         mutex_exit(&itask->itask_mutex);
5279 }
5280 
5281 void
5282 stmf_queue_task_for_abort(scsi_task_t *task, stmf_status_t s)
5283 {
5284         stmf_i_scsi_task_t *itask =
5285             (stmf_i_scsi_task_t *)task->task_stmf_private;
5286         stmf_worker_t *w;
5287 
5288         stmf_task_audit(itask, TE_TASK_ABORT, CMD_OR_IOF_NA, NULL);
5289 
5290         mutex_enter(&itask->itask_mutex);
5291         if ((itask->itask_flags & ITASK_BEING_ABORTED) ||
5292             ((itask->itask_flags & (ITASK_KNOWN_TO_TGT_PORT |
5293             ITASK_KNOWN_TO_LU)) == 0)) {
5294                 mutex_exit(&itask->itask_mutex);
5295                 return;
5296         }
5297         itask->itask_flags |= ITASK_BEING_ABORTED;
5298         task->task_completion_status = s;
5299 
5300         if (((w = itask->itask_worker) == NULL) ||
5301             (itask->itask_flags & ITASK_IN_TRANSITION)) {
5302                 mutex_exit(&itask->itask_mutex);
5303                 return;
5304         }
5305 
5306         /* Queue it and get out */
5307         if (itask->itask_flags & ITASK_IN_WORKER_QUEUE) {
5308                 mutex_exit(&itask->itask_mutex);
5309                 return;
5310         }
5311         mutex_enter(&w->worker_lock);
5312         STMF_ENQUEUE_ITASK(w, itask);
5313         mutex_exit(&w->worker_lock);
5314         mutex_exit(&itask->itask_mutex);
5315 }
5316 
5317 void
5318 stmf_abort(int abort_cmd, scsi_task_t *task, stmf_status_t s, void *arg)
5319 {
5320         stmf_i_scsi_task_t *itask = NULL;
5321         uint32_t f, rf;
5322 
5323         DTRACE_PROBE2(scsi__task__abort, scsi_task_t *, task,
5324             stmf_status_t, s);
5325 
5326         switch (abort_cmd) {
5327         case STMF_QUEUE_ABORT_LU:
5328                 stmf_task_lu_killall((stmf_lu_t *)arg, task, s);
5329                 return;
5330         case STMF_QUEUE_TASK_ABORT:
5331                 stmf_queue_task_for_abort(task, s);
5332                 return;
5333         case STMF_REQUEUE_TASK_ABORT_LPORT:
5334                 rf = ITASK_TGT_PORT_ABORT_CALLED;
5335                 f = ITASK_KNOWN_TO_TGT_PORT;
5336                 break;
5337         case STMF_REQUEUE_TASK_ABORT_LU:
5338                 rf = ITASK_LU_ABORT_CALLED;
5339                 f = ITASK_KNOWN_TO_LU;
5340                 break;
5341         default:
5342                 return;
5343         }
5344 
5345         itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
5346         mutex_enter(&itask->itask_mutex);
5347         f |= ITASK_BEING_ABORTED | rf;
5348 
5349         if ((itask->itask_flags & f) != f) {
5350                 mutex_exit(&itask->itask_mutex);
5351                 return;
5352         }
5353         itask->itask_flags &= ~rf;
5354         mutex_exit(&itask->itask_mutex);
5355 
5356 }
5357 
5358 /*
5359  * NOTE: stmf_abort_task_offline will release and then reacquire the
5360  * itask_mutex. This is required to prevent a lock order violation.
5361  */
5362 void
5363 stmf_task_lu_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof)
5364 {
5365         char                     info[STMF_CHANGE_INFO_LEN];
5366         stmf_i_scsi_task_t      *itask = TASK_TO_ITASK(task);
5367         unsigned long long      st;
5368 
5369         stmf_task_audit(itask, TE_TASK_LU_ABORTED, iof, NULL);
5370         ASSERT(mutex_owned(&itask->itask_mutex));
5371         st = s; /* gcc fix */
5372         if ((s != STMF_ABORT_SUCCESS) && (s != STMF_NOT_FOUND)) {
5373                 (void) snprintf(info, sizeof (info),
5374                     "task %p, lu failed to abort ret=%llx", (void *)task, st);
5375         } else if ((iof & STMF_IOF_LU_DONE) == 0) {
5376                 (void) snprintf(info, sizeof (info),
5377                     "Task aborted but LU is not finished, task ="
5378                     "%p, s=%llx, iof=%x", (void *)task, st, iof);
5379         } else {
5380                 /*
5381                  * LU abort successfully
5382                  */
5383                 atomic_and_32(&itask->itask_flags, ~ITASK_KNOWN_TO_LU);
5384                 return;
5385         }
5386 
5387         stmf_abort_task_offline(task, 1, info);
5388 }
5389 
5390 /*
5391  * NOTE: stmf_abort_task_offline will release and then reacquire the
5392  * itask_mutex. This is required to prevent a lock order violation.
5393  */
5394 void
5395 stmf_task_lport_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof)
5396 {
5397         char                    info[STMF_CHANGE_INFO_LEN];
5398         stmf_i_scsi_task_t      *itask = TASK_TO_ITASK(task);
5399         unsigned long long      st;
5400 
5401         ASSERT(mutex_owned(&itask->itask_mutex));
5402         stmf_task_audit(itask, TE_TASK_LPORT_ABORTED, iof, NULL);
5403         st = s;
5404         if ((s != STMF_ABORT_SUCCESS) && (s != STMF_NOT_FOUND)) {
5405                 (void) snprintf(info, sizeof (info),
5406                     "task %p, tgt port failed to abort ret=%llx", (void *)task,
5407                     st);
5408         } else if ((iof & STMF_IOF_LPORT_DONE) == 0) {
5409                 (void) snprintf(info, sizeof (info),
5410                     "Task aborted but tgt port is not finished, "
5411                     "task=%p, s=%llx, iof=%x", (void *)task, st, iof);
5412         } else {
5413                 /*
5414                  * LPORT abort successfully
5415                  */
5416                 atomic_and_32(&itask->itask_flags, ~ITASK_KNOWN_TO_TGT_PORT);
5417                 return;
5418         }
5419 
5420         stmf_abort_task_offline(task, 0, info);
5421 }
5422 
5423 void
5424 stmf_task_lport_aborted_unlocked(scsi_task_t *task, stmf_status_t s,
5425     uint32_t iof)
5426 {
5427         stmf_i_scsi_task_t      *itask = TASK_TO_ITASK(task);
5428 
5429         mutex_enter(&itask->itask_mutex);
5430         stmf_task_lport_aborted(task, s, iof);
5431         mutex_exit(&itask->itask_mutex);
5432 }
5433 
5434 stmf_status_t
5435 stmf_task_poll_lu(scsi_task_t *task, uint32_t timeout)
5436 {
5437         stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
5438             task->task_stmf_private;
5439         stmf_worker_t *w = itask->itask_worker;
5440         int i;
5441 
5442         mutex_enter(&itask->itask_mutex);
5443         ASSERT(itask->itask_flags & ITASK_KNOWN_TO_LU);
5444         mutex_enter(&w->worker_lock);
5445         if (itask->itask_ncmds >= ITASK_MAX_NCMDS) {
5446                 mutex_exit(&w->worker_lock);
5447                 mutex_exit(&itask->itask_mutex);
5448                 return (STMF_BUSY);
5449         }
5450         for (i = 0; i < itask->itask_ncmds; i++) {
5451                 if (itask->itask_cmd_stack[i] == ITASK_CMD_POLL_LU) {
5452                         mutex_exit(&w->worker_lock);
5453                         mutex_exit(&itask->itask_mutex);
5454                         return (STMF_SUCCESS);
5455                 }
5456         }
5457         itask->itask_cmd_stack[itask->itask_ncmds++] = ITASK_CMD_POLL_LU;
5458         if (timeout == ITASK_DEFAULT_POLL_TIMEOUT) {
5459                 itask->itask_poll_timeout = ddi_get_lbolt() + 1;
5460         } else {
5461                 clock_t t = drv_usectohz(timeout * 1000);
5462                 if (t == 0)
5463                         t = 1;
5464                 itask->itask_poll_timeout = ddi_get_lbolt() + t;
5465         }
5466         if ((itask->itask_flags & ITASK_IN_WORKER_QUEUE) == 0) {
5467                 STMF_ENQUEUE_ITASK(w, itask);
5468         }
5469         mutex_exit(&w->worker_lock);
5470         mutex_exit(&itask->itask_mutex);
5471         return (STMF_SUCCESS);
5472 }
5473 
5474 stmf_status_t
5475 stmf_task_poll_lport(scsi_task_t *task, uint32_t timeout)
5476 {
5477         stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
5478             task->task_stmf_private;
5479         stmf_worker_t *w = itask->itask_worker;
5480         int i;
5481 
5482         mutex_enter(&itask->itask_mutex);
5483         ASSERT(itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT);
5484         mutex_enter(&w->worker_lock);
5485         if (itask->itask_ncmds >= ITASK_MAX_NCMDS) {
5486                 mutex_exit(&w->worker_lock);
5487                 mutex_exit(&itask->itask_mutex);
5488                 return (STMF_BUSY);
5489         }
5490         for (i = 0; i < itask->itask_ncmds; i++) {
5491                 if (itask->itask_cmd_stack[i] == ITASK_CMD_POLL_LPORT) {
5492                         mutex_exit(&w->worker_lock);
5493                         mutex_exit(&itask->itask_mutex);
5494                         return (STMF_SUCCESS);
5495                 }
5496         }
5497         itask->itask_cmd_stack[itask->itask_ncmds++] = ITASK_CMD_POLL_LPORT;
5498         if (timeout == ITASK_DEFAULT_POLL_TIMEOUT) {
5499                 itask->itask_poll_timeout = ddi_get_lbolt() + 1;
5500         } else {
5501                 clock_t t = drv_usectohz(timeout * 1000);
5502                 if (t == 0)
5503                         t = 1;
5504                 itask->itask_poll_timeout = ddi_get_lbolt() + t;
5505         }
5506         if ((itask->itask_flags & ITASK_IN_WORKER_QUEUE) == 0) {
5507                 STMF_ENQUEUE_ITASK(w, itask);
5508         }
5509         mutex_exit(&w->worker_lock);
5510         mutex_exit(&itask->itask_mutex);
5511         return (STMF_SUCCESS);
5512 }
5513 
5514 void
5515 stmf_do_task_abort(scsi_task_t *task)
5516 {
5517         stmf_i_scsi_task_t      *itask = TASK_TO_ITASK(task);
5518         stmf_lu_t               *lu;
5519         stmf_local_port_t       *lport;
5520         unsigned long long       ret;
5521         uint32_t                 new = 0;
5522         uint8_t                  call_lu_abort, call_port_abort;
5523         char                     info[STMF_CHANGE_INFO_LEN];
5524 
5525         lu = task->task_lu;
5526         lport = task->task_lport;
5527         mutex_enter(&itask->itask_mutex);
5528         new = itask->itask_flags;
5529         if ((itask->itask_flags & (ITASK_KNOWN_TO_LU |
5530             ITASK_LU_ABORT_CALLED)) == ITASK_KNOWN_TO_LU) {
5531                 new |= ITASK_LU_ABORT_CALLED;
5532                 call_lu_abort = 1;
5533         } else {
5534                 call_lu_abort = 0;
5535         }
5536         itask->itask_flags = new;
5537 
5538         if (call_lu_abort) {
5539                 if ((itask->itask_flags & ITASK_DEFAULT_HANDLING) == 0) {
5540                         ret = lu->lu_abort(lu, STMF_LU_ABORT_TASK, task, 0);
5541                 } else {
5542                         ret = dlun0->lu_abort(lu, STMF_LU_ABORT_TASK, task, 0);
5543                 }
5544                 if ((ret == STMF_ABORT_SUCCESS) || (ret == STMF_NOT_FOUND)) {
5545                         stmf_task_lu_aborted(task, ret, STMF_IOF_LU_DONE);
5546                 } else if (ret == STMF_BUSY) {
5547                         atomic_and_32(&itask->itask_flags,
5548                             ~ITASK_LU_ABORT_CALLED);
5549                 } else if (ret != STMF_SUCCESS) {
5550                         (void) snprintf(info, sizeof (info),
5551                             "Abort failed by LU %p, ret %llx", (void *)lu, ret);
5552                         stmf_abort_task_offline(task, 1, info);
5553                 }
5554         } else if (itask->itask_flags & ITASK_KNOWN_TO_LU) {
5555                 if (ddi_get_lbolt() > (itask->itask_start_time +
5556                     STMF_SEC2TICK(lu->lu_abort_timeout?
5557                     lu->lu_abort_timeout : ITASK_DEFAULT_ABORT_TIMEOUT))) {
5558                         (void) snprintf(info, sizeof (info),
5559                             "lu abort timed out");
5560                         stmf_abort_task_offline(itask->itask_task, 1, info);
5561                 }
5562         }
5563 
5564         /*
5565          * NOTE: After the call to either stmf_abort_task_offline() or
5566          * stmf_task_lu_abort() the itask_mutex was dropped and reacquired
5567          * to avoid a deadlock situation with stmf_state.stmf_lock.
5568          */
5569 
5570         new = itask->itask_flags;
5571         if ((itask->itask_flags & (ITASK_KNOWN_TO_TGT_PORT |
5572             ITASK_TGT_PORT_ABORT_CALLED)) == ITASK_KNOWN_TO_TGT_PORT) {
5573                 new |= ITASK_TGT_PORT_ABORT_CALLED;
5574                 call_port_abort = 1;
5575         } else {
5576                 call_port_abort = 0;
5577         }
5578         itask->itask_flags = new;
5579 
5580         if (call_port_abort) {
5581                 ret = lport->lport_abort(lport, STMF_LPORT_ABORT_TASK, task, 0);
5582                 if ((ret == STMF_ABORT_SUCCESS) || (ret == STMF_NOT_FOUND)) {
5583                         stmf_task_lport_aborted(task, ret, STMF_IOF_LPORT_DONE);
5584                 } else if (ret == STMF_BUSY) {
5585                         atomic_and_32(&itask->itask_flags,
5586                             ~ITASK_TGT_PORT_ABORT_CALLED);
5587                 } else if (ret != STMF_SUCCESS) {
5588                         (void) snprintf(info, sizeof (info),
5589                             "Abort failed by tgt port %p ret %llx",
5590                             (void *)lport, ret);
5591                         stmf_abort_task_offline(task, 0, info);
5592                 }
5593         } else if (itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT) {
5594                 if (ddi_get_lbolt() > (itask->itask_start_time +
5595                     STMF_SEC2TICK(lport->lport_abort_timeout?
5596                     lport->lport_abort_timeout :
5597                     ITASK_DEFAULT_ABORT_TIMEOUT))) {
5598                         (void) snprintf(info, sizeof (info),
5599                             "lport abort timed out");
5600                         stmf_abort_task_offline(itask->itask_task, 0, info);
5601                 }
5602         }
5603         mutex_exit(&itask->itask_mutex);
5604 }
5605 
5606 stmf_status_t
5607 stmf_ctl(int cmd, void *obj, void *arg)
5608 {
5609         stmf_status_t                   ret;
5610         stmf_i_lu_t                     *ilu;
5611         stmf_i_local_port_t             *ilport;
5612         stmf_state_change_info_t        *ssci = (stmf_state_change_info_t *)arg;
5613 
5614         mutex_enter(&stmf_state.stmf_lock);
5615         ret = STMF_INVALID_ARG;
5616         if (cmd & STMF_CMD_LU_OP) {
5617                 ilu = stmf_lookup_lu((stmf_lu_t *)obj);
5618                 if (ilu == NULL) {
5619                         goto stmf_ctl_lock_exit;
5620                 }
5621                 DTRACE_PROBE3(lu__state__change,
5622                     stmf_lu_t *, ilu->ilu_lu,
5623                     int, cmd, stmf_state_change_info_t *, ssci);
 
5915         sdid->association = ID_IS_TARGET_PORT;
5916         sdid->ident_length = 20;
5917         /* Convert wwn value to "wwn.XXXXXXXXXXXXXXXX" format */
5918         (void) snprintf(wwn_str, sizeof (wwn_str),
5919             "wwn.%02X%02X%02X%02X%02X%02X%02X%02X",
5920             wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
5921         bcopy(wwn_str, (char *)sdid->ident, 20);
5922 }
5923 
5924 
5925 stmf_xfer_data_t *
5926 stmf_prepare_tpgs_data(uint8_t ilu_alua)
5927 {
5928         stmf_xfer_data_t *xd;
5929         stmf_i_local_port_t *ilport;
5930         uint8_t *p;
5931         uint32_t sz, asz, nports = 0, nports_standby = 0;
5932 
5933         mutex_enter(&stmf_state.stmf_lock);
5934         /* check if any ports are standby and create second group */
5935         for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
5936             ilport = ilport->ilport_next) {
5937                 if (ilport->ilport_standby == 1) {
5938                         nports_standby++;
5939                 } else {
5940                         nports++;
5941                 }
5942         }
5943 
5944         /*
5945          * Section 6.25 REPORT TARGET PORT GROUPS
5946          * The reply can contain many group replies. Each group is limited
5947          * to 255 port identifiers so we'll need to limit the amount of
5948          * data returned. For FC ports there's a physical limitation in
5949          * machines that make reaching 255 ports very, very unlikely. For
5950          * iSCSI on the other hand recent changes mean the port count could
5951          * be as high as 4096 (current limit). Limiting the data returned
5952          * for iSCSI isn't as bad as it sounds. This information is only
5953          * important for ALUA, which isn't supported for iSCSI. iSCSI uses
5954          * virtual IP addresses to deal with node fail over in a cluster.
5955          */
5956         nports = min(nports, 255);
5957         nports_standby = min(nports_standby, 255);
5958 
5959         /*
5960          * The first 4 bytes of the returned data is the length. The
5961          * size of the Target Port Group header is 8 bytes. So, that's where
5962          * the 12 comes from. Each port entry is 4 bytes in size.
5963          */
5964         sz = (nports * 4) + 12;
5965         if (nports_standby != 0 && ilu_alua != 0) {
5966                 /* --- Only add 8 bytes since it's just the Group header ----*/
5967                 sz += (nports_standby * 4) + 8;
5968         }
5969 
5970         /*
5971          * The stmf_xfer_data structure contains 4 bytes that will be
5972          * part of the data buffer. So, subtract the 4 bytes from the space
5973          * needed.
5974          */
5975         asz = sizeof (*xd) + sz - 4;
5976         xd = (stmf_xfer_data_t *)kmem_zalloc(asz, KM_NOSLEEP);
5977         if (xd == NULL) {
5978                 mutex_exit(&stmf_state.stmf_lock);
5979                 return (NULL);
5980         }
5981         xd->alloc_size = asz;
5982         xd->size_left = sz;
5983 
5984         p = xd->buf;
5985 
5986         /* ---- length values never include the field that holds the size ----*/
5987         *((uint32_t *)p) = BE_32(sz - 4);
5988         p += 4;
5989 
5990         /* ---- Now fill out the first Target Group header ---- */
5991         p[0] = 0x80;    /* PREF */
5992         p[1] = 5;       /* AO_SUP, S_SUP */
5993         if (stmf_state.stmf_alua_node == 1) {
5994                 p[3] = 1;       /* Group 1 */
5995         } else {
5996                 p[3] = 0;       /* Group 0 */
5997         }
5998         p[7] = nports & 0xff;
5999         p += 8;
6000         for (ilport = stmf_state.stmf_ilportlist; ilport != NULL && nports != 0;
6001             ilport = ilport->ilport_next) {
6002                 if (ilport->ilport_standby == 1) {
6003                         continue;
6004                 }
6005                 ((uint16_t *)p)[1] = BE_16(ilport->ilport_rtpid);
6006                 p += 4;
6007                 nports--;
6008         }
6009         if (nports_standby != 0 && ilu_alua != 0) {
6010                 p[0] = 0x02;    /* Non PREF, Standby */
6011                 p[1] = 5;       /* AO_SUP, S_SUP */
6012                 if (stmf_state.stmf_alua_node == 1) {
6013                         p[3] = 0;       /* Group 0 */
6014                 } else {
6015                         p[3] = 1;       /* Group 1 */
6016                 }
6017                 p[7] = nports_standby & 0xff;
6018                 p += 8;
6019                 for (ilport = stmf_state.stmf_ilportlist; ilport != NULL &&
6020                     nports_standby != 0; ilport = ilport->ilport_next) {
6021                         if (ilport->ilport_standby == 0) {
6022                                 continue;
6023                         }
6024                         ((uint16_t *)p)[1] = BE_16(ilport->ilport_rtpid);
6025                         p += 4;
6026                         nports_standby--;
6027                 }
6028         }
6029 
6030         mutex_exit(&stmf_state.stmf_lock);
6031 
6032         return (xd);
6033 }
6034 
6035 struct scsi_devid_desc *
6036 stmf_scsilib_get_devid_desc(uint16_t rtpid)
6037 {
6038         scsi_devid_desc_t *devid = NULL;
6039         stmf_i_local_port_t *ilport;
6040 
6041         mutex_enter(&stmf_state.stmf_lock);
6042 
6043         for (ilport = stmf_state.stmf_ilportlist; ilport;
6044             ilport = ilport->ilport_next) {
6045                 if (ilport->ilport_rtpid == rtpid) {
6046                         scsi_devid_desc_t *id = ilport->ilport_lport->lport_id;
 
6247                         break;
6248                 }
6249         }
6250 
6251         page[2] = (m >> 8) & 0xff;
6252         page[3] = m & 0xff;
6253 
6254         return (n);
6255 }
6256 
6257 void
6258 stmf_scsilib_handle_report_tpgs(scsi_task_t *task, stmf_data_buf_t *dbuf)
6259 {
6260         stmf_i_scsi_task_t *itask =
6261             (stmf_i_scsi_task_t *)task->task_stmf_private;
6262         stmf_i_lu_t *ilu =
6263             (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
6264         stmf_xfer_data_t *xd;
6265         uint32_t sz, minsz;
6266 
6267         mutex_enter(&itask->itask_mutex);
6268         itask->itask_flags |= ITASK_DEFAULT_HANDLING;
6269 
6270         task->task_cmd_xfer_length =
6271             ((((uint32_t)task->task_cdb[6]) << 24) |
6272             (((uint32_t)task->task_cdb[7]) << 16) |
6273             (((uint32_t)task->task_cdb[8]) << 8) |
6274             ((uint32_t)task->task_cdb[9]));
6275 
6276         if (task->task_additional_flags &
6277             TASK_AF_NO_EXPECTED_XFER_LENGTH) {
6278                 task->task_expected_xfer_length =
6279                     task->task_cmd_xfer_length;
6280         }
6281         mutex_exit(&itask->itask_mutex);
6282 
6283         if (task->task_cmd_xfer_length == 0) {
6284                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
6285                 return;
6286         }
6287         if (task->task_cmd_xfer_length < 4) {
6288                 stmf_scsilib_send_status(task, STATUS_CHECK,
6289                     STMF_SAA_INVALID_FIELD_IN_CDB);
6290                 return;
6291         }
6292 
6293         sz = min(task->task_expected_xfer_length,
6294             task->task_cmd_xfer_length);
6295 
6296         xd = stmf_prepare_tpgs_data(ilu->ilu_alua);
6297 
6298         if (xd == NULL) {
6299                 stmf_abort(STMF_QUEUE_TASK_ABORT, task,
6300                     STMF_ALLOC_FAILURE, NULL);
6301                 return;
 
6367         /*
6368          * To sync with target reset, grab this lock. The LU is not going
6369          * anywhere as there is atleast one task pending (this task).
6370          */
6371         mutex_enter(&stmf_state.stmf_lock);
6372 
6373         if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
6374                 mutex_exit(&stmf_state.stmf_lock);
6375                 stmf_scsilib_send_status(task, STATUS_CHECK,
6376                     STMF_SAA_OPERATION_IN_PROGRESS);
6377                 return;
6378         }
6379         atomic_or_32(&ilu->ilu_flags, ILU_RESET_ACTIVE);
6380         mutex_exit(&stmf_state.stmf_lock);
6381 
6382         /*
6383          * Mark this task as the one causing LU reset so that we know who
6384          * was responsible for setting the ILU_RESET_ACTIVE. In case this
6385          * task itself gets aborted, we will clear ILU_RESET_ACTIVE.
6386          */
6387         mutex_enter(&itask->itask_mutex);
6388         itask->itask_flags |= ITASK_DEFAULT_HANDLING | ITASK_CAUSING_LU_RESET;
6389         mutex_exit(&itask->itask_mutex);
6390 
6391         /* Initiatiate abort on all commands on this LU except this one */
6392         stmf_abort(STMF_QUEUE_ABORT_LU, task, STMF_ABORTED, task->task_lu);
6393 
6394         /* Start polling on this task */
6395         if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
6396             != STMF_SUCCESS) {
6397                 stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ALLOC_FAILURE,
6398                     NULL);
6399                 return;
6400         }
6401 }
6402 
6403 void
6404 stmf_handle_target_reset(scsi_task_t *task)
6405 {
6406         stmf_i_scsi_task_t *itask;
6407         stmf_i_lu_t *ilu;
6408         stmf_i_scsi_session_t *iss;
6409         stmf_lun_map_t *lm;
 
6445                 ilu = (stmf_i_lu_t *)(lm_ent->ent_lu->lu_stmf_private);
6446                 if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
6447                         atomic_and_32(&iss->iss_flags, ~ISS_RESET_ACTIVE);
6448                         rw_exit(iss->iss_lockp);
6449                         mutex_exit(&stmf_state.stmf_lock);
6450                         stmf_scsilib_send_status(task, STATUS_CHECK,
6451                             STMF_SAA_OPERATION_IN_PROGRESS);
6452                         return;
6453                 }
6454         }
6455         if (lf == 0) {
6456                 /* No luns in this session */
6457                 atomic_and_32(&iss->iss_flags, ~ISS_RESET_ACTIVE);
6458                 rw_exit(iss->iss_lockp);
6459                 mutex_exit(&stmf_state.stmf_lock);
6460                 stmf_scsilib_send_status(task, STATUS_GOOD, 0);
6461                 return;
6462         }
6463 
6464         /* ok, start the damage */
6465         mutex_enter(&itask->itask_mutex);
6466         itask->itask_flags |= ITASK_DEFAULT_HANDLING |
6467             ITASK_CAUSING_TARGET_RESET;
6468         mutex_exit(&itask->itask_mutex);
6469         for (i = 0; i < lm->lm_nentries; i++) {
6470                 if (lm->lm_plus[i] == NULL)
6471                         continue;
6472                 lm_ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
6473                 ilu = (stmf_i_lu_t *)(lm_ent->ent_lu->lu_stmf_private);
6474                 atomic_or_32(&ilu->ilu_flags, ILU_RESET_ACTIVE);
6475         }
6476 
6477         for (i = 0; i < lm->lm_nentries; i++) {
6478                 if (lm->lm_plus[i] == NULL)
6479                         continue;
6480                 lm_ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
6481                 stmf_abort(STMF_QUEUE_ABORT_LU, task, STMF_ABORTED,
6482                     lm_ent->ent_lu);
6483         }
6484 
6485         rw_exit(iss->iss_lockp);
6486         mutex_exit(&stmf_state.stmf_lock);
6487 
6488         /* Start polling on this task */
 
6506             (task->task_cdb[0] == SCMD_INQUIRY)) {
6507                 rw_exit(iss->iss_lockp);
6508                 return (0);
6509         }
6510         atomic_and_32(&iss->iss_flags,
6511             ~(ISS_LUN_INVENTORY_CHANGED | ISS_GOT_INITIAL_LUNS));
6512         rw_exit(iss->iss_lockp);
6513 
6514         if (task->task_cdb[0] == SCMD_REPORT_LUNS) {
6515                 return (0);
6516         }
6517         stmf_scsilib_send_status(task, STATUS_CHECK,
6518             STMF_SAA_REPORT_LUN_DATA_HAS_CHANGED);
6519         return (1);
6520 }
6521 
6522 void
6523 stmf_worker_init()
6524 {
6525         uint32_t i;
6526         stmf_worker_t *w;
6527 
6528         /* Make local copy of global tunables */
6529 
6530         /*
6531          * Allow workers to be scaled down to a very low number for cases
6532          * where the load is light.  If the number of threads gets below
6533          * 4 assume it is a mistake and force the threads back to a
6534          * reasonable number.  The low limit of 4 is simply legacy and
6535          * may be too low.
6536          */
6537         ASSERT(stmf_workers == NULL);
6538         if (stmf_nworkers < 4) {
6539                 stmf_nworkers = 64;
6540         }
6541 
6542         stmf_workers = (stmf_worker_t *)kmem_zalloc(
6543             sizeof (stmf_worker_t) * stmf_nworkers, KM_SLEEP);
6544         for (i = 0; i < stmf_nworkers; i++) {
6545                 stmf_worker_t *w = &stmf_workers[i];
6546                 mutex_init(&w->worker_lock, NULL, MUTEX_DRIVER, NULL);
6547                 cv_init(&w->worker_cv, NULL, CV_DRIVER, NULL);
6548         }
6549         stmf_workers_state = STMF_WORKERS_ENABLED;
6550 
6551         /* Check if we are starting */
6552         if (stmf_nworkers_cur < stmf_nworkers - 1) {
6553                 for (i = stmf_nworkers_cur; i < stmf_nworkers; i++) {
6554                         w = &stmf_workers[i];
6555                         w->worker_tid = thread_create(NULL, 0, stmf_worker_task,
6556                             (void *)&stmf_workers[i], 0, &p0, TS_RUN,
6557                             minclsyspri);
6558                         stmf_nworkers_accepting_cmds++;
6559                 }
6560                 return;
6561         }
6562 
6563         /* Lets wait for atleast one worker to start */
6564         while (stmf_nworkers_cur == 0)
6565                 delay(drv_usectohz(20 * 1000));
6566 }
6567 
6568 stmf_status_t
6569 stmf_worker_fini()
6570 {
6571         int i;
6572         clock_t sb;
6573 
6574         if (stmf_workers_state == STMF_WORKERS_DISABLED)
6575                 return (STMF_SUCCESS);
6576         ASSERT(stmf_workers);
6577         stmf_workers_state = STMF_WORKERS_DISABLED;
6578         cv_signal(&stmf_state.stmf_cv);
6579 
6580         sb = ddi_get_lbolt() + drv_usectohz(10 * 1000 * 1000);
6581         /* Wait for all the threads to die */
6582         while (stmf_nworkers_cur != 0) {
6583                 if (ddi_get_lbolt() > sb) {
6584                         stmf_workers_state = STMF_WORKERS_ENABLED;
6585                         return (STMF_BUSY);
6586                 }
6587                 delay(drv_usectohz(100 * 1000));
6588         }
6589         for (i = 0; i < stmf_nworkers; i++) {
6590                 stmf_worker_t *w = &stmf_workers[i];
6591                 mutex_destroy(&w->worker_lock);
6592                 cv_destroy(&w->worker_cv);
6593         }
6594         kmem_free(stmf_workers, sizeof (stmf_worker_t) * stmf_nworkers);
6595         stmf_workers = NULL;
6596 
6597         return (STMF_SUCCESS);
6598 }
6599 
6600 void
6601 stmf_worker_task(void *arg)
6602 {
6603         stmf_worker_t *w;
6604         stmf_i_scsi_session_t *iss;
6605         scsi_task_t *task;
6606         stmf_i_scsi_task_t *itask;
6607         stmf_data_buf_t *dbuf;
6608         stmf_lu_t *lu;
6609         clock_t wait_timer = 0;
6610         clock_t wait_ticks, wait_delta = 0;
6611         uint8_t curcmd;
6612         uint8_t abort_free;
6613         uint8_t wait_queue;
6614         uint8_t dec_qdepth;
6615 
6616         w = (stmf_worker_t *)arg;
6617         wait_ticks = drv_usectohz(10000);
6618 
6619         DTRACE_PROBE1(worker__create, stmf_worker_t, w);
6620         mutex_enter(&w->worker_lock);
6621         w->worker_flags |= STMF_WORKER_STARTED | STMF_WORKER_ACTIVE;
6622         atomic_inc_32(&stmf_nworkers_cur);
6623 
6624 stmf_worker_loop:
6625         if ((w->worker_ref_count == 0) &&
6626             (w->worker_flags & STMF_WORKER_TERMINATE)) {
6627                 w->worker_flags &= ~(STMF_WORKER_STARTED |
6628                     STMF_WORKER_ACTIVE | STMF_WORKER_TERMINATE);
6629                 w->worker_tid = NULL;
6630                 mutex_exit(&w->worker_lock);
6631                 DTRACE_PROBE1(worker__destroy, stmf_worker_t, w);
6632                 atomic_dec_32(&stmf_nworkers_cur);
6633                 thread_exit();
6634         }
6635 
6636         /* CONSTCOND */
6637         while (1) {
6638                 /* worker lock is held at this point */
6639                 dec_qdepth = 0;
6640                 if (wait_timer && (ddi_get_lbolt() >= wait_timer)) {
6641                         wait_timer = 0;
6642                         wait_delta = 0;
6643                         if (w->worker_wait_head) {
6644                                 ASSERT(w->worker_wait_tail);
6645                                 if (w->worker_task_head == NULL)
6646                                         w->worker_task_head =
6647                                             w->worker_wait_head;
6648                                 else
6649                                         w->worker_task_tail->itask_worker_next =
6650                                             w->worker_wait_head;
6651                                 w->worker_task_tail = w->worker_wait_tail;
6652                                 w->worker_wait_head = w->worker_wait_tail =
6653                                     NULL;
6654                         }
6655                 }
6656 
6657                 STMF_DEQUEUE_ITASK(w, itask);
6658                 if (itask == NULL)
6659                         break;
6660 
6661                 ASSERT((itask->itask_flags & ITASK_IN_FREE_LIST) == 0);
6662                 task = itask->itask_task;
6663                 DTRACE_PROBE2(worker__active, stmf_worker_t, w,
6664                     scsi_task_t *, task);
6665                 wait_queue = 0;
6666                 abort_free = 0;
6667                 mutex_exit(&w->worker_lock);
6668                 mutex_enter(&itask->itask_mutex);
6669                 mutex_enter(&w->worker_lock);
6670 
6671                 if (itask->itask_ncmds > 0) {
6672                         curcmd = itask->itask_cmd_stack[itask->itask_ncmds - 1];
6673                 } else {
6674                         ASSERT(itask->itask_flags & ITASK_BEING_ABORTED);
6675                 }
6676                 if (itask->itask_flags & ITASK_BEING_ABORTED) {
6677                         itask->itask_ncmds = 1;
6678                         curcmd = itask->itask_cmd_stack[0] =
6679                             ITASK_CMD_ABORT;
6680                         goto out_itask_flag_loop;
6681                 } else if ((curcmd & ITASK_CMD_MASK) == ITASK_CMD_NEW_TASK) {
6682                         /*
6683                          * set ITASK_KSTAT_IN_RUNQ, this flag
6684                          * will not reset until task completed
6685                          */
6686                         itask->itask_flags |= ITASK_KNOWN_TO_LU |
6687                             ITASK_KSTAT_IN_RUNQ;
6688                 } else {
6689                         goto out_itask_flag_loop;
6690                 }
6691 
6692 out_itask_flag_loop:
6693 
6694                 /*
6695                  * Decide if this task needs to go to a queue and/or if
6696                  * we can decrement the itask_cmd_stack.
6697                  */
6698                 if (curcmd == ITASK_CMD_ABORT) {
6699                         if (itask->itask_flags & (ITASK_KNOWN_TO_LU |
6700                             ITASK_KNOWN_TO_TGT_PORT)) {
6701                                 wait_queue = 1;
6702                         } else {
6703                                 abort_free = 1;
6704                         }
6705                 } else if ((curcmd & ITASK_CMD_POLL) &&
6706                     (itask->itask_poll_timeout > ddi_get_lbolt())) {
6707                         wait_queue = 1;
6708                 }
6709 
6710                 if (wait_queue) {
 
6729                         w->worker_task_tail = itask;
6730                 } else {
6731                         atomic_and_32(&itask->itask_flags,
6732                             ~ITASK_IN_WORKER_QUEUE);
6733                         /*
6734                          * This is where the queue depth should go down by
6735                          * one but we delay that on purpose to account for
6736                          * the call into the provider. The actual decrement
6737                          * happens after the worker has done its job.
6738                          */
6739                         dec_qdepth = 1;
6740                         itask->itask_waitq_time +=
6741                             gethrtime() - itask->itask_waitq_enter_timestamp;
6742                 }
6743 
6744                 /* We made it here means we are going to call LU */
6745                 if ((itask->itask_flags & ITASK_DEFAULT_HANDLING) == 0)
6746                         lu = task->task_lu;
6747                 else
6748                         lu = dlun0;
6749 
6750                 dbuf = itask->itask_dbufs[ITASK_CMD_BUF_NDX(curcmd)];
6751                 mutex_exit(&w->worker_lock);
6752                 curcmd &= ITASK_CMD_MASK;
6753                 stmf_task_audit(itask, TE_PROCESS_CMD, curcmd, dbuf);
6754                 mutex_exit(&itask->itask_mutex);
6755 
6756                 switch (curcmd) {
6757                 case ITASK_CMD_NEW_TASK:
6758                         iss = (stmf_i_scsi_session_t *)
6759                             task->task_session->ss_stmf_private;
6760                         stmf_itl_lu_new_task(itask);
6761                         if (iss->iss_flags & ISS_LUN_INVENTORY_CHANGED) {
6762                                 if (stmf_handle_cmd_during_ic(itask)) {
6763                                         break;
6764                                 }
6765                         }
6766 #ifdef  DEBUG
6767                         if (stmf_drop_task_counter > 0) {
6768                                 if (atomic_dec_32_nv(
6769                                     (uint32_t *)&stmf_drop_task_counter) == 1) {
6770                                         break;
6771                                 }
6772                         }
6773 #endif
6774                         DTRACE_PROBE1(scsi__task__start, scsi_task_t *, task);
6775                         lu->lu_new_task(task, dbuf);
6776                         break;
6777                 case ITASK_CMD_DATA_XFER_DONE:
6778                         lu->lu_dbuf_xfer_done(task, dbuf);
6779                         break;
6780                 case ITASK_CMD_STATUS_DONE:
6781                         lu->lu_send_status_done(task);
6782                         break;
6783                 case ITASK_CMD_ABORT:
6784                         if (abort_free) {
6785                                 mutex_enter(&itask->itask_mutex);
6786                                 stmf_task_free(task);
6787                         } else {
6788                                 stmf_do_task_abort(task);
6789                         }
6790                         break;
6791                 case ITASK_CMD_POLL_LU:
6792                         if (!wait_queue) {
6793                                 lu->lu_task_poll(task);
6794                         }
6795                         break;
6796                 case ITASK_CMD_POLL_LPORT:
6797                         if (!wait_queue)
6798                                 task->task_lport->lport_task_poll(task);
6799                         break;
6800                 case ITASK_CMD_SEND_STATUS:
6801                 /* case ITASK_CMD_XFER_DATA: */
6802                         break;
6803                 }
6804 
6805                 mutex_enter(&w->worker_lock);
6806                 if (dec_qdepth) {
6807                         w->worker_queue_depth--;
6808                 }
6809         }
6810         if ((w->worker_flags & STMF_WORKER_TERMINATE) && (wait_timer == 0)) {
6811                 if (w->worker_ref_count == 0)
6812                         goto stmf_worker_loop;
6813                 else {
6814                         wait_timer = ddi_get_lbolt() + 1;
6815                         wait_delta = 1;
6816                 }
6817         }
6818         w->worker_flags &= ~STMF_WORKER_ACTIVE;
6819         if (wait_timer) {
6820                 DTRACE_PROBE1(worker__timed__sleep, stmf_worker_t, w);
6821                 (void) cv_reltimedwait(&w->worker_cv, &w->worker_lock,
6822                     wait_delta, TR_CLOCK_TICK);
6823         } else {
6824                 DTRACE_PROBE1(worker__sleep, stmf_worker_t, w);
6825                 cv_wait(&w->worker_cv, &w->worker_lock);
6826         }
6827         DTRACE_PROBE1(worker__wakeup, stmf_worker_t, w);
6828         w->worker_flags |= STMF_WORKER_ACTIVE;
6829         goto stmf_worker_loop;
6830 }
6831 
6832 /*
6833  * Fills out a dbuf from stmf_xfer_data_t (contained in the db_lu_private).
6834  * If all the data has been filled out, frees the xd and makes
6835  * db_lu_private NULL.
6836  */
6837 void
6838 stmf_xd_to_dbuf(stmf_data_buf_t *dbuf, int set_rel_off)
6839 {
6840         stmf_xfer_data_t *xd;
6841         uint8_t *p;
6842         int i;
6843         uint32_t s;
6844 
6845         xd = (stmf_xfer_data_t *)dbuf->db_lu_private;
6846         dbuf->db_data_size = 0;
6847         if (set_rel_off)
6848                 dbuf->db_relative_offset = xd->size_done;
6849         for (i = 0; i < dbuf->db_sglist_length; i++) {
6850                 s = min(xd->size_left, dbuf->db_sglist[i].seg_length);
6851                 p = &xd->buf[xd->size_done];
 
6928                         stmf_abort(STMF_QUEUE_TASK_ABORT, task,
6929                             STMF_ALLOC_FAILURE, NULL);
6930                         return;
6931                 }
6932                 dbuf->db_lu_private = NULL;
6933 
6934                 p = dbuf->db_sglist[0].seg_addr;
6935 
6936                 /*
6937                  * Standard inquiry handling only.
6938                  */
6939 
6940                 bzero(p, inq_page_length + 5);
6941 
6942                 p[0] = DPQ_SUPPORTED | DTYPE_UNKNOWN;
6943                 p[2] = 5;
6944                 p[3] = 0x12;
6945                 p[4] = inq_page_length;
6946                 p[6] = 0x80;
6947 
6948                 (void) strncpy((char *)p+8, "NONE    ", 8);
6949                 (void) strncpy((char *)p+16, "NONE            ", 16);
6950                 (void) strncpy((char *)p+32, "NONE", 4);
6951 
6952                 dbuf->db_data_size = sz;
6953                 dbuf->db_relative_offset = 0;
6954                 dbuf->db_flags = DB_DIRECTION_TO_RPORT;
6955                 (void) stmf_xfer_data(task, dbuf, 0);
6956 
6957                 return;
6958 
6959         case SCMD_REPORT_LUNS:
6960                 task->task_cmd_xfer_length =
6961                     ((((uint32_t)task->task_cdb[6]) << 24) |
6962                     (((uint32_t)task->task_cdb[7]) << 16) |
6963                     (((uint32_t)task->task_cdb[8]) << 8) |
6964                     ((uint32_t)task->task_cdb[9]));
6965 
6966                 if (task->task_additional_flags &
6967                     TASK_AF_NO_EXPECTED_XFER_LENGTH) {
6968                         task->task_expected_xfer_length =
6969                             task->task_cmd_xfer_length;
6970                 }
 
7140         case TM_CLEAR_TASK_SET:
7141         case TM_LUN_RESET:
7142                 (void) stmf_lun_reset_poll(task->task_lu, task, 0);
7143                 return;
7144         case TM_TARGET_RESET:
7145         case TM_TARGET_COLD_RESET:
7146         case TM_TARGET_WARM_RESET:
7147                 stmf_target_reset_poll(task);
7148                 return;
7149         }
7150 }
7151 
7152 /* ARGSUSED */
7153 void
7154 stmf_dlun0_ctl(struct stmf_lu *lu, int cmd, void *arg)
7155 {
7156         /* This function will never be called */
7157         cmn_err(CE_WARN, "stmf_dlun0_ctl called with cmd %x", cmd);
7158 }
7159 
7160 /* ARGSUSED */
7161 void
7162 stmf_dlun0_task_done(struct scsi_task *task)
7163 {
7164 }
7165 
7166 void
7167 stmf_dlun_init()
7168 {
7169         stmf_i_lu_t *ilu;
7170 
7171         dlun0 = stmf_alloc(STMF_STRUCT_STMF_LU, 0, 0);
7172         dlun0->lu_task_alloc = stmf_dlun0_task_alloc;
7173         dlun0->lu_new_task = stmf_dlun0_new_task;
7174         dlun0->lu_dbuf_xfer_done = stmf_dlun0_dbuf_done;
7175         dlun0->lu_send_status_done = stmf_dlun0_status_done;
7176         dlun0->lu_task_free = stmf_dlun0_task_free;
7177         dlun0->lu_abort = stmf_dlun0_abort;
7178         dlun0->lu_task_poll = stmf_dlun0_task_poll;
7179         dlun0->lu_task_done = stmf_dlun0_task_done;
7180         dlun0->lu_ctl = stmf_dlun0_ctl;
7181 
7182         ilu = (stmf_i_lu_t *)dlun0->lu_stmf_private;
7183         ilu->ilu_cur_task_cntr = &ilu->ilu_task_cntr1;
7184 }
7185 
7186 stmf_status_t
7187 stmf_dlun_fini()
7188 {
7189         stmf_i_lu_t *ilu;
7190 
7191         ilu = (stmf_i_lu_t *)dlun0->lu_stmf_private;
7192 
7193         ASSERT(ilu->ilu_ntasks == ilu->ilu_ntasks_free);
7194         if (ilu->ilu_ntasks) {
7195                 stmf_i_scsi_task_t *itask, *nitask;
7196 
7197                 nitask = ilu->ilu_tasks;
7198                 do {
7199                         itask = nitask;
 
7424 {
7425         if (STMF_EVENT_ENABLED(ilport->ilport_event_hdl, eventid) &&
7426             (ilport->ilport_lport->lport_event_handler != NULL)) {
7427                 ilport->ilport_lport->lport_event_handler(
7428                     ilport->ilport_lport, eventid, arg, flags);
7429         }
7430 }
7431 
7432 /*
7433  * With the possibility of having multiple itl sessions pointing to the
7434  * same itl_kstat_info, the ilu_kstat_lock mutex is used to synchronize
7435  * the kstat update of the ilu_kstat_io, itl_kstat_taskq and itl_kstat_lu_xfer
7436  * statistics.
7437  */
7438 void
7439 stmf_itl_task_start(stmf_i_scsi_task_t *itask)
7440 {
7441         stmf_itl_data_t *itl = itask->itask_itl_datap;
7442         scsi_task_t     *task = itask->itask_task;
7443         stmf_i_lu_t     *ilu;
7444         stmf_i_scsi_session_t   *iss =
7445             itask->itask_task->task_session->ss_stmf_private;
7446         stmf_i_remote_port_t    *irport = iss->iss_irport;
7447 
7448         if (itl == NULL || task->task_lu == dlun0)
7449                 return;
7450         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7451         itask->itask_start_timestamp = gethrtime();
7452         itask->itask_xfer_done_timestamp = 0;
7453         if (ilu->ilu_kstat_io != NULL) {
7454                 mutex_enter(ilu->ilu_kstat_io->ks_lock);
7455                 stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter);
7456                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7457         }
7458 
7459         if (irport->irport_kstat_estat != NULL) {
7460                 if (task->task_flags & TF_READ_DATA)
7461                         atomic_inc_32(&irport->irport_nread_tasks);
7462                 else if (task->task_flags & TF_WRITE_DATA)
7463                         atomic_inc_32(&irport->irport_nwrite_tasks);
7464         }
7465 
7466         stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_enter);
7467 }
7468 
7469 void
7470 stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask)
7471 {
7472         stmf_itl_data_t *itl = itask->itask_itl_datap;
7473         scsi_task_t     *task = itask->itask_task;
7474         stmf_i_lu_t     *ilu;
7475 
7476         if (itl == NULL || task->task_lu == dlun0)
7477                 return;
7478         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7479         if (ilu->ilu_kstat_io != NULL) {
7480                 mutex_enter(ilu->ilu_kstat_io->ks_lock);
7481                 stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq);
7482                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7483         }
7484 
7485         stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_to_runq);
7486 }
7487 
7488 void
7489 stmf_itl_task_done(stmf_i_scsi_task_t *itask)
7490 {
7491         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7492         scsi_task_t             *task = itask->itask_task;
7493         stmf_i_lu_t     *ilu;
7494 
7495         itask->itask_done_timestamp = gethrtime();
7496 
7497         if (itl == NULL || task->task_lu == dlun0)
7498                 return;
7499         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7500 
7501         if (ilu->ilu_kstat_io == NULL)
7502                 return;
7503 
7504         stmf_update_kstat_rport_estat(task);
7505 
7506         mutex_enter(ilu->ilu_kstat_io->ks_lock);
7507 
7508         if (itask->itask_flags & ITASK_KSTAT_IN_RUNQ) {
7509                 stmf_update_kstat_lu_q(task, kstat_runq_exit);
7510                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7511                 stmf_update_kstat_lport_q(task, kstat_runq_exit);
7512         } else {
7513                 stmf_update_kstat_lu_q(task, kstat_waitq_exit);
7514                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7515                 stmf_update_kstat_lport_q(task, kstat_waitq_exit);
7516         }
7517 }
7518 
7519 void
7520 stmf_lu_xfer_done(scsi_task_t *task, boolean_t read, hrtime_t elapsed_time)
7521 {
7522         stmf_i_scsi_task_t *itask = task->task_stmf_private;
7523 
7524         if (task->task_lu == dlun0)
7525                 return;
7526 
7527         if (read) {
7528                 atomic_add_64((uint64_t *)&itask->itask_lu_read_time,
7529                     elapsed_time);
7530         } else {
7531                 atomic_add_64((uint64_t *)&itask->itask_lu_write_time,
7532                     elapsed_time);
7533         }
7534 }
7535 
7536 static void
7537 stmf_lport_xfer_start(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7538 {
7539         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7540 
7541         if (itl == NULL)
7542                 return;
7543 
7544         DTRACE_PROBE2(scsi__xfer__start, scsi_task_t *, itask->itask_task,
7545             stmf_data_buf_t *, dbuf);
7546 
7547         dbuf->db_xfer_start_timestamp = gethrtime();
7548 }
7549 
7550 static void
7551 stmf_lport_xfer_done(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7552 {
7553         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7554         hrtime_t                elapsed_time;
7555         uint64_t                xfer_size;
7556 
7557         if (itl == NULL)
7558                 return;
7559 
7560         xfer_size = (dbuf->db_xfer_status == STMF_SUCCESS) ?
7561             dbuf->db_data_size : 0;
7562 
7563         itask->itask_xfer_done_timestamp = gethrtime();
7564         elapsed_time = itask->itask_xfer_done_timestamp -
7565             dbuf->db_xfer_start_timestamp;
7566         if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
7567                 atomic_add_64((uint64_t *)&itask->itask_lport_read_time,
7568                     elapsed_time);
7569                 atomic_add_64((uint64_t *)&itask->itask_read_xfer,
7570                     xfer_size);
7571         } else {
7572                 atomic_add_64((uint64_t *)&itask->itask_lport_write_time,
7573                     elapsed_time);
7574                 atomic_add_64((uint64_t *)&itask->itask_write_xfer,
7575                     xfer_size);
7576         }
7577 
7578         DTRACE_PROBE3(scsi__xfer__end, scsi_task_t *, itask->itask_task,
7579             stmf_data_buf_t *, dbuf, hrtime_t, elapsed_time);
7580 
7581         dbuf->db_xfer_start_timestamp = 0;
7582 }
7583 
7584 void
7585 stmf_svc_init()
7586 {
7587         if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
7588                 return;
7589         list_create(&stmf_state.stmf_svc_list, sizeof (stmf_svc_req_t),
7590             offsetof(stmf_svc_req_t, svc_list_entry));
7591         stmf_state.stmf_svc_taskq = ddi_taskq_create(0, "STMF_SVC_TASKQ", 1,
7592             TASKQ_DEFAULTPRI, 0);
7593         (void) ddi_taskq_dispatch(stmf_state.stmf_svc_taskq,
7594             stmf_svc, 0, DDI_SLEEP);
7595 }
7596 
7597 stmf_status_t
7598 stmf_svc_fini()
7599 {
7600         uint32_t i;
7601 
7602         mutex_enter(&stmf_state.stmf_lock);
7603         if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED) {
7604                 stmf_state.stmf_svc_flags |= STMF_SVC_TERMINATE;
7605                 cv_signal(&stmf_state.stmf_cv);
7606         }
7607         mutex_exit(&stmf_state.stmf_lock);
7608 
7609         /* Wait for 5 seconds */
7610         for (i = 0; i < 500; i++) {
7611                 if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
7612                         delay(drv_usectohz(10000));
7613                 else
7614                         break;
7615         }
7616         if (i == 500)
7617                 return (STMF_BUSY);
7618 
7619         list_destroy(&stmf_state.stmf_svc_list);
7620         ddi_taskq_destroy(stmf_state.stmf_svc_taskq);
7621 
7622         return (STMF_SUCCESS);
7623 }
7624 
7625 struct stmf_svc_clocks {
7626         clock_t drain_start, drain_next;
7627         clock_t timing_start, timing_next;
7628         clock_t worker_delay;
7629 };
7630 
7631 /* ARGSUSED */
7632 void
7633 stmf_svc(void *arg)
7634 {
7635         stmf_svc_req_t *req;
7636         stmf_lu_t *lu;
7637         stmf_i_lu_t *ilu;
7638         stmf_local_port_t *lport;
7639         struct stmf_svc_clocks clks = { 0 };
7640 
7641         mutex_enter(&stmf_state.stmf_lock);
7642         stmf_state.stmf_svc_flags |= STMF_SVC_STARTED | STMF_SVC_ACTIVE;
7643 
7644         while (!(stmf_state.stmf_svc_flags & STMF_SVC_TERMINATE)) {
7645                 if (list_is_empty(&stmf_state.stmf_svc_list)) {
7646                         stmf_svc_timeout(&clks);
7647                         continue;
7648                 }
7649 
7650                 /*
7651                  * Pop the front request from the active list.  After this,
7652                  * the request will no longer be referenced by global state,
7653                  * so it should be safe to access it without holding the
7654                  * stmf state lock.
7655                  */
7656                 req = list_remove_head(&stmf_state.stmf_svc_list);
7657                 if (req == NULL)
7658                         continue;
7659 
7660                 switch (req->svc_cmd) {
7661                 case STMF_CMD_LPORT_ONLINE:
7662                         /* Fallthrough */
7663                 case STMF_CMD_LPORT_OFFLINE:
7664                         mutex_exit(&stmf_state.stmf_lock);
7665                         lport = (stmf_local_port_t *)req->svc_obj;
7666                         lport->lport_ctl(lport, req->svc_cmd, &req->svc_info);
7667                         break;
7668                 case STMF_CMD_LU_ONLINE:
7669                         mutex_exit(&stmf_state.stmf_lock);
7670                         lu = (stmf_lu_t *)req->svc_obj;
7671                         lu->lu_ctl(lu, req->svc_cmd, &req->svc_info);
7672                         break;
7673                 case STMF_CMD_LU_OFFLINE:
7674                         /* Remove all mappings of this LU */
7675                         stmf_session_lu_unmapall((stmf_lu_t *)req->svc_obj);
7676                         /* Kill all the pending I/Os for this LU */
7677                         mutex_exit(&stmf_state.stmf_lock);
7678                         stmf_task_lu_killall((stmf_lu_t *)req->svc_obj, NULL,
7679                             STMF_ABORTED);
 
7710         if (stmf_state.stmf_nlus &&
7711             ((!clks->timing_next) || (ddi_get_lbolt() >= clks->timing_next))) {
7712                 if (!stmf_state.stmf_svc_ilu_timing) {
7713                         /* we are starting a new round */
7714                         stmf_state.stmf_svc_ilu_timing =
7715                             stmf_state.stmf_ilulist;
7716                         clks->timing_start = ddi_get_lbolt();
7717                 }
7718 
7719                 stmf_check_ilu_timing();
7720                 if (!stmf_state.stmf_svc_ilu_timing) {
7721                         /* we finished a complete round */
7722                         clks->timing_next =
7723                             clks->timing_start + drv_usectohz(5*1000*1000);
7724                 } else {
7725                         /* we still have some ilu items to check */
7726                         clks->timing_next =
7727                             ddi_get_lbolt() + drv_usectohz(1*1000*1000);
7728                 }
7729 
7730                 if (!list_is_empty(&stmf_state.stmf_svc_list))
7731                         return;
7732         }
7733 
7734         /* Check if there are free tasks to clear */
7735         if (stmf_state.stmf_nlus &&
7736             ((!clks->drain_next) || (ddi_get_lbolt() >= clks->drain_next))) {
7737                 if (!stmf_state.stmf_svc_ilu_draining) {
7738                         /* we are starting a new round */
7739                         stmf_state.stmf_svc_ilu_draining =
7740                             stmf_state.stmf_ilulist;
7741                         clks->drain_start = ddi_get_lbolt();
7742                 }
7743 
7744                 stmf_check_freetask();
7745                 if (!stmf_state.stmf_svc_ilu_draining) {
7746                         /* we finished a complete round */
7747                         clks->drain_next =
7748                             clks->drain_start + drv_usectohz(10*1000*1000);
7749                 } else {
7750                         /* we still have some ilu items to check */
7751                         clks->drain_next =
7752                             ddi_get_lbolt() + drv_usectohz(1*1000*1000);
7753                 }
7754 
7755                 if (!list_is_empty(&stmf_state.stmf_svc_list))
7756                         return;
7757         }
7758 
7759         /* Check if any active session got its 1st LUN */
7760         if (stmf_state.stmf_process_initial_luns) {
7761                 int stmf_level = 0;
7762                 int port_level;
7763 
7764                 for (ilport = stmf_state.stmf_ilportlist; ilport;
7765                     ilport = next_ilport) {
7766                         int ilport_lock_held;
7767                         next_ilport = ilport->ilport_next;
7768 
7769                         if ((ilport->ilport_flags &
7770                             ILPORT_SS_GOT_INITIAL_LUNS) == 0)
7771                                 continue;
7772 
7773                         port_level = 0;
7774                         rw_enter(&ilport->ilport_lock, RW_READER);
7775                         ilport_lock_held = 1;
7776 
7777                         for (iss = ilport->ilport_ss_list; iss;
7778                             iss = iss->iss_next) {
 
7865         stmf_svc_req_t *req;
7866         int s;
7867 
7868         ASSERT(!mutex_owned(&stmf_state.stmf_lock));
7869         s = sizeof (stmf_svc_req_t);
7870         if (info->st_additional_info) {
7871                 s += strlen(info->st_additional_info) + 1;
7872         }
7873         req = kmem_zalloc(s, KM_SLEEP);
7874 
7875         req->svc_cmd = cmd;
7876         req->svc_obj = obj;
7877         req->svc_info.st_rflags = info->st_rflags;
7878         if (info->st_additional_info) {
7879                 req->svc_info.st_additional_info = (char *)(GET_BYTE_OFFSET(req,
7880                     sizeof (stmf_svc_req_t)));
7881                 (void) strcpy(req->svc_info.st_additional_info,
7882                     info->st_additional_info);
7883         }
7884         req->svc_req_alloc_size = s;
7885 
7886         mutex_enter(&stmf_state.stmf_lock);
7887         list_insert_tail(&stmf_state.stmf_svc_list, req);
7888         if ((stmf_state.stmf_svc_flags & STMF_SVC_ACTIVE) == 0) {
7889                 cv_signal(&stmf_state.stmf_cv);
7890         }
7891         mutex_exit(&stmf_state.stmf_lock);
7892 }
7893 
7894 static void
7895 stmf_svc_kill_obj_requests(void *obj)
7896 {
7897         stmf_svc_req_t *req;
7898 
7899         ASSERT(mutex_owned(&stmf_state.stmf_lock));
7900 
7901         for (req = list_head(&stmf_state.stmf_svc_list); req != NULL;
7902             req = list_next(&stmf_state.stmf_svc_list, req)) {
7903                 if (req->svc_obj == obj) {
7904                         list_remove(&stmf_state.stmf_svc_list, req);
7905                         kmem_free(req, req->svc_req_alloc_size);
7906                 }
7907         }
7908 }
7909 
7910 void
7911 stmf_trace(caddr_t ident, const char *fmt, ...)
7912 {
7913         va_list args;
7914         char tbuf[160];
7915         int len;
7916 
7917         if (!stmf_trace_on)
7918                 return;
7919         len = snprintf(tbuf, 158, "%s:%07lu: ", ident ? ident : "",
7920             ddi_get_lbolt());
7921         va_start(args, fmt);
7922         len += vsnprintf(tbuf + len, 158 - len, fmt, args);
7923         va_end(args);
7924 
7925         if (len > 158) {
 
7931         mutex_enter(&trace_buf_lock);
7932         bcopy(tbuf, &stmf_trace_buf[trace_buf_curndx], len+1);
7933         trace_buf_curndx += len;
7934         if (trace_buf_curndx > (trace_buf_size - 320))
7935                 trace_buf_curndx = 0;
7936         mutex_exit(&trace_buf_lock);
7937 }
7938 
7939 void
7940 stmf_trace_clear()
7941 {
7942         if (!stmf_trace_on)
7943                 return;
7944         mutex_enter(&trace_buf_lock);
7945         trace_buf_curndx = 0;
7946         if (trace_buf_size > 0)
7947                 stmf_trace_buf[0] = 0;
7948         mutex_exit(&trace_buf_lock);
7949 }
7950 
7951 /*
7952  * NOTE: Due to lock order problems that are not possible to fix this
7953  * method drops and reacquires the itask_mutex around the call to stmf_ctl.
7954  * Another possible work around would be to use a dispatch queue and have
7955  * the call to stmf_ctl run on another thread that's not holding the
7956  * itask_mutex. The problem with that approach is that it's difficult to
7957  * determine what impact an asynchronous change would have on the system state.
7958  */
7959 static void
7960 stmf_abort_task_offline(scsi_task_t *task, int offline_lu, char *info)
7961 {
7962         stmf_state_change_info_t        change_info;
7963         void                            *ctl_private;
7964         uint32_t                        ctl_cmd;
7965         int                             msg = 0;
7966         stmf_i_scsi_task_t              *itask =
7967             (stmf_i_scsi_task_t *)task->task_stmf_private;
7968 
7969         stmf_trace("FROM STMF", "abort_task_offline called for %s: %s",
7970             offline_lu ? "LU" : "LPORT", info ? info : "no additional info");
7971         change_info.st_additional_info = info;
7972         ASSERT(mutex_owned(&itask->itask_mutex));
7973 
7974         if (offline_lu) {
7975                 change_info.st_rflags = STMF_RFLAG_RESET |
7976                     STMF_RFLAG_LU_ABORT;
7977                 ctl_private = task->task_lu;
7978                 if (((stmf_i_lu_t *)
7979                     task->task_lu->lu_stmf_private)->ilu_state ==
7980                     STMF_STATE_ONLINE) {
7981                         msg = 1;
7982                 }
7983                 ctl_cmd = STMF_CMD_LU_OFFLINE;
7984         } else {
7985                 change_info.st_rflags = STMF_RFLAG_RESET |
7986                     STMF_RFLAG_LPORT_ABORT;
7987                 ctl_private = task->task_lport;
7988                 if (((stmf_i_local_port_t *)
7989                     task->task_lport->lport_stmf_private)->ilport_state ==
7990                     STMF_STATE_ONLINE) {
7991                         msg = 1;
7992                 }
7993                 ctl_cmd = STMF_CMD_LPORT_OFFLINE;
7994         }
7995 
7996         if (msg) {
7997                 stmf_trace(0, "Calling stmf_ctl to offline %s : %s",
7998                     offline_lu ? "LU" : "LPORT", info ? info :
7999                     "<no additional info>");
8000         }
8001         mutex_exit(&itask->itask_mutex);
8002         (void) stmf_ctl(ctl_cmd, ctl_private, &change_info);
8003         mutex_enter(&itask->itask_mutex);
8004 }
8005 
8006 static char
8007 stmf_ctoi(char c)
8008 {
8009         if ((c >= '0') && (c <= '9'))
8010                 c -= '0';
8011         else if ((c >= 'A') && (c <= 'F'))
8012                 c = c - 'A' + 10;
8013         else if ((c >= 'a') && (c <= 'f'))
8014                 c = c - 'a' + 10;
8015         else
8016                 c = -1;
8017         return (c);
8018 }
8019 
8020 /* Convert from Hex value in ASCII format to the equivalent bytes */
8021 static boolean_t
8022 stmf_base16_str_to_binary(char *c, int dplen, uint8_t *dp)
8023 {
 
8040 
8041 boolean_t
8042 stmf_scsilib_tptid_validate(scsi_transport_id_t *tptid, uint32_t total_sz,
8043     uint16_t *tptid_sz)
8044 {
8045         uint16_t tpd_len = SCSI_TPTID_SIZE;
8046 
8047         if (tptid_sz)
8048                 *tptid_sz = 0;
8049         if (total_sz < sizeof (scsi_transport_id_t))
8050                 return (B_FALSE);
8051 
8052         switch (tptid->protocol_id) {
8053 
8054         case PROTOCOL_FIBRE_CHANNEL:
8055                 /* FC Transport ID validation checks. SPC3 rev23, Table 284 */
8056                 if (total_sz < tpd_len || tptid->format_code != 0)
8057                         return (B_FALSE);
8058                 break;
8059 
8060         case PROTOCOL_iSCSI: /* CSTYLED */
8061                 {
8062                 iscsi_transport_id_t    *iscsiid;
8063                 uint16_t                adn_len, name_len;
8064 
8065                 /* Check for valid format code, SPC3 rev 23 Table 288 */
8066                 if ((total_sz < tpd_len) ||
8067                     (tptid->format_code != 0 && tptid->format_code != 1))
8068                         return (B_FALSE);
8069 
8070                 iscsiid = (iscsi_transport_id_t *)tptid;
8071                 adn_len = READ_SCSI16(iscsiid->add_len, uint16_t);
8072                 tpd_len = sizeof (iscsi_transport_id_t) + adn_len - 1;
8073 
8074                 /*
8075                  * iSCSI Transport ID validation checks.
8076                  * As per SPC3 rev 23 Section 7.5.4.6 and Table 289 & Table 290
8077                  */
8078                 if (adn_len < 20 || (adn_len % 4 != 0))
8079                         return (B_FALSE);
8080 
 
8085                 /* If the format_code is 1 check for ISID seperator */
8086                 if ((tptid->format_code == 1) && (strstr(iscsiid->iscsi_name,
8087                     SCSI_TPTID_ISCSI_ISID_SEPERATOR) == NULL))
8088                         return (B_FALSE);
8089 
8090                 }
8091                 break;
8092 
8093         case PROTOCOL_SRP:
8094                 /* SRP Transport ID validation checks. SPC3 rev23, Table 287 */
8095                 if (total_sz < tpd_len || tptid->format_code != 0)
8096                         return (B_FALSE);
8097                 break;
8098 
8099         case PROTOCOL_PARALLEL_SCSI:
8100         case PROTOCOL_SSA:
8101         case PROTOCOL_IEEE_1394:
8102         case PROTOCOL_SAS:
8103         case PROTOCOL_ADT:
8104         case PROTOCOL_ATAPI:
8105         default: /* CSTYLED */
8106                 {
8107                 stmf_dflt_scsi_tptid_t *dflttpd;
8108 
8109                 tpd_len = sizeof (stmf_dflt_scsi_tptid_t);
8110                 if (total_sz < tpd_len)
8111                         return (B_FALSE);
8112                 dflttpd = (stmf_dflt_scsi_tptid_t *)tptid;
8113                 tpd_len = tpd_len + SCSI_READ16(&dflttpd->ident_len) - 1;
8114                 if (total_sz < tpd_len)
8115                         return (B_FALSE);
8116                 }
8117                 break;
8118         }
8119         if (tptid_sz)
8120                 *tptid_sz = tpd_len;
8121         return (B_TRUE);
8122 }
8123 
8124 boolean_t
8125 stmf_scsilib_tptid_compare(scsi_transport_id_t *tpd1,
8126     scsi_transport_id_t *tpd2)
8127 {
8128         if ((tpd1->protocol_id != tpd2->protocol_id) ||
8129             (tpd1->format_code != tpd2->format_code))
8130                 return (B_FALSE);
8131 
8132         switch (tpd1->protocol_id) {
8133 
8134         case PROTOCOL_iSCSI: /* CSTYLED */
8135                 {
8136                 iscsi_transport_id_t *iscsitpd1, *iscsitpd2;
8137                 uint16_t len;
8138 
8139                 iscsitpd1 = (iscsi_transport_id_t *)tpd1;
8140                 iscsitpd2 = (iscsi_transport_id_t *)tpd2;
8141                 len = SCSI_READ16(&iscsitpd1->add_len);
8142                 if ((memcmp(iscsitpd1->add_len, iscsitpd2->add_len, 2) != 0) ||
8143                     (memcmp(iscsitpd1->iscsi_name, iscsitpd2->iscsi_name, len)
8144                     != 0))
8145                         return (B_FALSE);
8146                 }
8147                 break;
8148 
8149         case PROTOCOL_SRP: /* CSTYLED */
8150                 {
8151                 scsi_srp_transport_id_t *srptpd1, *srptpd2;
8152 
8153                 srptpd1 = (scsi_srp_transport_id_t *)tpd1;
8154                 srptpd2 = (scsi_srp_transport_id_t *)tpd2;
8155                 if (memcmp(srptpd1->srp_name, srptpd2->srp_name,
8156                     sizeof (srptpd1->srp_name)) != 0)
8157                         return (B_FALSE);
8158                 }
8159                 break;
8160 
8161         case PROTOCOL_FIBRE_CHANNEL: /* CSTYLED */
8162                 {
8163                 scsi_fc_transport_id_t *fctpd1, *fctpd2;
8164 
8165                 fctpd1 = (scsi_fc_transport_id_t *)tpd1;
8166                 fctpd2 = (scsi_fc_transport_id_t *)tpd2;
8167                 if (memcmp(fctpd1->port_name, fctpd2->port_name,
8168                     sizeof (fctpd1->port_name)) != 0)
8169                         return (B_FALSE);
8170                 }
8171                 break;
8172 
8173         case PROTOCOL_PARALLEL_SCSI:
8174         case PROTOCOL_SSA:
8175         case PROTOCOL_IEEE_1394:
8176         case PROTOCOL_SAS:
8177         case PROTOCOL_ADT:
8178         case PROTOCOL_ATAPI:
8179         default: /* CSTYLED */
8180                 {
8181                 stmf_dflt_scsi_tptid_t *dflt1, *dflt2;
8182                 uint16_t len;
8183 
8184                 dflt1 = (stmf_dflt_scsi_tptid_t *)tpd1;
8185                 dflt2 = (stmf_dflt_scsi_tptid_t *)tpd2;
8186                 len = SCSI_READ16(&dflt1->ident_len);
8187                 if ((memcmp(dflt1->ident_len, dflt2->ident_len, 2) != 0) ||
8188                     (memcmp(dflt1->ident, dflt2->ident, len) != 0))
8189                         return (B_FALSE);
8190                 }
8191                 break;
8192         }
8193         return (B_TRUE);
8194 }
8195 
8196 /*
8197  * Changes devid_desc to corresponding TransportID format
8198  * Returns :- pointer to stmf_remote_port_t
8199  * Note    :- Allocates continous memory for stmf_remote_port_t and TransportID,
 
8270                 ident_len = devid->ident_length;
8271                 sz = ALIGNED_TO_8BYTE_BOUNDARY(sizeof (stmf_dflt_scsi_tptid_t) +
8272                     ident_len - 1);
8273                 rpt = stmf_remote_port_alloc(sz);
8274                 rpt->rport_tptid->format_code = 0;
8275                 rpt->rport_tptid->protocol_id = devid->protocol_id;
8276                 dflt_tpd = (stmf_dflt_scsi_tptid_t *)rpt->rport_tptid;
8277                 SCSI_WRITE16(dflt_tpd->ident_len, ident_len);
8278                 (void) memcpy(dflt_tpd->ident, devid->ident, ident_len);
8279                 break;
8280         }
8281         return (rpt);
8282 
8283 devid_to_remote_port_fail:
8284         stmf_remote_port_free(rpt);
8285         return (NULL);
8286 
8287 }
8288 
8289 stmf_remote_port_t *
8290 stmf_remote_port_alloc(uint16_t tptid_sz)
8291 {
8292         stmf_remote_port_t *rpt;
8293         rpt = (stmf_remote_port_t *)kmem_zalloc(
8294             sizeof (stmf_remote_port_t) + tptid_sz, KM_SLEEP);
8295         rpt->rport_tptid_sz = tptid_sz;
8296         rpt->rport_tptid = (scsi_transport_id_t *)(rpt + 1);
8297         return (rpt);
8298 }
8299 
8300 void
8301 stmf_remote_port_free(stmf_remote_port_t *rpt)
8302 {
8303         /*
8304          * Note: stmf_scsilib_devid_to_remote_port() function allocates
8305          *      remote port structures for all transports in the same way, So
8306          *      it is safe to deallocate it in a protocol independent manner.
8307          *      If any of the allocation method changes, corresponding changes
8308          *      need to be made here too.
8309          */
8310         kmem_free(rpt, sizeof (stmf_remote_port_t) + rpt->rport_tptid_sz);
8311 }
8312 
8313 stmf_lu_t *
8314 stmf_check_and_hold_lu(scsi_task_t *task, uint8_t *guid)
8315 {
8316         stmf_i_scsi_session_t *iss;
8317         stmf_lu_t *lu;
8318         stmf_i_lu_t *ilu = NULL;
8319         stmf_lun_map_t *sm;
8320         stmf_lun_map_ent_t *lme;
8321         int i;
8322 
8323         iss = (stmf_i_scsi_session_t *)task->task_session->ss_stmf_private;
8324         rw_enter(iss->iss_lockp, RW_READER);
8325         sm = iss->iss_sm;
8326 
8327         for (i = 0; i < sm->lm_nentries; i++) {
8328                 if (sm->lm_plus[i] == NULL)
8329                         continue;
8330                 lme = (stmf_lun_map_ent_t *)sm->lm_plus[i];
8331                 lu = lme->ent_lu;
8332                 if (bcmp(lu->lu_id->ident, guid, 16) == 0) {
8333                         break;
8334                 }
8335                 lu = NULL;
8336         }
8337 
8338         if (!lu) {
8339                 goto hold_lu_done;
8340         }
8341 
8342         ilu = lu->lu_stmf_private;
8343         mutex_enter(&ilu->ilu_task_lock);
8344         ilu->ilu_additional_ref++;
8345         mutex_exit(&ilu->ilu_task_lock);
8346 
8347 hold_lu_done:
8348         rw_exit(iss->iss_lockp);
8349         return (lu);
8350 }
8351 
8352 void
8353 stmf_release_lu(stmf_lu_t *lu)
8354 {
8355         stmf_i_lu_t *ilu;
8356 
8357         ilu = lu->lu_stmf_private;
8358         ASSERT(ilu->ilu_additional_ref != 0);
8359         mutex_enter(&ilu->ilu_task_lock);
8360         ilu->ilu_additional_ref--;
8361         mutex_exit(&ilu->ilu_task_lock);
8362 }
8363 
8364 int
8365 stmf_is_task_being_aborted(scsi_task_t *task)
8366 {
8367         stmf_i_scsi_task_t *itask;
8368 
8369         itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
8370         if (itask->itask_flags & ITASK_BEING_ABORTED)
8371                 return (1);
8372 
8373         return (0);
8374 }
8375 
8376 volatile boolean_t stmf_pgr_aptpl_always = B_FALSE;
8377 
8378 boolean_t
8379 stmf_is_pgr_aptpl_always()
8380 {
8381         return (stmf_pgr_aptpl_always);
8382 }
 |