/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <sys/sysmacros.h>
#include <sys/stmf_ioctl.h>
#define PPPT_TGT_SM_STRINGS
#include "pppt.h"
typedef struct {
static void
static void
static void
static void
static void
static void
static void
static void
static void
static void
static void
static void
static void
static void
static void
pppt_tgt_offline_task(void *arg);
static void
pppt_tgt_dereg_retry(void *arg);
static void
pppt_tgt_dereg_task(void *arg);
static void
/*ARGSUSED*/
void
{
switch (cmd) {
case STMF_CMD_LPORT_ONLINE:
break;
case STMF_CMD_LPORT_OFFLINE:
break;
break;
break;
default:
ASSERT(0);
break;
}
}
{
int total_devid_len;
total_devid_len = sizeof (scsi_devid_desc_t) +
/*
* Each target is an STMF local port. Allocate an STMF local port
* including enough space to store a scsi_devid_desc_t for this target.
*/
sizeof (pppt_tgt_t) + total_devid_len, 0);
return (NULL);
}
/* Use pointer arithmetic to find scsi_devid_desc_t */
/*
* Since this is a proxy port we need to do set the relative
* target port identifier before registering it with STMF.
*/
/*
* Register the target with STMF. STMF may immediately ask us to go
* online so insure any additional config setup is complete.
*/
return (NULL);
}
return (result);
}
void
{
/* Destroy target */
}
{
return (result);
}
{
return (result);
}
void
{
/* Generate TE_DELETE event to target state machine */
}
int
{
int result;
/* Sort by code set then ident */
return (-1);
return (1);
}
/* Next by ident length */
return (-1);
return (1);
}
/* Code set and ident length both match, now compare idents */
if (result < 0) {
return (-1);
} else if (result > 0) {
return (1);
}
return (0);
}
/*
* Target state machine
*/
static void
{
}
static void
{
tgt->target_refcount++;
/*
* Use the target_sm_busy flag to keep the state machine single
* threaded. This also serves as recursion avoidance since this
* flag will always be set if we call pppt_tgt_sm_event from
* within the state machine code.
*/
if (!tgt->target_sm_busy) {
}
}
tgt->target_refcount--;
}
static void
{
/* State independent actions */
switch (ctx->te_ctx_event) {
case TE_DELETE:
break;
}
/* State dependent actions */
switch (tgt->target_state) {
case TS_CREATED:
break;
case TS_ONLINING:
break;
case TS_ONLINE:
break;
case TS_STMF_ONLINE:
break;
case TS_DELETING_NEED_OFFLINE:
break;
case TS_OFFLINING:
break;
case TS_OFFLINE:
break;
case TS_STMF_OFFLINE:
break;
case TS_DELETING_STMF_DEREG:
break;
break;
case TS_DELETING:
break;
default:
ASSERT(0);
}
}
static void
{
switch (ctx->te_ctx_event) {
case TE_STMF_ONLINE_REQ:
break;
case TE_DELETE:
break;
case TE_STMF_OFFLINE_REQ:
/*
* We're already offline but update to an equivelant
* state just to note that STMF talked to us.
*/
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
switch (ctx->te_ctx_event) {
case TE_ONLINE_SUCCESS:
break;
case TE_ONLINE_FAIL:
break;
case TE_DELETE:
/* TE_DELETE is handled in tgt_sm_event_dispatch() */
break;
case TE_STMF_ONLINE_REQ:
case TE_STMF_OFFLINE_REQ:
/*
* We can't complete STMF's request since we are busy going
* online.
*/
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
switch (ctx->te_ctx_event) {
if (tgt->target_deleting) {
} else {
}
break;
case TE_DELETE:
/* TE_DELETE is handled in tgt_sm_event_dispatch() */
break;
case TE_STMF_ONLINE_REQ:
case TE_STMF_OFFLINE_REQ:
/*
* We can't complete STMF's request since we are busy going
* online (waiting for acknowlegement from STMF)
*/
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
switch (ctx->te_ctx_event) {
case TE_DELETE:
break;
case TE_STMF_OFFLINE_REQ:
break;
case TE_STMF_ONLINE_REQ:
/* Already online */
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
switch (ctx->te_ctx_event) {
case TE_STMF_OFFLINE_REQ:
break;
case TE_DELETE:
/* TE_DELETE is handled in tgt_sm_event_dispatch() */
break;
case TE_STMF_ONLINE_REQ:
/*
* We can't complete STMF's request since we need to be offlined
*/
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
switch (ctx->te_ctx_event) {
case TE_OFFLINE_COMPLETE:
break;
case TE_DELETE:
/* TE_DELETE is handled in tgt_sm_event_dispatch() */
break;
case TE_STMF_ONLINE_REQ:
case TE_STMF_OFFLINE_REQ:
/*
* We can't complete STMF's request since we are busy going
* offline.
*/
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
switch (ctx->te_ctx_event) {
if (tgt->target_deleting) {
} else {
}
break;
case TE_DELETE:
/* TE_DELETE is handled in tgt_sm_event_dispatch() */
break;
case TE_STMF_ONLINE_REQ:
case TE_STMF_OFFLINE_REQ:
/*
* We can't complete STMF's request since we are busy going
* offline.
*/
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
switch (ctx->te_ctx_event) {
case TE_STMF_ONLINE_REQ:
break;
case TE_DELETE:
break;
case TE_STMF_OFFLINE_REQ:
/* Already offline */
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
/* Terminal state, no events */
switch (ctx->te_ctx_event) {
case TE_STMF_ONLINE_REQ:
case TE_STMF_OFFLINE_REQ:
/*
* We can't complete STMF's request since we are being deleted
*/
break;
/* Ignore */
break;
case TE_STMF_DEREG_SUCCESS:
break;
case TE_STMF_DEREG_FAIL:
break;
default:
ASSERT(0);
}
}
static void
{
/* Terminal state, no events */
switch (ctx->te_ctx_event) {
case TE_STMF_ONLINE_REQ:
case TE_STMF_OFFLINE_REQ:
/*
* We can't complete STMF's request since we are being deleted
*/
break;
/* Ignore */
break;
case TE_STMF_DEREG_RETRY:
break;
default:
ASSERT(0);
}
}
static void
{
/* Terminal state, no events */
switch (ctx->te_ctx_event) {
case TE_STMF_ONLINE_REQ:
case TE_STMF_OFFLINE_REQ:
/*
* We can't complete STMF's request since we are being deleted
*/
break;
/* Ignore */
break;
default:
ASSERT(0);
}
}
static void
{
}
static void
{
}
}
}
static void
{
/*
* Rather than guaranteeing the target state machine code will not
* block for long periods of time (tying up this callout thread)
* we will queue a task on the taskq to send the retry event.
* If it fails we'll setup another timeout and try again later.
*/
/* Dispatch failed, try again later */
}
}
static void
{
}
/*ARGSUSED*/
static void
{
/*
* Validate new state
*/
"tgt %p, %s(%d) --> %s(%d)\n",
switch (tgt->target_state) {
case TS_ONLINING:
/*
* Let STMF know the how the online operation completed.
* STMF will respond with an acknowlege later
*/
break;
case TS_ONLINE:
break;
case TS_STMF_ONLINE:
break;
case TS_DELETING_NEED_OFFLINE:
break;
case TS_OFFLINING:
/* Async callback generates completion event */
break;
case TS_OFFLINE:
break;
case TS_STMF_OFFLINE:
break;
case TS_DELETING_STMF_DEREG:
if (stmfrc == STMF_SUCCESS) {
} else {
}
break;
/* Retry dereg in 1 second */
break;
case TS_DELETING:
break;
default:
ASSERT(0);
}
}