pppt_tgt.c revision e617f2142235c62bb299718a60e6d2f79b6f472f
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * CDDL HEADER START
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * The contents of this file are subject to the terms of the
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Common Development and Distribution License (the "License").
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * You may not use this file except in compliance with the License.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * See the License for the specific language governing permissions
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * and limitations under the License.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * If applicable, add the following below this CDDL HEADER, with the
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * CDDL HEADER END
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Use is subject to license terms.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetypedef struct {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_tgt_sm_event(pppt_tgt_t *tgt, pppt_tgt_event_t event);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_event_locked(pppt_tgt_t *tgt, pppt_tgt_event_t event);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_event_dispatch(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_created(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_onlining(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_online(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_stmf_online(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_deleting_need_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_offlining(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_stmf_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_deleting_stmf_dereg(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_deleting_stmf_dereg_fail(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_deleting(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_new_state(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_tgt_sm_ctl(stmf_local_port_t *lport, int cmd, void *arg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt = (pppt_tgt_t *)lport->lport_port_private;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt_sm_event(pppt_tgt, TE_STMF_OFFLINE_REQ);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt_sm_event(pppt_tgt, TE_STMF_ONLINE_COMPLETE_ACK);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte pppt_tgt_sm_event(pppt_tgt, TE_STMF_OFFLINE_COMPLETE_ACK);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_tgt_create(stmf_ic_reg_port_msg_t *reg_port, stmf_status_t *msg_errcode)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Each target is an STMF local port. Allocate an STMF local port
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * including enough space to store a scsi_devid_desc_t for this target.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Use pointer arithmetic to find scsi_devid_desc_t */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte result->target_devid = (scsi_devid_desc_t *)(result + 1);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte bcopy(reg_port->icrp_port_id, result->target_devid, total_devid_len);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte result->target_devid->association = ID_IS_TARGET_PORT;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte mutex_init(&result->target_mutex, NULL, MUTEX_DEFAULT, NULL);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte cv_init(&result->target_cv, NULL, CV_DEFAULT, NULL);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte list_create(&result->target_events, sizeof (tgt_event_ctx_t),
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte avl_create(&result->target_sess_list, pppt_sess_avl_compare_by_name,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte sizeof (pppt_sess_t), offsetof(pppt_sess_t, ps_target_ln));
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte lport->lport_send_status = &pppt_lport_send_status;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Since this is a proxy port we need to do set the relative
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * target port identifier before registering it with STMF.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_set_port_standby(lport, reg_port->icrp_relative_port_id);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Register the target with STMF. STMF may immediately ask us to go
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * online so insure any additional config setup is complete.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (stmf_register_local_port(lport) != STMF_SUCCESS) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Destroy target */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_free(tgt->target_stmf_lport); /* Also frees "tgt' */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_tgt_lookup_locked(scsi_devid_desc_t *tgt_devid)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte result = avl_find(&pppt_global.global_target_list, &tmptgt, NULL);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Generate TE_DELETE event to target state machine */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_tgt_avl_compare(const void *void_tgt1, const void *void_tgt2)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Sort by code set then ident */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte return (-1);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Next by ident length */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte return (-1);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Code set and ident length both match, now compare idents */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte result = memcmp(ptgt1->target_devid->ident, ptgt2->target_devid->ident,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte return (-1);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte } else if (result > 0) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Target state machine
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortepppt_tgt_sm_event(pppt_tgt_t *tgt, pppt_tgt_event_t event)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_event_locked(pppt_tgt_t *tgt, pppt_tgt_event_t event)
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap event = (event < TE_MAX_EVENT) ? event : TE_UNDEFINED;
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap DTRACE_PROBE2(pppt__tgt__event, pppt_tgt_t *, tgt,
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap stmf_trace("pppt", "pppt_tgt_event: tgt %p event %s(%d)",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Use the target_sm_busy flag to keep the state machine single
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * threaded. This also serves as recursion avoidance since this
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * flag will always be set if we call pppt_tgt_sm_event from
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * within the state machine code.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_event_dispatch(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap stmf_trace("pppt", "pppt_tgt_event_dispatch: tgt %p event %s(%d)",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void *)tgt, pppt_te_name[ctx->te_ctx_event], ctx->te_ctx_event);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* State independent actions */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* State dependent actions */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_created(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We're already offline but update to an equivelant
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * state just to note that STMF talked to us.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_onlining(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We can't complete STMF's request since we are busy going
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ?
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_online(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_NEED_OFFLINE);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We can't complete STMF's request since we are busy going
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * online (waiting for acknowlegement from STMF)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ?
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_stmf_online(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_NEED_OFFLINE);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Already online */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_deleting_need_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We can't complete STMF's request since we need to be offlined
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_offlining(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We can't complete STMF's request since we are busy going
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ?
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* TE_DELETE is handled in tgt_sm_event_dispatch() */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We can't complete STMF's request since we are busy going
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ?
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_stmf_offline(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Already offline */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_deleting_stmf_dereg(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Terminal state, no events */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We can't complete STMF's request since we are being deleted
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ?
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG_FAIL);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_deleting_stmf_dereg_fail(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Terminal state, no events */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We can't complete STMF's request since we are being deleted
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ?
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte tgt_sm_new_state(tgt, ctx, TS_DELETING_STMF_DEREG);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_deleting(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Terminal state, no events */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We can't complete STMF's request since we are being deleted
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl((ctx->te_ctx_event == TE_STMF_ONLINE_REQ) ?
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Ignore */
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap (void) taskq_dispatch(pppt_global.global_dispatch_taskq,
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap stmf_trace("pppt", "pppt_tgt_offline %p", (void *)tgt);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ps = avl_first(&tgt->target_sess_list); ps != NULL; ps = next_ps) {
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap stmf_trace("pppt", "pppt_tgt_offline complete %p", (void *)tgt);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Rather than guaranteeing the target state machine code will not
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * block for long periods of time (tying up this callout thread)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * we will queue a task on the taskq to send the retry event.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * If it fails we'll setup another timeout and try again later.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (taskq_dispatch(pppt_global.global_dispatch_taskq,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Dispatch failed, try again later */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte drv_usectohz(TGT_DEREG_RETRY_SECONDS * 1000000));
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortetgt_sm_new_state(pppt_tgt_t *tgt, tgt_event_ctx_t *ctx,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_local_port_t *lport = tgt->target_stmf_lport;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Validate new state
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap stmf_trace("pppt", "pppt_target_state_change: "
e617f2142235c62bb299718a60e6d2f79b6f472fpeter dunlap "tgt %p, %s(%d) --> %s(%d)\n",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void *) tgt, pppt_ts_name[tgt->target_state], tgt->target_state,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Let STMF know the how the online operation completed.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * STMF will respond with an acknowlege later
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_ONLINE_COMPLETE, lport, &scs);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_OFFLINE, lport, &sci);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Async callback generates completion event */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmfrc = stmf_deregister_local_port(tgt->target_stmf_lport);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* Retry dereg in 1 second */