Print this page
3866 panic in idm module
3867 stmfCreateLu failed: GUID_IN_USE
3868 iscsi target not accepting any new connections
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Jeremy Jones <jeremy@delphix.com>
Reviewed by: Eric Diven <eric.diven@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: T Nguyen <truongqnguien@gmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>
3862 stmf + kstat = kernel panic
3863 stmf_itl_task_start() must check for ilu->ilu_kstat_io is non-null
3864 memory leak in the iSCSI code
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Jeremy Jones <jeremy@delphix.com>
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Richard Elling <richard.elling@gmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>
3621 ZFS LU stuck in the offlining state
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Jeff Biseda <jeff.biseda@delphix.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Approved by: Christopher Siden <christopher.siden@delphix.com>


   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  */
  27 
  28 #include <sys/conf.h>
  29 #include <sys/file.h>
  30 #include <sys/ddi.h>
  31 #include <sys/sunddi.h>
  32 #include <sys/modctl.h>
  33 #include <sys/scsi/scsi.h>
  34 #include <sys/scsi/generic/persist.h>
  35 #include <sys/scsi/impl/scsi_reset_notify.h>
  36 #include <sys/disp.h>
  37 #include <sys/byteorder.h>
  38 #include <sys/atomic.h>
  39 #include <sys/ethernet.h>
  40 #include <sys/sdt.h>
  41 #include <sys/nvpair.h>
  42 #include <sys/zone.h>
  43 #include <sys/id_space.h>
  44 
  45 #include <sys/stmf.h>


  48 #include <sys/stmf_ioctl.h>
  49 #include <sys/pppt_ic_if.h>
  50 
  51 #include "stmf_impl.h"
  52 #include "lun_map.h"
  53 #include "stmf_state.h"
  54 #include "stmf_stats.h"
  55 
  56 /*
  57  * Lock order:
  58  * stmf_state_lock --> ilport_lock/iss_lockp --> ilu_task_lock
  59  */
  60 
  61 static uint64_t stmf_session_counter = 0;
  62 static uint16_t stmf_rtpid_counter = 0;
  63 /* start messages at 1 */
  64 static uint64_t stmf_proxy_msg_id = 1;
  65 #define MSG_ID_TM_BIT   0x8000000000000000
  66 #define ALIGNED_TO_8BYTE_BOUNDARY(i)    (((i) + 7) & ~7)
  67 









  68 struct stmf_svc_clocks;
  69 
  70 static int stmf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
  71 static int stmf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
  72 static int stmf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
  73         void **result);
  74 static int stmf_open(dev_t *devp, int flag, int otype, cred_t *credp);
  75 static int stmf_close(dev_t dev, int flag, int otype, cred_t *credp);
  76 static int stmf_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
  77         cred_t *credp, int *rval);
  78 static int stmf_get_stmf_state(stmf_state_desc_t *std);
  79 static int stmf_set_stmf_state(stmf_state_desc_t *std);
  80 static void stmf_abort_task_offline(scsi_task_t *task, int offline_lu,
  81     char *info);
  82 static int stmf_set_alua_state(stmf_alua_state_desc_t *alua_state);
  83 static void stmf_get_alua_state(stmf_alua_state_desc_t *alua_state);
  84 
  85 static void stmf_task_audit(stmf_i_scsi_task_t *itask,
  86     task_audit_event_t te, uint32_t cmd_or_iof, stmf_data_buf_t *dbuf);
  87 
  88 static boolean_t stmf_base16_str_to_binary(char *c, int dplen, uint8_t *dp);
  89 static char stmf_ctoi(char c);
  90 stmf_xfer_data_t *stmf_prepare_tpgs_data(uint8_t ilu_alua);
  91 void stmf_svc_init();
  92 stmf_status_t stmf_svc_fini();
  93 void stmf_svc(void *arg);

  94 void stmf_svc_queue(int cmd, void *obj, stmf_state_change_info_t *info);
  95 static void stmf_svc_kill_obj_requests(void *obj);
  96 static void stmf_svc_timeout(struct stmf_svc_clocks *);
  97 void stmf_check_freetask();
  98 void stmf_abort_target_reset(scsi_task_t *task);
  99 stmf_status_t stmf_lun_reset_poll(stmf_lu_t *lu, struct scsi_task *task,
 100                                                         int target_reset);
 101 void stmf_target_reset_poll(struct scsi_task *task);
 102 void stmf_handle_lun_reset(scsi_task_t *task);
 103 void stmf_handle_target_reset(scsi_task_t *task);
 104 void stmf_xd_to_dbuf(stmf_data_buf_t *dbuf, int set_rel_off);
 105 int stmf_load_ppd_ioctl(stmf_ppioctl_data_t *ppi, uint64_t *ppi_token,
 106     uint32_t *err_ret);
 107 int stmf_delete_ppd_ioctl(stmf_ppioctl_data_t *ppi);
 108 int stmf_get_ppd_ioctl(stmf_ppioctl_data_t *ppi, stmf_ppioctl_data_t *ppi_out,
 109     uint32_t *err_ret);
 110 void stmf_delete_ppd(stmf_pp_data_t *ppd);
 111 void stmf_delete_all_ppds();
 112 void stmf_trace_clear();
 113 void stmf_worker_init();


 146 static void stmf_lport_xfer_start(stmf_i_scsi_task_t *itask,
 147     stmf_data_buf_t *dbuf);
 148 static void stmf_lport_xfer_done(stmf_i_scsi_task_t *itask,
 149     stmf_data_buf_t *dbuf);
 150 
 151 static void stmf_update_kstat_lu_q(scsi_task_t *, void());
 152 static void stmf_update_kstat_lport_q(scsi_task_t *, void());
 153 static void stmf_update_kstat_lu_io(scsi_task_t *, stmf_data_buf_t *);
 154 static void stmf_update_kstat_lport_io(scsi_task_t *, stmf_data_buf_t *);
 155 
 156 static int stmf_irport_compare(const void *void_irport1,
 157     const void *void_irport2);
 158 static stmf_i_remote_port_t *stmf_irport_create(scsi_devid_desc_t *rport_devid);
 159 static void stmf_irport_destroy(stmf_i_remote_port_t *irport);
 160 static stmf_i_remote_port_t *stmf_irport_register(
 161     scsi_devid_desc_t *rport_devid);
 162 static stmf_i_remote_port_t *stmf_irport_lookup_locked(
 163     scsi_devid_desc_t *rport_devid);
 164 static void stmf_irport_deregister(stmf_i_remote_port_t *irport);
 165 
 166 static void stmf_teardown_itl_kstats(stmf_i_itl_kstat_t *ks);
 167 static void stmf_delete_itl_kstat_by_lport(char *);
 168 static void stmf_delete_itl_kstat_by_guid(char *);
 169 static int stmf_itl_kstat_compare(const void*, const void*);
 170 static stmf_i_itl_kstat_t *stmf_itl_kstat_lookup(char *kstat_nm);
 171 static stmf_i_itl_kstat_t *stmf_itl_kstat_create(stmf_itl_data_t *itl,
 172     char *nm, scsi_devid_desc_t *lport, scsi_devid_desc_t *lun);
 173 
 174 extern struct mod_ops mod_driverops;
 175 
 176 /* =====[ Tunables ]===== */
 177 /* Internal tracing */
 178 volatile int    stmf_trace_on = 1;
 179 volatile int    stmf_trace_buf_size = (1 * 1024 * 1024);
 180 /*
 181  * The reason default task timeout is 75 is because we want the
 182  * host to timeout 1st and mostly host timeout is 60 seconds.
 183  */
 184 volatile int    stmf_default_task_timeout = 75;
 185 /*
 186  * Setting this to one means, you are responsible for config load and keeping
 187  * things in sync with persistent database.
 188  */
 189 volatile int    stmf_allow_modunload = 0;
 190 
 191 volatile int stmf_max_nworkers = 256;
 192 volatile int stmf_min_nworkers = 4;
 193 volatile int stmf_worker_scale_down_delay = 20;


 295         stmf_trace_buf = kmem_zalloc(stmf_trace_buf_size, KM_SLEEP);
 296         trace_buf_size = stmf_trace_buf_size;
 297         trace_buf_curndx = 0;
 298         mutex_init(&trace_buf_lock, NULL, MUTEX_DRIVER, 0);
 299         bzero(&stmf_state, sizeof (stmf_state_t));
 300         /* STMF service is off by default */
 301         stmf_state.stmf_service_running = 0;
 302         /* default lu/lport states are online */
 303         stmf_state.stmf_default_lu_state = STMF_STATE_ONLINE;
 304         stmf_state.stmf_default_lport_state = STMF_STATE_ONLINE;
 305         mutex_init(&stmf_state.stmf_lock, NULL, MUTEX_DRIVER, NULL);
 306         cv_init(&stmf_state.stmf_cv, NULL, CV_DRIVER, NULL);
 307         stmf_session_counter = (uint64_t)ddi_get_lbolt();
 308         avl_create(&stmf_state.stmf_irportlist,
 309             stmf_irport_compare, sizeof (stmf_i_remote_port_t),
 310             offsetof(stmf_i_remote_port_t, irport_ln));
 311         stmf_state.stmf_ilport_inst_space =
 312             id_space_create("lport-instances", 0, MAX_ILPORT);
 313         stmf_state.stmf_irport_inst_space =
 314             id_space_create("rport-instances", 0, MAX_IRPORT);
 315         avl_create(&stmf_state.stmf_itl_kstat_list,
 316             stmf_itl_kstat_compare, sizeof (stmf_i_itl_kstat_t),
 317             offsetof(stmf_i_itl_kstat_t, iitl_kstat_ln));
 318         stmf_view_init();
 319         stmf_svc_init();
 320         stmf_dlun_init();
 321         return (ret);
 322 }
 323 
 324 int
 325 _fini(void)
 326 {
 327         int ret;
 328         stmf_i_remote_port_t    *irport;
 329         stmf_i_itl_kstat_t      *ks_itl;
 330         void                    *avl_dest_cookie = NULL;
 331 
 332         if (stmf_state.stmf_service_running)
 333                 return (EBUSY);
 334         if ((!stmf_allow_modunload) &&
 335             (stmf_state.stmf_config_state != STMF_CONFIG_NONE)) {
 336                 return (EBUSY);
 337         }
 338         if (stmf_state.stmf_nlps || stmf_state.stmf_npps) {
 339                 return (EBUSY);
 340         }
 341         if (stmf_dlun_fini() != STMF_SUCCESS)
 342                 return (EBUSY);
 343         if (stmf_worker_fini() != STMF_SUCCESS) {
 344                 stmf_dlun_init();
 345                 return (EBUSY);
 346         }
 347         if (stmf_svc_fini() != STMF_SUCCESS) {
 348                 stmf_dlun_init();
 349                 stmf_worker_init();
 350                 return (EBUSY);
 351         }
 352 
 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         avl_dest_cookie = NULL;
 371         while ((ks_itl = avl_destroy_nodes(&stmf_state.stmf_itl_kstat_list,
 372             &avl_dest_cookie)) != NULL) {
 373                 stmf_teardown_itl_kstats(ks_itl);
 374                 kmem_free(ks_itl, sizeof (ks_itl));
 375         }
 376         avl_destroy(&stmf_state.stmf_itl_kstat_list);
 377 
 378         kmem_free(stmf_trace_buf, stmf_trace_buf_size);
 379         mutex_destroy(&trace_buf_lock);
 380         mutex_destroy(&stmf_state.stmf_lock);
 381         cv_destroy(&stmf_state.stmf_cv);
 382         return (ret);
 383 }
 384 
 385 int
 386 _info(struct modinfo *modinfop)
 387 {
 388         return (mod_info(&modlinkage, modinfop));
 389 }
 390 
 391 /* ARGSUSED */
 392 static int
 393 stmf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
 394 {
 395         switch (cmd) {
 396         case DDI_INFO_DEVT2DEVINFO:
 397                 *result = stmf_state.stmf_dip;


1575                 if (ilu->ilu_state != STMF_STATE_ONLINE)
1576                         continue;
1577                 (void) stmf_ctl(STMF_CMD_LU_OFFLINE, ilu->ilu_lu, &ssi);
1578         }
1579         mutex_enter(&stmf_state.stmf_lock);
1580         stmf_state.stmf_inventory_locked = 0;
1581         mutex_exit(&stmf_state.stmf_lock);
1582         return (0);
1583 }
1584 
1585 static int
1586 stmf_get_stmf_state(stmf_state_desc_t *std)
1587 {
1588         mutex_enter(&stmf_state.stmf_lock);
1589         std->state = stmf_get_service_state();
1590         std->config_state = stmf_state.stmf_config_state;
1591         mutex_exit(&stmf_state.stmf_lock);
1592 
1593         return (0);
1594 }

1595 /*
1596  * handles registration message from pppt for a logical unit
1597  */
1598 stmf_status_t
1599 stmf_ic_lu_reg(stmf_ic_reg_dereg_lun_msg_t *msg, uint32_t type)
1600 {
1601         stmf_i_lu_provider_t    *ilp;
1602         stmf_lu_provider_t      *lp;
1603         mutex_enter(&stmf_state.stmf_lock);
1604         for (ilp = stmf_state.stmf_ilplist; ilp != NULL; ilp = ilp->ilp_next) {
1605                 if (strcmp(msg->icrl_lu_provider_name,
1606                     ilp->ilp_lp->lp_name) == 0) {
1607                         lp = ilp->ilp_lp;
1608                         mutex_exit(&stmf_state.stmf_lock);
1609                         lp->lp_proxy_msg(msg->icrl_lun_id, msg->icrl_cb_arg,
1610                             msg->icrl_cb_arg_len, type);
1611                         return (STMF_SUCCESS);
1612                 }
1613         }
1614         mutex_exit(&stmf_state.stmf_lock);


3042         luid = stmf_lookup_id(&stmf_state.stmf_luid_list,
3043             lu->lu_id->ident_length, lu->lu_id->ident);
3044         if (luid) {
3045                 luid->id_pt_to_object = (void *)ilu;
3046                 ilu->ilu_luid = luid;
3047         }
3048         ilu->ilu_alias = NULL;
3049 
3050         ilu->ilu_next = stmf_state.stmf_ilulist;
3051         ilu->ilu_prev = NULL;
3052         if (ilu->ilu_next)
3053                 ilu->ilu_next->ilu_prev = ilu;
3054         stmf_state.stmf_ilulist = ilu;
3055         stmf_state.stmf_nlus++;
3056         if (lu->lu_lp) {
3057                 ((stmf_i_lu_provider_t *)
3058                     (lu->lu_lp->lp_stmf_private))->ilp_nlus++;
3059         }
3060         ilu->ilu_cur_task_cntr = &ilu->ilu_task_cntr1;
3061         STMF_EVENT_ALLOC_HANDLE(ilu->ilu_event_hdl);

3062         stmf_create_kstat_lu(ilu);
3063         /*
3064          * register with proxy module if available and logical unit
3065          * is in active state
3066          */
3067         if (stmf_state.stmf_alua_state == 1 &&
3068             ilu->ilu_access == STMF_LU_ACTIVE) {
3069                 stmf_ic_msg_status_t ic_ret = STMF_IC_MSG_SUCCESS;
3070                 stmf_ic_msg_t *ic_reg_lun;
3071                 if (lu->lu_lp && lu->lu_lp->lp_lpif_rev == LPIF_REV_2 &&
3072                     lu->lu_lp->lp_alua_support) {
3073                         ilu->ilu_alua = 1;
3074                         /* allocate the register message */
3075                         ic_reg_lun = ic_reg_lun_msg_alloc(p1,
3076                             lu->lu_lp->lp_name, lu->lu_proxy_reg_arg_len,
3077                             (uint8_t *)lu->lu_proxy_reg_arg, stmf_proxy_msg_id);
3078                         /* send the message */
3079                         if (ic_reg_lun) {
3080                                 ic_ret = ic_tx_msg(ic_reg_lun);
3081                                 if (ic_ret == STMF_IC_MSG_SUCCESS) {


3179                 }
3180                 if (ilu->ilu_luid) {
3181                         ((stmf_id_data_t *)ilu->ilu_luid)->id_pt_to_object =
3182                             NULL;
3183                         ilu->ilu_luid = NULL;
3184                 }
3185                 STMF_EVENT_FREE_HANDLE(ilu->ilu_event_hdl);
3186         } else {
3187                 mutex_exit(&stmf_state.stmf_lock);
3188                 return (STMF_BUSY);
3189         }
3190         if (ilu->ilu_kstat_info) {
3191                 kmem_free(ilu->ilu_kstat_info->ks_data,
3192                     ilu->ilu_kstat_info->ks_data_size);
3193                 kstat_delete(ilu->ilu_kstat_info);
3194         }
3195         if (ilu->ilu_kstat_io) {
3196                 kstat_delete(ilu->ilu_kstat_io);
3197                 mutex_destroy(&ilu->ilu_kstat_lock);
3198         }
3199         stmf_delete_itl_kstat_by_guid(ilu->ilu_ascii_hex_guid);
3200         mutex_exit(&stmf_state.stmf_lock);
3201         return (STMF_SUCCESS);
3202 }
3203 
3204 void
3205 stmf_set_port_standby(stmf_local_port_t *lport, uint16_t rtpid)
3206 {
3207         stmf_i_local_port_t *ilport =
3208             (stmf_i_local_port_t *)lport->lport_stmf_private;
3209         ilport->ilport_rtpid = rtpid;
3210         ilport->ilport_standby = 1;
3211 }
3212 
3213 void
3214 stmf_set_port_alua(stmf_local_port_t *lport)
3215 {
3216         stmf_i_local_port_t *ilport =
3217             (stmf_i_local_port_t *)lport->lport_stmf_private;
3218         ilport->ilport_alua = 1;
3219 }


3357                 stmf_state.stmf_nlports--;
3358                 if (lport->lport_pp) {
3359                         ((stmf_i_port_provider_t *)
3360                             (lport->lport_pp->pp_stmf_private))->ipp_npps--;
3361                 }
3362                 ilport->ilport_tg = NULL;
3363                 STMF_EVENT_FREE_HANDLE(ilport->ilport_event_hdl);
3364         } else {
3365                 mutex_exit(&stmf_state.stmf_lock);
3366                 return (STMF_BUSY);
3367         }
3368         if (ilport->ilport_kstat_info) {
3369                 kmem_free(ilport->ilport_kstat_info->ks_data,
3370                     ilport->ilport_kstat_info->ks_data_size);
3371                 kstat_delete(ilport->ilport_kstat_info);
3372         }
3373         if (ilport->ilport_kstat_io) {
3374                 kstat_delete(ilport->ilport_kstat_io);
3375                 mutex_destroy(&ilport->ilport_kstat_lock);
3376         }
3377         stmf_delete_itl_kstat_by_lport(ilport->ilport_kstat_tgt_name);
3378         mutex_exit(&stmf_state.stmf_lock);
3379         return (STMF_SUCCESS);
3380 }
3381 
3382 /*
3383  * Rport id/instance mappings remain valid until STMF is unloaded
3384  */
3385 static int
3386 stmf_irport_compare(const void *void_irport1, const void *void_irport2)
3387 {
3388         const   stmf_i_remote_port_t    *irport1 = void_irport1;
3389         const   stmf_i_remote_port_t    *irport2 = void_irport2;
3390         int                     result;
3391 
3392         /* Sort by code set then ident */
3393         if (irport1->irport_id->code_set <
3394             irport2->irport_id->code_set) {
3395                 return (-1);
3396         } else if (irport1->irport_id->code_set >
3397             irport2->irport_id->code_set) {


3686 
3687         mutex_enter(&stmf_state.stmf_lock);
3688         for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
3689             ilport = ilport->ilport_next) {
3690                 rw_enter(&ilport->ilport_lock, RW_WRITER);
3691                 for (iss = ilport->ilport_ss_list; iss != NULL;
3692                     iss = iss->iss_next) {
3693                         if (iss->iss_ss->ss_session_id == session_id) {
3694                                 if (!stay_locked)
3695                                         rw_exit(&ilport->ilport_lock);
3696                                 mutex_exit(&stmf_state.stmf_lock);
3697                                 return (iss);
3698                         }
3699                 }
3700                 rw_exit(&ilport->ilport_lock);
3701         }
3702         mutex_exit(&stmf_state.stmf_lock);
3703         return (NULL);
3704 }
3705 
3706 #define MAX_ALIAS               128
3707 
3708 static int
3709 stmf_itl_kstat_compare(const void *itl_kstat_1, const void *itl_kstat_2)
3710 {
3711         const   stmf_i_itl_kstat_t      *kstat_nm1 = itl_kstat_1;
3712         const   stmf_i_itl_kstat_t      *kstat_nm2 = itl_kstat_2;
3713         int     ret;
3714 
3715         ret = strcmp(kstat_nm1->iitl_kstat_nm, kstat_nm2->iitl_kstat_nm);
3716         if (ret < 0) {
3717                 return (-1);
3718         } else if (ret > 0) {
3719                 return (1);
3720         }
3721         return (0);
3722 }
3723 
3724 static stmf_i_itl_kstat_t *
3725 stmf_itl_kstat_lookup(char *kstat_nm)
3726 {
3727         stmf_i_itl_kstat_t      tmp;
3728         stmf_i_itl_kstat_t      *itl_kstat;
3729 
3730         ASSERT(mutex_owned(&stmf_state.stmf_lock));
3731         (void) strcpy(tmp.iitl_kstat_nm, kstat_nm);
3732         itl_kstat = avl_find(&stmf_state.stmf_itl_kstat_list, &tmp, NULL);
3733         return (itl_kstat);
3734 }
3735 
3736 static void
3737 stmf_delete_itl_kstat_by_lport(char *tgt)
3738 {
3739         stmf_i_itl_kstat_t      *ks_itl, *next;
3740 
3741         ASSERT(mutex_owned(&stmf_state.stmf_lock));
3742         ks_itl = avl_first(&stmf_state.stmf_itl_kstat_list);
3743         for (; ks_itl != NULL; ks_itl = next) {
3744                 next = AVL_NEXT(&stmf_state.stmf_itl_kstat_list, ks_itl);
3745                 if (strcmp(ks_itl->iitl_kstat_lport, tgt) == 0) {
3746                         stmf_teardown_itl_kstats(ks_itl);
3747                         avl_remove(&stmf_state.stmf_itl_kstat_list, ks_itl);
3748                         kmem_free(ks_itl, sizeof (stmf_i_itl_kstat_t));
3749                 }
3750         }
3751 }
3752 
3753 static void
3754 stmf_delete_itl_kstat_by_guid(char *guid)
3755 {
3756         stmf_i_itl_kstat_t      *ks_itl, *next;
3757 
3758         ASSERT(mutex_owned(&stmf_state.stmf_lock));
3759         ks_itl = avl_first(&stmf_state.stmf_itl_kstat_list);
3760         for (; ks_itl != NULL; ks_itl = next) {
3761                 next = AVL_NEXT(&stmf_state.stmf_itl_kstat_list, ks_itl);
3762                 if (strcmp(ks_itl->iitl_kstat_guid, guid) == 0) {
3763                         stmf_teardown_itl_kstats(ks_itl);
3764                         avl_remove(&stmf_state.stmf_itl_kstat_list, ks_itl);
3765                         kmem_free(ks_itl, sizeof (stmf_i_itl_kstat_t));
3766                 }
3767         }
3768 }
3769 
3770 static stmf_i_itl_kstat_t *
3771 stmf_itl_kstat_create(stmf_itl_data_t *itl, char *nm,
3772     scsi_devid_desc_t *lport, scsi_devid_desc_t *lun)
3773 {
3774         stmf_i_itl_kstat_t      *ks_itl;
3775         int                     i, len;
3776 
3777         ASSERT(mutex_owned(&stmf_state.stmf_lock));
3778         if ((ks_itl = stmf_itl_kstat_lookup(nm)) != NULL)
3779                 return (ks_itl);
3780 
3781         len = sizeof (stmf_i_itl_kstat_t);
3782         ks_itl = kmem_zalloc(len, KM_NOSLEEP);
3783         if (ks_itl == NULL)
3784                 return (NULL);
3785 
3786         (void) strcpy(ks_itl->iitl_kstat_nm, nm);
3787         bcopy(lport->ident, ks_itl->iitl_kstat_lport, lport->ident_length);
3788         ks_itl->iitl_kstat_lport[lport->ident_length] = '\0';
3789         for (i = 0; i < STMF_GUID_INPUT / 2; i++) {
3790                 (void) sprintf(&ks_itl->iitl_kstat_guid[i * 2], "%02x",
3791                     lun->ident[i]);
3792         }
3793         ks_itl->iitl_kstat_strbuf = itl->itl_kstat_strbuf;
3794         ks_itl->iitl_kstat_strbuflen = itl->itl_kstat_strbuflen;
3795         ks_itl->iitl_kstat_info = itl->itl_kstat_info;
3796         ks_itl->iitl_kstat_taskq = itl->itl_kstat_taskq;
3797         ks_itl->iitl_kstat_lu_xfer = itl->itl_kstat_lu_xfer;
3798         ks_itl->iitl_kstat_lport_xfer = itl->itl_kstat_lport_xfer;
3799         avl_add(&stmf_state.stmf_itl_kstat_list, ks_itl);
3800 
3801         return (ks_itl);
3802 }
3803 
3804 stmf_status_t
3805 stmf_setup_itl_kstats(stmf_itl_data_t *itl)
3806 {
3807         char                            ks_itl_id[32];
3808         char                            ks_nm[KSTAT_STRLEN];
3809         char                            ks_itl_nm[KSTAT_STRLEN];
3810         stmf_kstat_itl_info_t           *ks_itl;
3811         stmf_scsi_session_t             *ss;
3812         stmf_i_scsi_session_t           *iss;
3813         stmf_i_local_port_t             *ilport;
3814         char                            *strbuf;
3815         int                             id, len, i;
3816         char                            *rport_alias;
3817         char                            *lport_alias;
3818         char                            *lu_alias;
3819         stmf_i_itl_kstat_t              *tmp_kstat;
3820 
3821         /*
3822          * Allocate enough memory in the ITL to hold the relevant
3823          * identifiers.
3824          * rport and lport identifiers come from the stmf_scsi_session_t.
3825          * ident might not be null terminated.
3826          */
3827         ss = itl->itl_session->iss_ss;
3828         iss = ss->ss_stmf_private;
3829         ilport = ss->ss_lport->lport_stmf_private;
3830         (void) snprintf(ks_itl_id, 32, "%d.%d.%d",
3831             iss->iss_irport->irport_instance, ilport->ilport_instance,
3832             itl->itl_lun);
3833 
3834         (void) snprintf(ks_itl_nm, KSTAT_STRLEN, "itl_%s", ks_itl_id);
3835         /*
3836          * let's verify this itl_kstat already exist
3837          */
3838         if ((tmp_kstat = stmf_itl_kstat_lookup(ks_itl_nm)) != NULL) {
3839                 itl->itl_kstat_strbuf = tmp_kstat->iitl_kstat_strbuf;
3840                 itl->itl_kstat_strbuflen = tmp_kstat->iitl_kstat_strbuflen;
3841                 itl->itl_kstat_info = tmp_kstat->iitl_kstat_info;
3842                 itl->itl_kstat_taskq = tmp_kstat->iitl_kstat_taskq;
3843                 itl->itl_kstat_lu_xfer = tmp_kstat->iitl_kstat_lu_xfer;
3844                 itl->itl_kstat_lport_xfer = tmp_kstat->iitl_kstat_lport_xfer;
3845                 return (STMF_SUCCESS);
3846         }
3847 
3848         /* New itl_kstat */
3849         rport_alias = (ss->ss_rport_alias == NULL) ?
3850             "" : ss->ss_rport_alias;
3851         lport_alias = (ss->ss_lport->lport_alias == NULL) ?
3852             "" : ss->ss_lport->lport_alias;
3853         lu_alias = (itl->itl_ilu->ilu_lu->lu_alias == NULL) ?
3854             "" : itl->itl_ilu->ilu_lu->lu_alias;
3855 
3856         itl->itl_kstat_strbuflen = (ss->ss_rport_id->ident_length + 1) +
3857             (strnlen(rport_alias, MAX_ALIAS) + 1) +
3858             (ss->ss_lport->lport_id->ident_length + 1) +
3859             (strnlen(lport_alias, MAX_ALIAS) + 1) +
3860             (STMF_GUID_INPUT + 1) +
3861             (strnlen(lu_alias, MAX_ALIAS) + 1) +
3862             MAX_PROTO_STR_LEN;
3863         itl->itl_kstat_strbuf = kmem_zalloc(itl->itl_kstat_strbuflen,
3864             KM_NOSLEEP);
3865         if (itl->itl_kstat_strbuf == NULL) {
3866                 return (STMF_ALLOC_FAILURE);
3867         }
3868 
3869         ks_itl = (stmf_kstat_itl_info_t *)kmem_zalloc(sizeof (*ks_itl),
3870             KM_NOSLEEP);
3871         if (ks_itl == NULL) {
3872                 kmem_free(itl->itl_kstat_strbuf, itl->itl_kstat_strbuflen);
3873                 return (STMF_ALLOC_FAILURE);
3874         }
3875 
3876         if ((itl->itl_kstat_info = kstat_create(STMF_MODULE_NAME,
3877             0, ks_itl_nm, "misc", KSTAT_TYPE_NAMED,
3878             sizeof (stmf_kstat_itl_info_t) / sizeof (kstat_named_t),
3879             KSTAT_FLAG_VIRTUAL)) == NULL) {
3880                 goto itl_kstat_cleanup;
3881         }
3882 
3883         itl->itl_kstat_info->ks_data_size += itl->itl_kstat_strbuflen;
3884         itl->itl_kstat_info->ks_data = ks_itl;
3885 
3886         kstat_named_init(&ks_itl->i_rport_name, "rport-name",
3887             KSTAT_DATA_STRING);
3888         kstat_named_init(&ks_itl->i_rport_alias, "rport-alias",
3889             KSTAT_DATA_STRING);
3890         kstat_named_init(&ks_itl->i_lport_name, "lport-name",
3891             KSTAT_DATA_STRING);
3892         kstat_named_init(&ks_itl->i_lport_alias, "lport-alias",
3893             KSTAT_DATA_STRING);
3894         kstat_named_init(&ks_itl->i_protocol, "protocol",
3895             KSTAT_DATA_STRING);
3896         kstat_named_init(&ks_itl->i_lu_guid, "lu-guid",
3897             KSTAT_DATA_STRING);
3898         kstat_named_init(&ks_itl->i_lu_alias, "lu-alias",
3899             KSTAT_DATA_STRING);
3900         kstat_named_init(&ks_itl->i_lu_number, "lu-number",
3901             KSTAT_DATA_UINT64);
3902         kstat_named_init(&ks_itl->i_task_waitq_elapsed, "task-waitq-elapsed",
3903             KSTAT_DATA_UINT64);
3904         kstat_named_init(&ks_itl->i_task_read_elapsed, "task-read-elapsed",
3905             KSTAT_DATA_UINT64);
3906         kstat_named_init(&ks_itl->i_task_write_elapsed, "task-write-elapsed",
3907             KSTAT_DATA_UINT64);
3908         kstat_named_init(&ks_itl->i_lu_read_elapsed, "lu-read-elapsed",
3909             KSTAT_DATA_UINT64);
3910         kstat_named_init(&ks_itl->i_lu_write_elapsed, "lu-write-elapsed",
3911             KSTAT_DATA_UINT64);
3912         kstat_named_init(&ks_itl->i_lport_read_elapsed, "lport-read-elapsed",
3913             KSTAT_DATA_UINT64);
3914         kstat_named_init(&ks_itl->i_lport_write_elapsed, "lport-write-elapsed",
3915             KSTAT_DATA_UINT64);
3916 
3917         strbuf = itl->itl_kstat_strbuf;
3918 
3919         /* Rport */
3920         len = ss->ss_rport_id->ident_length;
3921         bcopy(ss->ss_rport_id->ident, strbuf, len);
3922         strbuf += len;
3923         *strbuf = '\0';
3924         kstat_named_setstr(&ks_itl->i_rport_name, strbuf - len);
3925         strbuf++;
3926 
3927         len = strnlen(rport_alias, MAX_ALIAS);
3928         (void) strncpy(strbuf, rport_alias, len + 1);
3929         kstat_named_setstr(&ks_itl->i_rport_alias, strbuf);
3930         strbuf += len + 1;
3931 
3932         /* Lport */
3933         len = ss->ss_lport->lport_id->ident_length;
3934         bcopy(ss->ss_lport->lport_id->ident, strbuf, len);
3935         strbuf += len;
3936         *strbuf = '\0';
3937         kstat_named_setstr(&ks_itl->i_lport_name, strbuf - len);
3938         strbuf++;
3939 
3940         len = strnlen(lport_alias, MAX_ALIAS);
3941         (void) strncpy(strbuf, lport_alias, len + 1);
3942         kstat_named_setstr(&ks_itl->i_lport_alias, strbuf);
3943         strbuf += len + 1;
3944 
3945         id = (ss->ss_lport->lport_id->protocol_id > PROTOCOL_ANY) ?
3946             PROTOCOL_ANY : ss->ss_lport->lport_id->protocol_id;
3947         kstat_named_setstr(&ks_itl->i_protocol, protocol_ident[id]);
3948 
3949         /* LU */
3950         for (i = 0; i < STMF_GUID_INPUT / 2; i++) {
3951                 (void) sprintf(&strbuf[i * 2], "%02x",
3952                     itl->itl_ilu->ilu_lu->lu_id->ident[i]);
3953         }
3954         kstat_named_setstr(&ks_itl->i_lu_guid, strbuf);
3955         strbuf += STMF_GUID_INPUT + 1;
3956 
3957         len = strnlen(lu_alias, MAX_ALIAS);
3958         (void) strncpy(strbuf, lu_alias, len + 1);
3959         kstat_named_setstr(&ks_itl->i_lu_alias, strbuf);
3960         strbuf += len + 1;
3961 
3962         ks_itl->i_lu_number.value.ui64 = itl->itl_lun;
3963 
3964         /* Now create the I/O kstats */
3965         (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_tasks_%s",  ks_itl_id);
3966         if ((itl->itl_kstat_taskq = kstat_create(STMF_MODULE_NAME, 0,
3967             ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) {
3968                 goto itl_kstat_cleanup;
3969         }
3970 
3971         (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_lu_%s",  ks_itl_id);
3972         if ((itl->itl_kstat_lu_xfer = kstat_create(STMF_MODULE_NAME, 0,
3973             ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) {
3974                 goto itl_kstat_cleanup;
3975         }
3976 
3977         (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_lport_%s",  ks_itl_id);
3978         if ((itl->itl_kstat_lport_xfer = kstat_create(STMF_MODULE_NAME, 0,
3979             ks_nm, "io", KSTAT_TYPE_IO, 1, 0)) == NULL) {
3980                 goto itl_kstat_cleanup;
3981         }
3982 
3983         /* Install all the kstats */
3984         kstat_install(itl->itl_kstat_info);
3985         kstat_install(itl->itl_kstat_taskq);
3986         kstat_install(itl->itl_kstat_lu_xfer);
3987         kstat_install(itl->itl_kstat_lport_xfer);
3988 
3989         /* Add new itl_kstat to stmf_itl_kstat_list */
3990         if (stmf_itl_kstat_create(itl, ks_itl_nm, ss->ss_lport->lport_id,
3991             itl->itl_ilu->ilu_lu->lu_id) != NULL)
3992                 return (STMF_SUCCESS);
3993 
3994 itl_kstat_cleanup:
3995         if (itl->itl_kstat_taskq)
3996                 kstat_delete(itl->itl_kstat_taskq);
3997         if (itl->itl_kstat_lu_xfer)
3998                 kstat_delete(itl->itl_kstat_lu_xfer);
3999         if (itl->itl_kstat_lport_xfer)
4000                 kstat_delete(itl->itl_kstat_lport_xfer);
4001         if (itl->itl_kstat_info)
4002                 kstat_delete(itl->itl_kstat_info);
4003         kmem_free(ks_itl, sizeof (*ks_itl));
4004         kmem_free(itl->itl_kstat_strbuf, itl->itl_kstat_strbuflen);
4005         cmn_err(CE_WARN, "STMF: kstat_create itl failed");
4006         return (STMF_ALLOC_FAILURE);
4007 }
4008 
4009 static void
4010 stmf_teardown_itl_kstats(stmf_i_itl_kstat_t *ks)
4011 {
4012         kstat_delete(ks->iitl_kstat_lport_xfer);
4013         kstat_delete(ks->iitl_kstat_lu_xfer);
4014         kstat_delete(ks->iitl_kstat_taskq);
4015         kmem_free(ks->iitl_kstat_info->ks_data, sizeof (stmf_kstat_itl_info_t));
4016         kstat_delete(ks->iitl_kstat_info);
4017         kmem_free(ks->iitl_kstat_strbuf, ks->iitl_kstat_strbuflen);
4018 }
4019 
4020 void
4021 stmf_release_itl_handle(stmf_lu_t *lu, stmf_itl_data_t *itl)
4022 {
4023         stmf_itl_data_t **itlpp;
4024         stmf_i_lu_t *ilu;
4025 
4026         ASSERT(itl->itl_flags & STMF_ITL_BEING_TERMINATED);
4027 
4028         ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4029         mutex_enter(&ilu->ilu_task_lock);
4030         for (itlpp = &ilu->ilu_itl_list; (*itlpp) != NULL;
4031             itlpp = &(*itlpp)->itl_next) {
4032                 if ((*itlpp) == itl)
4033                         break;
4034         }
4035         ASSERT((*itlpp) != NULL);
4036         *itlpp = itl->itl_next;
4037         mutex_exit(&ilu->ilu_task_lock);
4038         lu->lu_abort(lu, STMF_LU_ITL_HANDLE_REMOVED, itl->itl_handle,
4039             (uint32_t)itl->itl_hdlrm_reason);


4043 
4044 stmf_status_t
4045 stmf_register_itl_handle(stmf_lu_t *lu, uint8_t *lun,
4046     stmf_scsi_session_t *ss, uint64_t session_id, void *itl_handle)
4047 {
4048         stmf_itl_data_t *itl;
4049         stmf_i_scsi_session_t *iss;
4050         stmf_lun_map_ent_t *lun_map_ent;
4051         stmf_i_lu_t *ilu;
4052         uint16_t n;
4053 
4054         ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4055         if (ss == NULL) {
4056                 iss = stmf_session_id_to_issptr(session_id, 1);
4057                 if (iss == NULL)
4058                         return (STMF_NOT_FOUND);
4059         } else {
4060                 iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4061         }
4062 
4063         /*
4064          * Acquire stmf_lock for stmf_itl_kstat_lookup.
4065          */
4066         mutex_enter(&stmf_state.stmf_lock);
4067         rw_enter(iss->iss_lockp, RW_WRITER);
4068         n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
4069         lun_map_ent = (stmf_lun_map_ent_t *)
4070             stmf_get_ent_from_map(iss->iss_sm, n);
4071         if ((lun_map_ent == NULL) || (lun_map_ent->ent_lu != lu)) {
4072                 rw_exit(iss->iss_lockp);
4073                 mutex_exit(&stmf_state.stmf_lock);
4074                 return (STMF_NOT_FOUND);
4075         }
4076         if (lun_map_ent->ent_itl_datap != NULL) {
4077                 rw_exit(iss->iss_lockp);
4078                 mutex_exit(&stmf_state.stmf_lock);
4079                 return (STMF_ALREADY);
4080         }
4081 
4082         itl = (stmf_itl_data_t *)kmem_zalloc(sizeof (*itl), KM_NOSLEEP);
4083         if (itl == NULL) {
4084                 rw_exit(iss->iss_lockp);
4085                 mutex_exit(&stmf_state.stmf_lock);
4086                 return (STMF_ALLOC_FAILURE);
4087         }
4088 
4089         itl->itl_ilu = ilu;
4090         itl->itl_session = iss;
4091         itl->itl_counter = 1;
4092         itl->itl_lun = n;
4093         itl->itl_handle = itl_handle;
4094 
4095         if (stmf_setup_itl_kstats(itl) != STMF_SUCCESS) {
4096                 kmem_free(itl, sizeof (*itl));
4097                 rw_exit(iss->iss_lockp);
4098                 mutex_exit(&stmf_state.stmf_lock);
4099                 return (STMF_ALLOC_FAILURE);
4100         }
4101 
4102         mutex_enter(&ilu->ilu_task_lock);
4103         itl->itl_next = ilu->ilu_itl_list;
4104         ilu->ilu_itl_list = itl;
4105         mutex_exit(&ilu->ilu_task_lock);
4106         lun_map_ent->ent_itl_datap = itl;
4107         rw_exit(iss->iss_lockp);
4108         mutex_exit(&stmf_state.stmf_lock);
4109 
4110         return (STMF_SUCCESS);
4111 }
4112 
4113 void
4114 stmf_do_itl_dereg(stmf_lu_t *lu, stmf_itl_data_t *itl, uint8_t hdlrm_reason)
4115 {
4116         uint8_t old, new;
4117 
4118         do {
4119                 old = new = itl->itl_flags;
4120                 if (old & STMF_ITL_BEING_TERMINATED)
4121                         return;
4122                 new |= STMF_ITL_BEING_TERMINATED;
4123         } while (atomic_cas_8(&itl->itl_flags, old, new) != old);
4124         itl->itl_hdlrm_reason = hdlrm_reason;
4125 
4126         ASSERT(itl->itl_counter);
4127 
4128         if (atomic_add_32_nv(&itl->itl_counter, -1))
4129                 return;
4130 
4131         drv_usecwait(10);
4132         if (itl->itl_counter)
4133                 return;
4134 
4135         stmf_release_itl_handle(lu, itl);
4136 }
4137 
4138 stmf_status_t
4139 stmf_deregister_all_lu_itl_handles(stmf_lu_t *lu)
4140 {
4141         stmf_i_lu_t *ilu;
4142         stmf_i_local_port_t *ilport;
4143         stmf_i_scsi_session_t *iss;
4144         stmf_lun_map_t *lm;
4145         stmf_lun_map_ent_t *ent;
4146         uint32_t nmaps, nu;
4147         stmf_itl_data_t **itl_list;
4148         int i;
4149 
4150         ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
4151 
4152 dereg_itl_start:;
4153         nmaps = ilu->ilu_ref_cnt;
4154         if (nmaps == 0)


4185                                         }
4186                                 }
4187                         } /* lun table for a session */
4188                 } /* sessions */
4189                 rw_exit(&ilport->ilport_lock);
4190         } /* ports */
4191 
4192 dai_scan_done:
4193         mutex_exit(&stmf_state.stmf_lock);
4194 
4195         for (i = 0; i < nu; i++) {
4196                 stmf_do_itl_dereg(lu, itl_list[i],
4197                     STMF_ITL_REASON_DEREG_REQUEST);
4198         }
4199         kmem_free(itl_list, nmaps * sizeof (stmf_itl_data_t *));
4200 
4201         return (STMF_SUCCESS);
4202 }
4203 
4204 stmf_status_t
4205 stmf_deregister_itl_handle(stmf_lu_t *lu, uint8_t *lun,
4206     stmf_scsi_session_t *ss, uint64_t session_id, void *itl_handle)
4207 {
4208         stmf_i_scsi_session_t *iss;
4209         stmf_itl_data_t *itl;
4210         stmf_lun_map_ent_t *ent;
4211         stmf_lun_map_t *lm;
4212         int i;
4213         uint16_t n;
4214 
4215         if (ss == NULL) {
4216                 if (session_id == STMF_SESSION_ID_NONE)
4217                         return (STMF_INVALID_ARG);
4218                 iss = stmf_session_id_to_issptr(session_id, 1);
4219                 if (iss == NULL)
4220                         return (STMF_NOT_FOUND);
4221         } else {
4222                 iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4223                 rw_enter(iss->iss_lockp, RW_WRITER);
4224         }
4225         lm = iss->iss_sm;
4226         if (lm == NULL) {
4227                 rw_exit(iss->iss_lockp);
4228                 return (STMF_NOT_FOUND);
4229         }
4230 
4231         if (lun) {
4232                 n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
4233                 ent = (stmf_lun_map_ent_t *)
4234                     stmf_get_ent_from_map(iss->iss_sm, n);
4235         } else {
4236                 if (itl_handle == NULL) {
4237                         rw_exit(iss->iss_lockp);
4238                         return (STMF_INVALID_ARG);
4239                 }
4240                 ent = NULL;
4241                 for (i = 0; i < lm->lm_nentries; i++) {
4242                         if (lm->lm_plus[i] == NULL)
4243                                 continue;
4244                         ent = (stmf_lun_map_ent_t *)lm->lm_plus[i];
4245                         if (ent->ent_itl_datap &&
4246                             (ent->ent_itl_datap->itl_handle == itl_handle)) {
4247                                 break;
4248                         }
4249                 }
4250         }
4251         if ((ent == NULL) || (ent->ent_lu != lu) ||
4252             (ent->ent_itl_datap == NULL)) {
4253                 rw_exit(iss->iss_lockp);
4254                 return (STMF_NOT_FOUND);
4255         }
4256         itl = ent->ent_itl_datap;
4257         ent->ent_itl_datap = NULL;
4258         rw_exit(iss->iss_lockp);
4259         stmf_do_itl_dereg(lu, itl, STMF_ITL_REASON_DEREG_REQUEST);
4260 
4261         return (STMF_SUCCESS);
4262 }
4263 
4264 stmf_status_t
4265 stmf_get_itl_handle(stmf_lu_t *lu, uint8_t *lun, stmf_scsi_session_t *ss,
4266     uint64_t session_id, void **itl_handle_retp)
4267 {
4268         stmf_i_scsi_session_t *iss;
4269         stmf_lun_map_ent_t *ent;
4270         stmf_lun_map_t *lm;
4271         stmf_status_t ret;
4272         int i;
4273         uint16_t n;
4274 
4275         if (ss == NULL) {
4276                 iss = stmf_session_id_to_issptr(session_id, 1);
4277                 if (iss == NULL)
4278                         return (STMF_NOT_FOUND);
4279         } else {
4280                 iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4281                 rw_enter(iss->iss_lockp, RW_WRITER);
4282         }
4283 
4284         ent = NULL;


4430          */
4431         if (cdb_length_in >= 16)
4432                 cdb_length = cdb_length_in + 7;
4433         else
4434                 cdb_length = 16 + 7;
4435         iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4436         luNbr = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
4437         rw_enter(iss->iss_lockp, RW_READER);
4438         lun_map_ent =
4439             (stmf_lun_map_ent_t *)stmf_get_ent_from_map(iss->iss_sm, luNbr);
4440         if (!lun_map_ent) {
4441                 lu = dlun0;
4442         } else {
4443                 lu = lun_map_ent->ent_lu;
4444         }
4445         ilu = lu->lu_stmf_private;
4446         if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4447                 rw_exit(iss->iss_lockp);
4448                 return (NULL);
4449         }


4450         do {
4451                 if (ilu->ilu_free_tasks == NULL) {
4452                         new_task = 1;
4453                         break;
4454                 }
4455                 mutex_enter(&ilu->ilu_task_lock);
4456                 for (ppitask = &ilu->ilu_free_tasks; (*ppitask != NULL) &&
4457                     ((*ppitask)->itask_cdb_buf_size < cdb_length);
4458                     ppitask = &((*ppitask)->itask_lu_free_next))
4459                         ;
4460                 if (*ppitask) {
4461                         itask = *ppitask;
4462                         *ppitask = (*ppitask)->itask_lu_free_next;
4463                         ilu->ilu_ntasks_free--;
4464                         if (ilu->ilu_ntasks_free < ilu->ilu_ntasks_min_free)
4465                                 ilu->ilu_ntasks_min_free = ilu->ilu_ntasks_free;
4466                 } else {
4467                         new_task = 1;
4468                 }
4469                 mutex_exit(&ilu->ilu_task_lock);


4558         }
4559 
4560         rw_exit(iss->iss_lockp);
4561         return (task);
4562 }
4563 
4564 static void
4565 stmf_task_lu_free(scsi_task_t *task, stmf_i_scsi_session_t *iss)
4566 {
4567         stmf_i_scsi_task_t *itask =
4568             (stmf_i_scsi_task_t *)task->task_stmf_private;
4569         stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
4570 
4571         ASSERT(rw_lock_held(iss->iss_lockp));
4572         itask->itask_flags = ITASK_IN_FREE_LIST;
4573         itask->itask_proxy_msg_id = 0;
4574         mutex_enter(&ilu->ilu_task_lock);
4575         itask->itask_lu_free_next = ilu->ilu_free_tasks;
4576         ilu->ilu_free_tasks = itask;
4577         ilu->ilu_ntasks_free++;


4578         mutex_exit(&ilu->ilu_task_lock);
4579         atomic_add_32(itask->itask_ilu_task_cntr, -1);
4580 }
4581 
4582 void
4583 stmf_task_lu_check_freelist(stmf_i_lu_t *ilu)
4584 {
4585         uint32_t        num_to_release, ndx;
4586         stmf_i_scsi_task_t *itask;
4587         stmf_lu_t       *lu = ilu->ilu_lu;
4588 
4589         ASSERT(ilu->ilu_ntasks_min_free <= ilu->ilu_ntasks_free);
4590 
4591         /* free half of the minimal free of the free tasks */
4592         num_to_release = (ilu->ilu_ntasks_min_free + 1) / 2;
4593         if (!num_to_release) {
4594                 return;
4595         }
4596         for (ndx = 0; ndx < num_to_release; ndx++) {
4597                 mutex_enter(&ilu->ilu_task_lock);


6074 }
6075 
6076 static uint16_t stmf_lu_id_gen_number = 0;
6077 
6078 stmf_status_t
6079 stmf_scsilib_uniq_lu_id(uint32_t company_id, scsi_devid_desc_t *lu_id)
6080 {
6081         return (stmf_scsilib_uniq_lu_id2(company_id, 0, lu_id));
6082 }
6083 
6084 stmf_status_t
6085 stmf_scsilib_uniq_lu_id2(uint32_t company_id, uint32_t host_id,
6086     scsi_devid_desc_t *lu_id)
6087 {
6088         uint8_t *p;
6089         struct timeval32 timestamp32;
6090         uint32_t *t = (uint32_t *)&timestamp32;
6091         struct ether_addr mac;
6092         uint8_t *e = (uint8_t *)&mac;
6093         int hid = (int)host_id;

6094 
6095         if (company_id == COMPANY_ID_NONE)
6096                 company_id = COMPANY_ID_SUN;
6097 
6098         if (lu_id->ident_length != 0x10)
6099                 return (STMF_INVALID_ARG);
6100 
6101         p = (uint8_t *)lu_id;
6102 
6103         atomic_add_16(&stmf_lu_id_gen_number, 1);
6104 
6105         p[0] = 0xf1; p[1] = 3; p[2] = 0; p[3] = 0x10;
6106         p[4] = ((company_id >> 20) & 0xf) | 0x60;
6107         p[5] = (company_id >> 12) & 0xff;
6108         p[6] = (company_id >> 4) & 0xff;
6109         p[7] = (company_id << 4) & 0xf0;
6110         if (hid == 0 && !localetheraddr((struct ether_addr *)NULL, &mac)) {
6111                 hid = BE_32((int)zone_get_hostid(NULL));
6112         }
6113         if (hid != 0) {
6114                 e[0] = (hid >> 24) & 0xff;
6115                 e[1] = (hid >> 16) & 0xff;
6116                 e[2] = (hid >> 8) & 0xff;
6117                 e[3] = hid & 0xff;
6118                 e[4] = e[5] = 0;
6119         }
6120         bcopy(e, p+8, 6);
6121         uniqtime32(&timestamp32);
6122         *t = BE_32(*t);
6123         bcopy(t, p+14, 4);
6124         p[18] = (stmf_lu_id_gen_number >> 8) & 0xff;
6125         p[19] = stmf_lu_id_gen_number & 0xff;
6126 
6127         return (STMF_SUCCESS);
6128 }
6129 
6130 /*
6131  * saa is sense key, ASC, ASCQ
6132  */
6133 void
6134 stmf_scsilib_send_status(scsi_task_t *task, uint8_t st, uint32_t saa)
6135 {
6136         uint8_t sd[18];
6137         task->task_scsi_status = st;
6138         if (st == 2) {
6139                 bzero(sd, 18);
6140                 sd[0] = 0x70;
6141                 sd[2] = (saa >> 16) & 0xf;
6142                 sd[7] = 10;
6143                 sd[12] = (saa >> 8) & 0xff;
6144                 sd[13] = saa & 0xff;
6145                 task->task_sense_data = sd;


7527                     ilport->ilport_lport, eventid, arg, flags);
7528         }
7529 }
7530 
7531 /*
7532  * With the possibility of having multiple itl sessions pointing to the
7533  * same itl_kstat_info, the ilu_kstat_lock mutex is used to synchronize
7534  * the kstat update of the ilu_kstat_io, itl_kstat_taskq and itl_kstat_lu_xfer
7535  * statistics.
7536  */
7537 void
7538 stmf_itl_task_start(stmf_i_scsi_task_t *itask)
7539 {
7540         stmf_itl_data_t *itl = itask->itask_itl_datap;
7541         scsi_task_t     *task = itask->itask_task;
7542         stmf_i_lu_t     *ilu;
7543 
7544         if (itl == NULL || task->task_lu == dlun0)
7545                 return;
7546         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7547         mutex_enter(ilu->ilu_kstat_io->ks_lock);
7548         itask->itask_start_timestamp = gethrtime();
7549         kstat_waitq_enter(KSTAT_IO_PTR(itl->itl_kstat_taskq));

7550         stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter);
7551         mutex_exit(ilu->ilu_kstat_io->ks_lock);

7552 
7553         stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_enter);
7554 }
7555 
7556 void
7557 stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask)
7558 {
7559         stmf_itl_data_t *itl = itask->itask_itl_datap;
7560         scsi_task_t     *task = itask->itask_task;
7561         stmf_i_lu_t     *ilu;
7562 
7563         if (itl == NULL || task->task_lu == dlun0)
7564                 return;
7565         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;

7566         mutex_enter(ilu->ilu_kstat_io->ks_lock);
7567         kstat_waitq_to_runq(KSTAT_IO_PTR(itl->itl_kstat_taskq));
7568         stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq);
7569         mutex_exit(ilu->ilu_kstat_io->ks_lock);

7570 
7571         stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_to_runq);
7572 }
7573 
7574 void
7575 stmf_itl_task_done(stmf_i_scsi_task_t *itask)
7576 {
7577         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7578         scsi_task_t             *task = itask->itask_task;
7579         kstat_io_t              *kip;
7580         hrtime_t                elapsed_time;
7581         stmf_kstat_itl_info_t   *itli;
7582         stmf_i_lu_t     *ilu;
7583 


7584         if (itl == NULL || task->task_lu == dlun0)
7585                 return;
7586         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7587 



7588         mutex_enter(ilu->ilu_kstat_io->ks_lock);
7589         itli = (stmf_kstat_itl_info_t *)KSTAT_NAMED_PTR(itl->itl_kstat_info);
7590         kip = KSTAT_IO_PTR(itl->itl_kstat_taskq);
7591 
7592         itli->i_task_waitq_elapsed.value.ui64 += itask->itask_waitq_time;
7593 
7594         itask->itask_done_timestamp = gethrtime();
7595         elapsed_time =
7596             itask->itask_done_timestamp - itask->itask_start_timestamp;
7597 
7598         if (task->task_flags & TF_READ_DATA) {
7599                 kip->reads++;
7600                 kip->nread += itask->itask_read_xfer;
7601                 itli->i_task_read_elapsed.value.ui64 += elapsed_time;
7602                 itli->i_lu_read_elapsed.value.ui64 +=
7603                     itask->itask_lu_read_time;
7604                 itli->i_lport_read_elapsed.value.ui64 +=
7605                     itask->itask_lport_read_time;
7606         }
7607 
7608         if (task->task_flags & TF_WRITE_DATA) {
7609                 kip->writes++;
7610                 kip->nwritten += itask->itask_write_xfer;
7611                 itli->i_task_write_elapsed.value.ui64 += elapsed_time;
7612                 itli->i_lu_write_elapsed.value.ui64 +=
7613                     itask->itask_lu_write_time;
7614                 itli->i_lport_write_elapsed.value.ui64 +=
7615                     itask->itask_lport_write_time;
7616         }
7617 
7618         if (itask->itask_flags & ITASK_KSTAT_IN_RUNQ) {
7619                 kstat_runq_exit(kip);
7620                 stmf_update_kstat_lu_q(task, kstat_runq_exit);
7621                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7622                 stmf_update_kstat_lport_q(task, kstat_runq_exit);
7623         } else {
7624                 kstat_waitq_exit(kip);
7625                 stmf_update_kstat_lu_q(task, kstat_waitq_exit);
7626                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7627                 stmf_update_kstat_lport_q(task, kstat_waitq_exit);
7628         }
7629 }
7630 
7631 void
7632 stmf_lu_xfer_start(scsi_task_t *task)
7633 {
7634         stmf_i_scsi_task_t *itask = task->task_stmf_private;
7635         stmf_itl_data_t *itl = itask->itask_itl_datap;
7636         stmf_i_lu_t     *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7637         kstat_io_t              *kip;
7638 
7639         if (itl == NULL || task->task_lu == dlun0)
7640                 return;
7641 
7642         kip = KSTAT_IO_PTR(itl->itl_kstat_lu_xfer);
7643         mutex_enter(ilu->ilu_kstat_io->ks_lock);
7644         kstat_runq_enter(kip);
7645         mutex_exit(ilu->ilu_kstat_io->ks_lock);
7646 }
7647 
7648 void
7649 stmf_lu_xfer_done(scsi_task_t *task, boolean_t read, uint64_t xfer_bytes,
7650     hrtime_t elapsed_time)
7651 {
7652         stmf_i_scsi_task_t      *itask = task->task_stmf_private;
7653         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7654         stmf_i_lu_t     *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7655         kstat_io_t              *kip;
7656 
7657         if (itl == NULL || task->task_lu == dlun0)
7658                 return;
7659 
7660         if (read) {
7661                 atomic_add_64((uint64_t *)&itask->itask_lu_read_time,
7662                     elapsed_time);
7663         } else {
7664                 atomic_add_64((uint64_t *)&itask->itask_lu_write_time,
7665                     elapsed_time);
7666         }
7667 
7668         kip = KSTAT_IO_PTR(itl->itl_kstat_lu_xfer);
7669         mutex_enter(ilu->ilu_kstat_io->ks_lock);
7670         kstat_runq_exit(kip);
7671         if (read) {
7672                 kip->reads++;
7673                 kip->nread += xfer_bytes;
7674         } else {
7675                 kip->writes++;
7676                 kip->nwritten += xfer_bytes;
7677         }
7678         mutex_exit(ilu->ilu_kstat_io->ks_lock);
7679 }
7680 
7681 static void
7682 stmf_lport_xfer_start(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7683 {
7684         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7685 
7686         if (itl == NULL)
7687                 return;
7688 
7689         DTRACE_PROBE2(scsi__xfer__start, scsi_task_t *, itask->itask_task,
7690             stmf_data_buf_t *, dbuf);
7691 
7692         dbuf->db_xfer_start_timestamp = gethrtime();
7693 }
7694 
7695 static void
7696 stmf_lport_xfer_done(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7697 {
7698         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7699         scsi_task_t             *task;
7700         stmf_i_local_port_t     *ilp;
7701         kstat_io_t              *kip;
7702         hrtime_t                elapsed_time;
7703         uint64_t                xfer_size;
7704 
7705         if (itl == NULL)
7706                 return;
7707 
7708         task = (scsi_task_t *)itask->itask_task;
7709         ilp = (stmf_i_local_port_t *)task->task_lport->lport_stmf_private;
7710         xfer_size = (dbuf->db_xfer_status == STMF_SUCCESS) ?
7711             dbuf->db_data_size : 0;
7712 
7713         elapsed_time = gethrtime() - dbuf->db_xfer_start_timestamp;
7714         if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
7715                 atomic_add_64((uint64_t *)&itask->itask_lport_read_time,
7716                     elapsed_time);
7717                 atomic_add_64((uint64_t *)&itask->itask_read_xfer,
7718                     xfer_size);
7719         } else {
7720                 atomic_add_64((uint64_t *)&itask->itask_lport_write_time,
7721                     elapsed_time);
7722                 atomic_add_64((uint64_t *)&itask->itask_write_xfer,
7723                     xfer_size);
7724         }
7725 
7726         DTRACE_PROBE3(scsi__xfer__end, scsi_task_t *, itask->itask_task,
7727             stmf_data_buf_t *, dbuf, hrtime_t, elapsed_time);
7728 
7729         kip = KSTAT_IO_PTR(itl->itl_kstat_lport_xfer);
7730         mutex_enter(ilp->ilport_kstat_io->ks_lock);
7731         if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
7732                 kip->reads++;
7733                 kip->nread += xfer_size;
7734         } else {
7735                 kip->writes++;
7736                 kip->nwritten += xfer_size;
7737         }
7738         mutex_exit(ilp->ilport_kstat_io->ks_lock);
7739 
7740         dbuf->db_xfer_start_timestamp = 0;
7741 }
7742 
7743 void
7744 stmf_svc_init()
7745 {
7746         if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
7747                 return;
7748         stmf_state.stmf_svc_tailp = &stmf_state.stmf_svc_active;
7749         stmf_state.stmf_svc_taskq = ddi_taskq_create(0, "STMF_SVC_TASKQ", 1,
7750             TASKQ_DEFAULTPRI, 0);
7751         (void) ddi_taskq_dispatch(stmf_state.stmf_svc_taskq,
7752             stmf_svc, 0, DDI_SLEEP);
7753 }
7754 
7755 stmf_status_t
7756 stmf_svc_fini()
7757 {
7758         uint32_t i;
7759 


7821                         /* Fallthrough */
7822                 case STMF_CMD_LPORT_OFFLINE:
7823                         mutex_exit(&stmf_state.stmf_lock);
7824                         lport = (stmf_local_port_t *)req->svc_obj;
7825                         lport->lport_ctl(lport, req->svc_cmd, &req->svc_info);
7826                         break;
7827                 case STMF_CMD_LU_ONLINE:
7828                         mutex_exit(&stmf_state.stmf_lock);
7829                         lu = (stmf_lu_t *)req->svc_obj;
7830                         lu->lu_ctl(lu, req->svc_cmd, &req->svc_info);
7831                         break;
7832                 case STMF_CMD_LU_OFFLINE:
7833                         /* Remove all mappings of this LU */
7834                         stmf_session_lu_unmapall((stmf_lu_t *)req->svc_obj);
7835                         /* Kill all the pending I/Os for this LU */
7836                         mutex_exit(&stmf_state.stmf_lock);
7837                         stmf_task_lu_killall((stmf_lu_t *)req->svc_obj, NULL,
7838                             STMF_ABORTED);
7839                         lu = (stmf_lu_t *)req->svc_obj;
7840                         ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
7841                         if (ilu->ilu_ntasks != ilu->ilu_ntasks_free)
7842                                 break;
7843                         lu->lu_ctl(lu, req->svc_cmd, &req->svc_info);
7844                         break;
7845                 default:
7846                         cmn_err(CE_PANIC, "stmf_svc: unknown cmd %d",
7847                             req->svc_cmd);
7848                 }
7849 

7850                 mutex_enter(&stmf_state.stmf_lock);
7851         }
7852 
7853         stmf_state.stmf_svc_flags &= ~(STMF_SVC_STARTED | STMF_SVC_ACTIVE);
7854         mutex_exit(&stmf_state.stmf_lock);
7855 }
7856 
7857 static void
7858 stmf_svc_timeout(struct stmf_svc_clocks *clks)
7859 {
7860         clock_t td;
7861         stmf_i_local_port_t *ilport, *next_ilport;
7862         stmf_i_scsi_session_t *iss;
7863 
7864         ASSERT(mutex_owned(&stmf_state.stmf_lock));
7865 
7866         td = drv_usectohz(20000);
7867 
7868         /* Do timeouts */
7869         if (stmf_state.stmf_nlus &&


7974                                     ~ILPORT_SS_GOT_INITIAL_LUNS);
7975                         /* drop the lock if we are holding it. */
7976                         if (ilport_lock_held == 1)
7977                                 rw_exit(&ilport->ilport_lock);
7978 
7979                         /* Max 4 session at a time */
7980                         if (stmf_level >= 4)
7981                                 break;
7982                 }
7983 
7984                 if (stmf_level == 0)
7985                         stmf_state.stmf_process_initial_luns = 0;
7986         }
7987 
7988         stmf_state.stmf_svc_flags &= ~STMF_SVC_ACTIVE;
7989         (void) cv_reltimedwait(&stmf_state.stmf_cv,
7990             &stmf_state.stmf_lock, td, TR_CLOCK_TICK);
7991         stmf_state.stmf_svc_flags |= STMF_SVC_ACTIVE;
7992 }
7993 


































7994 void
7995 stmf_svc_queue(int cmd, void *obj, stmf_state_change_info_t *info)
7996 {
7997         stmf_svc_req_t *req;
7998         int s;
7999 
8000         ASSERT(!mutex_owned(&stmf_state.stmf_lock));
8001         s = sizeof (stmf_svc_req_t);
8002         if (info->st_additional_info) {
8003                 s += strlen(info->st_additional_info) + 1;
8004         }
8005         req = kmem_zalloc(s, KM_SLEEP);
8006 
8007         req->svc_cmd = cmd;
8008         req->svc_obj = obj;
8009         req->svc_info.st_rflags = info->st_rflags;
8010         if (info->st_additional_info) {
8011                 req->svc_info.st_additional_info = (char *)(GET_BYTE_OFFSET(req,
8012                     sizeof (stmf_svc_req_t)));
8013                 (void) strcpy(req->svc_info.st_additional_info,




   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>
  46 
  47 #include <sys/stmf.h>


  50 #include <sys/stmf_ioctl.h>
  51 #include <sys/pppt_ic_if.h>
  52 
  53 #include "stmf_impl.h"
  54 #include "lun_map.h"
  55 #include "stmf_state.h"
  56 #include "stmf_stats.h"
  57 
  58 /*
  59  * Lock order:
  60  * stmf_state_lock --> ilport_lock/iss_lockp --> ilu_task_lock
  61  */
  62 
  63 static uint64_t stmf_session_counter = 0;
  64 static uint16_t stmf_rtpid_counter = 0;
  65 /* start messages at 1 */
  66 static uint64_t stmf_proxy_msg_id = 1;
  67 #define MSG_ID_TM_BIT   0x8000000000000000
  68 #define ALIGNED_TO_8BYTE_BOUNDARY(i)    (((i) + 7) & ~7)
  69 
  70 /*
  71  * When stmf_io_deadman_enabled is set to B_TRUE, we check that finishing up
  72  * I/O operations on an offlining LU doesn't take longer than stmf_io_deadman
  73  * seconds. If it does, we trigger a panic to inform the user of hung I/O
  74  * blocking us for too long.
  75  */
  76 boolean_t stmf_io_deadman_enabled = B_TRUE;
  77 int stmf_io_deadman = 1000;                     /* seconds */
  78 
  79 struct stmf_svc_clocks;
  80 
  81 static int stmf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
  82 static int stmf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
  83 static int stmf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
  84         void **result);
  85 static int stmf_open(dev_t *devp, int flag, int otype, cred_t *credp);
  86 static int stmf_close(dev_t dev, int flag, int otype, cred_t *credp);
  87 static int stmf_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
  88         cred_t *credp, int *rval);
  89 static int stmf_get_stmf_state(stmf_state_desc_t *std);
  90 static int stmf_set_stmf_state(stmf_state_desc_t *std);
  91 static void stmf_abort_task_offline(scsi_task_t *task, int offline_lu,
  92     char *info);
  93 static int stmf_set_alua_state(stmf_alua_state_desc_t *alua_state);
  94 static void stmf_get_alua_state(stmf_alua_state_desc_t *alua_state);
  95 
  96 static void stmf_task_audit(stmf_i_scsi_task_t *itask,
  97     task_audit_event_t te, uint32_t cmd_or_iof, stmf_data_buf_t *dbuf);
  98 
  99 static boolean_t stmf_base16_str_to_binary(char *c, int dplen, uint8_t *dp);
 100 static char stmf_ctoi(char c);
 101 stmf_xfer_data_t *stmf_prepare_tpgs_data(uint8_t ilu_alua);
 102 void stmf_svc_init();
 103 stmf_status_t stmf_svc_fini();
 104 void stmf_svc(void *arg);
 105 static void stmf_wait_ilu_tasks_finish(stmf_i_lu_t *ilu);
 106 void stmf_svc_queue(int cmd, void *obj, stmf_state_change_info_t *info);
 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();


 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;


 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);
 323 }
 324 
 325 int
 326 _fini(void)
 327 {
 328         int ret;
 329         stmf_i_remote_port_t    *irport;

 330         void                    *avl_dest_cookie = NULL;
 331 
 332         if (stmf_state.stmf_service_running)
 333                 return (EBUSY);
 334         if ((!stmf_allow_modunload) &&
 335             (stmf_state.stmf_config_state != STMF_CONFIG_NONE)) {
 336                 return (EBUSY);
 337         }
 338         if (stmf_state.stmf_nlps || stmf_state.stmf_npps) {
 339                 return (EBUSY);
 340         }
 341         if (stmf_dlun_fini() != STMF_SUCCESS)
 342                 return (EBUSY);
 343         if (stmf_worker_fini() != STMF_SUCCESS) {
 344                 stmf_dlun_init();
 345                 return (EBUSY);
 346         }
 347         if (stmf_svc_fini() != STMF_SUCCESS) {
 348                 stmf_dlun_init();
 349                 stmf_worker_init();
 350                 return (EBUSY);
 351         }
 352 
 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;


1567                 if (ilu->ilu_state != STMF_STATE_ONLINE)
1568                         continue;
1569                 (void) stmf_ctl(STMF_CMD_LU_OFFLINE, ilu->ilu_lu, &ssi);
1570         }
1571         mutex_enter(&stmf_state.stmf_lock);
1572         stmf_state.stmf_inventory_locked = 0;
1573         mutex_exit(&stmf_state.stmf_lock);
1574         return (0);
1575 }
1576 
1577 static int
1578 stmf_get_stmf_state(stmf_state_desc_t *std)
1579 {
1580         mutex_enter(&stmf_state.stmf_lock);
1581         std->state = stmf_get_service_state();
1582         std->config_state = stmf_state.stmf_config_state;
1583         mutex_exit(&stmf_state.stmf_lock);
1584 
1585         return (0);
1586 }
1587 
1588 /*
1589  * handles registration message from pppt for a logical unit
1590  */
1591 stmf_status_t
1592 stmf_ic_lu_reg(stmf_ic_reg_dereg_lun_msg_t *msg, uint32_t type)
1593 {
1594         stmf_i_lu_provider_t    *ilp;
1595         stmf_lu_provider_t      *lp;
1596         mutex_enter(&stmf_state.stmf_lock);
1597         for (ilp = stmf_state.stmf_ilplist; ilp != NULL; ilp = ilp->ilp_next) {
1598                 if (strcmp(msg->icrl_lu_provider_name,
1599                     ilp->ilp_lp->lp_name) == 0) {
1600                         lp = ilp->ilp_lp;
1601                         mutex_exit(&stmf_state.stmf_lock);
1602                         lp->lp_proxy_msg(msg->icrl_lun_id, msg->icrl_cb_arg,
1603                             msg->icrl_cb_arg_len, type);
1604                         return (STMF_SUCCESS);
1605                 }
1606         }
1607         mutex_exit(&stmf_state.stmf_lock);


3035         luid = stmf_lookup_id(&stmf_state.stmf_luid_list,
3036             lu->lu_id->ident_length, lu->lu_id->ident);
3037         if (luid) {
3038                 luid->id_pt_to_object = (void *)ilu;
3039                 ilu->ilu_luid = luid;
3040         }
3041         ilu->ilu_alias = NULL;
3042 
3043         ilu->ilu_next = stmf_state.stmf_ilulist;
3044         ilu->ilu_prev = NULL;
3045         if (ilu->ilu_next)
3046                 ilu->ilu_next->ilu_prev = ilu;
3047         stmf_state.stmf_ilulist = ilu;
3048         stmf_state.stmf_nlus++;
3049         if (lu->lu_lp) {
3050                 ((stmf_i_lu_provider_t *)
3051                     (lu->lu_lp->lp_stmf_private))->ilp_nlus++;
3052         }
3053         ilu->ilu_cur_task_cntr = &ilu->ilu_task_cntr1;
3054         STMF_EVENT_ALLOC_HANDLE(ilu->ilu_event_hdl);
3055         cv_init(&ilu->ilu_offline_pending_cv, NULL, CV_DRIVER, NULL);
3056         stmf_create_kstat_lu(ilu);
3057         /*
3058          * register with proxy module if available and logical unit
3059          * is in active state
3060          */
3061         if (stmf_state.stmf_alua_state == 1 &&
3062             ilu->ilu_access == STMF_LU_ACTIVE) {
3063                 stmf_ic_msg_status_t ic_ret = STMF_IC_MSG_SUCCESS;
3064                 stmf_ic_msg_t *ic_reg_lun;
3065                 if (lu->lu_lp && lu->lu_lp->lp_lpif_rev == LPIF_REV_2 &&
3066                     lu->lu_lp->lp_alua_support) {
3067                         ilu->ilu_alua = 1;
3068                         /* allocate the register message */
3069                         ic_reg_lun = ic_reg_lun_msg_alloc(p1,
3070                             lu->lu_lp->lp_name, lu->lu_proxy_reg_arg_len,
3071                             (uint8_t *)lu->lu_proxy_reg_arg, stmf_proxy_msg_id);
3072                         /* send the message */
3073                         if (ic_reg_lun) {
3074                                 ic_ret = ic_tx_msg(ic_reg_lun);
3075                                 if (ic_ret == STMF_IC_MSG_SUCCESS) {


3173                 }
3174                 if (ilu->ilu_luid) {
3175                         ((stmf_id_data_t *)ilu->ilu_luid)->id_pt_to_object =
3176                             NULL;
3177                         ilu->ilu_luid = NULL;
3178                 }
3179                 STMF_EVENT_FREE_HANDLE(ilu->ilu_event_hdl);
3180         } else {
3181                 mutex_exit(&stmf_state.stmf_lock);
3182                 return (STMF_BUSY);
3183         }
3184         if (ilu->ilu_kstat_info) {
3185                 kmem_free(ilu->ilu_kstat_info->ks_data,
3186                     ilu->ilu_kstat_info->ks_data_size);
3187                 kstat_delete(ilu->ilu_kstat_info);
3188         }
3189         if (ilu->ilu_kstat_io) {
3190                 kstat_delete(ilu->ilu_kstat_io);
3191                 mutex_destroy(&ilu->ilu_kstat_lock);
3192         }
3193         cv_destroy(&ilu->ilu_offline_pending_cv);
3194         mutex_exit(&stmf_state.stmf_lock);
3195         return (STMF_SUCCESS);
3196 }
3197 
3198 void
3199 stmf_set_port_standby(stmf_local_port_t *lport, uint16_t rtpid)
3200 {
3201         stmf_i_local_port_t *ilport =
3202             (stmf_i_local_port_t *)lport->lport_stmf_private;
3203         ilport->ilport_rtpid = rtpid;
3204         ilport->ilport_standby = 1;
3205 }
3206 
3207 void
3208 stmf_set_port_alua(stmf_local_port_t *lport)
3209 {
3210         stmf_i_local_port_t *ilport =
3211             (stmf_i_local_port_t *)lport->lport_stmf_private;
3212         ilport->ilport_alua = 1;
3213 }


3351                 stmf_state.stmf_nlports--;
3352                 if (lport->lport_pp) {
3353                         ((stmf_i_port_provider_t *)
3354                             (lport->lport_pp->pp_stmf_private))->ipp_npps--;
3355                 }
3356                 ilport->ilport_tg = NULL;
3357                 STMF_EVENT_FREE_HANDLE(ilport->ilport_event_hdl);
3358         } else {
3359                 mutex_exit(&stmf_state.stmf_lock);
3360                 return (STMF_BUSY);
3361         }
3362         if (ilport->ilport_kstat_info) {
3363                 kmem_free(ilport->ilport_kstat_info->ks_data,
3364                     ilport->ilport_kstat_info->ks_data_size);
3365                 kstat_delete(ilport->ilport_kstat_info);
3366         }
3367         if (ilport->ilport_kstat_io) {
3368                 kstat_delete(ilport->ilport_kstat_io);
3369                 mutex_destroy(&ilport->ilport_kstat_lock);
3370         }

3371         mutex_exit(&stmf_state.stmf_lock);
3372         return (STMF_SUCCESS);
3373 }
3374 
3375 /*
3376  * Rport id/instance mappings remain valid until STMF is unloaded
3377  */
3378 static int
3379 stmf_irport_compare(const void *void_irport1, const void *void_irport2)
3380 {
3381         const   stmf_i_remote_port_t    *irport1 = void_irport1;
3382         const   stmf_i_remote_port_t    *irport2 = void_irport2;
3383         int                     result;
3384 
3385         /* Sort by code set then ident */
3386         if (irport1->irport_id->code_set <
3387             irport2->irport_id->code_set) {
3388                 return (-1);
3389         } else if (irport1->irport_id->code_set >
3390             irport2->irport_id->code_set) {


3679 
3680         mutex_enter(&stmf_state.stmf_lock);
3681         for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
3682             ilport = ilport->ilport_next) {
3683                 rw_enter(&ilport->ilport_lock, RW_WRITER);
3684                 for (iss = ilport->ilport_ss_list; iss != NULL;
3685                     iss = iss->iss_next) {
3686                         if (iss->iss_ss->ss_session_id == session_id) {
3687                                 if (!stay_locked)
3688                                         rw_exit(&ilport->ilport_lock);
3689                                 mutex_exit(&stmf_state.stmf_lock);
3690                                 return (iss);
3691                         }
3692                 }
3693                 rw_exit(&ilport->ilport_lock);
3694         }
3695         mutex_exit(&stmf_state.stmf_lock);
3696         return (NULL);
3697 }
3698 


























































































































































































































































































































3699 void
3700 stmf_release_itl_handle(stmf_lu_t *lu, stmf_itl_data_t *itl)
3701 {
3702         stmf_itl_data_t **itlpp;
3703         stmf_i_lu_t *ilu;
3704 
3705         ASSERT(itl->itl_flags & STMF_ITL_BEING_TERMINATED);
3706 
3707         ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
3708         mutex_enter(&ilu->ilu_task_lock);
3709         for (itlpp = &ilu->ilu_itl_list; (*itlpp) != NULL;
3710             itlpp = &(*itlpp)->itl_next) {
3711                 if ((*itlpp) == itl)
3712                         break;
3713         }
3714         ASSERT((*itlpp) != NULL);
3715         *itlpp = itl->itl_next;
3716         mutex_exit(&ilu->ilu_task_lock);
3717         lu->lu_abort(lu, STMF_LU_ITL_HANDLE_REMOVED, itl->itl_handle,
3718             (uint32_t)itl->itl_hdlrm_reason);


3722 
3723 stmf_status_t
3724 stmf_register_itl_handle(stmf_lu_t *lu, uint8_t *lun,
3725     stmf_scsi_session_t *ss, uint64_t session_id, void *itl_handle)
3726 {
3727         stmf_itl_data_t *itl;
3728         stmf_i_scsi_session_t *iss;
3729         stmf_lun_map_ent_t *lun_map_ent;
3730         stmf_i_lu_t *ilu;
3731         uint16_t n;
3732 
3733         ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
3734         if (ss == NULL) {
3735                 iss = stmf_session_id_to_issptr(session_id, 1);
3736                 if (iss == NULL)
3737                         return (STMF_NOT_FOUND);
3738         } else {
3739                 iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
3740         }
3741 



3742         mutex_enter(&stmf_state.stmf_lock);
3743         rw_enter(iss->iss_lockp, RW_WRITER);
3744         n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
3745         lun_map_ent = (stmf_lun_map_ent_t *)
3746             stmf_get_ent_from_map(iss->iss_sm, n);
3747         if ((lun_map_ent == NULL) || (lun_map_ent->ent_lu != lu)) {
3748                 rw_exit(iss->iss_lockp);
3749                 mutex_exit(&stmf_state.stmf_lock);
3750                 return (STMF_NOT_FOUND);
3751         }
3752         if (lun_map_ent->ent_itl_datap != NULL) {
3753                 rw_exit(iss->iss_lockp);
3754                 mutex_exit(&stmf_state.stmf_lock);
3755                 return (STMF_ALREADY);
3756         }
3757 
3758         itl = (stmf_itl_data_t *)kmem_zalloc(sizeof (*itl), KM_NOSLEEP);
3759         if (itl == NULL) {
3760                 rw_exit(iss->iss_lockp);
3761                 mutex_exit(&stmf_state.stmf_lock);
3762                 return (STMF_ALLOC_FAILURE);
3763         }
3764 
3765         itl->itl_ilu = ilu;
3766         itl->itl_session = iss;
3767         itl->itl_counter = 1;
3768         itl->itl_lun = n;
3769         itl->itl_handle = itl_handle;
3770 







3771         mutex_enter(&ilu->ilu_task_lock);
3772         itl->itl_next = ilu->ilu_itl_list;
3773         ilu->ilu_itl_list = itl;
3774         mutex_exit(&ilu->ilu_task_lock);
3775         lun_map_ent->ent_itl_datap = itl;
3776         rw_exit(iss->iss_lockp);
3777         mutex_exit(&stmf_state.stmf_lock);
3778 
3779         return (STMF_SUCCESS);
3780 }
3781 
3782 void
3783 stmf_do_itl_dereg(stmf_lu_t *lu, stmf_itl_data_t *itl, uint8_t hdlrm_reason)
3784 {
3785         uint8_t old, new;
3786 
3787         do {
3788                 old = new = itl->itl_flags;
3789                 if (old & STMF_ITL_BEING_TERMINATED)
3790                         return;
3791                 new |= STMF_ITL_BEING_TERMINATED;
3792         } while (atomic_cas_8(&itl->itl_flags, old, new) != old);
3793         itl->itl_hdlrm_reason = hdlrm_reason;
3794 
3795         ASSERT(itl->itl_counter);
3796 
3797         if (atomic_add_32_nv(&itl->itl_counter, -1))
3798                 return;
3799 




3800         stmf_release_itl_handle(lu, itl);
3801 }
3802 
3803 stmf_status_t
3804 stmf_deregister_all_lu_itl_handles(stmf_lu_t *lu)
3805 {
3806         stmf_i_lu_t *ilu;
3807         stmf_i_local_port_t *ilport;
3808         stmf_i_scsi_session_t *iss;
3809         stmf_lun_map_t *lm;
3810         stmf_lun_map_ent_t *ent;
3811         uint32_t nmaps, nu;
3812         stmf_itl_data_t **itl_list;
3813         int i;
3814 
3815         ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
3816 
3817 dereg_itl_start:;
3818         nmaps = ilu->ilu_ref_cnt;
3819         if (nmaps == 0)


3850                                         }
3851                                 }
3852                         } /* lun table for a session */
3853                 } /* sessions */
3854                 rw_exit(&ilport->ilport_lock);
3855         } /* ports */
3856 
3857 dai_scan_done:
3858         mutex_exit(&stmf_state.stmf_lock);
3859 
3860         for (i = 0; i < nu; i++) {
3861                 stmf_do_itl_dereg(lu, itl_list[i],
3862                     STMF_ITL_REASON_DEREG_REQUEST);
3863         }
3864         kmem_free(itl_list, nmaps * sizeof (stmf_itl_data_t *));
3865 
3866         return (STMF_SUCCESS);
3867 }
3868 
3869 stmf_status_t




























































3870 stmf_get_itl_handle(stmf_lu_t *lu, uint8_t *lun, stmf_scsi_session_t *ss,
3871     uint64_t session_id, void **itl_handle_retp)
3872 {
3873         stmf_i_scsi_session_t *iss;
3874         stmf_lun_map_ent_t *ent;
3875         stmf_lun_map_t *lm;
3876         stmf_status_t ret;
3877         int i;
3878         uint16_t n;
3879 
3880         if (ss == NULL) {
3881                 iss = stmf_session_id_to_issptr(session_id, 1);
3882                 if (iss == NULL)
3883                         return (STMF_NOT_FOUND);
3884         } else {
3885                 iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
3886                 rw_enter(iss->iss_lockp, RW_WRITER);
3887         }
3888 
3889         ent = NULL;


4035          */
4036         if (cdb_length_in >= 16)
4037                 cdb_length = cdb_length_in + 7;
4038         else
4039                 cdb_length = 16 + 7;
4040         iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
4041         luNbr = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
4042         rw_enter(iss->iss_lockp, RW_READER);
4043         lun_map_ent =
4044             (stmf_lun_map_ent_t *)stmf_get_ent_from_map(iss->iss_sm, luNbr);
4045         if (!lun_map_ent) {
4046                 lu = dlun0;
4047         } else {
4048                 lu = lun_map_ent->ent_lu;
4049         }
4050         ilu = lu->lu_stmf_private;
4051         if (ilu->ilu_flags & ILU_RESET_ACTIVE) {
4052                 rw_exit(iss->iss_lockp);
4053                 return (NULL);
4054         }
4055         ASSERT(lu == dlun0 || (ilu->ilu_state != STMF_STATE_OFFLINING &&
4056             ilu->ilu_state != STMF_STATE_OFFLINE));
4057         do {
4058                 if (ilu->ilu_free_tasks == NULL) {
4059                         new_task = 1;
4060                         break;
4061                 }
4062                 mutex_enter(&ilu->ilu_task_lock);
4063                 for (ppitask = &ilu->ilu_free_tasks; (*ppitask != NULL) &&
4064                     ((*ppitask)->itask_cdb_buf_size < cdb_length);
4065                     ppitask = &((*ppitask)->itask_lu_free_next))
4066                         ;
4067                 if (*ppitask) {
4068                         itask = *ppitask;
4069                         *ppitask = (*ppitask)->itask_lu_free_next;
4070                         ilu->ilu_ntasks_free--;
4071                         if (ilu->ilu_ntasks_free < ilu->ilu_ntasks_min_free)
4072                                 ilu->ilu_ntasks_min_free = ilu->ilu_ntasks_free;
4073                 } else {
4074                         new_task = 1;
4075                 }
4076                 mutex_exit(&ilu->ilu_task_lock);


4165         }
4166 
4167         rw_exit(iss->iss_lockp);
4168         return (task);
4169 }
4170 
4171 static void
4172 stmf_task_lu_free(scsi_task_t *task, stmf_i_scsi_session_t *iss)
4173 {
4174         stmf_i_scsi_task_t *itask =
4175             (stmf_i_scsi_task_t *)task->task_stmf_private;
4176         stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
4177 
4178         ASSERT(rw_lock_held(iss->iss_lockp));
4179         itask->itask_flags = ITASK_IN_FREE_LIST;
4180         itask->itask_proxy_msg_id = 0;
4181         mutex_enter(&ilu->ilu_task_lock);
4182         itask->itask_lu_free_next = ilu->ilu_free_tasks;
4183         ilu->ilu_free_tasks = itask;
4184         ilu->ilu_ntasks_free++;
4185         if (ilu->ilu_ntasks == ilu->ilu_ntasks_free)
4186                 cv_signal(&ilu->ilu_offline_pending_cv);
4187         mutex_exit(&ilu->ilu_task_lock);
4188         atomic_add_32(itask->itask_ilu_task_cntr, -1);
4189 }
4190 
4191 void
4192 stmf_task_lu_check_freelist(stmf_i_lu_t *ilu)
4193 {
4194         uint32_t        num_to_release, ndx;
4195         stmf_i_scsi_task_t *itask;
4196         stmf_lu_t       *lu = ilu->ilu_lu;
4197 
4198         ASSERT(ilu->ilu_ntasks_min_free <= ilu->ilu_ntasks_free);
4199 
4200         /* free half of the minimal free of the free tasks */
4201         num_to_release = (ilu->ilu_ntasks_min_free + 1) / 2;
4202         if (!num_to_release) {
4203                 return;
4204         }
4205         for (ndx = 0; ndx < num_to_release; ndx++) {
4206                 mutex_enter(&ilu->ilu_task_lock);


5683 }
5684 
5685 static uint16_t stmf_lu_id_gen_number = 0;
5686 
5687 stmf_status_t
5688 stmf_scsilib_uniq_lu_id(uint32_t company_id, scsi_devid_desc_t *lu_id)
5689 {
5690         return (stmf_scsilib_uniq_lu_id2(company_id, 0, lu_id));
5691 }
5692 
5693 stmf_status_t
5694 stmf_scsilib_uniq_lu_id2(uint32_t company_id, uint32_t host_id,
5695     scsi_devid_desc_t *lu_id)
5696 {
5697         uint8_t *p;
5698         struct timeval32 timestamp32;
5699         uint32_t *t = (uint32_t *)&timestamp32;
5700         struct ether_addr mac;
5701         uint8_t *e = (uint8_t *)&mac;
5702         int hid = (int)host_id;
5703         uint16_t gen_number;
5704 
5705         if (company_id == COMPANY_ID_NONE)
5706                 company_id = COMPANY_ID_SUN;
5707 
5708         if (lu_id->ident_length != 0x10)
5709                 return (STMF_INVALID_ARG);
5710 
5711         p = (uint8_t *)lu_id;
5712 
5713         gen_number = atomic_add_16_nv(&stmf_lu_id_gen_number, 1);
5714 
5715         p[0] = 0xf1; p[1] = 3; p[2] = 0; p[3] = 0x10;
5716         p[4] = ((company_id >> 20) & 0xf) | 0x60;
5717         p[5] = (company_id >> 12) & 0xff;
5718         p[6] = (company_id >> 4) & 0xff;
5719         p[7] = (company_id << 4) & 0xf0;
5720         if (hid == 0 && !localetheraddr((struct ether_addr *)NULL, &mac)) {
5721                 hid = BE_32((int)zone_get_hostid(NULL));
5722         }
5723         if (hid != 0) {
5724                 e[0] = (hid >> 24) & 0xff;
5725                 e[1] = (hid >> 16) & 0xff;
5726                 e[2] = (hid >> 8) & 0xff;
5727                 e[3] = hid & 0xff;
5728                 e[4] = e[5] = 0;
5729         }
5730         bcopy(e, p+8, 6);
5731         uniqtime32(&timestamp32);
5732         *t = BE_32(*t);
5733         bcopy(t, p+14, 4);
5734         p[18] = (gen_number >> 8) & 0xff;
5735         p[19] = gen_number & 0xff;
5736 
5737         return (STMF_SUCCESS);
5738 }
5739 
5740 /*
5741  * saa is sense key, ASC, ASCQ
5742  */
5743 void
5744 stmf_scsilib_send_status(scsi_task_t *task, uint8_t st, uint32_t saa)
5745 {
5746         uint8_t sd[18];
5747         task->task_scsi_status = st;
5748         if (st == 2) {
5749                 bzero(sd, 18);
5750                 sd[0] = 0x70;
5751                 sd[2] = (saa >> 16) & 0xf;
5752                 sd[7] = 10;
5753                 sd[12] = (saa >> 8) & 0xff;
5754                 sd[13] = saa & 0xff;
5755                 task->task_sense_data = sd;


7137                     ilport->ilport_lport, eventid, arg, flags);
7138         }
7139 }
7140 
7141 /*
7142  * With the possibility of having multiple itl sessions pointing to the
7143  * same itl_kstat_info, the ilu_kstat_lock mutex is used to synchronize
7144  * the kstat update of the ilu_kstat_io, itl_kstat_taskq and itl_kstat_lu_xfer
7145  * statistics.
7146  */
7147 void
7148 stmf_itl_task_start(stmf_i_scsi_task_t *itask)
7149 {
7150         stmf_itl_data_t *itl = itask->itask_itl_datap;
7151         scsi_task_t     *task = itask->itask_task;
7152         stmf_i_lu_t     *ilu;
7153 
7154         if (itl == NULL || task->task_lu == dlun0)
7155                 return;
7156         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;

7157         itask->itask_start_timestamp = gethrtime();
7158         if (ilu->ilu_kstat_io != NULL) {
7159                 mutex_enter(ilu->ilu_kstat_io->ks_lock);
7160                 stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter);
7161                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7162         }
7163 
7164         stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_enter);
7165 }
7166 
7167 void
7168 stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask)
7169 {
7170         stmf_itl_data_t *itl = itask->itask_itl_datap;
7171         scsi_task_t     *task = itask->itask_task;
7172         stmf_i_lu_t     *ilu;
7173 
7174         if (itl == NULL || task->task_lu == dlun0)
7175                 return;
7176         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7177         if (ilu->ilu_kstat_io != NULL) {
7178                 mutex_enter(ilu->ilu_kstat_io->ks_lock);

7179                 stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq);
7180                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7181         }
7182 
7183         stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_to_runq);
7184 }
7185 
7186 void
7187 stmf_itl_task_done(stmf_i_scsi_task_t *itask)
7188 {
7189         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7190         scsi_task_t             *task = itask->itask_task;



7191         stmf_i_lu_t     *ilu;
7192 
7193         itask->itask_done_timestamp = gethrtime();
7194 
7195         if (itl == NULL || task->task_lu == dlun0)
7196                 return;
7197         ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
7198 
7199         if (ilu->ilu_kstat_io == NULL)
7200                 return;
7201 
7202         mutex_enter(ilu->ilu_kstat_io->ks_lock);


7203 


























7204         if (itask->itask_flags & ITASK_KSTAT_IN_RUNQ) {

7205                 stmf_update_kstat_lu_q(task, kstat_runq_exit);
7206                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7207                 stmf_update_kstat_lport_q(task, kstat_runq_exit);
7208         } else {

7209                 stmf_update_kstat_lu_q(task, kstat_waitq_exit);
7210                 mutex_exit(ilu->ilu_kstat_io->ks_lock);
7211                 stmf_update_kstat_lport_q(task, kstat_waitq_exit);
7212         }
7213 }
7214 


















































7215 static void
7216 stmf_lport_xfer_start(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7217 {
7218         stmf_itl_data_t         *itl = itask->itask_itl_datap;
7219 
7220         if (itl == NULL)
7221                 return;
7222 
7223         DTRACE_PROBE2(scsi__xfer__start, scsi_task_t *, itask->itask_task,
7224             stmf_data_buf_t *, dbuf);
7225 
7226         dbuf->db_xfer_start_timestamp = gethrtime();
7227 }
7228 
7229 static void
7230 stmf_lport_xfer_done(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
7231 {
7232         stmf_itl_data_t         *itl = itask->itask_itl_datap;



7233         hrtime_t                elapsed_time;
7234         uint64_t                xfer_size;
7235 
7236         if (itl == NULL)
7237                 return;
7238 


7239         xfer_size = (dbuf->db_xfer_status == STMF_SUCCESS) ?
7240             dbuf->db_data_size : 0;
7241 
7242         elapsed_time = gethrtime() - dbuf->db_xfer_start_timestamp;
7243         if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
7244                 atomic_add_64((uint64_t *)&itask->itask_lport_read_time,
7245                     elapsed_time);
7246                 atomic_add_64((uint64_t *)&itask->itask_read_xfer,
7247                     xfer_size);
7248         } else {
7249                 atomic_add_64((uint64_t *)&itask->itask_lport_write_time,
7250                     elapsed_time);
7251                 atomic_add_64((uint64_t *)&itask->itask_write_xfer,
7252                     xfer_size);
7253         }
7254 
7255         DTRACE_PROBE3(scsi__xfer__end, scsi_task_t *, itask->itask_task,
7256             stmf_data_buf_t *, dbuf, hrtime_t, elapsed_time);
7257 











7258         dbuf->db_xfer_start_timestamp = 0;
7259 }
7260 
7261 void
7262 stmf_svc_init()
7263 {
7264         if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
7265                 return;
7266         stmf_state.stmf_svc_tailp = &stmf_state.stmf_svc_active;
7267         stmf_state.stmf_svc_taskq = ddi_taskq_create(0, "STMF_SVC_TASKQ", 1,
7268             TASKQ_DEFAULTPRI, 0);
7269         (void) ddi_taskq_dispatch(stmf_state.stmf_svc_taskq,
7270             stmf_svc, 0, DDI_SLEEP);
7271 }
7272 
7273 stmf_status_t
7274 stmf_svc_fini()
7275 {
7276         uint32_t i;
7277 


7339                         /* Fallthrough */
7340                 case STMF_CMD_LPORT_OFFLINE:
7341                         mutex_exit(&stmf_state.stmf_lock);
7342                         lport = (stmf_local_port_t *)req->svc_obj;
7343                         lport->lport_ctl(lport, req->svc_cmd, &req->svc_info);
7344                         break;
7345                 case STMF_CMD_LU_ONLINE:
7346                         mutex_exit(&stmf_state.stmf_lock);
7347                         lu = (stmf_lu_t *)req->svc_obj;
7348                         lu->lu_ctl(lu, req->svc_cmd, &req->svc_info);
7349                         break;
7350                 case STMF_CMD_LU_OFFLINE:
7351                         /* Remove all mappings of this LU */
7352                         stmf_session_lu_unmapall((stmf_lu_t *)req->svc_obj);
7353                         /* Kill all the pending I/Os for this LU */
7354                         mutex_exit(&stmf_state.stmf_lock);
7355                         stmf_task_lu_killall((stmf_lu_t *)req->svc_obj, NULL,
7356                             STMF_ABORTED);
7357                         lu = (stmf_lu_t *)req->svc_obj;
7358                         ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
7359                         stmf_wait_ilu_tasks_finish(ilu);

7360                         lu->lu_ctl(lu, req->svc_cmd, &req->svc_info);
7361                         break;
7362                 default:
7363                         cmn_err(CE_PANIC, "stmf_svc: unknown cmd %d",
7364                             req->svc_cmd);
7365                 }
7366 
7367                 kmem_free(req, req->svc_req_alloc_size);
7368                 mutex_enter(&stmf_state.stmf_lock);
7369         }
7370 
7371         stmf_state.stmf_svc_flags &= ~(STMF_SVC_STARTED | STMF_SVC_ACTIVE);
7372         mutex_exit(&stmf_state.stmf_lock);
7373 }
7374 
7375 static void
7376 stmf_svc_timeout(struct stmf_svc_clocks *clks)
7377 {
7378         clock_t td;
7379         stmf_i_local_port_t *ilport, *next_ilport;
7380         stmf_i_scsi_session_t *iss;
7381 
7382         ASSERT(mutex_owned(&stmf_state.stmf_lock));
7383 
7384         td = drv_usectohz(20000);
7385 
7386         /* Do timeouts */
7387         if (stmf_state.stmf_nlus &&


7492                                     ~ILPORT_SS_GOT_INITIAL_LUNS);
7493                         /* drop the lock if we are holding it. */
7494                         if (ilport_lock_held == 1)
7495                                 rw_exit(&ilport->ilport_lock);
7496 
7497                         /* Max 4 session at a time */
7498                         if (stmf_level >= 4)
7499                                 break;
7500                 }
7501 
7502                 if (stmf_level == 0)
7503                         stmf_state.stmf_process_initial_luns = 0;
7504         }
7505 
7506         stmf_state.stmf_svc_flags &= ~STMF_SVC_ACTIVE;
7507         (void) cv_reltimedwait(&stmf_state.stmf_cv,
7508             &stmf_state.stmf_lock, td, TR_CLOCK_TICK);
7509         stmf_state.stmf_svc_flags |= STMF_SVC_ACTIVE;
7510 }
7511 
7512 /*
7513  * Waits for ongoing I/O tasks to finish on an LU in preparation for
7514  * the LU's offlining. The LU should already be in an Offlining state
7515  * (otherwise I/O to the LU might never end). There is an additional
7516  * enforcement of this via a deadman timer check.
7517  */
7518 static void
7519 stmf_wait_ilu_tasks_finish(stmf_i_lu_t *ilu)
7520 {
7521         clock_t start, now, deadline;
7522 
7523         start = now = ddi_get_lbolt();
7524         deadline = start + drv_usectohz(stmf_io_deadman * 1000000llu);
7525         mutex_enter(&ilu->ilu_task_lock);
7526         while (ilu->ilu_ntasks != ilu->ilu_ntasks_free) {
7527                 (void) cv_timedwait(&ilu->ilu_offline_pending_cv,
7528                     &ilu->ilu_task_lock, deadline);
7529                 now = ddi_get_lbolt();
7530                 if (now > deadline) {
7531                         if (stmf_io_deadman_enabled) {
7532                                 cmn_err(CE_PANIC, "stmf_svc: I/O deadman hit "
7533                                     "on STMF_CMD_LU_OFFLINE after %d seconds",
7534                                     stmf_io_deadman);
7535                         } else {
7536                                 /* keep on spinning */
7537                                 deadline = now + drv_usectohz(stmf_io_deadman *
7538                                     1000000llu);
7539                         }
7540                 }
7541         }
7542         mutex_exit(&ilu->ilu_task_lock);
7543         DTRACE_PROBE1(deadman__timeout__wait, clock_t, now - start);
7544 }
7545 
7546 void
7547 stmf_svc_queue(int cmd, void *obj, stmf_state_change_info_t *info)
7548 {
7549         stmf_svc_req_t *req;
7550         int s;
7551 
7552         ASSERT(!mutex_owned(&stmf_state.stmf_lock));
7553         s = sizeof (stmf_svc_req_t);
7554         if (info->st_additional_info) {
7555                 s += strlen(info->st_additional_info) + 1;
7556         }
7557         req = kmem_zalloc(s, KM_SLEEP);
7558 
7559         req->svc_cmd = cmd;
7560         req->svc_obj = obj;
7561         req->svc_info.st_rflags = info->st_rflags;
7562         if (info->st_additional_info) {
7563                 req->svc_info.st_additional_info = (char *)(GET_BYTE_OFFSET(req,
7564                     sizeof (stmf_svc_req_t)));
7565                 (void) strcpy(req->svc_info.st_additional_info,