1*45039663SJohn Forte /* 2*45039663SJohn Forte * CDDL HEADER START 3*45039663SJohn Forte * 4*45039663SJohn Forte * The contents of this file are subject to the terms of the 5*45039663SJohn Forte * Common Development and Distribution License (the "License"). 6*45039663SJohn Forte * You may not use this file except in compliance with the License. 7*45039663SJohn Forte * 8*45039663SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*45039663SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*45039663SJohn Forte * See the License for the specific language governing permissions 11*45039663SJohn Forte * and limitations under the License. 12*45039663SJohn Forte * 13*45039663SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*45039663SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*45039663SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*45039663SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*45039663SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*45039663SJohn Forte * 19*45039663SJohn Forte * CDDL HEADER END 20*45039663SJohn Forte */ 21*45039663SJohn Forte /* 22*45039663SJohn Forte * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*45039663SJohn Forte * Use is subject to license terms. 24*45039663SJohn Forte */ 25*45039663SJohn Forte 26*45039663SJohn Forte #include <sys/cpuvar.h> 27*45039663SJohn Forte #include <sys/types.h> 28*45039663SJohn Forte #include <sys/conf.h> 29*45039663SJohn Forte #include <sys/file.h> 30*45039663SJohn Forte #include <sys/ddi.h> 31*45039663SJohn Forte #include <sys/sunddi.h> 32*45039663SJohn Forte #include <sys/modctl.h> 33*45039663SJohn Forte #include <sys/sysmacros.h> 34*45039663SJohn Forte 35*45039663SJohn Forte #include <sys/socket.h> 36*45039663SJohn Forte #include <sys/strsubr.h> 37*45039663SJohn Forte #include <sys/door.h> 38*45039663SJohn Forte #include <sys/note.h> 39*45039663SJohn Forte #include <sys/sdt.h> 40*45039663SJohn Forte 41*45039663SJohn Forte #include <sys/stmf.h> 42*45039663SJohn Forte #include <sys/stmf_ioctl.h> 43*45039663SJohn Forte #include <sys/portif.h> 44*45039663SJohn Forte #define PPPT_TGT_SM_STRINGS 45*45039663SJohn Forte #include <pppt.h> 46*45039663SJohn Forte 47*45039663SJohn Forte typedef struct { 48*45039663SJohn Forte list_node_t te_ctx_node; 49*45039663SJohn Forte pppt_tgt_event_t te_ctx_event; 50*45039663SJohn Forte } tgt_event_ctx_t; 51*45039663SJohn Forte 52*45039663SJohn Forte static void 53*45039663SJohn Forte pppt_tgt_sm_event(pppt_tgt_t *tgt, pppt_tgt_event_t event); 54*45039663SJohn Forte 55*45039663SJohn Forte static void 56*45039663SJohn Forte tgt_sm_event_locked(pppt_tgt_t *tgt, pppt_tgt_event_t event); 57*45039663SJohn Forte 58*45039663SJohn Forte static void 59*45039663SJohn Forte tgt_sm_event_dispatch(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 60*45039663SJohn Forte 61*45039663SJohn Forte static void 62*45039663SJohn Forte tgt_sm_created(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 63*45039663SJohn Forte 64*45039663SJohn Forte static void 65*45039663SJohn Forte tgt_sm_onlining(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 66*45039663SJohn Forte 67*45039663SJohn Forte static void 68*45039663SJohn Forte tgt_sm_online(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 69*45039663SJohn Forte 70*45039663SJohn Forte static void 71*45039663SJohn Forte tgt_sm_stmf_online(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 72*45039663SJohn Forte 73*45039663SJohn Forte static void 74*45039663SJohn Forte tgt_sm_deleting_need_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 75*45039663SJohn Forte 76*45039663SJohn Forte static void 77*45039663SJohn Forte tgt_sm_offlining(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 78*45039663SJohn Forte 79*45039663SJohn Forte static void 80*45039663SJohn Forte tgt_sm_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 81*45039663SJohn Forte 82*45039663SJohn Forte static void 83*45039663SJohn Forte tgt_sm_stmf_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 84*45039663SJohn Forte 85*45039663SJohn Forte static void 86*45039663SJohn Forte tgt_sm_deleting_stmf_dereg(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 87*45039663SJohn Forte 88*45039663SJohn Forte static void 89*45039663SJohn Forte tgt_sm_deleting_stmf_dereg_fail(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 90*45039663SJohn Forte 91*45039663SJohn Forte static void 92*45039663SJohn Forte tgt_sm_deleting(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx); 93*45039663SJohn Forte 94*45039663SJohn Forte static void 95*45039663SJohn Forte pppt_tgt_dereg_retry(void *arg); 96*45039663SJohn Forte 97*45039663SJohn Forte static void 98*45039663SJohn Forte pppt_tgt_dereg_task(void *arg); 99*45039663SJohn Forte 100*45039663SJohn Forte static void 101*45039663SJohn Forte tgt_sm_new_state(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx, 102*45039663SJohn Forte pppt_tgt_state_t new_state); 103*45039663SJohn Forte 104*45039663SJohn Forte /*ARGSUSED*/ 105*45039663SJohn Forte void 106*45039663SJohn Forte pppt_tgt_sm_ctl(stmf_local_port_t *lport, int cmd, void *arg) 107*45039663SJohn Forte { 108*45039663SJohn Forte pppt_tgt_t *pppt_tgt; 109*45039663SJohn Forte 110*45039663SJohn Forte pppt_tgt = (pppt_tgt_t *)lport->lport_port_private; 111*45039663SJohn Forte 112*45039663SJohn Forte switch (cmd) { 113*45039663SJohn Forte case STMF_CMD_LPORT_ONLINE: 114*45039663SJohn Forte pppt_tgt_sm_event(pppt_tgt, TE_STMF_ONLINE_REQ); 115*45039663SJohn Forte break; 116*45039663SJohn Forte case STMF_CMD_LPORT_OFFLINE: 117*45039663SJohn Forte pppt_tgt_sm_event(pppt_tgt, TE_STMF_OFFLINE_REQ); 118*45039663SJohn Forte break; 119*45039663SJohn Forte case STMF_ACK_LPORT_ONLINE_COMPLETE: 120*45039663SJohn Forte pppt_tgt_sm_event(pppt_tgt, TE_STMF_ONLINE_COMPLETE_ACK); 121*45039663SJohn Forte break; 122*45039663SJohn Forte case STMF_ACK_LPORT_OFFLINE_COMPLETE: 123*45039663SJohn Forte pppt_tgt_sm_event(pppt_tgt, TE_STMF_OFFLINE_COMPLETE_ACK); 124*45039663SJohn Forte break; 125*45039663SJohn Forte 126*45039663SJohn Forte default: 127*45039663SJohn Forte ASSERT(0); 128*45039663SJohn Forte break; 129*45039663SJohn Forte } 130*45039663SJohn Forte } 131*45039663SJohn Forte 132*45039663SJohn Forte pppt_tgt_t * 133*45039663SJohn Forte pppt_tgt_create(stmf_ic_reg_port_msg_t *reg_port, stmf_status_t *msg_errcode) 134*45039663SJohn Forte { 135*45039663SJohn Forte pppt_tgt_t *result; 136*45039663SJohn Forte stmf_local_port_t *lport; 137*45039663SJohn Forte int total_devid_len; 138*45039663SJohn Forte 139*45039663SJohn Forte total_devid_len = sizeof (scsi_devid_desc_t) + 140*45039663SJohn Forte reg_port->icrp_port_id->ident_length - 1; 141*45039663SJohn Forte 142*45039663SJohn Forte /* 143*45039663SJohn Forte * Each target is an STMF local port. Allocate an STMF local port 144*45039663SJohn Forte * including enough space to store a scsi_devid_desc_t for this target. 145*45039663SJohn Forte */ 146*45039663SJohn Forte lport = stmf_alloc(STMF_STRUCT_STMF_LOCAL_PORT, 147*45039663SJohn Forte sizeof (pppt_tgt_t) + total_devid_len, 0); 148*45039663SJohn Forte if (lport == NULL) { 149*45039663SJohn Forte *msg_errcode = STMF_ALLOC_FAILURE; 150*45039663SJohn Forte return (NULL); 151*45039663SJohn Forte } 152*45039663SJohn Forte 153*45039663SJohn Forte result = lport->lport_port_private; 154*45039663SJohn Forte result->target_state = TS_CREATED; 155*45039663SJohn Forte /* Use pointer arithmetic to find scsi_devid_desc_t */ 156*45039663SJohn Forte result->target_devid = (scsi_devid_desc_t *)(result + 1); 157*45039663SJohn Forte bcopy(reg_port->icrp_port_id, result->target_devid, total_devid_len); 158*45039663SJohn Forte result->target_devid->piv = 1; 159*45039663SJohn Forte result->target_devid->code_set = CODE_SET_ASCII; 160*45039663SJohn Forte result->target_devid->association = ID_IS_TARGET_PORT; 161*45039663SJohn Forte 162*45039663SJohn Forte mutex_init(&result->target_mutex, NULL, MUTEX_DEFAULT, NULL); 163*45039663SJohn Forte cv_init(&result->target_cv, NULL, CV_DEFAULT, NULL); 164*45039663SJohn Forte list_create(&result->target_events, sizeof (tgt_event_ctx_t), 165*45039663SJohn Forte offsetof(tgt_event_ctx_t, te_ctx_node)); 166*45039663SJohn Forte avl_create(&result->target_sess_list, pppt_sess_avl_compare_by_name, 167*45039663SJohn Forte sizeof (pppt_sess_t), offsetof(pppt_sess_t, ps_target_ln)); 168*45039663SJohn Forte 169*45039663SJohn Forte lport->lport_abort_timeout = 120; /* seconds */ 170*45039663SJohn Forte lport->lport_id = result->target_devid; 171*45039663SJohn Forte lport->lport_pp = pppt_global.global_pp; 172*45039663SJohn Forte lport->lport_ds = pppt_global.global_dbuf_store; 173*45039663SJohn Forte lport->lport_xfer_data = &pppt_lport_xfer_data; 174*45039663SJohn Forte lport->lport_send_status = &pppt_lport_send_status; 175*45039663SJohn Forte lport->lport_task_free = &pppt_lport_task_free; 176*45039663SJohn Forte lport->lport_abort = &pppt_lport_abort; 177*45039663SJohn Forte lport->lport_ctl = &pppt_lport_ctl; 178*45039663SJohn Forte result->target_stmf_lport = lport; 179*45039663SJohn Forte 180*45039663SJohn Forte /* 181*45039663SJohn Forte * Since this is a proxy port we need to do set the relative 182*45039663SJohn Forte * target port identifier before registering it with STMF. 183*45039663SJohn Forte */ 184*45039663SJohn Forte stmf_set_port_standby(lport, reg_port->icrp_relative_port_id); 185*45039663SJohn Forte 186*45039663SJohn Forte /* 187*45039663SJohn Forte * Register the target with STMF. STMF may immediately ask us to go 188*45039663SJohn Forte * online so insure any additional config setup is complete. 189*45039663SJohn Forte */ 190*45039663SJohn Forte if (stmf_register_local_port(lport) != STMF_SUCCESS) { 191*45039663SJohn Forte *msg_errcode = STMF_FAILURE; 192*45039663SJohn Forte pppt_tgt_destroy(result); 193*45039663SJohn Forte return (NULL); 194*45039663SJohn Forte } 195*45039663SJohn Forte 196*45039663SJohn Forte return (result); 197*45039663SJohn Forte 198*45039663SJohn Forte } 199*45039663SJohn Forte 200*45039663SJohn Forte void 201*45039663SJohn Forte pppt_tgt_destroy(pppt_tgt_t *tgt) 202*45039663SJohn Forte { 203*45039663SJohn Forte /* Destroy target */ 204*45039663SJohn Forte avl_destroy(&tgt->target_sess_list); 205*45039663SJohn Forte list_destroy(&tgt->target_events); 206*45039663SJohn Forte cv_destroy(&tgt->target_cv); 207*45039663SJohn Forte mutex_destroy(&tgt->target_mutex); 208*45039663SJohn Forte stmf_free(tgt->target_stmf_lport); /* Also frees "tgt' */ 209*45039663SJohn Forte } 210*45039663SJohn Forte 211*45039663SJohn Forte pppt_tgt_t * 212*45039663SJohn Forte pppt_tgt_lookup(scsi_devid_desc_t *tgt_devid) 213*45039663SJohn Forte { 214*45039663SJohn Forte pppt_tgt_t *result; 215*45039663SJohn Forte PPPT_GLOBAL_LOCK(); 216*45039663SJohn Forte result = pppt_tgt_lookup_locked(tgt_devid); 217*45039663SJohn Forte PPPT_GLOBAL_UNLOCK(); 218*45039663SJohn Forte 219*45039663SJohn Forte return (result); 220*45039663SJohn Forte } 221*45039663SJohn Forte 222*45039663SJohn Forte pppt_tgt_t * 223*45039663SJohn Forte pppt_tgt_lookup_locked(scsi_devid_desc_t *tgt_devid) 224*45039663SJohn Forte { 225*45039663SJohn Forte pppt_tgt_t *result; 226*45039663SJohn Forte pppt_tgt_t tmptgt; 227*45039663SJohn Forte 228*45039663SJohn Forte bzero(&tmptgt, sizeof (tmptgt)); 229*45039663SJohn Forte tmptgt.target_devid = tgt_devid; 230*45039663SJohn Forte 231*45039663SJohn Forte result = avl_find(&pppt_global.global_target_list, &tmptgt, NULL); 232*45039663SJohn Forte 233*45039663SJohn Forte return (result); 234*45039663SJohn Forte } 235*45039663SJohn Forte 236*45039663SJohn Forte void 237*45039663SJohn Forte pppt_tgt_async_delete(pppt_tgt_t *tgt) 238*45039663SJohn Forte { 239*45039663SJohn Forte /* Generate TE_DELETE event to target state machine */ 240*45039663SJohn Forte pppt_tgt_sm_event(tgt, TE_DELETE); 241*45039663SJohn Forte } 242*45039663SJohn Forte 243*45039663SJohn Forte int 244*45039663SJohn Forte pppt_tgt_avl_compare(const void *void_tgt1, const void *void_tgt2) 245*45039663SJohn Forte { 246*45039663SJohn Forte const pppt_tgt_t *ptgt1 = void_tgt1; 247*45039663SJohn Forte const pppt_tgt_t *ptgt2 = void_tgt2; 248*45039663SJohn Forte int result; 249*45039663SJohn Forte 250*45039663SJohn Forte /* Sort by code set then ident */ 251*45039663SJohn Forte if (ptgt1->target_devid->code_set < 252*45039663SJohn Forte ptgt2->target_devid->code_set) { 253*45039663SJohn Forte return (-1); 254*45039663SJohn Forte } else if (ptgt1->target_devid->code_set > 255*45039663SJohn Forte ptgt2->target_devid->code_set) { 256*45039663SJohn Forte return (1); 257*45039663SJohn Forte } 258*45039663SJohn Forte 259*45039663SJohn Forte /* Next by ident length */ 260*45039663SJohn Forte if (ptgt1->target_devid->ident_length < 261*45039663SJohn Forte ptgt2->target_devid->ident_length) { 262*45039663SJohn Forte return (-1); 263*45039663SJohn Forte } else if (ptgt1->target_devid->ident_length > 264*45039663SJohn Forte ptgt2->target_devid->ident_length) { 265*45039663SJohn Forte return (1); 266*45039663SJohn Forte } 267*45039663SJohn Forte 268*45039663SJohn Forte /* Code set and ident length both match, now compare idents */ 269*45039663SJohn Forte result = memcmp(ptgt1->target_devid->ident, ptgt2->target_devid->ident, 270*45039663SJohn Forte ptgt1->target_devid->ident_length); 271*45039663SJohn Forte 272*45039663SJohn Forte if (result < 0) { 273*45039663SJohn Forte return (-1); 274*45039663SJohn Forte } else if (result > 0) { 275*45039663SJohn Forte return (1); 276*45039663SJohn Forte } 277*45039663SJohn Forte 278*45039663SJohn Forte return (0); 279*45039663SJohn Forte } 280*45039663SJohn Forte 281*45039663SJohn Forte /* 282*45039663SJohn Forte * Target state machine 283*45039663SJohn Forte */ 284*45039663SJohn Forte 285*45039663SJohn Forte static void 286*45039663SJohn Forte pppt_tgt_sm_event(pppt_tgt_t *tgt, pppt_tgt_event_t event) 287*45039663SJohn Forte { 288*45039663SJohn Forte mutex_enter(&tgt->target_mutex); 289*45039663SJohn Forte tgt_sm_event_locked(tgt, event); 290*45039663SJohn Forte mutex_exit(&tgt->target_mutex); 291*45039663SJohn Forte } 292*45039663SJohn Forte 293*45039663SJohn Forte static void 294*45039663SJohn Forte tgt_sm_event_locked(pppt_tgt_t *tgt, pppt_tgt_event_t event) 295*45039663SJohn Forte { 296*45039663SJohn Forte tgt_event_ctx_t *ctx; 297*45039663SJohn Forte 298*45039663SJohn Forte tgt->target_refcount++; 299*45039663SJohn Forte 300*45039663SJohn Forte ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP); 301*45039663SJohn Forte 302*45039663SJohn Forte ctx->te_ctx_event = event; 303*45039663SJohn Forte 304*45039663SJohn Forte list_insert_tail(&tgt->target_events, ctx); 305*45039663SJohn Forte 306*45039663SJohn Forte /* 307*45039663SJohn Forte * Use the target_sm_busy flag to keep the state machine single 308*45039663SJohn Forte * threaded. This also serves as recursion avoidance since this 309*45039663SJohn Forte * flag will always be set if we call pppt_tgt_sm_event from 310*45039663SJohn Forte * within the state machine code. 311*45039663SJohn Forte */ 312*45039663SJohn Forte if (!tgt->target_sm_busy) { 313*45039663SJohn Forte tgt->target_sm_busy = B_TRUE; 314*45039663SJohn Forte while (!list_is_empty(&tgt->target_events)) { 315*45039663SJohn Forte ctx = list_head(&tgt->target_events); 316*45039663SJohn Forte list_remove(&tgt->target_events, ctx); 317*45039663SJohn Forte mutex_exit(&tgt->target_mutex); 318*45039663SJohn Forte tgt_sm_event_dispatch(tgt, ctx); 319*45039663SJohn Forte mutex_enter(&tgt->target_mutex); 320*45039663SJohn Forte } 321*45039663SJohn Forte tgt->target_sm_busy = B_FALSE; 322*45039663SJohn Forte 323*45039663SJohn Forte } 324*45039663SJohn Forte 325*45039663SJohn Forte tgt->target_refcount--; 326*45039663SJohn Forte cv_signal(&tgt->target_cv); 327*45039663SJohn Forte } 328*45039663SJohn Forte 329*45039663SJohn Forte static void 330*45039663SJohn Forte tgt_sm_event_dispatch(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 331*45039663SJohn Forte { 332*45039663SJohn Forte DTRACE_PROBE2(pppt__tgt__event, pppt_tgt_t *, tgt, 333*45039663SJohn Forte tgt_event_ctx_t *, ctx); 334*45039663SJohn Forte 335*45039663SJohn Forte PPPT_LOG(CE_NOTE, "tgt_sm_event_dispatch: tgt %p event %s(%d)", 336*45039663SJohn Forte (void *)tgt, pppt_te_name[ctx->te_ctx_event], ctx->te_ctx_event); 337*45039663SJohn Forte 338*45039663SJohn Forte /* State independent actions */ 339*45039663SJohn Forte switch (ctx->te_ctx_event) { 340*45039663SJohn Forte case TE_DELETE: 341*45039663SJohn Forte tgt->target_deleting = B_TRUE; 342*45039663SJohn Forte break; 343*45039663SJohn Forte } 344*45039663SJohn Forte 345*45039663SJohn Forte /* State dependent actions */ 346*45039663SJohn Forte switch (tgt->target_state) { 347*45039663SJohn Forte case TS_CREATED: 348*45039663SJohn Forte tgt_sm_created(tgt, ctx); 349*45039663SJohn Forte break; 350*45039663SJohn Forte case TS_ONLINING: 351*45039663SJohn Forte tgt_sm_onlining(tgt, ctx); 352*45039663SJohn Forte break; 353*45039663SJohn Forte case TS_ONLINE: 354*45039663SJohn Forte tgt_sm_online(tgt, ctx); 355*45039663SJohn Forte break; 356*45039663SJohn Forte case TS_STMF_ONLINE: 357*45039663SJohn Forte tgt_sm_stmf_online(tgt, ctx); 358*45039663SJohn Forte break; 359*45039663SJohn Forte case TS_DELETING_NEED_OFFLINE: 360*45039663SJohn Forte tgt_sm_deleting_need_offline(tgt, ctx); 361*45039663SJohn Forte break; 362*45039663SJohn Forte case TS_OFFLINING: 363*45039663SJohn Forte tgt_sm_offlining(tgt, ctx); 364*45039663SJohn Forte break; 365*45039663SJohn Forte case TS_OFFLINE: 366*45039663SJohn Forte tgt_sm_offline(tgt, ctx); 367*45039663SJohn Forte break; 368*45039663SJohn Forte case TS_STMF_OFFLINE: 369*45039663SJohn Forte tgt_sm_stmf_offline(tgt, ctx); 370*45039663SJohn Forte break; 371*45039663SJohn Forte case TS_DELETING_STMF_DEREG: 372*45039663SJohn Forte tgt_sm_deleting_stmf_dereg(tgt, ctx); 373*45039663SJohn Forte break; 374*45039663SJohn Forte case TS_DELETING_STMF_DEREG_FAIL: 375*45039663SJohn Forte tgt_sm_deleting_stmf_dereg_fail(tgt, ctx); 376*45039663SJohn Forte break; 377*45039663SJohn Forte case TS_DELETING: 378*45039663SJohn Forte tgt_sm_deleting(tgt, ctx); 379*45039663SJohn Forte break; 380*45039663SJohn Forte default: 381*45039663SJohn Forte ASSERT(0); 382*45039663SJohn Forte } 383*45039663SJohn Forte 384*45039663SJohn Forte kmem_free(ctx, sizeof (*ctx)); 385*45039663SJohn Forte } 386*45039663SJohn Forte 387*45039663SJohn Forte static void 388*45039663SJohn Forte tgt_sm_created(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 389*45039663SJohn Forte { 390*45039663SJohn Forte stmf_change_status_t scs; 391*45039663SJohn Forte 392*45039663SJohn Forte switch (ctx->te_ctx_event) { 393*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 394*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_ONLINING); 395*45039663SJohn Forte break; 396*45039663SJohn Forte case TE_DELETE: 397*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG); 398*45039663SJohn Forte break; 399*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 400*45039663SJohn Forte /* 401*45039663SJohn Forte * We're already offline but update to an equivelant 402*45039663SJohn Forte * state just to note that STMF talked to us. 403*45039663SJohn Forte */ 404*45039663SJohn Forte scs.st_completion_status = STMF_SUCCESS; 405*45039663SJohn Forte scs.st_additional_info = NULL; 406*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_OFFLINE); 407*45039663SJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE, 408*45039663SJohn Forte tgt->target_stmf_lport, &scs); 409*45039663SJohn Forte break; 410*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 411*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 412*45039663SJohn Forte /* Ignore */ 413*45039663SJohn Forte break; 414*45039663SJohn Forte default: 415*45039663SJohn Forte ASSERT(0); 416*45039663SJohn Forte } 417*45039663SJohn Forte } 418*45039663SJohn Forte 419*45039663SJohn Forte static void 420*45039663SJohn Forte tgt_sm_onlining(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 421*45039663SJohn Forte { 422*45039663SJohn Forte stmf_change_status_t scs; 423*45039663SJohn Forte 424*45039663SJohn Forte switch (ctx->te_ctx_event) { 425*45039663SJohn Forte case TE_ONLINE_SUCCESS: 426*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_ONLINE); 427*45039663SJohn Forte break; 428*45039663SJohn Forte case TE_ONLINE_FAIL: 429*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_STMF_OFFLINE); 430*45039663SJohn Forte break; 431*45039663SJohn Forte case TE_DELETE: 432*45039663SJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */ 433*45039663SJohn Forte break; 434*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 435*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 436*45039663SJohn Forte /* 437*45039663SJohn Forte * We can't complete STMF's request since we are busy going 438*45039663SJohn Forte * online. 439*45039663SJohn Forte */ 440*45039663SJohn Forte scs.st_completion_status = STMF_INVALID_ARG; 441*45039663SJohn Forte scs.st_additional_info = NULL; 442*45039663SJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ? 443*45039663SJohn Forte STMF_CMD_LPORT_ONLINE_COMPLETE : 444*45039663SJohn Forte STMF_CMD_LPORT_OFFLINE_COMPLETE, 445*45039663SJohn Forte tgt->target_stmf_lport, &scs); 446*45039663SJohn Forte break; 447*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 448*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 449*45039663SJohn Forte /* Ignore */ 450*45039663SJohn Forte break; 451*45039663SJohn Forte default: 452*45039663SJohn Forte ASSERT(0); 453*45039663SJohn Forte } 454*45039663SJohn Forte } 455*45039663SJohn Forte 456*45039663SJohn Forte static void 457*45039663SJohn Forte tgt_sm_online(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 458*45039663SJohn Forte { 459*45039663SJohn Forte stmf_change_status_t scs; 460*45039663SJohn Forte 461*45039663SJohn Forte switch (ctx->te_ctx_event) { 462*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 463*45039663SJohn Forte if (tgt->target_deleting) { 464*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_NEED_OFFLINE); 465*45039663SJohn Forte } else { 466*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_STMF_ONLINE); 467*45039663SJohn Forte } 468*45039663SJohn Forte break; 469*45039663SJohn Forte case TE_DELETE: 470*45039663SJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */ 471*45039663SJohn Forte break; 472*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 473*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 474*45039663SJohn Forte /* 475*45039663SJohn Forte * We can't complete STMF's request since we are busy going 476*45039663SJohn Forte * online (waiting for acknowlegement from STMF) 477*45039663SJohn Forte */ 478*45039663SJohn Forte scs.st_completion_status = STMF_INVALID_ARG; 479*45039663SJohn Forte scs.st_additional_info = NULL; 480*45039663SJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ? 481*45039663SJohn Forte STMF_CMD_LPORT_ONLINE_COMPLETE : 482*45039663SJohn Forte STMF_CMD_LPORT_OFFLINE_COMPLETE, 483*45039663SJohn Forte tgt->target_stmf_lport, &scs); 484*45039663SJohn Forte break; 485*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 486*45039663SJohn Forte /* Ignore */ 487*45039663SJohn Forte break; 488*45039663SJohn Forte default: 489*45039663SJohn Forte ASSERT(0); 490*45039663SJohn Forte } 491*45039663SJohn Forte } 492*45039663SJohn Forte 493*45039663SJohn Forte 494*45039663SJohn Forte static void 495*45039663SJohn Forte tgt_sm_stmf_online(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 496*45039663SJohn Forte { 497*45039663SJohn Forte stmf_change_status_t scs; 498*45039663SJohn Forte 499*45039663SJohn Forte switch (ctx->te_ctx_event) { 500*45039663SJohn Forte case TE_DELETE: 501*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_NEED_OFFLINE); 502*45039663SJohn Forte break; 503*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 504*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_OFFLINING); 505*45039663SJohn Forte break; 506*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 507*45039663SJohn Forte /* Already online */ 508*45039663SJohn Forte scs.st_completion_status = STMF_ALREADY; 509*45039663SJohn Forte scs.st_additional_info = NULL; 510*45039663SJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, 511*45039663SJohn Forte tgt->target_stmf_lport, &scs); 512*45039663SJohn Forte break; 513*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 514*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 515*45039663SJohn Forte /* Ignore */ 516*45039663SJohn Forte break; 517*45039663SJohn Forte default: 518*45039663SJohn Forte ASSERT(0); 519*45039663SJohn Forte } 520*45039663SJohn Forte } 521*45039663SJohn Forte 522*45039663SJohn Forte 523*45039663SJohn Forte static void 524*45039663SJohn Forte tgt_sm_deleting_need_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 525*45039663SJohn Forte { 526*45039663SJohn Forte stmf_change_status_t scs; 527*45039663SJohn Forte 528*45039663SJohn Forte switch (ctx->te_ctx_event) { 529*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 530*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_OFFLINING); 531*45039663SJohn Forte break; 532*45039663SJohn Forte case TE_DELETE: 533*45039663SJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */ 534*45039663SJohn Forte break; 535*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 536*45039663SJohn Forte /* 537*45039663SJohn Forte * We can't complete STMF's request since we need to be offlined 538*45039663SJohn Forte */ 539*45039663SJohn Forte scs.st_completion_status = STMF_INVALID_ARG; 540*45039663SJohn Forte scs.st_additional_info = NULL; 541*45039663SJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, 542*45039663SJohn Forte tgt->target_stmf_lport, &scs); 543*45039663SJohn Forte break; 544*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 545*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 546*45039663SJohn Forte /* Ignore */ 547*45039663SJohn Forte break; 548*45039663SJohn Forte default: 549*45039663SJohn Forte ASSERT(0); 550*45039663SJohn Forte } 551*45039663SJohn Forte } 552*45039663SJohn Forte 553*45039663SJohn Forte 554*45039663SJohn Forte static void 555*45039663SJohn Forte tgt_sm_offlining(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 556*45039663SJohn Forte { 557*45039663SJohn Forte stmf_change_status_t scs; 558*45039663SJohn Forte 559*45039663SJohn Forte switch (ctx->te_ctx_event) { 560*45039663SJohn Forte case TE_OFFLINE_COMPLETE: 561*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_OFFLINE); 562*45039663SJohn Forte break; 563*45039663SJohn Forte case TE_DELETE: 564*45039663SJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */ 565*45039663SJohn Forte break; 566*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 567*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 568*45039663SJohn Forte /* 569*45039663SJohn Forte * We can't complete STMF's request since we are busy going 570*45039663SJohn Forte * offline. 571*45039663SJohn Forte */ 572*45039663SJohn Forte scs.st_completion_status = STMF_INVALID_ARG; 573*45039663SJohn Forte scs.st_additional_info = NULL; 574*45039663SJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ? 575*45039663SJohn Forte STMF_CMD_LPORT_ONLINE_COMPLETE : 576*45039663SJohn Forte STMF_CMD_LPORT_OFFLINE_COMPLETE, 577*45039663SJohn Forte tgt->target_stmf_lport, &scs); 578*45039663SJohn Forte break; 579*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 580*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 581*45039663SJohn Forte /* Ignore */ 582*45039663SJohn Forte break; 583*45039663SJohn Forte default: 584*45039663SJohn Forte ASSERT(0); 585*45039663SJohn Forte } 586*45039663SJohn Forte } 587*45039663SJohn Forte 588*45039663SJohn Forte 589*45039663SJohn Forte static void 590*45039663SJohn Forte tgt_sm_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 591*45039663SJohn Forte { 592*45039663SJohn Forte stmf_change_status_t scs; 593*45039663SJohn Forte 594*45039663SJohn Forte switch (ctx->te_ctx_event) { 595*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 596*45039663SJohn Forte if (tgt->target_deleting) { 597*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG); 598*45039663SJohn Forte } else { 599*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_STMF_OFFLINE); 600*45039663SJohn Forte } 601*45039663SJohn Forte break; 602*45039663SJohn Forte case TE_DELETE: 603*45039663SJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */ 604*45039663SJohn Forte break; 605*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 606*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 607*45039663SJohn Forte /* 608*45039663SJohn Forte * We can't complete STMF's request since we are busy going 609*45039663SJohn Forte * offline. 610*45039663SJohn Forte */ 611*45039663SJohn Forte scs.st_completion_status = STMF_INVALID_ARG; 612*45039663SJohn Forte scs.st_additional_info = NULL; 613*45039663SJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ? 614*45039663SJohn Forte STMF_CMD_LPORT_ONLINE_COMPLETE : 615*45039663SJohn Forte STMF_CMD_LPORT_OFFLINE_COMPLETE, 616*45039663SJohn Forte tgt->target_stmf_lport, &scs); 617*45039663SJohn Forte break; 618*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 619*45039663SJohn Forte /* Ignore */ 620*45039663SJohn Forte break; 621*45039663SJohn Forte default: 622*45039663SJohn Forte ASSERT(0); 623*45039663SJohn Forte } 624*45039663SJohn Forte } 625*45039663SJohn Forte 626*45039663SJohn Forte 627*45039663SJohn Forte static void 628*45039663SJohn Forte tgt_sm_stmf_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 629*45039663SJohn Forte { 630*45039663SJohn Forte stmf_change_status_t scs; 631*45039663SJohn Forte 632*45039663SJohn Forte switch (ctx->te_ctx_event) { 633*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 634*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_ONLINING); 635*45039663SJohn Forte break; 636*45039663SJohn Forte case TE_DELETE: 637*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG); 638*45039663SJohn Forte break; 639*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 640*45039663SJohn Forte /* Already offline */ 641*45039663SJohn Forte scs.st_completion_status = STMF_ALREADY; 642*45039663SJohn Forte scs.st_additional_info = NULL; 643*45039663SJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE, 644*45039663SJohn Forte tgt->target_stmf_lport, &scs); 645*45039663SJohn Forte break; 646*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 647*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 648*45039663SJohn Forte /* Ignore */ 649*45039663SJohn Forte break; 650*45039663SJohn Forte default: 651*45039663SJohn Forte ASSERT(0); 652*45039663SJohn Forte } 653*45039663SJohn Forte } 654*45039663SJohn Forte 655*45039663SJohn Forte 656*45039663SJohn Forte static void 657*45039663SJohn Forte tgt_sm_deleting_stmf_dereg(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 658*45039663SJohn Forte { 659*45039663SJohn Forte stmf_change_status_t scs; 660*45039663SJohn Forte 661*45039663SJohn Forte /* Terminal state, no events */ 662*45039663SJohn Forte switch (ctx->te_ctx_event) { 663*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 664*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 665*45039663SJohn Forte /* 666*45039663SJohn Forte * We can't complete STMF's request since we are being deleted 667*45039663SJohn Forte */ 668*45039663SJohn Forte scs.st_completion_status = STMF_INVALID_ARG; 669*45039663SJohn Forte scs.st_additional_info = NULL; 670*45039663SJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ? 671*45039663SJohn Forte STMF_CMD_LPORT_ONLINE_COMPLETE : 672*45039663SJohn Forte STMF_CMD_LPORT_OFFLINE_COMPLETE, 673*45039663SJohn Forte tgt->target_stmf_lport, &scs); 674*45039663SJohn Forte break; 675*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 676*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 677*45039663SJohn Forte /* Ignore */ 678*45039663SJohn Forte break; 679*45039663SJohn Forte case TE_STMF_DEREG_SUCCESS: 680*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING); 681*45039663SJohn Forte break; 682*45039663SJohn Forte case TE_STMF_DEREG_FAIL: 683*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG_FAIL); 684*45039663SJohn Forte break; 685*45039663SJohn Forte default: 686*45039663SJohn Forte ASSERT(0); 687*45039663SJohn Forte } 688*45039663SJohn Forte } 689*45039663SJohn Forte 690*45039663SJohn Forte static void 691*45039663SJohn Forte tgt_sm_deleting_stmf_dereg_fail(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 692*45039663SJohn Forte { 693*45039663SJohn Forte stmf_change_status_t scs; 694*45039663SJohn Forte 695*45039663SJohn Forte /* Terminal state, no events */ 696*45039663SJohn Forte switch (ctx->te_ctx_event) { 697*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 698*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 699*45039663SJohn Forte /* 700*45039663SJohn Forte * We can't complete STMF's request since we are being deleted 701*45039663SJohn Forte */ 702*45039663SJohn Forte scs.st_completion_status = STMF_INVALID_ARG; 703*45039663SJohn Forte scs.st_additional_info = NULL; 704*45039663SJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ? 705*45039663SJohn Forte STMF_CMD_LPORT_ONLINE_COMPLETE : 706*45039663SJohn Forte STMF_CMD_LPORT_OFFLINE_COMPLETE, 707*45039663SJohn Forte tgt->target_stmf_lport, &scs); 708*45039663SJohn Forte break; 709*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 710*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 711*45039663SJohn Forte /* Ignore */ 712*45039663SJohn Forte break; 713*45039663SJohn Forte case TE_STMF_DEREG_RETRY: 714*45039663SJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG); 715*45039663SJohn Forte break; 716*45039663SJohn Forte default: 717*45039663SJohn Forte ASSERT(0); 718*45039663SJohn Forte } 719*45039663SJohn Forte } 720*45039663SJohn Forte 721*45039663SJohn Forte static void 722*45039663SJohn Forte tgt_sm_deleting(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx) 723*45039663SJohn Forte { 724*45039663SJohn Forte stmf_change_status_t scs; 725*45039663SJohn Forte 726*45039663SJohn Forte /* Terminal state, no events */ 727*45039663SJohn Forte switch (ctx->te_ctx_event) { 728*45039663SJohn Forte case TE_STMF_ONLINE_REQ: 729*45039663SJohn Forte case TE_STMF_OFFLINE_REQ: 730*45039663SJohn Forte /* 731*45039663SJohn Forte * We can't complete STMF's request since we are being deleted 732*45039663SJohn Forte */ 733*45039663SJohn Forte scs.st_completion_status = STMF_INVALID_ARG; 734*45039663SJohn Forte scs.st_additional_info = NULL; 735*45039663SJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ? 736*45039663SJohn Forte STMF_CMD_LPORT_ONLINE_COMPLETE : 737*45039663SJohn Forte STMF_CMD_LPORT_OFFLINE_COMPLETE, 738*45039663SJohn Forte tgt->target_stmf_lport, &scs); 739*45039663SJohn Forte break; 740*45039663SJohn Forte case TE_STMF_ONLINE_COMPLETE_ACK: 741*45039663SJohn Forte case TE_STMF_OFFLINE_COMPLETE_ACK: 742*45039663SJohn Forte /* Ignore */ 743*45039663SJohn Forte break; 744*45039663SJohn Forte default: 745*45039663SJohn Forte ASSERT(0); 746*45039663SJohn Forte } 747*45039663SJohn Forte } 748*45039663SJohn Forte 749*45039663SJohn Forte static void 750*45039663SJohn Forte pppt_tgt_offline(void *arg) 751*45039663SJohn Forte { 752*45039663SJohn Forte pppt_tgt_t *tgt = arg; 753*45039663SJohn Forte pppt_sess_t *ps, *next_ps; 754*45039663SJohn Forte stmf_change_status_t scs; 755*45039663SJohn Forte 756*45039663SJohn Forte PPPT_LOG(CE_NOTE, "pppt_tgt_offline %p", (void *)tgt); 757*45039663SJohn Forte 758*45039663SJohn Forte PPPT_GLOBAL_LOCK(); 759*45039663SJohn Forte mutex_enter(&tgt->target_mutex); 760*45039663SJohn Forte for (ps = avl_first(&tgt->target_sess_list); ps != NULL; ps = next_ps) { 761*45039663SJohn Forte next_ps = AVL_NEXT(&tgt->target_sess_list, ps); 762*45039663SJohn Forte mutex_enter(&ps->ps_mutex); 763*45039663SJohn Forte PPPT_LOG(CE_NOTE, "pppt_tgt_offline closing session %p(%d)", 764*45039663SJohn Forte (void *)ps, ps->ps_closed); 765*45039663SJohn Forte if (!ps->ps_closed) { 766*45039663SJohn Forte pppt_sess_close_locked(ps); 767*45039663SJohn Forte } 768*45039663SJohn Forte mutex_exit(&ps->ps_mutex); 769*45039663SJohn Forte } 770*45039663SJohn Forte mutex_exit(&tgt->target_mutex); 771*45039663SJohn Forte PPPT_GLOBAL_UNLOCK(); 772*45039663SJohn Forte 773*45039663SJohn Forte pppt_tgt_sm_event(tgt, TE_OFFLINE_COMPLETE); 774*45039663SJohn Forte 775*45039663SJohn Forte scs.st_completion_status = STMF_SUCCESS; 776*45039663SJohn Forte scs.st_additional_info = NULL; 777*45039663SJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_OFFLINE_COMPLETE, 778*45039663SJohn Forte tgt->target_stmf_lport, &scs); 779*45039663SJohn Forte 780*45039663SJohn Forte PPPT_LOG(CE_NOTE, "pppt_tgt_offline complete %p", (void *)tgt); 781*45039663SJohn Forte } 782*45039663SJohn Forte 783*45039663SJohn Forte static void 784*45039663SJohn Forte pppt_tgt_dereg_retry(void *arg) 785*45039663SJohn Forte { 786*45039663SJohn Forte pppt_tgt_t *tgt = arg; 787*45039663SJohn Forte 788*45039663SJohn Forte /* 789*45039663SJohn Forte * Rather than guaranteeing the target state machine code will not 790*45039663SJohn Forte * block for long periods of time (tying up this callout thread) 791*45039663SJohn Forte * we will queue a task on the taskq to send the retry event. 792*45039663SJohn Forte * If it fails we'll setup another timeout and try again later. 793*45039663SJohn Forte */ 794*45039663SJohn Forte if (taskq_dispatch(pppt_global.global_dispatch_taskq, 795*45039663SJohn Forte pppt_tgt_dereg_task, tgt, KM_NOSLEEP) == NULL) { 796*45039663SJohn Forte /* Dispatch failed, try again later */ 797*45039663SJohn Forte (void) timeout(pppt_tgt_dereg_retry, tgt, 798*45039663SJohn Forte drv_usectohz(TGT_DEREG_RETRY_SECONDS * 1000000)); 799*45039663SJohn Forte } 800*45039663SJohn Forte } 801*45039663SJohn Forte 802*45039663SJohn Forte static void 803*45039663SJohn Forte pppt_tgt_dereg_task(void *arg) 804*45039663SJohn Forte { 805*45039663SJohn Forte pppt_tgt_t *tgt = arg; 806*45039663SJohn Forte 807*45039663SJohn Forte pppt_tgt_sm_event(tgt, TE_STMF_DEREG_RETRY); 808*45039663SJohn Forte } 809*45039663SJohn Forte 810*45039663SJohn Forte /*ARGSUSED*/ 811*45039663SJohn Forte static void 812*45039663SJohn Forte tgt_sm_new_state(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx, 813*45039663SJohn Forte pppt_tgt_state_t new_state) 814*45039663SJohn Forte { 815*45039663SJohn Forte stmf_local_port_t *lport = tgt->target_stmf_lport; 816*45039663SJohn Forte stmf_change_status_t scs; 817*45039663SJohn Forte stmf_state_change_info_t sci; 818*45039663SJohn Forte stmf_status_t stmfrc; 819*45039663SJohn Forte 820*45039663SJohn Forte scs.st_completion_status = STMF_SUCCESS; 821*45039663SJohn Forte scs.st_additional_info = NULL; 822*45039663SJohn Forte 823*45039663SJohn Forte /* 824*45039663SJohn Forte * Validate new state 825*45039663SJohn Forte */ 826*45039663SJohn Forte ASSERT(new_state != TS_UNDEFINED); 827*45039663SJohn Forte ASSERT3U(new_state, <, TS_MAX_STATE); 828*45039663SJohn Forte 829*45039663SJohn Forte new_state = (new_state < TS_MAX_STATE) ? 830*45039663SJohn Forte new_state : TS_UNDEFINED; 831*45039663SJohn Forte 832*45039663SJohn Forte PPPT_LOG(CE_NOTE, "tgt_sm_new_state: tgt %p, %s(%d) --> %s(%d)\n", 833*45039663SJohn Forte (void *) tgt, pppt_ts_name[tgt->target_state], tgt->target_state, 834*45039663SJohn Forte pppt_ts_name[new_state], new_state); 835*45039663SJohn Forte DTRACE_PROBE3(pppt__target__state__change, 836*45039663SJohn Forte pppt_tgt_t *, tgt, tgt_event_ctx_t *, ctx, 837*45039663SJohn Forte pppt_tgt_state_t, new_state); 838*45039663SJohn Forte 839*45039663SJohn Forte mutex_enter(&tgt->target_mutex); 840*45039663SJohn Forte tgt->target_last_state = tgt->target_state; 841*45039663SJohn Forte tgt->target_state = new_state; 842*45039663SJohn Forte cv_signal(&tgt->target_cv); 843*45039663SJohn Forte mutex_exit(&tgt->target_mutex); 844*45039663SJohn Forte 845*45039663SJohn Forte switch (tgt->target_state) { 846*45039663SJohn Forte case TS_ONLINING: 847*45039663SJohn Forte pppt_tgt_sm_event(tgt, TE_ONLINE_SUCCESS); 848*45039663SJohn Forte 849*45039663SJohn Forte /* 850*45039663SJohn Forte * Let STMF know the how the online operation completed. 851*45039663SJohn Forte * STMF will respond with an acknowlege later 852*45039663SJohn Forte */ 853*45039663SJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, lport, &scs); 854*45039663SJohn Forte break; 855*45039663SJohn Forte case TS_ONLINE: 856*45039663SJohn Forte break; 857*45039663SJohn Forte case TS_STMF_ONLINE: 858*45039663SJohn Forte break; 859*45039663SJohn Forte case TS_DELETING_NEED_OFFLINE: 860*45039663SJohn Forte sci.st_rflags = STMF_RFLAG_STAY_OFFLINED; 861*45039663SJohn Forte sci.st_additional_info = "Offline for delete"; 862*45039663SJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_OFFLINE, lport, &sci); 863*45039663SJohn Forte break; 864*45039663SJohn Forte case TS_OFFLINING: 865*45039663SJohn Forte /* Async callback generates completion event */ 866*45039663SJohn Forte pppt_tgt_offline(tgt); 867*45039663SJohn Forte break; 868*45039663SJohn Forte case TS_OFFLINE: 869*45039663SJohn Forte break; 870*45039663SJohn Forte case TS_STMF_OFFLINE: 871*45039663SJohn Forte break; 872*45039663SJohn Forte case TS_DELETING_STMF_DEREG: 873*45039663SJohn Forte stmfrc = stmf_deregister_local_port(tgt->target_stmf_lport); 874*45039663SJohn Forte if (stmfrc == STMF_SUCCESS) { 875*45039663SJohn Forte pppt_tgt_sm_event(tgt, TE_STMF_DEREG_SUCCESS); 876*45039663SJohn Forte } else { 877*45039663SJohn Forte pppt_tgt_sm_event(tgt, TE_STMF_DEREG_FAIL); 878*45039663SJohn Forte } 879*45039663SJohn Forte break; 880*45039663SJohn Forte case TS_DELETING_STMF_DEREG_FAIL: 881*45039663SJohn Forte /* Retry dereg in 1 second */ 882*45039663SJohn Forte (void) timeout(pppt_tgt_dereg_retry, tgt, 883*45039663SJohn Forte drv_usectohz(TGT_DEREG_RETRY_SECONDS * 1000000)); 884*45039663SJohn Forte break; 885*45039663SJohn Forte case TS_DELETING: 886*45039663SJohn Forte break; 887*45039663SJohn Forte default: 888*45039663SJohn Forte ASSERT(0); 889*45039663SJohn Forte } 890*45039663SJohn Forte } 891