1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte /* 22*30e7468fSPeter Dunlap * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23fcf3ce44SJohn Forte * Use is subject to license terms. 24fcf3ce44SJohn Forte * 25fcf3ce44SJohn Forte * iSCSI command interfaces 26fcf3ce44SJohn Forte */ 27fcf3ce44SJohn Forte 28fcf3ce44SJohn Forte #include "iscsi.h" 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte /* internal interfaces */ 31fcf3ce44SJohn Forte static void iscsi_cmd_state_free(iscsi_cmd_t *icmdp, 32fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg); 33fcf3ce44SJohn Forte static void iscsi_cmd_state_pending(iscsi_cmd_t *icmdp, 34fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg); 35fcf3ce44SJohn Forte static void iscsi_cmd_state_active(iscsi_cmd_t *icmdp, 36fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg); 37fcf3ce44SJohn Forte static void iscsi_cmd_state_aborting(iscsi_cmd_t *icmdp, 38fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg); 39*30e7468fSPeter Dunlap static void iscsi_cmd_state_idm_aborting(iscsi_cmd_t *icmdp, 40*30e7468fSPeter Dunlap iscsi_cmd_event_t event, void *arg); 41fcf3ce44SJohn Forte static void iscsi_cmd_state_completed(iscsi_cmd_t *icmdp, 42fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg); 43fcf3ce44SJohn Forte static char *iscsi_cmd_state_str(iscsi_cmd_state_t state); 44fcf3ce44SJohn Forte static char *iscsi_cmd_event_str(iscsi_cmd_event_t event); 45fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */ 46fcf3ce44SJohn Forte static char *iscsi_cmd_type_str(iscsi_cmd_type_t type); 47fcf3ce44SJohn Forte 48fcf3ce44SJohn Forte #define ISCSI_INTERNAL_CMD_TIMEOUT 60 49fcf3ce44SJohn Forte 50fcf3ce44SJohn Forte #define ISCSI_CMD_ISSUE_CALLBACK(icmdp, status) \ 51fcf3ce44SJohn Forte icmdp->cmd_completed = B_TRUE; \ 52fcf3ce44SJohn Forte icmdp->cmd_result = status; \ 53fcf3ce44SJohn Forte cv_broadcast(&icmdp->cmd_completion); 54fcf3ce44SJohn Forte 55fcf3ce44SJohn Forte #define ISCSI_CMD_SET_REASON_STAT(icmdp, reason, stat) \ 56fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_reason = reason; \ 57fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_statistics = stat; 58fcf3ce44SJohn Forte 59fcf3ce44SJohn Forte /* 60fcf3ce44SJohn Forte * The following private tunable, settable via 61fcf3ce44SJohn Forte * set iscsi:iscsi_cmd_timeout_factor = 2 62fcf3ce44SJohn Forte * in /etc/system, provides customer relief for configurations experiencing 63fcf3ce44SJohn Forte * SCSI command timeouts due to high-latency/high-loss network connections 64fcf3ce44SJohn Forte * or slow target response (possibly due to backing store issues). If frequent 65fcf3ce44SJohn Forte * use of this tunable is necessary, a beter mechanism must be provided. 66fcf3ce44SJohn Forte */ 67fcf3ce44SJohn Forte int iscsi_cmd_timeout_factor = 1; 68fcf3ce44SJohn Forte 69fcf3ce44SJohn Forte /* 70fcf3ce44SJohn Forte * +--------------------------------------------------------------------+ 71fcf3ce44SJohn Forte * | External Command Interfaces | 72fcf3ce44SJohn Forte * +--------------------------------------------------------------------+ 73fcf3ce44SJohn Forte */ 74fcf3ce44SJohn Forte 75fcf3ce44SJohn Forte /* 76fcf3ce44SJohn Forte * iscsi_cmd_state_machine - This function is used to drive the 77fcf3ce44SJohn Forte * state machine of the internal iscsi commands. It takes in a command 78fcf3ce44SJohn Forte * and the associated event affecting the command. 79fcf3ce44SJohn Forte * 80fcf3ce44SJohn Forte * 7.1.3 Command State Diagram for an Initiator 81fcf3ce44SJohn Forte * Symbolic Names for States: 82fcf3ce44SJohn Forte * C1: FREE - State on instantiation, or after successful 83fcf3ce44SJohn Forte * completion. 84fcf3ce44SJohn Forte * C2: PENDING - Command is in the session's pending queue awaiting 85fcf3ce44SJohn Forte * its turn to be sent on the wire. 86fcf3ce44SJohn Forte * C3: ACTIVE - Command has been sent on the wire and is 87fcf3ce44SJohn Forte * awaiting completion. 88fcf3ce44SJohn Forte * C4: ABORTING - Command which was sent on the wire has not timed 89fcf3ce44SJohn Forte * out or been requested to abort by an upper layer 90fcf3ce44SJohn Forte * driver. At this point there is a task management 91fcf3ce44SJohn Forte * command in the active queue trying to abort the task. 92*30e7468fSPeter Dunlap * C4': IDM ABORTING - SCSI command is owned by IDM and idm_task_abort 93*30e7468fSPeter Dunlap * has been called for this command. 94fcf3ce44SJohn Forte * C5: COMPLETED - Command which is ready to complete via pkt callback. 95fcf3ce44SJohn Forte * 96fcf3ce44SJohn Forte * The state diagram is as follows: 97fcf3ce44SJohn Forte * ------- 98fcf3ce44SJohn Forte * / C1 \ 99fcf3ce44SJohn Forte * I-------->\ /<------------ 100fcf3ce44SJohn Forte * N| ---+--- | 101fcf3ce44SJohn Forte * T| |E1 | 102fcf3ce44SJohn Forte * E| V | 103fcf3ce44SJohn Forte * R| ------- | 104fcf3ce44SJohn Forte * N+--------/ C2 \ | 105fcf3ce44SJohn Forte * A| E4/6/7\ /-------- | 106fcf3ce44SJohn Forte * L| ---+--- E4/6/7| | 107*30e7468fSPeter Dunlap * | |E2 E10 | | 108fcf3ce44SJohn Forte * C| V | S | 109fcf3ce44SJohn Forte * M| _______ | C | 110fcf3ce44SJohn Forte * D+--------/ C3 \ | S | 111fcf3ce44SJohn Forte * S E3/4/6/7\ /-------+ I | 112*30e7468fSPeter Dunlap * /---+---E3/4/6/7| | 113*30e7468fSPeter Dunlap * / | E9/10| | 114*30e7468fSPeter Dunlap * ------/ E4/6| | C | 115*30e7468fSPeter Dunlap * | V | M | 116*30e7468fSPeter Dunlap * E7| ------- | D | 117*30e7468fSPeter Dunlap * SCSI| - >/ C4 \ | S | 118*30e7468fSPeter Dunlap * | / \ /-------+ | 119*30e7468fSPeter Dunlap * | | ---+---E3/6/7/9| | 120*30e7468fSPeter Dunlap * | | E4| | V /E8 121*30e7468fSPeter Dunlap * | ------ | ------- 122*30e7468fSPeter Dunlap * +-\ / / C5 \ 123*30e7468fSPeter Dunlap * V \-------/ /---->\ / 124*30e7468fSPeter Dunlap * ------- E7 / ---+--- 125*30e7468fSPeter Dunlap * / C4' \ / 126*30e7468fSPeter Dunlap * \ /------/ E9 127*30e7468fSPeter Dunlap * ------- 128fcf3ce44SJohn Forte * 129fcf3ce44SJohn Forte * The state transition table is as follows: 130fcf3ce44SJohn Forte * 131*30e7468fSPeter Dunlap * +---------+---+---+-----+----+--------------+ 132*30e7468fSPeter Dunlap * |C1 |C2 |C3 |C4 |C4' |C5 | 133*30e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+ 134*30e7468fSPeter Dunlap * C1| - |E1 | - | - | - | | 135*30e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+ 136*30e7468fSPeter Dunlap * C2|E4/6/7 |- |E2 | - | - |E4/6/7/10 | 137*30e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+ 138*30e7468fSPeter Dunlap * C3|E3/4/6/7 |- |- |E4/6 |E7 |E3/4/6/7/9/10 | 139*30e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+ 140*30e7468fSPeter Dunlap * C4| |- |- |E4 |E7 |E3/6/7/9 | 141*30e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+ 142*30e7468fSPeter Dunlap * C4'| |- |- |- |- |E9 | 143*30e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+ 144*30e7468fSPeter Dunlap * C5|E8 | | | | | | 145*30e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+ 146fcf3ce44SJohn Forte * 147fcf3ce44SJohn Forte * Event definitions: 148fcf3ce44SJohn Forte * 149fcf3ce44SJohn Forte * -E1: Command was requested to be sent on wire 150fcf3ce44SJohn Forte * -E2: Command was submitted and now active on wire 151fcf3ce44SJohn Forte * -E3: Command was successfully completed 152fcf3ce44SJohn Forte * - SCSI command is move to completion queue 153fcf3ce44SJohn Forte * - ABORT/RESET/etc are completed. 154fcf3ce44SJohn Forte * -E4: Command has been requested to abort 155fcf3ce44SJohn Forte * - SCSI command in pending queue will be returned 156fcf3ce44SJohn Forte * to caller with aborted status. 157fcf3ce44SJohn Forte * - SCSI command state updated and iscsi_handle_abort() 158fcf3ce44SJohn Forte * will be called. 159fcf3ce44SJohn Forte * - SCSI command with ABORTING state has already 160fcf3ce44SJohn Forte * been requested to abort ignore request. 161fcf3ce44SJohn Forte * - ABORT/RESET commands will be destroyed and the 162fcf3ce44SJohn Forte * caller will be notify of the failure. 163fcf3ce44SJohn Forte * - All other commands will just be destroyed. 164fcf3ce44SJohn Forte * -E6: Command has timed out 165fcf3ce44SJohn Forte * - SCSI commands in pending queue will be returned up the 166fcf3ce44SJohn Forte * stack with TIMEOUT errors. 167fcf3ce44SJohn Forte * - SCSI commands in the active queue and timed out 168fcf3ce44SJohn Forte * will be moved to the aborting queue. 169fcf3ce44SJohn Forte * - SCSI commands in ABORTING state will be returned up 170fcf3ce44SJohn Forte * up the stack with TIMEOUT errors. 171fcf3ce44SJohn Forte * - ABORT/RESET commands will be destroyed and the caller 172fcf3ce44SJohn Forte * notified of the failure. 173fcf3ce44SJohn Forte * - All other commands will just be detroyed. 174fcf3ce44SJohn Forte * -E7: Connection has encountered a problem 175fcf3ce44SJohn Forte * -E8: Command has completed 176fcf3ce44SJohn Forte * - Only SCSI cmds should receive these events 177fcf3ce44SJohn Forte * and reach the command state. 178*30e7468fSPeter Dunlap * -E9: Callback received for previous idm_task_abort request 179*30e7468fSPeter Dunlap * -E10: The command this abort was associated with has terminated on its own 180fcf3ce44SJohn Forte */ 181fcf3ce44SJohn Forte void 182fcf3ce44SJohn Forte iscsi_cmd_state_machine(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg) 183fcf3ce44SJohn Forte { 184fcf3ce44SJohn Forte boolean_t release_lock = B_TRUE; 185fcf3ce44SJohn Forte 186fcf3ce44SJohn Forte ASSERT(icmdp != NULL); 187fcf3ce44SJohn Forte ASSERT(arg != NULL); 188fcf3ce44SJohn Forte 189fcf3ce44SJohn Forte DTRACE_PROBE3(event, iscsi_cmd_t *, icmdp, char *, 190fcf3ce44SJohn Forte iscsi_cmd_state_str(icmdp->cmd_state), 191fcf3ce44SJohn Forte char *, iscsi_cmd_event_str(event)); 192fcf3ce44SJohn Forte 193fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_mutex); 194*30e7468fSPeter Dunlap 195*30e7468fSPeter Dunlap /* Audit event */ 196*30e7468fSPeter Dunlap idm_sm_audit_event(&icmdp->cmd_state_audit, 197*30e7468fSPeter Dunlap SAS_ISCSI_CMD, icmdp->cmd_state, event, (uintptr_t)arg); 198*30e7468fSPeter Dunlap 199fcf3ce44SJohn Forte icmdp->cmd_prev_state = icmdp->cmd_state; 200fcf3ce44SJohn Forte switch (icmdp->cmd_state) { 201fcf3ce44SJohn Forte case ISCSI_CMD_STATE_FREE: 202fcf3ce44SJohn Forte iscsi_cmd_state_free(icmdp, event, arg); 203fcf3ce44SJohn Forte break; 204fcf3ce44SJohn Forte 205fcf3ce44SJohn Forte case ISCSI_CMD_STATE_PENDING: 206fcf3ce44SJohn Forte iscsi_cmd_state_pending(icmdp, event, arg); 207fcf3ce44SJohn Forte break; 208fcf3ce44SJohn Forte 209fcf3ce44SJohn Forte case ISCSI_CMD_STATE_ACTIVE: 210fcf3ce44SJohn Forte iscsi_cmd_state_active(icmdp, event, arg); 211fcf3ce44SJohn Forte break; 212fcf3ce44SJohn Forte 213fcf3ce44SJohn Forte case ISCSI_CMD_STATE_ABORTING: 214fcf3ce44SJohn Forte iscsi_cmd_state_aborting(icmdp, event, arg); 215fcf3ce44SJohn Forte break; 216fcf3ce44SJohn Forte 217*30e7468fSPeter Dunlap case ISCSI_CMD_STATE_IDM_ABORTING: 218*30e7468fSPeter Dunlap iscsi_cmd_state_idm_aborting(icmdp, event, arg); 219*30e7468fSPeter Dunlap break; 220*30e7468fSPeter Dunlap 221fcf3ce44SJohn Forte case ISCSI_CMD_STATE_COMPLETED: 222fcf3ce44SJohn Forte iscsi_cmd_state_completed(icmdp, event, arg); 223fcf3ce44SJohn Forte 224fcf3ce44SJohn Forte /* 225fcf3ce44SJohn Forte * Once completed event is processed we DO NOT 226fcf3ce44SJohn Forte * want to touch it again because the caller 227fcf3ce44SJohn Forte * (sd, st, etc) may have freed the command. 228fcf3ce44SJohn Forte */ 229fcf3ce44SJohn Forte release_lock = B_FALSE; 230fcf3ce44SJohn Forte break; 231fcf3ce44SJohn Forte 232fcf3ce44SJohn Forte default: 233fcf3ce44SJohn Forte ASSERT(FALSE); 234fcf3ce44SJohn Forte } 235fcf3ce44SJohn Forte 236fcf3ce44SJohn Forte if (release_lock == B_TRUE) { 237*30e7468fSPeter Dunlap /* Audit state if not completed */ 238*30e7468fSPeter Dunlap idm_sm_audit_state_change(&icmdp->cmd_state_audit, 239*30e7468fSPeter Dunlap SAS_ISCSI_CMD, icmdp->cmd_prev_state, icmdp->cmd_state); 240*30e7468fSPeter Dunlap 241d233de7eSJack Meng if (!(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_FREE) || 242d233de7eSJack Meng !(icmdp->cmd_misc_flags & 243d233de7eSJack Meng ISCSI_CMD_MISCFLAG_INTERNAL)) { 244fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_mutex); 245fcf3ce44SJohn Forte return; 246fcf3ce44SJohn Forte } 247fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_mutex); 248fcf3ce44SJohn Forte iscsi_cmd_free(icmdp); 249fcf3ce44SJohn Forte } 250fcf3ce44SJohn Forte } 251fcf3ce44SJohn Forte 252fcf3ce44SJohn Forte /* 253fcf3ce44SJohn Forte * iscsi_cmd_alloc - 254fcf3ce44SJohn Forte * 255fcf3ce44SJohn Forte */ 256fcf3ce44SJohn Forte iscsi_cmd_t * 257fcf3ce44SJohn Forte iscsi_cmd_alloc(iscsi_conn_t *icp, int km_flags) 258fcf3ce44SJohn Forte { 259fcf3ce44SJohn Forte iscsi_cmd_t *icmdp; 260fcf3ce44SJohn Forte 261fcf3ce44SJohn Forte icmdp = kmem_zalloc(sizeof (iscsi_cmd_t), km_flags); 262fcf3ce44SJohn Forte if (icmdp) { 263fcf3ce44SJohn Forte icmdp->cmd_sig = ISCSI_SIG_CMD; 264fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 265fcf3ce44SJohn Forte icmdp->cmd_conn = icp; 266d233de7eSJack Meng icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_INTERNAL; 267*30e7468fSPeter Dunlap idm_sm_audit_init(&icmdp->cmd_state_audit); 268fcf3ce44SJohn Forte mutex_init(&icmdp->cmd_mutex, NULL, MUTEX_DRIVER, NULL); 269fcf3ce44SJohn Forte cv_init(&icmdp->cmd_completion, NULL, CV_DRIVER, NULL); 270fcf3ce44SJohn Forte } 271fcf3ce44SJohn Forte return (icmdp); 272fcf3ce44SJohn Forte } 273fcf3ce44SJohn Forte 274fcf3ce44SJohn Forte /* 275fcf3ce44SJohn Forte * iscsi_cmd_free - 276fcf3ce44SJohn Forte * 277fcf3ce44SJohn Forte */ 278fcf3ce44SJohn Forte void 279fcf3ce44SJohn Forte iscsi_cmd_free(iscsi_cmd_t *icmdp) 280fcf3ce44SJohn Forte { 281fcf3ce44SJohn Forte ASSERT(icmdp != NULL); 282fcf3ce44SJohn Forte ASSERT(icmdp->cmd_sig == ISCSI_SIG_CMD); 283fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_FREE); 284fcf3ce44SJohn Forte ASSERT(icmdp->cmd_next == NULL); 285fcf3ce44SJohn Forte ASSERT(icmdp->cmd_prev == NULL); 286d233de7eSJack Meng ASSERT(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_INTERNAL); 287*30e7468fSPeter Dunlap if (icmdp->cmd_type == ISCSI_CMD_TYPE_ABORT) 288fcf3ce44SJohn Forte ASSERT(icmdp->cmd_un.abort.icmdp == NULL); 289fcf3ce44SJohn Forte else if (icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) { 290fcf3ce44SJohn Forte ASSERT(icmdp->cmd_un.scsi.r2t_icmdp == NULL); 291fcf3ce44SJohn Forte ASSERT(icmdp->cmd_un.scsi.abort_icmdp == NULL); 292fcf3ce44SJohn Forte } 293fcf3ce44SJohn Forte mutex_destroy(&icmdp->cmd_mutex); 294fcf3ce44SJohn Forte cv_destroy(&icmdp->cmd_completion); 295fcf3ce44SJohn Forte kmem_free(icmdp, sizeof (iscsi_cmd_t)); 296fcf3ce44SJohn Forte } 297fcf3ce44SJohn Forte 298fcf3ce44SJohn Forte /* 299fcf3ce44SJohn Forte * +--------------------------------------------------------------------+ 300fcf3ce44SJohn Forte * | Internal Command Interfaces | 301fcf3ce44SJohn Forte * +--------------------------------------------------------------------+ 302fcf3ce44SJohn Forte */ 303fcf3ce44SJohn Forte /* 304fcf3ce44SJohn Forte * iscsi_cmd_state_free - 305fcf3ce44SJohn Forte * 306fcf3ce44SJohn Forte */ 307fcf3ce44SJohn Forte static void 308fcf3ce44SJohn Forte iscsi_cmd_state_free(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg) 309fcf3ce44SJohn Forte { 310fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg; 311fcf3ce44SJohn Forte 312fcf3ce44SJohn Forte ASSERT(icmdp != NULL); 313fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_FREE); 314fcf3ce44SJohn Forte ASSERT(isp != NULL); 315fcf3ce44SJohn Forte 316fcf3ce44SJohn Forte /* switch on event change */ 317fcf3ce44SJohn Forte switch (event) { 318fcf3ce44SJohn Forte /* -E1: Command was requested to be sent on wire */ 319fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E1: 320fcf3ce44SJohn Forte 321fcf3ce44SJohn Forte /* setup timestamps and timeouts for this command */ 322fcf3ce44SJohn Forte icmdp->cmd_lbolt_pending = ddi_get_lbolt(); 323fcf3ce44SJohn Forte if (icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) { 324fcf3ce44SJohn Forte /* 325fcf3ce44SJohn Forte * Establish absolute time when command should timeout. 326*30e7468fSPeter Dunlap * For commands that depend on cmdsn window to go 327fcf3ce44SJohn Forte * active, the timeout will be ignored while on 328fcf3ce44SJohn Forte * the pending queue and a new timeout will be 329fcf3ce44SJohn Forte * established when the command goes active. 330fcf3ce44SJohn Forte */ 331fcf3ce44SJohn Forte if (icmdp->cmd_un.scsi.pkt && 332fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_time) 333fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = 334fcf3ce44SJohn Forte icmdp->cmd_lbolt_pending + SEC_TO_TICK( 335fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_time * 336fcf3ce44SJohn Forte iscsi_cmd_timeout_factor); 337fcf3ce44SJohn Forte else 338fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = 0; 339fcf3ce44SJohn Forte } else { 340fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = icmdp->cmd_lbolt_pending + 341fcf3ce44SJohn Forte SEC_TO_TICK(ISCSI_INTERNAL_CMD_TIMEOUT * 342fcf3ce44SJohn Forte iscsi_cmd_timeout_factor); 343fcf3ce44SJohn Forte } 344fcf3ce44SJohn Forte 345fcf3ce44SJohn Forte /* place into pending queue */ 346fcf3ce44SJohn Forte iscsi_enqueue_pending_cmd(isp, icmdp); 347fcf3ce44SJohn Forte 348fcf3ce44SJohn Forte break; 349fcf3ce44SJohn Forte 350fcf3ce44SJohn Forte /* All other events are invalid for this state */ 351fcf3ce44SJohn Forte default: 352fcf3ce44SJohn Forte ASSERT(FALSE); 353fcf3ce44SJohn Forte } 354fcf3ce44SJohn Forte } 355fcf3ce44SJohn Forte 356fcf3ce44SJohn Forte /* 357fcf3ce44SJohn Forte * iscsi_cmd_state_pending - 358fcf3ce44SJohn Forte * 359fcf3ce44SJohn Forte */ 360fcf3ce44SJohn Forte static void 361fcf3ce44SJohn Forte iscsi_cmd_state_pending(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg) 362fcf3ce44SJohn Forte { 363fcf3ce44SJohn Forte iscsi_status_t status; 364fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg; 365fcf3ce44SJohn Forte boolean_t free_icmdp = B_FALSE; 366fcf3ce44SJohn Forte int rval; 367fcf3ce44SJohn Forte 368fcf3ce44SJohn Forte ASSERT(icmdp != NULL); 369fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_PENDING); 370fcf3ce44SJohn Forte ASSERT(isp != NULL); 371fcf3ce44SJohn Forte 372fcf3ce44SJohn Forte /* switch on event change */ 373fcf3ce44SJohn Forte switch (event) { 374fcf3ce44SJohn Forte /* -E2: Command was submitted and now active on wire */ 375fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E2: 376fcf3ce44SJohn Forte 377fcf3ce44SJohn Forte /* A connection should have already been assigned */ 378*30e7468fSPeter Dunlap ASSERT(mutex_owned(&isp->sess_queue_pending.mutex)); 379fcf3ce44SJohn Forte ASSERT(icmdp->cmd_conn != NULL); 380fcf3ce44SJohn Forte 381fcf3ce44SJohn Forte /* 382fcf3ce44SJohn Forte * RESERVE RESOURSES 383fcf3ce44SJohn Forte */ 384fcf3ce44SJohn Forte switch (icmdp->cmd_type) { 385fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI: 386fcf3ce44SJohn Forte /* check cmdsn window */ 387fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 388fcf3ce44SJohn Forte if (!iscsi_sna_lte(isp->sess_cmdsn, 389fcf3ce44SJohn Forte isp->sess_maxcmdsn)) { 390fcf3ce44SJohn Forte /* cmdsn window closed */ 391fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 392fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex); 393fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE; 394d233de7eSJack Meng icmdp->cmd_misc_flags |= 395d233de7eSJack Meng ISCSI_CMD_MISCFLAG_STUCK; 396fcf3ce44SJohn Forte return; 397fcf3ce44SJohn Forte } 398fcf3ce44SJohn Forte 399fcf3ce44SJohn Forte /* assign itt */ 400*30e7468fSPeter Dunlap status = iscsi_sess_reserve_scsi_itt(icmdp); 401fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) { 402fcf3ce44SJohn Forte /* no available itt slots */ 403fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 404fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex); 405fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE; 406d233de7eSJack Meng icmdp->cmd_misc_flags |= 407d233de7eSJack Meng ISCSI_CMD_MISCFLAG_STUCK; 408fcf3ce44SJohn Forte return; 409fcf3ce44SJohn Forte } 410fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 411fcf3ce44SJohn Forte break; 412fcf3ce44SJohn Forte 413fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT: 414fcf3ce44SJohn Forte /* 415fcf3ce44SJohn Forte * Verify ABORT's parent SCSI command is still 416fcf3ce44SJohn Forte * there. If parent SCSI command is completed 417fcf3ce44SJohn Forte * then there is no longer any reason to abort 418fcf3ce44SJohn Forte * the parent command. This could occur due 419fcf3ce44SJohn Forte * to a connection or target reset. 420fcf3ce44SJohn Forte */ 421fcf3ce44SJohn Forte ASSERT(icmdp->cmd_un.abort.icmdp != NULL); 422fcf3ce44SJohn Forte if (icmdp->cmd_un.abort.icmdp->cmd_state == 423fcf3ce44SJohn Forte ISCSI_CMD_STATE_COMPLETED) { 424fcf3ce44SJohn Forte iscsi_dequeue_pending_cmd(isp, icmdp); 425fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex); 426fcf3ce44SJohn Forte 427fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_un.abort.icmdp-> 428fcf3ce44SJohn Forte cmd_mutex); 429fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp-> 430fcf3ce44SJohn Forte cmd_un.scsi.abort_icmdp = NULL; 431fcf3ce44SJohn Forte cv_broadcast(&icmdp->cmd_un.abort.icmdp-> 432fcf3ce44SJohn Forte cmd_completion); 433fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_un.abort.icmdp-> 434fcf3ce44SJohn Forte cmd_mutex); 435fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL; 436fcf3ce44SJohn Forte 437fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 438d233de7eSJack Meng icmdp->cmd_misc_flags |= 439d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 440fcf3ce44SJohn Forte return; 441fcf3ce44SJohn Forte } 442fcf3ce44SJohn Forte /* FALLTHRU */ 443fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET: 444fcf3ce44SJohn Forte /* FALLTHRU */ 445fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT: 446fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 447fcf3ce44SJohn Forte /* assign itt */ 448fcf3ce44SJohn Forte status = iscsi_sess_reserve_itt(isp, icmdp); 449fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) { 450fcf3ce44SJohn Forte /* no available itt slots */ 451fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 452fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex); 453fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE; 454fcf3ce44SJohn Forte return; 455fcf3ce44SJohn Forte } 456fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 457fcf3ce44SJohn Forte break; 458fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP: 459fcf3ce44SJohn Forte /* assign itt, if needed */ 460fcf3ce44SJohn Forte if (icmdp->cmd_itt == ISCSI_RSVD_TASK_TAG) { 461fcf3ce44SJohn Forte /* not expecting a response */ 462fcf3ce44SJohn Forte free_icmdp = B_TRUE; 463fcf3ce44SJohn Forte } else { 464fcf3ce44SJohn Forte /* expecting response, assign an itt */ 465fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 466fcf3ce44SJohn Forte /* assign itt */ 467fcf3ce44SJohn Forte status = iscsi_sess_reserve_itt(isp, icmdp); 468fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) { 469fcf3ce44SJohn Forte /* no available itt slots */ 470fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 471fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending. 472fcf3ce44SJohn Forte mutex); 473fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE; 474fcf3ce44SJohn Forte return; 475fcf3ce44SJohn Forte } 476fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 477fcf3ce44SJohn Forte } 478fcf3ce44SJohn Forte break; 479fcf3ce44SJohn Forte 480fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT: 481fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 482fcf3ce44SJohn Forte /* check cmdsn window */ 483fcf3ce44SJohn Forte if (!iscsi_sna_lte(isp->sess_cmdsn, 484fcf3ce44SJohn Forte isp->sess_maxcmdsn)) { 485fcf3ce44SJohn Forte /* cmdsn window closed */ 486fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE; 487fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 488fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex); 489d233de7eSJack Meng icmdp->cmd_misc_flags |= 490d233de7eSJack Meng ISCSI_CMD_MISCFLAG_STUCK; 491fcf3ce44SJohn Forte return; 492fcf3ce44SJohn Forte } 493fcf3ce44SJohn Forte if (icmdp->cmd_un.text.stage == 494fcf3ce44SJohn Forte ISCSI_CMD_TEXT_INITIAL_REQ) { 495fcf3ce44SJohn Forte /* assign itt */ 496fcf3ce44SJohn Forte status = iscsi_sess_reserve_itt(isp, icmdp); 497fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) { 498fcf3ce44SJohn Forte /* no available itt slots */ 499fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 500fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending. 501fcf3ce44SJohn Forte mutex); 502fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE; 503d233de7eSJack Meng icmdp->cmd_misc_flags |= 504d233de7eSJack Meng ISCSI_CMD_MISCFLAG_STUCK; 505fcf3ce44SJohn Forte return; 506fcf3ce44SJohn Forte } 507fcf3ce44SJohn Forte } 508fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 509fcf3ce44SJohn Forte break; 510fcf3ce44SJohn Forte 511fcf3ce44SJohn Forte default: 512fcf3ce44SJohn Forte ASSERT(FALSE); 513fcf3ce44SJohn Forte } 514fcf3ce44SJohn Forte 515fcf3ce44SJohn Forte /* 516fcf3ce44SJohn Forte * RESOURCES RESERVED 517fcf3ce44SJohn Forte * 518fcf3ce44SJohn Forte * Now that we have the resources reserved, establish timeout 519fcf3ce44SJohn Forte * for cmd_type values that depend on having an open cmdsn 520fcf3ce44SJohn Forte * window (i.e. cmd_type that called iscsi_sna_lte() above). 521fcf3ce44SJohn Forte */ 522fcf3ce44SJohn Forte if (icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) { 523fcf3ce44SJohn Forte if (icmdp->cmd_un.scsi.pkt && 524fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_time) 525fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = 526fcf3ce44SJohn Forte ddi_get_lbolt() + SEC_TO_TICK( 527fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_time * 528fcf3ce44SJohn Forte iscsi_cmd_timeout_factor); 529fcf3ce44SJohn Forte else 530fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = 0; 531fcf3ce44SJohn Forte } else if (icmdp->cmd_type == ISCSI_CMD_TYPE_TEXT) { 532fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = ddi_get_lbolt() + 533fcf3ce44SJohn Forte SEC_TO_TICK(ISCSI_INTERNAL_CMD_TIMEOUT * 534fcf3ce44SJohn Forte iscsi_cmd_timeout_factor); 535fcf3ce44SJohn Forte } 536fcf3ce44SJohn Forte 537fcf3ce44SJohn Forte /* remove command from pending queue */ 538fcf3ce44SJohn Forte iscsi_dequeue_pending_cmd(isp, icmdp); 539fcf3ce44SJohn Forte /* check if expecting a response */ 540fcf3ce44SJohn Forte if (free_icmdp == B_FALSE) { 541fcf3ce44SJohn Forte /* response expected, move to active queue */ 542fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_conn->conn_queue_active.mutex); 543fcf3ce44SJohn Forte iscsi_enqueue_active_cmd(icmdp->cmd_conn, icmdp); 544fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_conn->conn_queue_active.mutex); 545fcf3ce44SJohn Forte } 546fcf3ce44SJohn Forte 547fcf3ce44SJohn Forte /* 548fcf3ce44SJohn Forte * TRANSFER COMMAND 549fcf3ce44SJohn Forte */ 550fcf3ce44SJohn Forte rval = iscsi_tx_cmd(isp, icmdp); 551fcf3ce44SJohn Forte 552fcf3ce44SJohn Forte ASSERT(!mutex_owned(&isp->sess_queue_pending.mutex)); 553fcf3ce44SJohn Forte 554fcf3ce44SJohn Forte /* 555fcf3ce44SJohn Forte * CHECK SUCCESS/FAILURE 556fcf3ce44SJohn Forte */ 557fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(rval)) { 558fcf3ce44SJohn Forte /* 559fcf3ce44SJohn Forte * iscsi_tx_cmd failed. No cleanup is required 560fcf3ce44SJohn Forte * of commands that were put in the active queue. 561fcf3ce44SJohn Forte * If the tx failed then rx will also fail and cleanup 562fcf3ce44SJohn Forte * all items in the active/aborted queue in a common. 563fcf3ce44SJohn Forte */ 564fcf3ce44SJohn Forte 565fcf3ce44SJohn Forte /* EMPTY */ 566fcf3ce44SJohn Forte } 567fcf3ce44SJohn Forte 568fcf3ce44SJohn Forte /* free temporary commands */ 569fcf3ce44SJohn Forte if (free_icmdp == B_TRUE) { 570fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 571d233de7eSJack Meng icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_FREE; 572fcf3ce44SJohn Forte } 573fcf3ce44SJohn Forte break; 574fcf3ce44SJohn Forte 575*30e7468fSPeter Dunlap /* -E10: Abort is no longer required for this command */ 576*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E10: 577*30e7468fSPeter Dunlap /* 578*30e7468fSPeter Dunlap * Acquiring the sess_queue_pending lock while the 579*30e7468fSPeter Dunlap * conn_queue_active lock is held conflicts with the 580*30e7468fSPeter Dunlap * locking order in iscsi_cmd_state_pending where 581*30e7468fSPeter Dunlap * conn_queue_active is acquired while sess_queue_pending 582*30e7468fSPeter Dunlap * is held. Normally this would be a dangerous lock 583*30e7468fSPeter Dunlap * order conflict, except that we know that if we are 584*30e7468fSPeter Dunlap * seeing ISCSI_CMD_EVENT_E10 then the command being 585*30e7468fSPeter Dunlap * aborted is in "aborting" state and by extension 586*30e7468fSPeter Dunlap * is not in "pending" state. Therefore the code 587*30e7468fSPeter Dunlap * path with that alternate lock order will not execute. 588*30e7468fSPeter Dunlap * That's good because we can't drop the lock here without 589*30e7468fSPeter Dunlap * risking a deadlock. 590*30e7468fSPeter Dunlap */ 591*30e7468fSPeter Dunlap ASSERT(mutex_owned(&icmdp->cmd_conn->conn_queue_active.mutex)); 592*30e7468fSPeter Dunlap mutex_enter(&isp->sess_queue_pending.mutex); 593*30e7468fSPeter Dunlap 594*30e7468fSPeter Dunlap icmdp->cmd_lbolt_aborting = ddi_get_lbolt(); 595*30e7468fSPeter Dunlap 596*30e7468fSPeter Dunlap iscsi_dequeue_pending_cmd(isp, icmdp); 597*30e7468fSPeter Dunlap 598*30e7468fSPeter Dunlap icmdp->cmd_un.abort.icmdp->cmd_un.scsi.abort_icmdp = NULL; 599*30e7468fSPeter Dunlap icmdp->cmd_un.abort.icmdp = NULL; 600*30e7468fSPeter Dunlap icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_FREE; 601*30e7468fSPeter Dunlap icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 602*30e7468fSPeter Dunlap 603*30e7468fSPeter Dunlap mutex_exit(&isp->sess_queue_pending.mutex); 604*30e7468fSPeter Dunlap break; 605*30e7468fSPeter Dunlap 606fcf3ce44SJohn Forte /* -E4: Command has been requested to abort */ 607fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E4: 608*30e7468fSPeter Dunlap ASSERT(mutex_owned(&isp->sess_queue_pending.mutex)); 609fcf3ce44SJohn Forte 610fcf3ce44SJohn Forte icmdp->cmd_lbolt_aborting = ddi_get_lbolt(); 611fcf3ce44SJohn Forte ISCSI_CMD_SET_REASON_STAT(icmdp, 612fcf3ce44SJohn Forte CMD_ABORTED, STAT_ABORTED); 613fcf3ce44SJohn Forte 614fcf3ce44SJohn Forte iscsi_dequeue_pending_cmd(isp, icmdp); 615fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp); 616fcf3ce44SJohn Forte 617fcf3ce44SJohn Forte icmdp->cmd_lbolt_aborting = ddi_get_lbolt(); 618fcf3ce44SJohn Forte 619fcf3ce44SJohn Forte break; 620fcf3ce44SJohn Forte 621fcf3ce44SJohn Forte /* -E7: Command has been reset */ 622fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E7: 623fcf3ce44SJohn Forte 624fcf3ce44SJohn Forte /* FALLTHRU */ 625fcf3ce44SJohn Forte 626fcf3ce44SJohn Forte /* -E6: Command has timed out */ 627fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E6: 628*30e7468fSPeter Dunlap ASSERT(mutex_owned(&isp->sess_queue_pending.mutex)); 629fcf3ce44SJohn Forte iscsi_dequeue_pending_cmd(isp, icmdp); 630fcf3ce44SJohn Forte 631fcf3ce44SJohn Forte switch (icmdp->cmd_type) { 632fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI: 633fcf3ce44SJohn Forte /* Complete to caller as TIMEOUT */ 634fcf3ce44SJohn Forte if (event == ISCSI_CMD_EVENT_E6) { 635fcf3ce44SJohn Forte ISCSI_CMD_SET_REASON_STAT(icmdp, 636fcf3ce44SJohn Forte CMD_TIMEOUT, STAT_TIMEOUT); 637fcf3ce44SJohn Forte } else { 638fcf3ce44SJohn Forte ISCSI_CMD_SET_REASON_STAT(icmdp, 639fcf3ce44SJohn Forte CMD_TRAN_ERR, 0); 640fcf3ce44SJohn Forte } 641fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp); 642fcf3ce44SJohn Forte break; 643fcf3ce44SJohn Forte 644fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP: 645fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 646fcf3ce44SJohn Forte /* 647fcf3ce44SJohn Forte * Timeout occured. Just free NOP. Another 648fcf3ce44SJohn Forte * NOP request will be spawned to replace 649fcf3ce44SJohn Forte * this one. 650fcf3ce44SJohn Forte */ 651d233de7eSJack Meng icmdp->cmd_misc_flags |= 652d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 653d233de7eSJack Meng 654fcf3ce44SJohn Forte break; 655fcf3ce44SJohn Forte 656fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT: 657fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_un.abort.icmdp->cmd_mutex); 658fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp-> 659fcf3ce44SJohn Forte cmd_un.scsi.abort_icmdp = NULL; 660fcf3ce44SJohn Forte cv_broadcast(&icmdp->cmd_un.abort.icmdp-> 661fcf3ce44SJohn Forte cmd_completion); 662fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_un.abort.icmdp->cmd_mutex); 663fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL; 664fcf3ce44SJohn Forte 665fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 666d233de7eSJack Meng icmdp->cmd_misc_flags |= 667d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 668fcf3ce44SJohn Forte break; 669fcf3ce44SJohn Forte 670fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET: 671fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 672fcf3ce44SJohn Forte /* 673fcf3ce44SJohn Forte * If we are failing a RESET we need 674fcf3ce44SJohn Forte * to notify the tran_reset caller. 675fcf3ce44SJohn Forte * with the cmd and notify caller. 676fcf3ce44SJohn Forte */ 677fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, 678fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED); 679fcf3ce44SJohn Forte break; 680fcf3ce44SJohn Forte 681fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT: 682fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 683fcf3ce44SJohn Forte /* notify requester of failure */ 684fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, 685fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED); 686fcf3ce44SJohn Forte break; 687fcf3ce44SJohn Forte 688fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT: 689fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 690fcf3ce44SJohn Forte icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP; 691fcf3ce44SJohn Forte /* 692fcf3ce44SJohn Forte * If a TEXT command fails, notify the owner. 693fcf3ce44SJohn Forte */ 694fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, 695fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED); 696fcf3ce44SJohn Forte break; 697fcf3ce44SJohn Forte 698fcf3ce44SJohn Forte default: 699fcf3ce44SJohn Forte ASSERT(FALSE); 700fcf3ce44SJohn Forte break; 701fcf3ce44SJohn Forte } 702fcf3ce44SJohn Forte break; 703fcf3ce44SJohn Forte 704fcf3ce44SJohn Forte /* All other events are invalid for this state */ 705fcf3ce44SJohn Forte default: 706fcf3ce44SJohn Forte ASSERT(FALSE); 707fcf3ce44SJohn Forte } 708fcf3ce44SJohn Forte } 709fcf3ce44SJohn Forte 710fcf3ce44SJohn Forte 711fcf3ce44SJohn Forte /* 712fcf3ce44SJohn Forte * iscsi_cmd_state_active - 713fcf3ce44SJohn Forte * 714fcf3ce44SJohn Forte */ 715fcf3ce44SJohn Forte static void 716fcf3ce44SJohn Forte iscsi_cmd_state_active(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg) 717fcf3ce44SJohn Forte { 718fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg; 719fcf3ce44SJohn Forte iscsi_hba_t *ihp; 720fcf3ce44SJohn Forte iscsi_cmd_t *t_icmdp = NULL; 721fcf3ce44SJohn Forte iscsi_conn_t *icp = NULL; 722fcf3ce44SJohn Forte 723fcf3ce44SJohn Forte ASSERT(icmdp != NULL); 724fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_ACTIVE); 725fcf3ce44SJohn Forte ASSERT(isp != NULL); 726fcf3ce44SJohn Forte 727fcf3ce44SJohn Forte ihp = isp->sess_hba; 728fcf3ce44SJohn Forte ASSERT(ihp != NULL); 729fcf3ce44SJohn Forte 730fcf3ce44SJohn Forte icp = icmdp->cmd_conn; 731fcf3ce44SJohn Forte ASSERT(icp != NULL); 732fcf3ce44SJohn Forte ASSERT(mutex_owned(&icp->conn_queue_active.mutex)); 733fcf3ce44SJohn Forte 734fcf3ce44SJohn Forte /* switch on event change */ 735fcf3ce44SJohn Forte switch (event) { 736fcf3ce44SJohn Forte /* -E3: Command was successfully completed */ 737fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E3: 738fcf3ce44SJohn Forte /* 739fcf3ce44SJohn Forte * Remove command from the active list. We need to protect 740fcf3ce44SJohn Forte * someone from looking up this command ITT until it's 741fcf3ce44SJohn Forte * freed of the command is moved to a new queue location. 742fcf3ce44SJohn Forte */ 743fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 744fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 745fcf3ce44SJohn Forte 746fcf3ce44SJohn Forte switch (icmdp->cmd_type) { 747fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI: 748*30e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp); 749fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 750fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp); 751fcf3ce44SJohn Forte break; 752fcf3ce44SJohn Forte 753fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP: 754fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 755fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 756fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 757fcf3ce44SJohn Forte 758fcf3ce44SJohn Forte /* free alloc */ 759d233de7eSJack Meng icmdp->cmd_misc_flags |= 760d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 761d233de7eSJack Meng 762fcf3ce44SJohn Forte break; 763fcf3ce44SJohn Forte 764fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT: 765fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 766fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 767fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 768fcf3ce44SJohn Forte 769fcf3ce44SJohn Forte /* 770fcf3ce44SJohn Forte * Abort was completed successfully. We should 771fcf3ce44SJohn Forte * complete the parent scsi command if it still 772fcf3ce44SJohn Forte * exists as timed out, and the state is not 773fcf3ce44SJohn Forte * COMPLETED 774fcf3ce44SJohn Forte */ 775fcf3ce44SJohn Forte t_icmdp = icmdp->cmd_un.abort.icmdp; 776fcf3ce44SJohn Forte ASSERT(t_icmdp != NULL); 777fcf3ce44SJohn Forte mutex_enter(&t_icmdp->cmd_mutex); 778*30e7468fSPeter Dunlap t_icmdp->cmd_un.scsi.abort_icmdp = NULL; 779fcf3ce44SJohn Forte if (t_icmdp->cmd_state != ISCSI_CMD_STATE_COMPLETED) { 780fcf3ce44SJohn Forte iscsi_dequeue_active_cmd( 781fcf3ce44SJohn Forte t_icmdp->cmd_conn, t_icmdp); 782*30e7468fSPeter Dunlap mutex_enter( 783*30e7468fSPeter Dunlap &icp->conn_queue_idm_aborting.mutex); 784*30e7468fSPeter Dunlap iscsi_enqueue_idm_aborting_cmd( 785*30e7468fSPeter Dunlap t_icmdp->cmd_conn, 786*30e7468fSPeter Dunlap t_icmdp); 787*30e7468fSPeter Dunlap mutex_exit(&icp->conn_queue_idm_aborting.mutex); 788fcf3ce44SJohn Forte 789*30e7468fSPeter Dunlap /* 790*30e7468fSPeter Dunlap * Complete abort processing after IDM 791*30e7468fSPeter Dunlap * calls us back. Set the status to use 792*30e7468fSPeter Dunlap * when we complete the command. 793*30e7468fSPeter Dunlap */ 794fcf3ce44SJohn Forte ISCSI_CMD_SET_REASON_STAT( 795fcf3ce44SJohn Forte t_icmdp, CMD_TIMEOUT, STAT_TIMEOUT); 796*30e7468fSPeter Dunlap idm_task_abort(icp->conn_ic, t_icmdp->cmd_itp, 797*30e7468fSPeter Dunlap AT_TASK_MGMT_ABORT); 798*30e7468fSPeter Dunlap } else { 799*30e7468fSPeter Dunlap cv_broadcast(&t_icmdp->cmd_completion); 800fcf3ce44SJohn Forte } 801fcf3ce44SJohn Forte mutex_exit(&t_icmdp->cmd_mutex); 802fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL; 803fcf3ce44SJohn Forte 804d233de7eSJack Meng icmdp->cmd_misc_flags |= 805d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 806d233de7eSJack Meng 807fcf3ce44SJohn Forte break; 808fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET: 809fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 810fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 811fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 812fcf3ce44SJohn Forte 813fcf3ce44SJohn Forte /* 814fcf3ce44SJohn Forte * Complete the abort/reset successfully. 815fcf3ce44SJohn Forte */ 816fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, ISCSI_STATUS_SUCCESS); 817fcf3ce44SJohn Forte break; 818fcf3ce44SJohn Forte 819fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT: 820fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 821fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 822fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 823fcf3ce44SJohn Forte 824fcf3ce44SJohn Forte /* 825fcf3ce44SJohn Forte * Complete the logout successfully. 826fcf3ce44SJohn Forte */ 827fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, ISCSI_STATUS_SUCCESS); 828fcf3ce44SJohn Forte break; 829fcf3ce44SJohn Forte 830fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT: 831fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 832fcf3ce44SJohn Forte if (icmdp->cmd_un.text.stage == 833fcf3ce44SJohn Forte ISCSI_CMD_TEXT_FINAL_RSP) { 834fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 835fcf3ce44SJohn Forte } 836fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 837fcf3ce44SJohn Forte 838fcf3ce44SJohn Forte /* 839fcf3ce44SJohn Forte * Complete the text command successfully. 840fcf3ce44SJohn Forte */ 841fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, icmdp->cmd_result); 842fcf3ce44SJohn Forte break; 843fcf3ce44SJohn Forte 844fcf3ce44SJohn Forte default: 845fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 846fcf3ce44SJohn Forte ASSERT(FALSE); 847fcf3ce44SJohn Forte } 848fcf3ce44SJohn Forte 849fcf3ce44SJohn Forte ASSERT(!mutex_owned(&isp->sess_cmdsn_mutex)); 850fcf3ce44SJohn Forte break; 851fcf3ce44SJohn Forte 852*30e7468fSPeter Dunlap /* -E10,E4: Command has been requested to abort */ 853*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E10: 854*30e7468fSPeter Dunlap /* FALLTHRU */ 855fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E4: 856fcf3ce44SJohn Forte 857fcf3ce44SJohn Forte /* E4 is only for resets and aborts */ 858fcf3ce44SJohn Forte ASSERT((icmdp->cmd_type == ISCSI_CMD_TYPE_ABORT) || 859fcf3ce44SJohn Forte (icmdp->cmd_type == ISCSI_CMD_TYPE_RESET)); 860fcf3ce44SJohn Forte /* FALLTHRU */ 861fcf3ce44SJohn Forte 862fcf3ce44SJohn Forte /* -E6: Command has timed out */ 863fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E6: 864fcf3ce44SJohn Forte 865fcf3ce44SJohn Forte switch (icmdp->cmd_type) { 866fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI: 867fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_ABORTING; 868fcf3ce44SJohn Forte iscsi_handle_abort(icmdp); 869fcf3ce44SJohn Forte break; 870fcf3ce44SJohn Forte 871fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP: 872fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 873fcf3ce44SJohn Forte 874fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 875fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 876fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 877fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 878fcf3ce44SJohn Forte 879d233de7eSJack Meng icmdp->cmd_misc_flags |= 880d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 881d233de7eSJack Meng 882fcf3ce44SJohn Forte break; 883fcf3ce44SJohn Forte 884fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT: 885fcf3ce44SJohn Forte icmdp->cmd_state = 886fcf3ce44SJohn Forte ISCSI_CMD_STATE_FREE; 887fcf3ce44SJohn Forte 888fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 889fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 890fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 891fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 892fcf3ce44SJohn Forte 893fcf3ce44SJohn Forte /* 894*30e7468fSPeter Dunlap * If this is an E4 then we may need to deal with 895*30e7468fSPeter Dunlap * the abort's associated SCSI command. If this 896*30e7468fSPeter Dunlap * is an E10 then IDM is already cleaning up the 897*30e7468fSPeter Dunlap * SCSI command and all we need to do is break the 898*30e7468fSPeter Dunlap * linkage between them and free the abort command. 899fcf3ce44SJohn Forte */ 900*30e7468fSPeter Dunlap t_icmdp = icmdp->cmd_un.abort.icmdp; 901*30e7468fSPeter Dunlap ASSERT(t_icmdp != NULL); 902*30e7468fSPeter Dunlap if (event != ISCSI_CMD_EVENT_E10) { 903*30e7468fSPeter Dunlap 904*30e7468fSPeter Dunlap mutex_enter(&t_icmdp->cmd_mutex); 905*30e7468fSPeter Dunlap t_icmdp->cmd_un.scsi.abort_icmdp = NULL; 906*30e7468fSPeter Dunlap /* 907*30e7468fSPeter Dunlap * If abort command is aborted then we should 908*30e7468fSPeter Dunlap * not act on the parent scsi command. If the 909*30e7468fSPeter Dunlap * abort command timed out then we need to 910*30e7468fSPeter Dunlap * complete the parent command if it still 911*30e7468fSPeter Dunlap * exists with a timeout failure. 912*30e7468fSPeter Dunlap */ 913*30e7468fSPeter Dunlap if ((event == ISCSI_CMD_EVENT_E6) && 914*30e7468fSPeter Dunlap (t_icmdp->cmd_state != 915*30e7468fSPeter Dunlap ISCSI_CMD_STATE_IDM_ABORTING) && 916*30e7468fSPeter Dunlap (t_icmdp->cmd_state != 917*30e7468fSPeter Dunlap ISCSI_CMD_STATE_COMPLETED)) { 918*30e7468fSPeter Dunlap 919*30e7468fSPeter Dunlap iscsi_dequeue_active_cmd( 920*30e7468fSPeter Dunlap t_icmdp->cmd_conn, t_icmdp); 921*30e7468fSPeter Dunlap mutex_enter(&icp-> 922*30e7468fSPeter Dunlap conn_queue_idm_aborting.mutex); 923*30e7468fSPeter Dunlap iscsi_enqueue_idm_aborting_cmd( 924*30e7468fSPeter Dunlap t_icmdp->cmd_conn, t_icmdp); 925*30e7468fSPeter Dunlap mutex_exit(&icp-> 926*30e7468fSPeter Dunlap conn_queue_idm_aborting.mutex); 927*30e7468fSPeter Dunlap /* 928*30e7468fSPeter Dunlap * Complete abort processing after IDM 929*30e7468fSPeter Dunlap * calls us back. Set the status to use 930*30e7468fSPeter Dunlap * when we complete the command. 931*30e7468fSPeter Dunlap */ 932*30e7468fSPeter Dunlap ISCSI_CMD_SET_REASON_STAT(t_icmdp, 933*30e7468fSPeter Dunlap CMD_TIMEOUT, STAT_TIMEOUT); 934*30e7468fSPeter Dunlap idm_task_abort(icp->conn_ic, 935*30e7468fSPeter Dunlap t_icmdp->cmd_itp, 936*30e7468fSPeter Dunlap AT_TASK_MGMT_ABORT); 937*30e7468fSPeter Dunlap } else { 938*30e7468fSPeter Dunlap cv_broadcast(&t_icmdp->cmd_completion); 939*30e7468fSPeter Dunlap } 940*30e7468fSPeter Dunlap mutex_exit(&t_icmdp->cmd_mutex); 941*30e7468fSPeter Dunlap } else { 942*30e7468fSPeter Dunlap t_icmdp->cmd_un.scsi.abort_icmdp = NULL; 943fcf3ce44SJohn Forte } 944fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL; 945d233de7eSJack Meng icmdp->cmd_misc_flags |= 946d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 947fcf3ce44SJohn Forte break; 948fcf3ce44SJohn Forte 949fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET: 950fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 951fcf3ce44SJohn Forte 952fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 953fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 954fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 955fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 956fcf3ce44SJohn Forte 957fcf3ce44SJohn Forte /* 958fcf3ce44SJohn Forte * If we are failing a RESET we need 959fcf3ce44SJohn Forte * to notify the tran_reset caller. 960fcf3ce44SJohn Forte * It will free the memory associated 961fcf3ce44SJohn Forte * with the cmd and notify caller. 962fcf3ce44SJohn Forte */ 963fcf3ce44SJohn Forte 964fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, 965fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED); 966fcf3ce44SJohn Forte break; 967fcf3ce44SJohn Forte 968fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT: 969fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 970fcf3ce44SJohn Forte 971fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 972fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 973fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 974fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 975fcf3ce44SJohn Forte 976fcf3ce44SJohn Forte /* 977fcf3ce44SJohn Forte * Notify caller of failure. 978fcf3ce44SJohn Forte */ 979fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, 980fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED); 981fcf3ce44SJohn Forte break; 982fcf3ce44SJohn Forte 983fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT: 984fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 985fcf3ce44SJohn Forte icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP; 986fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 987fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 988fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 989fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 990fcf3ce44SJohn Forte 991fcf3ce44SJohn Forte /* 992fcf3ce44SJohn Forte * If a TEXT command fails, notify caller so 993fcf3ce44SJohn Forte * it can free assocated command 994fcf3ce44SJohn Forte */ 995fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, 996fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED); 997fcf3ce44SJohn Forte break; 998fcf3ce44SJohn Forte 999fcf3ce44SJohn Forte default: 1000fcf3ce44SJohn Forte ASSERT(FALSE); 1001fcf3ce44SJohn Forte } 1002fcf3ce44SJohn Forte 1003fcf3ce44SJohn Forte ASSERT(!mutex_owned(&isp->sess_cmdsn_mutex)); 1004fcf3ce44SJohn Forte break; 1005fcf3ce44SJohn Forte 1006fcf3ce44SJohn Forte /* -E7: Connection has encountered a problem */ 1007fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E7: 1008fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 1009fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 1010fcf3ce44SJohn Forte 1011fcf3ce44SJohn Forte switch (icmdp->cmd_type) { 1012fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI: 1013fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 1014*30e7468fSPeter Dunlap mutex_enter(&icp->conn_queue_idm_aborting.mutex); 1015*30e7468fSPeter Dunlap iscsi_enqueue_idm_aborting_cmd(icmdp->cmd_conn, icmdp); 1016*30e7468fSPeter Dunlap mutex_exit(&icp->conn_queue_idm_aborting.mutex); 1017fcf3ce44SJohn Forte 1018*30e7468fSPeter Dunlap ISCSI_CMD_SET_REASON_STAT(icmdp, CMD_TRAN_ERR, 0); 1019*30e7468fSPeter Dunlap idm_task_abort(icp->conn_ic, icmdp->cmd_itp, 1020*30e7468fSPeter Dunlap AT_TASK_MGMT_ABORT); 1021fcf3ce44SJohn Forte break; 1022fcf3ce44SJohn Forte 1023fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP: 1024fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 1025fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 1026fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 1027fcf3ce44SJohn Forte 1028d233de7eSJack Meng icmdp->cmd_misc_flags |= 1029d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 1030fcf3ce44SJohn Forte break; 1031fcf3ce44SJohn Forte 1032fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT: 1033fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 1034fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 1035fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 1036fcf3ce44SJohn Forte 1037fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_un.abort.icmdp->cmd_mutex); 1038fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp-> 1039fcf3ce44SJohn Forte cmd_un.scsi.abort_icmdp = NULL; 1040fcf3ce44SJohn Forte cv_broadcast(&icmdp->cmd_un.abort.icmdp-> 1041fcf3ce44SJohn Forte cmd_completion); 1042fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_un.abort.icmdp->cmd_mutex); 1043fcf3ce44SJohn Forte /* 1044fcf3ce44SJohn Forte * Nullify the abort command's pointer to its 1045fcf3ce44SJohn Forte * parent command. It does not have to complete its 1046fcf3ce44SJohn Forte * parent command because the parent command will 1047fcf3ce44SJohn Forte * also get an E7. 1048fcf3ce44SJohn Forte */ 1049fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL; 1050fcf3ce44SJohn Forte 1051d233de7eSJack Meng icmdp->cmd_misc_flags |= 1052d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE; 1053fcf3ce44SJohn Forte break; 1054fcf3ce44SJohn Forte 1055fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET: 1056fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 1057fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 1058fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 1059fcf3ce44SJohn Forte /* 1060fcf3ce44SJohn Forte * If we are failing a ABORT we need 1061fcf3ce44SJohn Forte * to notify the tran_abort caller. 1062fcf3ce44SJohn Forte * It will free the memory associated 1063fcf3ce44SJohn Forte * with the cmd and notify caller. 1064fcf3ce44SJohn Forte */ 1065fcf3ce44SJohn Forte 1066fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, 1067fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED); 1068fcf3ce44SJohn Forte break; 1069fcf3ce44SJohn Forte 1070fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT: 1071fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 1072fcf3ce44SJohn Forte /* 1073fcf3ce44SJohn Forte * A connection problem and we attempted to 1074fcf3ce44SJohn Forte * logout? I guess we can just free the 1075fcf3ce44SJohn Forte * request. Someone has already pushed the 1076fcf3ce44SJohn Forte * connection state. 1077fcf3ce44SJohn Forte */ 1078fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 1079fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 1080fcf3ce44SJohn Forte 1081fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, ISCSI_STATUS_SUCCESS); 1082fcf3ce44SJohn Forte break; 1083fcf3ce44SJohn Forte 1084fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT: 1085fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 1086fcf3ce44SJohn Forte icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP; 1087fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp); 1088fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 1089fcf3ce44SJohn Forte 1090fcf3ce44SJohn Forte /* 1091fcf3ce44SJohn Forte * If a TEXT command fails, notify caller so 1092fcf3ce44SJohn Forte * it can free assocated command 1093fcf3ce44SJohn Forte */ 1094fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, 1095fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED); 1096fcf3ce44SJohn Forte break; 1097fcf3ce44SJohn Forte 1098fcf3ce44SJohn Forte default: 1099fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 1100fcf3ce44SJohn Forte ASSERT(FALSE); 1101fcf3ce44SJohn Forte break; 1102fcf3ce44SJohn Forte } 1103fcf3ce44SJohn Forte 1104fcf3ce44SJohn Forte ASSERT(!mutex_owned(&isp->sess_cmdsn_mutex)); 1105fcf3ce44SJohn Forte break; 1106fcf3ce44SJohn Forte 1107*30e7468fSPeter Dunlap /* -E9: IDM is no longer processing this command */ 1108*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E9: 1109*30e7468fSPeter Dunlap iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 1110*30e7468fSPeter Dunlap 1111*30e7468fSPeter Dunlap iscsi_task_cleanup(ISCSI_OP_SCSI_RSP, icmdp); 1112*30e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp); 1113*30e7468fSPeter Dunlap 1114*30e7468fSPeter Dunlap ISCSI_CMD_SET_REASON_STAT(icmdp, CMD_TRAN_ERR, 0); 1115*30e7468fSPeter Dunlap iscsi_enqueue_completed_cmd(isp, icmdp); 1116*30e7468fSPeter Dunlap break; 1117*30e7468fSPeter Dunlap 1118fcf3ce44SJohn Forte /* All other events are invalid for this state */ 1119fcf3ce44SJohn Forte default: 1120fcf3ce44SJohn Forte ASSERT(FALSE); 1121fcf3ce44SJohn Forte } 1122fcf3ce44SJohn Forte } 1123fcf3ce44SJohn Forte 1124fcf3ce44SJohn Forte 1125fcf3ce44SJohn Forte /* 1126fcf3ce44SJohn Forte * iscsi_cmd_state_aborting - 1127fcf3ce44SJohn Forte * 1128fcf3ce44SJohn Forte */ 1129fcf3ce44SJohn Forte static void 1130fcf3ce44SJohn Forte iscsi_cmd_state_aborting(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg) 1131fcf3ce44SJohn Forte { 1132fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg; 1133*30e7468fSPeter Dunlap iscsi_cmd_t *a_icmdp; 1134fcf3ce44SJohn Forte 1135fcf3ce44SJohn Forte ASSERT(icmdp != NULL); 1136fcf3ce44SJohn Forte ASSERT(icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI); 1137fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_ABORTING); 1138fcf3ce44SJohn Forte ASSERT(isp != NULL); 1139fcf3ce44SJohn Forte ASSERT(mutex_owned(&icmdp->cmd_conn->conn_queue_active.mutex)); 1140fcf3ce44SJohn Forte 1141fcf3ce44SJohn Forte /* switch on event change */ 1142fcf3ce44SJohn Forte switch (event) { 1143fcf3ce44SJohn Forte /* -E3: Command was successfully completed */ 1144fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E3: 1145fcf3ce44SJohn Forte /* 1146fcf3ce44SJohn Forte * Remove command from the aborting list 1147fcf3ce44SJohn Forte */ 1148fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex); 1149fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 1150*30e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp); 1151fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex); 1152fcf3ce44SJohn Forte 1153fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp); 1154fcf3ce44SJohn Forte break; 1155fcf3ce44SJohn Forte 1156fcf3ce44SJohn Forte /* -E4: Command has been requested to abort */ 1157fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E4: 1158fcf3ce44SJohn Forte /* 1159fcf3ce44SJohn Forte * An upper level driver might attempt to 1160fcf3ce44SJohn Forte * abort a command that we are already 1161fcf3ce44SJohn Forte * aborting due to a nop. Since we are 1162fcf3ce44SJohn Forte * already in the process of aborting 1163fcf3ce44SJohn Forte * ignore the request. 1164fcf3ce44SJohn Forte */ 1165fcf3ce44SJohn Forte break; 1166fcf3ce44SJohn Forte 1167fcf3ce44SJohn Forte /* -E6: Command has timed out */ 1168fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E6: 1169fcf3ce44SJohn Forte ASSERT(FALSE); 1170fcf3ce44SJohn Forte /* 1171fcf3ce44SJohn Forte * Timeouts should not occur on command in abort queue 1172fcf3ce44SJohn Forte * they are already be processed due to a timeout. 1173fcf3ce44SJohn Forte */ 1174fcf3ce44SJohn Forte break; 1175fcf3ce44SJohn Forte 1176fcf3ce44SJohn Forte /* -E7: Connection has encountered a problem */ 1177fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E7: 1178fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 1179*30e7468fSPeter Dunlap mutex_enter(&icmdp->cmd_conn->conn_queue_idm_aborting.mutex); 1180*30e7468fSPeter Dunlap iscsi_enqueue_idm_aborting_cmd(icmdp->cmd_conn, icmdp); 1181*30e7468fSPeter Dunlap mutex_exit(&icmdp->cmd_conn->conn_queue_idm_aborting.mutex); 1182fcf3ce44SJohn Forte 1183*30e7468fSPeter Dunlap /* 1184*30e7468fSPeter Dunlap * Since we are in "aborting" state there is another command 1185*30e7468fSPeter Dunlap * representing the abort of this command. This command 1186*30e7468fSPeter Dunlap * will cleanup at some indeterminate time after the call 1187*30e7468fSPeter Dunlap * to idm_task_abort so we can't leave the abort request 1188*30e7468fSPeter Dunlap * active. An E10 event to the abort command will cause 1189*30e7468fSPeter Dunlap * it to complete immediately. 1190*30e7468fSPeter Dunlap */ 1191*30e7468fSPeter Dunlap if ((a_icmdp = icmdp->cmd_un.scsi.abort_icmdp) != NULL) { 1192*30e7468fSPeter Dunlap iscsi_cmd_state_machine(a_icmdp, 1193*30e7468fSPeter Dunlap ISCSI_CMD_EVENT_E10, arg); 1194*30e7468fSPeter Dunlap } 1195*30e7468fSPeter Dunlap 1196*30e7468fSPeter Dunlap ISCSI_CMD_SET_REASON_STAT(icmdp, CMD_TRAN_ERR, 0); 1197*30e7468fSPeter Dunlap idm_task_abort(icmdp->cmd_conn->conn_ic, icmdp->cmd_itp, 1198*30e7468fSPeter Dunlap AT_TASK_MGMT_ABORT); 1199*30e7468fSPeter Dunlap break; 1200*30e7468fSPeter Dunlap 1201*30e7468fSPeter Dunlap /* -E9: IDM is no longer processing this command */ 1202*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E9: 1203*30e7468fSPeter Dunlap iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp); 1204*30e7468fSPeter Dunlap 1205*30e7468fSPeter Dunlap iscsi_task_cleanup(ISCSI_OP_SCSI_RSP, icmdp); 1206*30e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp); 1207*30e7468fSPeter Dunlap 1208*30e7468fSPeter Dunlap ISCSI_CMD_SET_REASON_STAT(icmdp, CMD_TRAN_ERR, 0); 1209*30e7468fSPeter Dunlap iscsi_enqueue_completed_cmd(isp, icmdp); 1210*30e7468fSPeter Dunlap break; 1211*30e7468fSPeter Dunlap 1212*30e7468fSPeter Dunlap /* All other events are invalid for this state */ 1213*30e7468fSPeter Dunlap default: 1214*30e7468fSPeter Dunlap ASSERT(FALSE); 1215*30e7468fSPeter Dunlap } 1216*30e7468fSPeter Dunlap } 1217*30e7468fSPeter Dunlap 1218*30e7468fSPeter Dunlap static void 1219*30e7468fSPeter Dunlap iscsi_cmd_state_idm_aborting(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, 1220*30e7468fSPeter Dunlap void *arg) 1221*30e7468fSPeter Dunlap { 1222*30e7468fSPeter Dunlap iscsi_sess_t *isp = (iscsi_sess_t *)arg; 1223*30e7468fSPeter Dunlap 1224*30e7468fSPeter Dunlap ASSERT(icmdp != NULL); 1225*30e7468fSPeter Dunlap ASSERT(icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI); 1226*30e7468fSPeter Dunlap ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_IDM_ABORTING); 1227*30e7468fSPeter Dunlap ASSERT(isp != NULL); 1228*30e7468fSPeter Dunlap 1229*30e7468fSPeter Dunlap /* switch on event change */ 1230*30e7468fSPeter Dunlap switch (event) { 1231*30e7468fSPeter Dunlap /* -E3: Command was successfully completed */ 1232*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E3: 1233*30e7468fSPeter Dunlap /* 1234*30e7468fSPeter Dunlap * iscsi_rx_process_cmd_rsp() and iscsi_rx_process_data_rsp() 1235*30e7468fSPeter Dunlap * are supposed to confirm the cmd state is appropriate before 1236*30e7468fSPeter Dunlap * generating an E3 event. E3 is not allowed in this state. 1237*30e7468fSPeter Dunlap */ 1238*30e7468fSPeter Dunlap ASSERT(0); 1239*30e7468fSPeter Dunlap break; 1240*30e7468fSPeter Dunlap 1241*30e7468fSPeter Dunlap /* -E4: Command has been requested to abort */ 1242*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E4: 1243*30e7468fSPeter Dunlap /* 1244*30e7468fSPeter Dunlap * An upper level driver might attempt to 1245*30e7468fSPeter Dunlap * abort a command that we are already 1246*30e7468fSPeter Dunlap * aborting due to a nop. Since we are 1247*30e7468fSPeter Dunlap * already in the process of aborting 1248*30e7468fSPeter Dunlap * ignore the request. 1249*30e7468fSPeter Dunlap */ 1250*30e7468fSPeter Dunlap break; 1251*30e7468fSPeter Dunlap 1252*30e7468fSPeter Dunlap /* -E6: Command has timed out */ 1253*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E6: 1254*30e7468fSPeter Dunlap ASSERT(FALSE); 1255*30e7468fSPeter Dunlap /* 1256*30e7468fSPeter Dunlap * Timeouts should not occur on aborting commands 1257*30e7468fSPeter Dunlap */ 1258*30e7468fSPeter Dunlap break; 1259*30e7468fSPeter Dunlap 1260*30e7468fSPeter Dunlap /* -E7: Connection has encountered a problem */ 1261*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E7: 1262*30e7468fSPeter Dunlap /* 1263*30e7468fSPeter Dunlap * We have already requested IDM to stop processing this 1264*30e7468fSPeter Dunlap * command so ignore this request. 1265*30e7468fSPeter Dunlap */ 1266*30e7468fSPeter Dunlap break; 1267*30e7468fSPeter Dunlap 1268*30e7468fSPeter Dunlap /* -E9: IDM is no longer processing this command */ 1269*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E9: 1270*30e7468fSPeter Dunlap mutex_enter(&icmdp->cmd_conn->conn_queue_idm_aborting.mutex); 1271*30e7468fSPeter Dunlap iscsi_dequeue_idm_aborting_cmd(icmdp->cmd_conn, icmdp); 1272*30e7468fSPeter Dunlap mutex_exit(&icmdp->cmd_conn->conn_queue_idm_aborting.mutex); 1273*30e7468fSPeter Dunlap 1274*30e7468fSPeter Dunlap /* This is always an error so make sure an error has been set */ 1275*30e7468fSPeter Dunlap ASSERT(icmdp->cmd_un.scsi.pkt->pkt_reason != CMD_CMPLT); 1276*30e7468fSPeter Dunlap iscsi_task_cleanup(ISCSI_OP_SCSI_RSP, icmdp); 1277*30e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp); 1278*30e7468fSPeter Dunlap 1279*30e7468fSPeter Dunlap /* 1280*30e7468fSPeter Dunlap * Whoever called idm_task_abort should have set the completion 1281*30e7468fSPeter Dunlap * status beforehand. 1282*30e7468fSPeter Dunlap */ 1283fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp); 1284*30e7468fSPeter Dunlap cv_broadcast(&icmdp->cmd_completion); 1285fcf3ce44SJohn Forte break; 1286fcf3ce44SJohn Forte 1287fcf3ce44SJohn Forte /* All other events are invalid for this state */ 1288fcf3ce44SJohn Forte default: 1289fcf3ce44SJohn Forte ASSERT(FALSE); 1290fcf3ce44SJohn Forte } 1291fcf3ce44SJohn Forte } 1292fcf3ce44SJohn Forte 1293fcf3ce44SJohn Forte 1294fcf3ce44SJohn Forte /* 1295fcf3ce44SJohn Forte * iscsi_cmd_state_completed - 1296fcf3ce44SJohn Forte * 1297fcf3ce44SJohn Forte */ 1298fcf3ce44SJohn Forte static void 1299fcf3ce44SJohn Forte iscsi_cmd_state_completed(iscsi_cmd_t *icmdp, 1300fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg) 1301fcf3ce44SJohn Forte { 1302fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg; 1303fcf3ce44SJohn Forte 1304fcf3ce44SJohn Forte ASSERT(icmdp != NULL); 1305fcf3ce44SJohn Forte ASSERT(icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI); 1306fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_COMPLETED); 1307fcf3ce44SJohn Forte ASSERT(isp != NULL); 1308fcf3ce44SJohn Forte 1309fcf3ce44SJohn Forte /* switch on event change */ 1310fcf3ce44SJohn Forte switch (event) { 1311fcf3ce44SJohn Forte /* -E8: */ 1312fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E8: 1313fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE; 1314fcf3ce44SJohn Forte 1315fcf3ce44SJohn Forte /* the caller has already remove cmd from queue */ 1316fcf3ce44SJohn Forte 1317fcf3ce44SJohn Forte icmdp->cmd_next = NULL; 1318fcf3ce44SJohn Forte icmdp->cmd_prev = NULL; 1319fcf3ce44SJohn Forte iscsi_iodone(isp, icmdp); 1320fcf3ce44SJohn Forte break; 1321fcf3ce44SJohn Forte /* All other events are invalid for this state */ 1322fcf3ce44SJohn Forte default: 1323fcf3ce44SJohn Forte ASSERT(FALSE); 1324fcf3ce44SJohn Forte } 1325fcf3ce44SJohn Forte } 1326fcf3ce44SJohn Forte 1327fcf3ce44SJohn Forte 1328fcf3ce44SJohn Forte /* 1329fcf3ce44SJohn Forte * iscsi_cmd_state_str - 1330fcf3ce44SJohn Forte * 1331fcf3ce44SJohn Forte */ 1332fcf3ce44SJohn Forte static char * 1333fcf3ce44SJohn Forte iscsi_cmd_state_str(iscsi_cmd_state_t state) 1334fcf3ce44SJohn Forte { 1335fcf3ce44SJohn Forte switch (state) { 1336fcf3ce44SJohn Forte case ISCSI_CMD_STATE_FREE: 1337fcf3ce44SJohn Forte return ("free"); 1338fcf3ce44SJohn Forte case ISCSI_CMD_STATE_PENDING: 1339fcf3ce44SJohn Forte return ("pending"); 1340fcf3ce44SJohn Forte case ISCSI_CMD_STATE_ACTIVE: 1341fcf3ce44SJohn Forte return ("active"); 1342fcf3ce44SJohn Forte case ISCSI_CMD_STATE_ABORTING: 1343fcf3ce44SJohn Forte return ("aborting"); 1344*30e7468fSPeter Dunlap case ISCSI_CMD_STATE_IDM_ABORTING: 1345*30e7468fSPeter Dunlap return ("idm-aborting"); 1346fcf3ce44SJohn Forte case ISCSI_CMD_STATE_COMPLETED: 1347fcf3ce44SJohn Forte return ("completed"); 1348fcf3ce44SJohn Forte default: 1349fcf3ce44SJohn Forte return ("unknown"); 1350fcf3ce44SJohn Forte } 1351fcf3ce44SJohn Forte } 1352fcf3ce44SJohn Forte 1353fcf3ce44SJohn Forte 1354fcf3ce44SJohn Forte /* 1355fcf3ce44SJohn Forte * iscsi_cmd_event_str - 1356fcf3ce44SJohn Forte * 1357fcf3ce44SJohn Forte */ 1358fcf3ce44SJohn Forte static char * 1359fcf3ce44SJohn Forte iscsi_cmd_event_str(iscsi_cmd_event_t event) 1360fcf3ce44SJohn Forte { 1361fcf3ce44SJohn Forte switch (event) { 1362fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E1: 1363fcf3ce44SJohn Forte return ("E1"); 1364fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E2: 1365fcf3ce44SJohn Forte return ("E2"); 1366fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E3: 1367fcf3ce44SJohn Forte return ("E3"); 1368fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E4: 1369fcf3ce44SJohn Forte return ("E4"); 1370fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E6: 1371fcf3ce44SJohn Forte return ("E6"); 1372fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E7: 1373fcf3ce44SJohn Forte return ("E7"); 1374fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E8: 1375fcf3ce44SJohn Forte return ("E8"); 1376*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E9: 1377*30e7468fSPeter Dunlap return ("E9"); 1378*30e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E10: 1379*30e7468fSPeter Dunlap return ("E10"); 1380fcf3ce44SJohn Forte default: 1381fcf3ce44SJohn Forte return ("unknown"); 1382fcf3ce44SJohn Forte } 1383fcf3ce44SJohn Forte } 1384fcf3ce44SJohn Forte 1385fcf3ce44SJohn Forte 1386fcf3ce44SJohn Forte /* 1387fcf3ce44SJohn Forte * iscsi_cmd_event_str - 1388fcf3ce44SJohn Forte * 1389fcf3ce44SJohn Forte */ 1390fcf3ce44SJohn Forte static char * 1391fcf3ce44SJohn Forte iscsi_cmd_type_str(iscsi_cmd_type_t type) 1392fcf3ce44SJohn Forte { 1393fcf3ce44SJohn Forte switch (type) { 1394fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI: 1395fcf3ce44SJohn Forte return ("scsi"); 1396fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP: 1397fcf3ce44SJohn Forte return ("nop"); 1398fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT: 1399fcf3ce44SJohn Forte return ("abort"); 1400fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET: 1401fcf3ce44SJohn Forte return ("reset"); 1402fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT: 1403fcf3ce44SJohn Forte return ("logout"); 1404fcf3ce44SJohn Forte default: 1405fcf3ce44SJohn Forte return ("unknown"); 1406fcf3ce44SJohn Forte } 1407fcf3ce44SJohn Forte } 1408