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 /*
2230e7468fSPeter Dunlap * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23fcf3ce44SJohn Forte * Use is subject to license terms.
24fcf3ce44SJohn Forte *
25*61dfa509SRick McNeal * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
26fcf3ce44SJohn Forte * iSCSI command interfaces
27fcf3ce44SJohn Forte */
28fcf3ce44SJohn Forte
29fcf3ce44SJohn Forte #include "iscsi.h"
30fcf3ce44SJohn Forte
31fcf3ce44SJohn Forte /* internal interfaces */
32fcf3ce44SJohn Forte static void iscsi_cmd_state_free(iscsi_cmd_t *icmdp,
33fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg);
34fcf3ce44SJohn Forte static void iscsi_cmd_state_pending(iscsi_cmd_t *icmdp,
35fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg);
36fcf3ce44SJohn Forte static void iscsi_cmd_state_active(iscsi_cmd_t *icmdp,
37fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg);
38fcf3ce44SJohn Forte static void iscsi_cmd_state_aborting(iscsi_cmd_t *icmdp,
39fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg);
4030e7468fSPeter Dunlap static void iscsi_cmd_state_idm_aborting(iscsi_cmd_t *icmdp,
4130e7468fSPeter Dunlap iscsi_cmd_event_t event, void *arg);
42fcf3ce44SJohn Forte static void iscsi_cmd_state_completed(iscsi_cmd_t *icmdp,
43fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg);
44fcf3ce44SJohn Forte static char *iscsi_cmd_state_str(iscsi_cmd_state_t state);
45fcf3ce44SJohn Forte static char *iscsi_cmd_event_str(iscsi_cmd_event_t event);
46fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
47fcf3ce44SJohn Forte static char *iscsi_cmd_type_str(iscsi_cmd_type_t type);
48fcf3ce44SJohn Forte
49fcf3ce44SJohn Forte #define ISCSI_INTERNAL_CMD_TIMEOUT 60
50fcf3ce44SJohn Forte
51fcf3ce44SJohn Forte #define ISCSI_CMD_ISSUE_CALLBACK(icmdp, status) \
52fcf3ce44SJohn Forte icmdp->cmd_completed = B_TRUE; \
53fcf3ce44SJohn Forte icmdp->cmd_result = status; \
54fcf3ce44SJohn Forte cv_broadcast(&icmdp->cmd_completion);
55fcf3ce44SJohn Forte
56fcf3ce44SJohn Forte #define ISCSI_CMD_SET_REASON_STAT(icmdp, reason, stat) \
57fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_reason = reason; \
58fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_statistics = stat;
59fcf3ce44SJohn Forte
60fcf3ce44SJohn Forte /*
61fcf3ce44SJohn Forte * The following private tunable, settable via
62fcf3ce44SJohn Forte * set iscsi:iscsi_cmd_timeout_factor = 2
63fcf3ce44SJohn Forte * in /etc/system, provides customer relief for configurations experiencing
64fcf3ce44SJohn Forte * SCSI command timeouts due to high-latency/high-loss network connections
65fcf3ce44SJohn Forte * or slow target response (possibly due to backing store issues). If frequent
66fcf3ce44SJohn Forte * use of this tunable is necessary, a beter mechanism must be provided.
67fcf3ce44SJohn Forte */
68fcf3ce44SJohn Forte int iscsi_cmd_timeout_factor = 1;
69fcf3ce44SJohn Forte
70fcf3ce44SJohn Forte /*
71fcf3ce44SJohn Forte * +--------------------------------------------------------------------+
72fcf3ce44SJohn Forte * | External Command Interfaces |
73fcf3ce44SJohn Forte * +--------------------------------------------------------------------+
74fcf3ce44SJohn Forte */
75fcf3ce44SJohn Forte
76fcf3ce44SJohn Forte /*
77fcf3ce44SJohn Forte * iscsi_cmd_state_machine - This function is used to drive the
78fcf3ce44SJohn Forte * state machine of the internal iscsi commands. It takes in a command
79fcf3ce44SJohn Forte * and the associated event affecting the command.
80fcf3ce44SJohn Forte *
81fcf3ce44SJohn Forte * 7.1.3 Command State Diagram for an Initiator
82fcf3ce44SJohn Forte * Symbolic Names for States:
83fcf3ce44SJohn Forte * C1: FREE - State on instantiation, or after successful
84fcf3ce44SJohn Forte * completion.
85fcf3ce44SJohn Forte * C2: PENDING - Command is in the session's pending queue awaiting
86fcf3ce44SJohn Forte * its turn to be sent on the wire.
87fcf3ce44SJohn Forte * C3: ACTIVE - Command has been sent on the wire and is
88fcf3ce44SJohn Forte * awaiting completion.
89fcf3ce44SJohn Forte * C4: ABORTING - Command which was sent on the wire has not timed
90fcf3ce44SJohn Forte * out or been requested to abort by an upper layer
91fcf3ce44SJohn Forte * driver. At this point there is a task management
92fcf3ce44SJohn Forte * command in the active queue trying to abort the task.
9330e7468fSPeter Dunlap * C4': IDM ABORTING - SCSI command is owned by IDM and idm_task_abort
9430e7468fSPeter Dunlap * has been called for this command.
95fcf3ce44SJohn Forte * C5: COMPLETED - Command which is ready to complete via pkt callback.
96fcf3ce44SJohn Forte *
97fcf3ce44SJohn Forte * The state diagram is as follows:
98fcf3ce44SJohn Forte * -------
99fcf3ce44SJohn Forte * / C1 \
100fcf3ce44SJohn Forte * I-------->\ /<------------
101fcf3ce44SJohn Forte * N| ---+--- |
102fcf3ce44SJohn Forte * T| |E1 |
103fcf3ce44SJohn Forte * E| V |
104fcf3ce44SJohn Forte * R| ------- |
105fcf3ce44SJohn Forte * N+--------/ C2 \ |
106fcf3ce44SJohn Forte * A| E4/6/7\ /-------- |
107fcf3ce44SJohn Forte * L| ---+--- E4/6/7| |
10830e7468fSPeter Dunlap * | |E2 E10 | |
109fcf3ce44SJohn Forte * C| V | S |
110fcf3ce44SJohn Forte * M| _______ | C |
111fcf3ce44SJohn Forte * D+--------/ C3 \ | S |
112fcf3ce44SJohn Forte * S E3/4/6/7\ /-------+ I |
11330e7468fSPeter Dunlap * /---+---E3/4/6/7| |
11430e7468fSPeter Dunlap * / | E9/10| |
11530e7468fSPeter Dunlap * ------/ E4/6| | C |
11630e7468fSPeter Dunlap * | V | M |
11730e7468fSPeter Dunlap * E7| ------- | D |
11830e7468fSPeter Dunlap * SCSI| - >/ C4 \ | S |
11930e7468fSPeter Dunlap * | / \ /-------+ |
12030e7468fSPeter Dunlap * | | ---+---E3/6/7/9| |
12130e7468fSPeter Dunlap * | | E4| | V /E8
12230e7468fSPeter Dunlap * | ------ | -------
12330e7468fSPeter Dunlap * +-\ / / C5 \
12430e7468fSPeter Dunlap * V \-------/ /---->\ /
12530e7468fSPeter Dunlap * ------- E7 / ---+---
12630e7468fSPeter Dunlap * / C4' \ /
12730e7468fSPeter Dunlap * \ /------/ E9
12830e7468fSPeter Dunlap * -------
129fcf3ce44SJohn Forte *
130fcf3ce44SJohn Forte * The state transition table is as follows:
131fcf3ce44SJohn Forte *
13230e7468fSPeter Dunlap * +---------+---+---+-----+----+--------------+
13330e7468fSPeter Dunlap * |C1 |C2 |C3 |C4 |C4' |C5 |
13430e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+
13530e7468fSPeter Dunlap * C1| - |E1 | - | - | - | |
13630e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+
13730e7468fSPeter Dunlap * C2|E4/6/7 |- |E2 | - | - |E4/6/7/10 |
13830e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+
13930e7468fSPeter Dunlap * C3|E3/4/6/7 |- |- |E4/6 |E7 |E3/4/6/7/9/10 |
14030e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+
14130e7468fSPeter Dunlap * C4| |- |- |E4 |E7 |E3/6/7/9 |
14230e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+
14330e7468fSPeter Dunlap * C4'| |- |- |- |- |E9 |
14430e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+
14530e7468fSPeter Dunlap * C5|E8 | | | | | |
14630e7468fSPeter Dunlap * ---+---------+---+---+-----+----+--------------+
147fcf3ce44SJohn Forte *
148fcf3ce44SJohn Forte * Event definitions:
149fcf3ce44SJohn Forte *
150fcf3ce44SJohn Forte * -E1: Command was requested to be sent on wire
151fcf3ce44SJohn Forte * -E2: Command was submitted and now active on wire
152fcf3ce44SJohn Forte * -E3: Command was successfully completed
153fcf3ce44SJohn Forte * - SCSI command is move to completion queue
154fcf3ce44SJohn Forte * - ABORT/RESET/etc are completed.
155fcf3ce44SJohn Forte * -E4: Command has been requested to abort
156fcf3ce44SJohn Forte * - SCSI command in pending queue will be returned
157fcf3ce44SJohn Forte * to caller with aborted status.
158fcf3ce44SJohn Forte * - SCSI command state updated and iscsi_handle_abort()
159fcf3ce44SJohn Forte * will be called.
160fcf3ce44SJohn Forte * - SCSI command with ABORTING state has already
161fcf3ce44SJohn Forte * been requested to abort ignore request.
162fcf3ce44SJohn Forte * - ABORT/RESET commands will be destroyed and the
163fcf3ce44SJohn Forte * caller will be notify of the failure.
164fcf3ce44SJohn Forte * - All other commands will just be destroyed.
165fcf3ce44SJohn Forte * -E6: Command has timed out
166fcf3ce44SJohn Forte * - SCSI commands in pending queue will be returned up the
167fcf3ce44SJohn Forte * stack with TIMEOUT errors.
168fcf3ce44SJohn Forte * - SCSI commands in the active queue and timed out
169fcf3ce44SJohn Forte * will be moved to the aborting queue.
170fcf3ce44SJohn Forte * - SCSI commands in ABORTING state will be returned up
171fcf3ce44SJohn Forte * up the stack with TIMEOUT errors.
172fcf3ce44SJohn Forte * - ABORT/RESET commands will be destroyed and the caller
173fcf3ce44SJohn Forte * notified of the failure.
174fcf3ce44SJohn Forte * - All other commands will just be detroyed.
175fcf3ce44SJohn Forte * -E7: Connection has encountered a problem
176fcf3ce44SJohn Forte * -E8: Command has completed
177fcf3ce44SJohn Forte * - Only SCSI cmds should receive these events
178fcf3ce44SJohn Forte * and reach the command state.
17930e7468fSPeter Dunlap * -E9: Callback received for previous idm_task_abort request
18030e7468fSPeter Dunlap * -E10: The command this abort was associated with has terminated on its own
181fcf3ce44SJohn Forte */
182fcf3ce44SJohn Forte void
iscsi_cmd_state_machine(iscsi_cmd_t * icmdp,iscsi_cmd_event_t event,void * arg)183fcf3ce44SJohn Forte iscsi_cmd_state_machine(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg)
184fcf3ce44SJohn Forte {
185fcf3ce44SJohn Forte boolean_t release_lock = B_TRUE;
186fcf3ce44SJohn Forte
187fcf3ce44SJohn Forte ASSERT(icmdp != NULL);
188fcf3ce44SJohn Forte ASSERT(arg != NULL);
189fcf3ce44SJohn Forte
190fcf3ce44SJohn Forte DTRACE_PROBE3(event, iscsi_cmd_t *, icmdp, char *,
191fcf3ce44SJohn Forte iscsi_cmd_state_str(icmdp->cmd_state),
192fcf3ce44SJohn Forte char *, iscsi_cmd_event_str(event));
193fcf3ce44SJohn Forte
194fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_mutex);
19530e7468fSPeter Dunlap
19630e7468fSPeter Dunlap /* Audit event */
19730e7468fSPeter Dunlap idm_sm_audit_event(&icmdp->cmd_state_audit,
19830e7468fSPeter Dunlap SAS_ISCSI_CMD, icmdp->cmd_state, event, (uintptr_t)arg);
19930e7468fSPeter Dunlap
200fcf3ce44SJohn Forte icmdp->cmd_prev_state = icmdp->cmd_state;
201fcf3ce44SJohn Forte switch (icmdp->cmd_state) {
202fcf3ce44SJohn Forte case ISCSI_CMD_STATE_FREE:
203fcf3ce44SJohn Forte iscsi_cmd_state_free(icmdp, event, arg);
204fcf3ce44SJohn Forte break;
205fcf3ce44SJohn Forte
206fcf3ce44SJohn Forte case ISCSI_CMD_STATE_PENDING:
207fcf3ce44SJohn Forte iscsi_cmd_state_pending(icmdp, event, arg);
208fcf3ce44SJohn Forte break;
209fcf3ce44SJohn Forte
210fcf3ce44SJohn Forte case ISCSI_CMD_STATE_ACTIVE:
211fcf3ce44SJohn Forte iscsi_cmd_state_active(icmdp, event, arg);
212fcf3ce44SJohn Forte break;
213fcf3ce44SJohn Forte
214fcf3ce44SJohn Forte case ISCSI_CMD_STATE_ABORTING:
215fcf3ce44SJohn Forte iscsi_cmd_state_aborting(icmdp, event, arg);
216fcf3ce44SJohn Forte break;
217fcf3ce44SJohn Forte
21830e7468fSPeter Dunlap case ISCSI_CMD_STATE_IDM_ABORTING:
21930e7468fSPeter Dunlap iscsi_cmd_state_idm_aborting(icmdp, event, arg);
22030e7468fSPeter Dunlap break;
22130e7468fSPeter Dunlap
222fcf3ce44SJohn Forte case ISCSI_CMD_STATE_COMPLETED:
223fcf3ce44SJohn Forte iscsi_cmd_state_completed(icmdp, event, arg);
224fcf3ce44SJohn Forte
225fcf3ce44SJohn Forte /*
226fcf3ce44SJohn Forte * Once completed event is processed we DO NOT
227fcf3ce44SJohn Forte * want to touch it again because the caller
228fcf3ce44SJohn Forte * (sd, st, etc) may have freed the command.
229fcf3ce44SJohn Forte */
230fcf3ce44SJohn Forte release_lock = B_FALSE;
231fcf3ce44SJohn Forte break;
232fcf3ce44SJohn Forte
233fcf3ce44SJohn Forte default:
234fcf3ce44SJohn Forte ASSERT(FALSE);
235fcf3ce44SJohn Forte }
236fcf3ce44SJohn Forte
237fcf3ce44SJohn Forte if (release_lock == B_TRUE) {
23830e7468fSPeter Dunlap /* Audit state if not completed */
23930e7468fSPeter Dunlap idm_sm_audit_state_change(&icmdp->cmd_state_audit,
24030e7468fSPeter Dunlap SAS_ISCSI_CMD, icmdp->cmd_prev_state, icmdp->cmd_state);
24130e7468fSPeter Dunlap
242d233de7eSJack Meng if (!(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_FREE) ||
243d233de7eSJack Meng !(icmdp->cmd_misc_flags &
244d233de7eSJack Meng ISCSI_CMD_MISCFLAG_INTERNAL)) {
245fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_mutex);
246fcf3ce44SJohn Forte return;
247fcf3ce44SJohn Forte }
248fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_mutex);
249fcf3ce44SJohn Forte iscsi_cmd_free(icmdp);
250fcf3ce44SJohn Forte }
251fcf3ce44SJohn Forte }
252fcf3ce44SJohn Forte
253fcf3ce44SJohn Forte /*
254fcf3ce44SJohn Forte * iscsi_cmd_alloc -
255fcf3ce44SJohn Forte *
256fcf3ce44SJohn Forte */
257fcf3ce44SJohn Forte iscsi_cmd_t *
iscsi_cmd_alloc(iscsi_conn_t * icp,int km_flags)258fcf3ce44SJohn Forte iscsi_cmd_alloc(iscsi_conn_t *icp, int km_flags)
259fcf3ce44SJohn Forte {
260fcf3ce44SJohn Forte iscsi_cmd_t *icmdp;
261fcf3ce44SJohn Forte
262fcf3ce44SJohn Forte icmdp = kmem_zalloc(sizeof (iscsi_cmd_t), km_flags);
263fcf3ce44SJohn Forte if (icmdp) {
264fcf3ce44SJohn Forte icmdp->cmd_sig = ISCSI_SIG_CMD;
265fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
266fcf3ce44SJohn Forte icmdp->cmd_conn = icp;
267d233de7eSJack Meng icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_INTERNAL;
26830e7468fSPeter Dunlap idm_sm_audit_init(&icmdp->cmd_state_audit);
269fcf3ce44SJohn Forte mutex_init(&icmdp->cmd_mutex, NULL, MUTEX_DRIVER, NULL);
270fcf3ce44SJohn Forte cv_init(&icmdp->cmd_completion, NULL, CV_DRIVER, NULL);
271fcf3ce44SJohn Forte }
272fcf3ce44SJohn Forte return (icmdp);
273fcf3ce44SJohn Forte }
274fcf3ce44SJohn Forte
275fcf3ce44SJohn Forte /*
276fcf3ce44SJohn Forte * iscsi_cmd_free -
277fcf3ce44SJohn Forte *
278fcf3ce44SJohn Forte */
279fcf3ce44SJohn Forte void
iscsi_cmd_free(iscsi_cmd_t * icmdp)280fcf3ce44SJohn Forte iscsi_cmd_free(iscsi_cmd_t *icmdp)
281fcf3ce44SJohn Forte {
282fcf3ce44SJohn Forte ASSERT(icmdp != NULL);
283fcf3ce44SJohn Forte ASSERT(icmdp->cmd_sig == ISCSI_SIG_CMD);
284fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_FREE);
285fcf3ce44SJohn Forte ASSERT(icmdp->cmd_next == NULL);
286fcf3ce44SJohn Forte ASSERT(icmdp->cmd_prev == NULL);
287d233de7eSJack Meng ASSERT(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_INTERNAL);
28830e7468fSPeter Dunlap if (icmdp->cmd_type == ISCSI_CMD_TYPE_ABORT)
289fcf3ce44SJohn Forte ASSERT(icmdp->cmd_un.abort.icmdp == NULL);
290fcf3ce44SJohn Forte else if (icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) {
291fcf3ce44SJohn Forte ASSERT(icmdp->cmd_un.scsi.r2t_icmdp == NULL);
292fcf3ce44SJohn Forte ASSERT(icmdp->cmd_un.scsi.abort_icmdp == NULL);
293fcf3ce44SJohn Forte }
294fcf3ce44SJohn Forte mutex_destroy(&icmdp->cmd_mutex);
295fcf3ce44SJohn Forte cv_destroy(&icmdp->cmd_completion);
296fcf3ce44SJohn Forte kmem_free(icmdp, sizeof (iscsi_cmd_t));
297fcf3ce44SJohn Forte }
298fcf3ce44SJohn Forte
299fcf3ce44SJohn Forte /*
300fcf3ce44SJohn Forte * +--------------------------------------------------------------------+
301fcf3ce44SJohn Forte * | Internal Command Interfaces |
302fcf3ce44SJohn Forte * +--------------------------------------------------------------------+
303fcf3ce44SJohn Forte */
304fcf3ce44SJohn Forte /*
305fcf3ce44SJohn Forte * iscsi_cmd_state_free -
306fcf3ce44SJohn Forte *
307fcf3ce44SJohn Forte */
308fcf3ce44SJohn Forte static void
iscsi_cmd_state_free(iscsi_cmd_t * icmdp,iscsi_cmd_event_t event,void * arg)309fcf3ce44SJohn Forte iscsi_cmd_state_free(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg)
310fcf3ce44SJohn Forte {
311fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg;
312fcf3ce44SJohn Forte
313fcf3ce44SJohn Forte ASSERT(icmdp != NULL);
314fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_FREE);
315fcf3ce44SJohn Forte ASSERT(isp != NULL);
316fcf3ce44SJohn Forte
317fcf3ce44SJohn Forte /* switch on event change */
318fcf3ce44SJohn Forte switch (event) {
319fcf3ce44SJohn Forte /* -E1: Command was requested to be sent on wire */
320fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E1:
321fcf3ce44SJohn Forte
322fcf3ce44SJohn Forte /* setup timestamps and timeouts for this command */
323fcf3ce44SJohn Forte icmdp->cmd_lbolt_pending = ddi_get_lbolt();
324fcf3ce44SJohn Forte if (icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) {
325fcf3ce44SJohn Forte /*
326fcf3ce44SJohn Forte * Establish absolute time when command should timeout.
32730e7468fSPeter Dunlap * For commands that depend on cmdsn window to go
328fcf3ce44SJohn Forte * active, the timeout will be ignored while on
329fcf3ce44SJohn Forte * the pending queue and a new timeout will be
330fcf3ce44SJohn Forte * established when the command goes active.
331fcf3ce44SJohn Forte */
332fcf3ce44SJohn Forte if (icmdp->cmd_un.scsi.pkt &&
333fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_time)
334fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout =
335fcf3ce44SJohn Forte icmdp->cmd_lbolt_pending + SEC_TO_TICK(
336fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_time *
337fcf3ce44SJohn Forte iscsi_cmd_timeout_factor);
338fcf3ce44SJohn Forte else
339fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = 0;
3402b79d384Sbing zhao - Sun Microsystems - Beijing China
3412b79d384Sbing zhao - Sun Microsystems - Beijing China icmdp->cmd_un.scsi.pkt_stat &=
3422b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_CMD_PKT_STAT_INIT;
343fcf3ce44SJohn Forte } else {
344fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = icmdp->cmd_lbolt_pending +
345fcf3ce44SJohn Forte SEC_TO_TICK(ISCSI_INTERNAL_CMD_TIMEOUT *
346fcf3ce44SJohn Forte iscsi_cmd_timeout_factor);
347fcf3ce44SJohn Forte }
348fcf3ce44SJohn Forte
349fcf3ce44SJohn Forte /* place into pending queue */
350fcf3ce44SJohn Forte iscsi_enqueue_pending_cmd(isp, icmdp);
351fcf3ce44SJohn Forte
352fcf3ce44SJohn Forte break;
353fcf3ce44SJohn Forte
354fcf3ce44SJohn Forte /* All other events are invalid for this state */
355fcf3ce44SJohn Forte default:
356fcf3ce44SJohn Forte ASSERT(FALSE);
357fcf3ce44SJohn Forte }
358fcf3ce44SJohn Forte }
359fcf3ce44SJohn Forte
360fcf3ce44SJohn Forte /*
361fcf3ce44SJohn Forte * iscsi_cmd_state_pending -
362fcf3ce44SJohn Forte *
363fcf3ce44SJohn Forte */
364fcf3ce44SJohn Forte static void
iscsi_cmd_state_pending(iscsi_cmd_t * icmdp,iscsi_cmd_event_t event,void * arg)365fcf3ce44SJohn Forte iscsi_cmd_state_pending(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg)
366fcf3ce44SJohn Forte {
367fcf3ce44SJohn Forte iscsi_status_t status;
368fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg;
369fcf3ce44SJohn Forte boolean_t free_icmdp = B_FALSE;
370fcf3ce44SJohn Forte int rval;
371fcf3ce44SJohn Forte
372fcf3ce44SJohn Forte ASSERT(icmdp != NULL);
373fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_PENDING);
374fcf3ce44SJohn Forte ASSERT(isp != NULL);
375fcf3ce44SJohn Forte
376fcf3ce44SJohn Forte /* switch on event change */
377fcf3ce44SJohn Forte switch (event) {
378fcf3ce44SJohn Forte /* -E2: Command was submitted and now active on wire */
379fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E2:
380fcf3ce44SJohn Forte
381fcf3ce44SJohn Forte /* A connection should have already been assigned */
38230e7468fSPeter Dunlap ASSERT(mutex_owned(&isp->sess_queue_pending.mutex));
383fcf3ce44SJohn Forte ASSERT(icmdp->cmd_conn != NULL);
384fcf3ce44SJohn Forte
385fcf3ce44SJohn Forte /*
386fcf3ce44SJohn Forte * RESERVE RESOURSES
387fcf3ce44SJohn Forte */
388fcf3ce44SJohn Forte switch (icmdp->cmd_type) {
389fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI:
390fcf3ce44SJohn Forte /* check cmdsn window */
391fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
392fcf3ce44SJohn Forte if (!iscsi_sna_lte(isp->sess_cmdsn,
393fcf3ce44SJohn Forte isp->sess_maxcmdsn)) {
394fcf3ce44SJohn Forte /* cmdsn window closed */
395fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
396fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex);
397fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE;
398d233de7eSJack Meng icmdp->cmd_misc_flags |=
399d233de7eSJack Meng ISCSI_CMD_MISCFLAG_STUCK;
400fcf3ce44SJohn Forte return;
401fcf3ce44SJohn Forte }
402fcf3ce44SJohn Forte
403fcf3ce44SJohn Forte /* assign itt */
40430e7468fSPeter Dunlap status = iscsi_sess_reserve_scsi_itt(icmdp);
405fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) {
406fcf3ce44SJohn Forte /* no available itt slots */
407fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
408fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex);
409fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE;
410d233de7eSJack Meng icmdp->cmd_misc_flags |=
411d233de7eSJack Meng ISCSI_CMD_MISCFLAG_STUCK;
412fcf3ce44SJohn Forte return;
413fcf3ce44SJohn Forte }
414fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
415fcf3ce44SJohn Forte break;
416fcf3ce44SJohn Forte
417fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT:
418fcf3ce44SJohn Forte /*
419fcf3ce44SJohn Forte * Verify ABORT's parent SCSI command is still
420fcf3ce44SJohn Forte * there. If parent SCSI command is completed
421fcf3ce44SJohn Forte * then there is no longer any reason to abort
422fcf3ce44SJohn Forte * the parent command. This could occur due
423fcf3ce44SJohn Forte * to a connection or target reset.
424fcf3ce44SJohn Forte */
425fcf3ce44SJohn Forte ASSERT(icmdp->cmd_un.abort.icmdp != NULL);
426fcf3ce44SJohn Forte if (icmdp->cmd_un.abort.icmdp->cmd_state ==
427fcf3ce44SJohn Forte ISCSI_CMD_STATE_COMPLETED) {
428fcf3ce44SJohn Forte iscsi_dequeue_pending_cmd(isp, icmdp);
429fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex);
430fcf3ce44SJohn Forte
431fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_un.abort.icmdp->
432fcf3ce44SJohn Forte cmd_mutex);
433fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp->
434fcf3ce44SJohn Forte cmd_un.scsi.abort_icmdp = NULL;
435fcf3ce44SJohn Forte cv_broadcast(&icmdp->cmd_un.abort.icmdp->
436fcf3ce44SJohn Forte cmd_completion);
437fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_un.abort.icmdp->
438fcf3ce44SJohn Forte cmd_mutex);
439fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL;
440fcf3ce44SJohn Forte
441fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
442d233de7eSJack Meng icmdp->cmd_misc_flags |=
443d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
444fcf3ce44SJohn Forte return;
445fcf3ce44SJohn Forte }
446fcf3ce44SJohn Forte /* FALLTHRU */
447fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET:
448fcf3ce44SJohn Forte /* FALLTHRU */
449fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT:
450fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
451fcf3ce44SJohn Forte /* assign itt */
452fcf3ce44SJohn Forte status = iscsi_sess_reserve_itt(isp, icmdp);
453fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) {
454fcf3ce44SJohn Forte /* no available itt slots */
455fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
456fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex);
457fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE;
458fcf3ce44SJohn Forte return;
459fcf3ce44SJohn Forte }
460fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
461fcf3ce44SJohn Forte break;
462fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP:
463fcf3ce44SJohn Forte /* assign itt, if needed */
464fcf3ce44SJohn Forte if (icmdp->cmd_itt == ISCSI_RSVD_TASK_TAG) {
465fcf3ce44SJohn Forte /* not expecting a response */
466fcf3ce44SJohn Forte free_icmdp = B_TRUE;
467fcf3ce44SJohn Forte } else {
468fcf3ce44SJohn Forte /* expecting response, assign an itt */
469fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
470fcf3ce44SJohn Forte /* assign itt */
471fcf3ce44SJohn Forte status = iscsi_sess_reserve_itt(isp, icmdp);
472fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) {
473fcf3ce44SJohn Forte /* no available itt slots */
474fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
475fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.
476fcf3ce44SJohn Forte mutex);
477fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE;
478fcf3ce44SJohn Forte return;
479fcf3ce44SJohn Forte }
480fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
481fcf3ce44SJohn Forte }
482fcf3ce44SJohn Forte break;
483fcf3ce44SJohn Forte
484fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT:
485fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
486fcf3ce44SJohn Forte /* check cmdsn window */
487fcf3ce44SJohn Forte if (!iscsi_sna_lte(isp->sess_cmdsn,
488fcf3ce44SJohn Forte isp->sess_maxcmdsn)) {
489fcf3ce44SJohn Forte /* cmdsn window closed */
490fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE;
491fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
492fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.mutex);
493d233de7eSJack Meng icmdp->cmd_misc_flags |=
494d233de7eSJack Meng ISCSI_CMD_MISCFLAG_STUCK;
495fcf3ce44SJohn Forte return;
496fcf3ce44SJohn Forte }
497fcf3ce44SJohn Forte if (icmdp->cmd_un.text.stage ==
498fcf3ce44SJohn Forte ISCSI_CMD_TEXT_INITIAL_REQ) {
499fcf3ce44SJohn Forte /* assign itt */
500fcf3ce44SJohn Forte status = iscsi_sess_reserve_itt(isp, icmdp);
501fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(status)) {
502fcf3ce44SJohn Forte /* no available itt slots */
503fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
504fcf3ce44SJohn Forte mutex_exit(&isp->sess_queue_pending.
505fcf3ce44SJohn Forte mutex);
506fcf3ce44SJohn Forte isp->sess_window_open = B_FALSE;
507d233de7eSJack Meng icmdp->cmd_misc_flags |=
508d233de7eSJack Meng ISCSI_CMD_MISCFLAG_STUCK;
509fcf3ce44SJohn Forte return;
510fcf3ce44SJohn Forte }
511fcf3ce44SJohn Forte }
512fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
513fcf3ce44SJohn Forte break;
514fcf3ce44SJohn Forte
515fcf3ce44SJohn Forte default:
516fcf3ce44SJohn Forte ASSERT(FALSE);
517fcf3ce44SJohn Forte }
518fcf3ce44SJohn Forte
519fcf3ce44SJohn Forte /*
520fcf3ce44SJohn Forte * RESOURCES RESERVED
521fcf3ce44SJohn Forte *
522fcf3ce44SJohn Forte * Now that we have the resources reserved, establish timeout
523fcf3ce44SJohn Forte * for cmd_type values that depend on having an open cmdsn
524fcf3ce44SJohn Forte * window (i.e. cmd_type that called iscsi_sna_lte() above).
525fcf3ce44SJohn Forte */
526fcf3ce44SJohn Forte if (icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) {
527fcf3ce44SJohn Forte if (icmdp->cmd_un.scsi.pkt &&
528fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_time)
529fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout =
530fcf3ce44SJohn Forte ddi_get_lbolt() + SEC_TO_TICK(
531fcf3ce44SJohn Forte icmdp->cmd_un.scsi.pkt->pkt_time *
532fcf3ce44SJohn Forte iscsi_cmd_timeout_factor);
533fcf3ce44SJohn Forte else
534fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = 0;
535fcf3ce44SJohn Forte } else if (icmdp->cmd_type == ISCSI_CMD_TYPE_TEXT) {
536fcf3ce44SJohn Forte icmdp->cmd_lbolt_timeout = ddi_get_lbolt() +
537fcf3ce44SJohn Forte SEC_TO_TICK(ISCSI_INTERNAL_CMD_TIMEOUT *
538fcf3ce44SJohn Forte iscsi_cmd_timeout_factor);
539fcf3ce44SJohn Forte }
540fcf3ce44SJohn Forte
541fcf3ce44SJohn Forte /* remove command from pending queue */
542fcf3ce44SJohn Forte iscsi_dequeue_pending_cmd(isp, icmdp);
543fcf3ce44SJohn Forte /* check if expecting a response */
544fcf3ce44SJohn Forte if (free_icmdp == B_FALSE) {
545fcf3ce44SJohn Forte /* response expected, move to active queue */
546fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_conn->conn_queue_active.mutex);
547fcf3ce44SJohn Forte iscsi_enqueue_active_cmd(icmdp->cmd_conn, icmdp);
548fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_conn->conn_queue_active.mutex);
549fcf3ce44SJohn Forte }
550fcf3ce44SJohn Forte
551fcf3ce44SJohn Forte /*
552fcf3ce44SJohn Forte * TRANSFER COMMAND
553fcf3ce44SJohn Forte */
554fcf3ce44SJohn Forte rval = iscsi_tx_cmd(isp, icmdp);
555fcf3ce44SJohn Forte
556fcf3ce44SJohn Forte ASSERT(!mutex_owned(&isp->sess_queue_pending.mutex));
557fcf3ce44SJohn Forte
558fcf3ce44SJohn Forte /*
559fcf3ce44SJohn Forte * CHECK SUCCESS/FAILURE
560fcf3ce44SJohn Forte */
561fcf3ce44SJohn Forte if (!ISCSI_SUCCESS(rval)) {
562fcf3ce44SJohn Forte /*
563fcf3ce44SJohn Forte * iscsi_tx_cmd failed. No cleanup is required
564fcf3ce44SJohn Forte * of commands that were put in the active queue.
565fcf3ce44SJohn Forte * If the tx failed then rx will also fail and cleanup
566fcf3ce44SJohn Forte * all items in the active/aborted queue in a common.
567fcf3ce44SJohn Forte */
568fcf3ce44SJohn Forte
569fcf3ce44SJohn Forte /* EMPTY */
570fcf3ce44SJohn Forte }
571fcf3ce44SJohn Forte
572fcf3ce44SJohn Forte /* free temporary commands */
573fcf3ce44SJohn Forte if (free_icmdp == B_TRUE) {
574fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
575d233de7eSJack Meng icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_FREE;
576fcf3ce44SJohn Forte }
577fcf3ce44SJohn Forte break;
578fcf3ce44SJohn Forte
57930e7468fSPeter Dunlap /* -E10: Abort is no longer required for this command */
58030e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E10:
58130e7468fSPeter Dunlap /*
58230e7468fSPeter Dunlap * Acquiring the sess_queue_pending lock while the
58330e7468fSPeter Dunlap * conn_queue_active lock is held conflicts with the
58430e7468fSPeter Dunlap * locking order in iscsi_cmd_state_pending where
58530e7468fSPeter Dunlap * conn_queue_active is acquired while sess_queue_pending
58630e7468fSPeter Dunlap * is held. Normally this would be a dangerous lock
58730e7468fSPeter Dunlap * order conflict, except that we know that if we are
58830e7468fSPeter Dunlap * seeing ISCSI_CMD_EVENT_E10 then the command being
58930e7468fSPeter Dunlap * aborted is in "aborting" state and by extension
59030e7468fSPeter Dunlap * is not in "pending" state. Therefore the code
59130e7468fSPeter Dunlap * path with that alternate lock order will not execute.
59230e7468fSPeter Dunlap * That's good because we can't drop the lock here without
59330e7468fSPeter Dunlap * risking a deadlock.
59430e7468fSPeter Dunlap */
59530e7468fSPeter Dunlap ASSERT(mutex_owned(&icmdp->cmd_conn->conn_queue_active.mutex));
59630e7468fSPeter Dunlap mutex_enter(&isp->sess_queue_pending.mutex);
59730e7468fSPeter Dunlap
59830e7468fSPeter Dunlap icmdp->cmd_lbolt_aborting = ddi_get_lbolt();
59930e7468fSPeter Dunlap
60030e7468fSPeter Dunlap iscsi_dequeue_pending_cmd(isp, icmdp);
60130e7468fSPeter Dunlap
60230e7468fSPeter Dunlap icmdp->cmd_un.abort.icmdp->cmd_un.scsi.abort_icmdp = NULL;
60330e7468fSPeter Dunlap icmdp->cmd_un.abort.icmdp = NULL;
60430e7468fSPeter Dunlap icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_FREE;
60530e7468fSPeter Dunlap icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
60630e7468fSPeter Dunlap
60730e7468fSPeter Dunlap mutex_exit(&isp->sess_queue_pending.mutex);
60830e7468fSPeter Dunlap break;
60930e7468fSPeter Dunlap
610fcf3ce44SJohn Forte /* -E4: Command has been requested to abort */
611fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E4:
61230e7468fSPeter Dunlap ASSERT(mutex_owned(&isp->sess_queue_pending.mutex));
613fcf3ce44SJohn Forte
614fcf3ce44SJohn Forte icmdp->cmd_lbolt_aborting = ddi_get_lbolt();
615fcf3ce44SJohn Forte ISCSI_CMD_SET_REASON_STAT(icmdp,
616fcf3ce44SJohn Forte CMD_ABORTED, STAT_ABORTED);
617fcf3ce44SJohn Forte
618fcf3ce44SJohn Forte iscsi_dequeue_pending_cmd(isp, icmdp);
619fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp);
620fcf3ce44SJohn Forte
621fcf3ce44SJohn Forte icmdp->cmd_lbolt_aborting = ddi_get_lbolt();
622fcf3ce44SJohn Forte
623fcf3ce44SJohn Forte break;
624fcf3ce44SJohn Forte
625fcf3ce44SJohn Forte /* -E7: Command has been reset */
626fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E7:
627fcf3ce44SJohn Forte
628fcf3ce44SJohn Forte /* FALLTHRU */
629fcf3ce44SJohn Forte
630fcf3ce44SJohn Forte /* -E6: Command has timed out */
631fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E6:
63230e7468fSPeter Dunlap ASSERT(mutex_owned(&isp->sess_queue_pending.mutex));
633fcf3ce44SJohn Forte iscsi_dequeue_pending_cmd(isp, icmdp);
634fcf3ce44SJohn Forte
635fcf3ce44SJohn Forte switch (icmdp->cmd_type) {
636fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI:
637fcf3ce44SJohn Forte /* Complete to caller as TIMEOUT */
638fcf3ce44SJohn Forte if (event == ISCSI_CMD_EVENT_E6) {
639fcf3ce44SJohn Forte ISCSI_CMD_SET_REASON_STAT(icmdp,
640fcf3ce44SJohn Forte CMD_TIMEOUT, STAT_TIMEOUT);
641fcf3ce44SJohn Forte } else {
642fcf3ce44SJohn Forte ISCSI_CMD_SET_REASON_STAT(icmdp,
6432b79d384Sbing zhao - Sun Microsystems - Beijing China CMD_TRAN_ERR, icmdp->cmd_un.scsi.pkt_stat);
644fcf3ce44SJohn Forte }
645fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp);
646fcf3ce44SJohn Forte break;
647fcf3ce44SJohn Forte
648fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP:
649fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
650fcf3ce44SJohn Forte /*
651fcf3ce44SJohn Forte * Timeout occured. Just free NOP. Another
652fcf3ce44SJohn Forte * NOP request will be spawned to replace
653fcf3ce44SJohn Forte * this one.
654fcf3ce44SJohn Forte */
655d233de7eSJack Meng icmdp->cmd_misc_flags |=
656d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
657d233de7eSJack Meng
658fcf3ce44SJohn Forte break;
659fcf3ce44SJohn Forte
660fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT:
661fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_un.abort.icmdp->cmd_mutex);
662fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp->
663fcf3ce44SJohn Forte cmd_un.scsi.abort_icmdp = NULL;
664fcf3ce44SJohn Forte cv_broadcast(&icmdp->cmd_un.abort.icmdp->
665fcf3ce44SJohn Forte cmd_completion);
666fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_un.abort.icmdp->cmd_mutex);
667fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL;
668fcf3ce44SJohn Forte
669fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
670d233de7eSJack Meng icmdp->cmd_misc_flags |=
671d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
672fcf3ce44SJohn Forte break;
673fcf3ce44SJohn Forte
674fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET:
675fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
676fcf3ce44SJohn Forte /*
677fcf3ce44SJohn Forte * If we are failing a RESET we need
678fcf3ce44SJohn Forte * to notify the tran_reset caller.
679fcf3ce44SJohn Forte * with the cmd and notify caller.
680fcf3ce44SJohn Forte */
681fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp,
682fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED);
683fcf3ce44SJohn Forte break;
684fcf3ce44SJohn Forte
685fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT:
686fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
687fcf3ce44SJohn Forte /* notify requester of failure */
688fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp,
689fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED);
690fcf3ce44SJohn Forte break;
691fcf3ce44SJohn Forte
692fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT:
693fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
694fcf3ce44SJohn Forte icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
695fcf3ce44SJohn Forte /*
696fcf3ce44SJohn Forte * If a TEXT command fails, notify the owner.
697fcf3ce44SJohn Forte */
698fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp,
699fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED);
700fcf3ce44SJohn Forte break;
701fcf3ce44SJohn Forte
702fcf3ce44SJohn Forte default:
703fcf3ce44SJohn Forte ASSERT(FALSE);
704fcf3ce44SJohn Forte break;
705fcf3ce44SJohn Forte }
706fcf3ce44SJohn Forte break;
707fcf3ce44SJohn Forte
708fcf3ce44SJohn Forte /* All other events are invalid for this state */
709fcf3ce44SJohn Forte default:
710fcf3ce44SJohn Forte ASSERT(FALSE);
711fcf3ce44SJohn Forte }
712fcf3ce44SJohn Forte }
713fcf3ce44SJohn Forte
714fcf3ce44SJohn Forte
715fcf3ce44SJohn Forte /*
716fcf3ce44SJohn Forte * iscsi_cmd_state_active -
717fcf3ce44SJohn Forte *
718fcf3ce44SJohn Forte */
719fcf3ce44SJohn Forte static void
iscsi_cmd_state_active(iscsi_cmd_t * icmdp,iscsi_cmd_event_t event,void * arg)720fcf3ce44SJohn Forte iscsi_cmd_state_active(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg)
721fcf3ce44SJohn Forte {
722fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg;
723fcf3ce44SJohn Forte iscsi_hba_t *ihp;
724fcf3ce44SJohn Forte iscsi_cmd_t *t_icmdp = NULL;
725fcf3ce44SJohn Forte iscsi_conn_t *icp = NULL;
726fcf3ce44SJohn Forte
727fcf3ce44SJohn Forte ASSERT(icmdp != NULL);
728fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_ACTIVE);
729fcf3ce44SJohn Forte ASSERT(isp != NULL);
730fcf3ce44SJohn Forte
731fcf3ce44SJohn Forte ihp = isp->sess_hba;
732fcf3ce44SJohn Forte ASSERT(ihp != NULL);
733fcf3ce44SJohn Forte
734fcf3ce44SJohn Forte icp = icmdp->cmd_conn;
735fcf3ce44SJohn Forte ASSERT(icp != NULL);
736fcf3ce44SJohn Forte ASSERT(mutex_owned(&icp->conn_queue_active.mutex));
737fcf3ce44SJohn Forte
738fcf3ce44SJohn Forte /* switch on event change */
739fcf3ce44SJohn Forte switch (event) {
740fcf3ce44SJohn Forte /* -E3: Command was successfully completed */
741fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E3:
742fcf3ce44SJohn Forte /*
743fcf3ce44SJohn Forte * Remove command from the active list. We need to protect
744fcf3ce44SJohn Forte * someone from looking up this command ITT until it's
745fcf3ce44SJohn Forte * freed of the command is moved to a new queue location.
746fcf3ce44SJohn Forte */
747fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
748fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
749fcf3ce44SJohn Forte
750fcf3ce44SJohn Forte switch (icmdp->cmd_type) {
751fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI:
75230e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp);
753fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
754fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp);
755fcf3ce44SJohn Forte break;
756fcf3ce44SJohn Forte
757fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP:
758fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
759fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
760fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
761fcf3ce44SJohn Forte
762fcf3ce44SJohn Forte /* free alloc */
763d233de7eSJack Meng icmdp->cmd_misc_flags |=
764d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
765d233de7eSJack Meng
766fcf3ce44SJohn Forte break;
767fcf3ce44SJohn Forte
768fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT:
769fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
770fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
771fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
772fcf3ce44SJohn Forte
773fcf3ce44SJohn Forte /*
774fcf3ce44SJohn Forte * Abort was completed successfully. We should
775fcf3ce44SJohn Forte * complete the parent scsi command if it still
776fcf3ce44SJohn Forte * exists as timed out, and the state is not
777fcf3ce44SJohn Forte * COMPLETED
778fcf3ce44SJohn Forte */
779fcf3ce44SJohn Forte t_icmdp = icmdp->cmd_un.abort.icmdp;
780fcf3ce44SJohn Forte ASSERT(t_icmdp != NULL);
781fcf3ce44SJohn Forte mutex_enter(&t_icmdp->cmd_mutex);
78230e7468fSPeter Dunlap t_icmdp->cmd_un.scsi.abort_icmdp = NULL;
783fcf3ce44SJohn Forte if (t_icmdp->cmd_state != ISCSI_CMD_STATE_COMPLETED) {
784fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(
785fcf3ce44SJohn Forte t_icmdp->cmd_conn, t_icmdp);
78630e7468fSPeter Dunlap mutex_enter(
78730e7468fSPeter Dunlap &icp->conn_queue_idm_aborting.mutex);
78830e7468fSPeter Dunlap iscsi_enqueue_idm_aborting_cmd(
78930e7468fSPeter Dunlap t_icmdp->cmd_conn,
79030e7468fSPeter Dunlap t_icmdp);
79130e7468fSPeter Dunlap mutex_exit(&icp->conn_queue_idm_aborting.mutex);
792fcf3ce44SJohn Forte
79330e7468fSPeter Dunlap /*
79430e7468fSPeter Dunlap * Complete abort processing after IDM
79530e7468fSPeter Dunlap * calls us back. Set the status to use
79630e7468fSPeter Dunlap * when we complete the command.
79730e7468fSPeter Dunlap */
798fcf3ce44SJohn Forte ISCSI_CMD_SET_REASON_STAT(
7992b79d384Sbing zhao - Sun Microsystems - Beijing China t_icmdp, CMD_TIMEOUT, STAT_ABORTED);
800*61dfa509SRick McNeal (void) idm_task_abort(icp->conn_ic,
801*61dfa509SRick McNeal t_icmdp->cmd_itp, AT_TASK_MGMT_ABORT);
80230e7468fSPeter Dunlap } else {
80330e7468fSPeter Dunlap cv_broadcast(&t_icmdp->cmd_completion);
804fcf3ce44SJohn Forte }
805fcf3ce44SJohn Forte mutex_exit(&t_icmdp->cmd_mutex);
806fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL;
807fcf3ce44SJohn Forte
808d233de7eSJack Meng icmdp->cmd_misc_flags |=
809d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
810d233de7eSJack Meng
811fcf3ce44SJohn Forte break;
812fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET:
813fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
814fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
815fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
816fcf3ce44SJohn Forte
817fcf3ce44SJohn Forte /*
8182b79d384Sbing zhao - Sun Microsystems - Beijing China * Complete the abort/reset command.
819fcf3ce44SJohn Forte */
8202b79d384Sbing zhao - Sun Microsystems - Beijing China if (icmdp->cmd_un.reset.response !=
8212b79d384Sbing zhao - Sun Microsystems - Beijing China SCSI_TCP_TM_RESP_COMPLETE) {
8222b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_CMD_ISSUE_CALLBACK(icmdp,
8232b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_STATUS_CMD_FAILED);
8242b79d384Sbing zhao - Sun Microsystems - Beijing China } else {
8252b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_CMD_ISSUE_CALLBACK(icmdp,
8262b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_STATUS_SUCCESS);
8272b79d384Sbing zhao - Sun Microsystems - Beijing China }
8282b79d384Sbing zhao - Sun Microsystems - Beijing China
829fcf3ce44SJohn Forte break;
830fcf3ce44SJohn Forte
831fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT:
832fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
833fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
834fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
835fcf3ce44SJohn Forte
836fcf3ce44SJohn Forte /*
837fcf3ce44SJohn Forte * Complete the logout successfully.
838fcf3ce44SJohn Forte */
839fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, ISCSI_STATUS_SUCCESS);
840fcf3ce44SJohn Forte break;
841fcf3ce44SJohn Forte
842fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT:
843fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
844fcf3ce44SJohn Forte if (icmdp->cmd_un.text.stage ==
845fcf3ce44SJohn Forte ISCSI_CMD_TEXT_FINAL_RSP) {
846fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
847fcf3ce44SJohn Forte }
848fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
849fcf3ce44SJohn Forte
850fcf3ce44SJohn Forte /*
851fcf3ce44SJohn Forte * Complete the text command successfully.
852fcf3ce44SJohn Forte */
853fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, icmdp->cmd_result);
854fcf3ce44SJohn Forte break;
855fcf3ce44SJohn Forte
856fcf3ce44SJohn Forte default:
857fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
858fcf3ce44SJohn Forte ASSERT(FALSE);
859fcf3ce44SJohn Forte }
860fcf3ce44SJohn Forte
861fcf3ce44SJohn Forte ASSERT(!mutex_owned(&isp->sess_cmdsn_mutex));
862fcf3ce44SJohn Forte break;
863fcf3ce44SJohn Forte
86430e7468fSPeter Dunlap /* -E10,E4: Command has been requested to abort */
86530e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E10:
86630e7468fSPeter Dunlap /* FALLTHRU */
867fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E4:
868fcf3ce44SJohn Forte
869fcf3ce44SJohn Forte /* E4 is only for resets and aborts */
870fcf3ce44SJohn Forte ASSERT((icmdp->cmd_type == ISCSI_CMD_TYPE_ABORT) ||
871fcf3ce44SJohn Forte (icmdp->cmd_type == ISCSI_CMD_TYPE_RESET));
872fcf3ce44SJohn Forte /* FALLTHRU */
873fcf3ce44SJohn Forte
874fcf3ce44SJohn Forte /* -E6: Command has timed out */
875fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E6:
876fcf3ce44SJohn Forte
877fcf3ce44SJohn Forte switch (icmdp->cmd_type) {
878fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI:
879fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_ABORTING;
880fcf3ce44SJohn Forte iscsi_handle_abort(icmdp);
881fcf3ce44SJohn Forte break;
882fcf3ce44SJohn Forte
883fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP:
884fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
885fcf3ce44SJohn Forte
886fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
887fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
888fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
889fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
890fcf3ce44SJohn Forte
891d233de7eSJack Meng icmdp->cmd_misc_flags |=
892d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
893d233de7eSJack Meng
894fcf3ce44SJohn Forte break;
895fcf3ce44SJohn Forte
896fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT:
897fcf3ce44SJohn Forte icmdp->cmd_state =
898fcf3ce44SJohn Forte ISCSI_CMD_STATE_FREE;
899fcf3ce44SJohn Forte
900fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
901fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
902fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
903fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
904fcf3ce44SJohn Forte
905fcf3ce44SJohn Forte /*
90630e7468fSPeter Dunlap * If this is an E4 then we may need to deal with
90730e7468fSPeter Dunlap * the abort's associated SCSI command. If this
90830e7468fSPeter Dunlap * is an E10 then IDM is already cleaning up the
90930e7468fSPeter Dunlap * SCSI command and all we need to do is break the
91030e7468fSPeter Dunlap * linkage between them and free the abort command.
911fcf3ce44SJohn Forte */
91230e7468fSPeter Dunlap t_icmdp = icmdp->cmd_un.abort.icmdp;
91330e7468fSPeter Dunlap ASSERT(t_icmdp != NULL);
91430e7468fSPeter Dunlap if (event != ISCSI_CMD_EVENT_E10) {
91530e7468fSPeter Dunlap
91630e7468fSPeter Dunlap mutex_enter(&t_icmdp->cmd_mutex);
91730e7468fSPeter Dunlap t_icmdp->cmd_un.scsi.abort_icmdp = NULL;
91830e7468fSPeter Dunlap /*
91930e7468fSPeter Dunlap * If abort command is aborted then we should
92030e7468fSPeter Dunlap * not act on the parent scsi command. If the
92130e7468fSPeter Dunlap * abort command timed out then we need to
92230e7468fSPeter Dunlap * complete the parent command if it still
92330e7468fSPeter Dunlap * exists with a timeout failure.
92430e7468fSPeter Dunlap */
92530e7468fSPeter Dunlap if ((event == ISCSI_CMD_EVENT_E6) &&
92630e7468fSPeter Dunlap (t_icmdp->cmd_state !=
92730e7468fSPeter Dunlap ISCSI_CMD_STATE_IDM_ABORTING) &&
92830e7468fSPeter Dunlap (t_icmdp->cmd_state !=
92930e7468fSPeter Dunlap ISCSI_CMD_STATE_COMPLETED)) {
93030e7468fSPeter Dunlap
93130e7468fSPeter Dunlap iscsi_dequeue_active_cmd(
93230e7468fSPeter Dunlap t_icmdp->cmd_conn, t_icmdp);
93330e7468fSPeter Dunlap mutex_enter(&icp->
93430e7468fSPeter Dunlap conn_queue_idm_aborting.mutex);
93530e7468fSPeter Dunlap iscsi_enqueue_idm_aborting_cmd(
93630e7468fSPeter Dunlap t_icmdp->cmd_conn, t_icmdp);
93730e7468fSPeter Dunlap mutex_exit(&icp->
93830e7468fSPeter Dunlap conn_queue_idm_aborting.mutex);
93930e7468fSPeter Dunlap /*
94030e7468fSPeter Dunlap * Complete abort processing after IDM
94130e7468fSPeter Dunlap * calls us back. Set the status to use
94230e7468fSPeter Dunlap * when we complete the command.
94330e7468fSPeter Dunlap */
94430e7468fSPeter Dunlap ISCSI_CMD_SET_REASON_STAT(t_icmdp,
94530e7468fSPeter Dunlap CMD_TIMEOUT, STAT_TIMEOUT);
946*61dfa509SRick McNeal (void) idm_task_abort(icp->conn_ic,
94730e7468fSPeter Dunlap t_icmdp->cmd_itp,
94830e7468fSPeter Dunlap AT_TASK_MGMT_ABORT);
94930e7468fSPeter Dunlap } else {
95030e7468fSPeter Dunlap cv_broadcast(&t_icmdp->cmd_completion);
95130e7468fSPeter Dunlap }
95230e7468fSPeter Dunlap mutex_exit(&t_icmdp->cmd_mutex);
95330e7468fSPeter Dunlap } else {
95430e7468fSPeter Dunlap t_icmdp->cmd_un.scsi.abort_icmdp = NULL;
955fcf3ce44SJohn Forte }
956fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL;
957d233de7eSJack Meng icmdp->cmd_misc_flags |=
958d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
959fcf3ce44SJohn Forte break;
960fcf3ce44SJohn Forte
961fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET:
962fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
963fcf3ce44SJohn Forte
964fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
965fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
966fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
967fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
968fcf3ce44SJohn Forte
969fcf3ce44SJohn Forte /*
970fcf3ce44SJohn Forte * If we are failing a RESET we need
971fcf3ce44SJohn Forte * to notify the tran_reset caller.
972fcf3ce44SJohn Forte * It will free the memory associated
973fcf3ce44SJohn Forte * with the cmd and notify caller.
974fcf3ce44SJohn Forte */
975fcf3ce44SJohn Forte
976fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp,
977fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED);
978fcf3ce44SJohn Forte break;
979fcf3ce44SJohn Forte
980fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT:
981fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
982fcf3ce44SJohn Forte
983fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
984fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
985fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
986fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
987fcf3ce44SJohn Forte
988fcf3ce44SJohn Forte /*
989fcf3ce44SJohn Forte * Notify caller of failure.
990fcf3ce44SJohn Forte */
991fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp,
992fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED);
993fcf3ce44SJohn Forte break;
994fcf3ce44SJohn Forte
995fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT:
996fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
997fcf3ce44SJohn Forte icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
998fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
999fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
1000fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
1001fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
1002fcf3ce44SJohn Forte
1003fcf3ce44SJohn Forte /*
1004fcf3ce44SJohn Forte * If a TEXT command fails, notify caller so
1005fcf3ce44SJohn Forte * it can free assocated command
1006fcf3ce44SJohn Forte */
1007fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp,
1008fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED);
1009fcf3ce44SJohn Forte break;
1010fcf3ce44SJohn Forte
1011fcf3ce44SJohn Forte default:
1012fcf3ce44SJohn Forte ASSERT(FALSE);
1013fcf3ce44SJohn Forte }
1014fcf3ce44SJohn Forte
1015fcf3ce44SJohn Forte ASSERT(!mutex_owned(&isp->sess_cmdsn_mutex));
1016fcf3ce44SJohn Forte break;
1017fcf3ce44SJohn Forte
1018fcf3ce44SJohn Forte /* -E7: Connection has encountered a problem */
1019fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E7:
1020fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
1021fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
1022fcf3ce44SJohn Forte
1023fcf3ce44SJohn Forte switch (icmdp->cmd_type) {
1024fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI:
1025fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
102630e7468fSPeter Dunlap mutex_enter(&icp->conn_queue_idm_aborting.mutex);
102730e7468fSPeter Dunlap iscsi_enqueue_idm_aborting_cmd(icmdp->cmd_conn, icmdp);
102830e7468fSPeter Dunlap mutex_exit(&icp->conn_queue_idm_aborting.mutex);
10292b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_CMD_SET_REASON_STAT(icmdp,
10302b79d384Sbing zhao - Sun Microsystems - Beijing China CMD_TRAN_ERR, icmdp->cmd_un.scsi.pkt_stat);
1031*61dfa509SRick McNeal (void) idm_task_abort(icp->conn_ic, icmdp->cmd_itp,
103230e7468fSPeter Dunlap AT_TASK_MGMT_ABORT);
1033fcf3ce44SJohn Forte break;
1034fcf3ce44SJohn Forte
1035fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP:
1036fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
1037fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
1038fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
1039fcf3ce44SJohn Forte
1040d233de7eSJack Meng icmdp->cmd_misc_flags |=
1041d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
1042fcf3ce44SJohn Forte break;
1043fcf3ce44SJohn Forte
1044fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT:
1045fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
1046fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
1047fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
1048fcf3ce44SJohn Forte
1049fcf3ce44SJohn Forte mutex_enter(&icmdp->cmd_un.abort.icmdp->cmd_mutex);
1050fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp->
1051fcf3ce44SJohn Forte cmd_un.scsi.abort_icmdp = NULL;
1052fcf3ce44SJohn Forte cv_broadcast(&icmdp->cmd_un.abort.icmdp->
1053fcf3ce44SJohn Forte cmd_completion);
1054fcf3ce44SJohn Forte mutex_exit(&icmdp->cmd_un.abort.icmdp->cmd_mutex);
1055fcf3ce44SJohn Forte /*
1056fcf3ce44SJohn Forte * Nullify the abort command's pointer to its
1057fcf3ce44SJohn Forte * parent command. It does not have to complete its
1058fcf3ce44SJohn Forte * parent command because the parent command will
1059fcf3ce44SJohn Forte * also get an E7.
1060fcf3ce44SJohn Forte */
1061fcf3ce44SJohn Forte icmdp->cmd_un.abort.icmdp = NULL;
1062fcf3ce44SJohn Forte
1063d233de7eSJack Meng icmdp->cmd_misc_flags |=
1064d233de7eSJack Meng ISCSI_CMD_MISCFLAG_FREE;
1065fcf3ce44SJohn Forte break;
1066fcf3ce44SJohn Forte
1067fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET:
1068fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
1069fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
1070fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
1071fcf3ce44SJohn Forte /*
1072fcf3ce44SJohn Forte * If we are failing a ABORT we need
1073fcf3ce44SJohn Forte * to notify the tran_abort caller.
1074fcf3ce44SJohn Forte * It will free the memory associated
1075fcf3ce44SJohn Forte * with the cmd and notify caller.
1076fcf3ce44SJohn Forte */
1077fcf3ce44SJohn Forte
1078fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp,
1079fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED);
1080fcf3ce44SJohn Forte break;
1081fcf3ce44SJohn Forte
1082fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT:
1083fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
1084fcf3ce44SJohn Forte /*
1085fcf3ce44SJohn Forte * A connection problem and we attempted to
1086fcf3ce44SJohn Forte * logout? I guess we can just free the
1087fcf3ce44SJohn Forte * request. Someone has already pushed the
1088fcf3ce44SJohn Forte * connection state.
1089fcf3ce44SJohn Forte */
1090fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
1091fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
1092fcf3ce44SJohn Forte
1093fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp, ISCSI_STATUS_SUCCESS);
1094fcf3ce44SJohn Forte break;
1095fcf3ce44SJohn Forte
1096fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_TEXT:
1097fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
1098fcf3ce44SJohn Forte icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1099fcf3ce44SJohn Forte iscsi_sess_release_itt(isp, icmdp);
1100fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
1101fcf3ce44SJohn Forte
1102fcf3ce44SJohn Forte /*
1103fcf3ce44SJohn Forte * If a TEXT command fails, notify caller so
1104fcf3ce44SJohn Forte * it can free assocated command
1105fcf3ce44SJohn Forte */
1106fcf3ce44SJohn Forte ISCSI_CMD_ISSUE_CALLBACK(icmdp,
1107fcf3ce44SJohn Forte ISCSI_STATUS_CMD_FAILED);
1108fcf3ce44SJohn Forte break;
1109fcf3ce44SJohn Forte
1110fcf3ce44SJohn Forte default:
1111fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
1112fcf3ce44SJohn Forte ASSERT(FALSE);
1113fcf3ce44SJohn Forte break;
1114fcf3ce44SJohn Forte }
1115fcf3ce44SJohn Forte
1116fcf3ce44SJohn Forte ASSERT(!mutex_owned(&isp->sess_cmdsn_mutex));
1117fcf3ce44SJohn Forte break;
1118fcf3ce44SJohn Forte
111930e7468fSPeter Dunlap /* -E9: IDM is no longer processing this command */
112030e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E9:
112130e7468fSPeter Dunlap iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
112230e7468fSPeter Dunlap
112330e7468fSPeter Dunlap iscsi_task_cleanup(ISCSI_OP_SCSI_RSP, icmdp);
112430e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp);
112530e7468fSPeter Dunlap
11262b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_CMD_SET_REASON_STAT(icmdp, CMD_TRAN_ERR,
11272b79d384Sbing zhao - Sun Microsystems - Beijing China icmdp->cmd_un.scsi.pkt_stat);
112830e7468fSPeter Dunlap iscsi_enqueue_completed_cmd(isp, icmdp);
112930e7468fSPeter Dunlap break;
113030e7468fSPeter Dunlap
1131fcf3ce44SJohn Forte /* All other events are invalid for this state */
1132fcf3ce44SJohn Forte default:
1133fcf3ce44SJohn Forte ASSERT(FALSE);
1134fcf3ce44SJohn Forte }
1135fcf3ce44SJohn Forte }
1136fcf3ce44SJohn Forte
1137fcf3ce44SJohn Forte
1138fcf3ce44SJohn Forte /*
1139fcf3ce44SJohn Forte * iscsi_cmd_state_aborting -
1140fcf3ce44SJohn Forte *
1141fcf3ce44SJohn Forte */
1142fcf3ce44SJohn Forte static void
iscsi_cmd_state_aborting(iscsi_cmd_t * icmdp,iscsi_cmd_event_t event,void * arg)1143fcf3ce44SJohn Forte iscsi_cmd_state_aborting(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event, void *arg)
1144fcf3ce44SJohn Forte {
1145fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg;
114630e7468fSPeter Dunlap iscsi_cmd_t *a_icmdp;
1147fcf3ce44SJohn Forte
1148fcf3ce44SJohn Forte ASSERT(icmdp != NULL);
1149fcf3ce44SJohn Forte ASSERT(icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI);
1150fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_ABORTING);
1151fcf3ce44SJohn Forte ASSERT(isp != NULL);
1152fcf3ce44SJohn Forte ASSERT(mutex_owned(&icmdp->cmd_conn->conn_queue_active.mutex));
1153fcf3ce44SJohn Forte
1154fcf3ce44SJohn Forte /* switch on event change */
1155fcf3ce44SJohn Forte switch (event) {
1156fcf3ce44SJohn Forte /* -E3: Command was successfully completed */
1157fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E3:
1158fcf3ce44SJohn Forte /*
1159fcf3ce44SJohn Forte * Remove command from the aborting list
1160fcf3ce44SJohn Forte */
1161fcf3ce44SJohn Forte mutex_enter(&isp->sess_cmdsn_mutex);
1162fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
116330e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp);
1164fcf3ce44SJohn Forte mutex_exit(&isp->sess_cmdsn_mutex);
1165fcf3ce44SJohn Forte
1166fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp);
1167fcf3ce44SJohn Forte break;
1168fcf3ce44SJohn Forte
1169fcf3ce44SJohn Forte /* -E4: Command has been requested to abort */
1170fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E4:
1171fcf3ce44SJohn Forte /*
1172fcf3ce44SJohn Forte * An upper level driver might attempt to
1173fcf3ce44SJohn Forte * abort a command that we are already
1174fcf3ce44SJohn Forte * aborting due to a nop. Since we are
1175fcf3ce44SJohn Forte * already in the process of aborting
1176fcf3ce44SJohn Forte * ignore the request.
1177fcf3ce44SJohn Forte */
1178fcf3ce44SJohn Forte break;
1179fcf3ce44SJohn Forte
1180fcf3ce44SJohn Forte /* -E6: Command has timed out */
1181fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E6:
1182fcf3ce44SJohn Forte ASSERT(FALSE);
1183fcf3ce44SJohn Forte /*
1184fcf3ce44SJohn Forte * Timeouts should not occur on command in abort queue
1185fcf3ce44SJohn Forte * they are already be processed due to a timeout.
1186fcf3ce44SJohn Forte */
1187fcf3ce44SJohn Forte break;
1188fcf3ce44SJohn Forte
1189fcf3ce44SJohn Forte /* -E7: Connection has encountered a problem */
1190fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E7:
1191fcf3ce44SJohn Forte iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
119230e7468fSPeter Dunlap mutex_enter(&icmdp->cmd_conn->conn_queue_idm_aborting.mutex);
119330e7468fSPeter Dunlap iscsi_enqueue_idm_aborting_cmd(icmdp->cmd_conn, icmdp);
119430e7468fSPeter Dunlap mutex_exit(&icmdp->cmd_conn->conn_queue_idm_aborting.mutex);
1195fcf3ce44SJohn Forte
119630e7468fSPeter Dunlap /*
119730e7468fSPeter Dunlap * Since we are in "aborting" state there is another command
119830e7468fSPeter Dunlap * representing the abort of this command. This command
119930e7468fSPeter Dunlap * will cleanup at some indeterminate time after the call
120030e7468fSPeter Dunlap * to idm_task_abort so we can't leave the abort request
120130e7468fSPeter Dunlap * active. An E10 event to the abort command will cause
120230e7468fSPeter Dunlap * it to complete immediately.
120330e7468fSPeter Dunlap */
120430e7468fSPeter Dunlap if ((a_icmdp = icmdp->cmd_un.scsi.abort_icmdp) != NULL) {
120530e7468fSPeter Dunlap iscsi_cmd_state_machine(a_icmdp,
120630e7468fSPeter Dunlap ISCSI_CMD_EVENT_E10, arg);
120730e7468fSPeter Dunlap }
120830e7468fSPeter Dunlap
12092b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_CMD_SET_REASON_STAT(icmdp,
12102b79d384Sbing zhao - Sun Microsystems - Beijing China CMD_TRAN_ERR, icmdp->cmd_un.scsi.pkt_stat);
12112b79d384Sbing zhao - Sun Microsystems - Beijing China
1212*61dfa509SRick McNeal (void) idm_task_abort(icmdp->cmd_conn->conn_ic, icmdp->cmd_itp,
121330e7468fSPeter Dunlap AT_TASK_MGMT_ABORT);
121430e7468fSPeter Dunlap break;
121530e7468fSPeter Dunlap
121630e7468fSPeter Dunlap /* -E9: IDM is no longer processing this command */
121730e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E9:
121830e7468fSPeter Dunlap iscsi_dequeue_active_cmd(icmdp->cmd_conn, icmdp);
121930e7468fSPeter Dunlap
122030e7468fSPeter Dunlap iscsi_task_cleanup(ISCSI_OP_SCSI_RSP, icmdp);
122130e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp);
122230e7468fSPeter Dunlap
12232b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_CMD_SET_REASON_STAT(icmdp, CMD_TRAN_ERR,
12242b79d384Sbing zhao - Sun Microsystems - Beijing China icmdp->cmd_un.scsi.pkt_stat);
122530e7468fSPeter Dunlap iscsi_enqueue_completed_cmd(isp, icmdp);
122630e7468fSPeter Dunlap break;
122730e7468fSPeter Dunlap
122830e7468fSPeter Dunlap /* All other events are invalid for this state */
122930e7468fSPeter Dunlap default:
123030e7468fSPeter Dunlap ASSERT(FALSE);
123130e7468fSPeter Dunlap }
123230e7468fSPeter Dunlap }
123330e7468fSPeter Dunlap
123430e7468fSPeter Dunlap static void
iscsi_cmd_state_idm_aborting(iscsi_cmd_t * icmdp,iscsi_cmd_event_t event,void * arg)123530e7468fSPeter Dunlap iscsi_cmd_state_idm_aborting(iscsi_cmd_t *icmdp, iscsi_cmd_event_t event,
123630e7468fSPeter Dunlap void *arg)
123730e7468fSPeter Dunlap {
123830e7468fSPeter Dunlap iscsi_sess_t *isp = (iscsi_sess_t *)arg;
123930e7468fSPeter Dunlap
124030e7468fSPeter Dunlap ASSERT(icmdp != NULL);
124130e7468fSPeter Dunlap ASSERT(icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI);
124230e7468fSPeter Dunlap ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_IDM_ABORTING);
124330e7468fSPeter Dunlap ASSERT(isp != NULL);
124430e7468fSPeter Dunlap
124530e7468fSPeter Dunlap /* switch on event change */
124630e7468fSPeter Dunlap switch (event) {
124730e7468fSPeter Dunlap /* -E3: Command was successfully completed */
124830e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E3:
124930e7468fSPeter Dunlap /*
125030e7468fSPeter Dunlap * iscsi_rx_process_cmd_rsp() and iscsi_rx_process_data_rsp()
125130e7468fSPeter Dunlap * are supposed to confirm the cmd state is appropriate before
125230e7468fSPeter Dunlap * generating an E3 event. E3 is not allowed in this state.
125330e7468fSPeter Dunlap */
125430e7468fSPeter Dunlap ASSERT(0);
125530e7468fSPeter Dunlap break;
125630e7468fSPeter Dunlap
125730e7468fSPeter Dunlap /* -E4: Command has been requested to abort */
125830e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E4:
125930e7468fSPeter Dunlap /*
126030e7468fSPeter Dunlap * An upper level driver might attempt to
126130e7468fSPeter Dunlap * abort a command that we are already
126230e7468fSPeter Dunlap * aborting due to a nop. Since we are
126330e7468fSPeter Dunlap * already in the process of aborting
126430e7468fSPeter Dunlap * ignore the request.
126530e7468fSPeter Dunlap */
126630e7468fSPeter Dunlap break;
126730e7468fSPeter Dunlap
126830e7468fSPeter Dunlap /* -E6: Command has timed out */
126930e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E6:
127030e7468fSPeter Dunlap ASSERT(FALSE);
127130e7468fSPeter Dunlap /*
127230e7468fSPeter Dunlap * Timeouts should not occur on aborting commands
127330e7468fSPeter Dunlap */
127430e7468fSPeter Dunlap break;
127530e7468fSPeter Dunlap
127630e7468fSPeter Dunlap /* -E7: Connection has encountered a problem */
127730e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E7:
127830e7468fSPeter Dunlap /*
127930e7468fSPeter Dunlap * We have already requested IDM to stop processing this
12802b79d384Sbing zhao - Sun Microsystems - Beijing China * command so just update the pkt_statistics.
128130e7468fSPeter Dunlap */
12822b79d384Sbing zhao - Sun Microsystems - Beijing China ISCSI_CMD_SET_REASON_STAT(icmdp,
12832b79d384Sbing zhao - Sun Microsystems - Beijing China CMD_TRAN_ERR, icmdp->cmd_un.scsi.pkt_stat);
128430e7468fSPeter Dunlap break;
128530e7468fSPeter Dunlap
128630e7468fSPeter Dunlap /* -E9: IDM is no longer processing this command */
128730e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E9:
128830e7468fSPeter Dunlap mutex_enter(&icmdp->cmd_conn->conn_queue_idm_aborting.mutex);
128930e7468fSPeter Dunlap iscsi_dequeue_idm_aborting_cmd(icmdp->cmd_conn, icmdp);
129030e7468fSPeter Dunlap mutex_exit(&icmdp->cmd_conn->conn_queue_idm_aborting.mutex);
129130e7468fSPeter Dunlap
129230e7468fSPeter Dunlap /* This is always an error so make sure an error has been set */
129330e7468fSPeter Dunlap ASSERT(icmdp->cmd_un.scsi.pkt->pkt_reason != CMD_CMPLT);
129430e7468fSPeter Dunlap iscsi_task_cleanup(ISCSI_OP_SCSI_RSP, icmdp);
129530e7468fSPeter Dunlap iscsi_sess_release_scsi_itt(icmdp);
129630e7468fSPeter Dunlap
129730e7468fSPeter Dunlap /*
129830e7468fSPeter Dunlap * Whoever called idm_task_abort should have set the completion
129930e7468fSPeter Dunlap * status beforehand.
130030e7468fSPeter Dunlap */
1301fcf3ce44SJohn Forte iscsi_enqueue_completed_cmd(isp, icmdp);
130230e7468fSPeter Dunlap cv_broadcast(&icmdp->cmd_completion);
1303fcf3ce44SJohn Forte break;
1304fcf3ce44SJohn Forte
1305fcf3ce44SJohn Forte /* All other events are invalid for this state */
1306fcf3ce44SJohn Forte default:
1307fcf3ce44SJohn Forte ASSERT(FALSE);
1308fcf3ce44SJohn Forte }
1309fcf3ce44SJohn Forte }
1310fcf3ce44SJohn Forte
1311fcf3ce44SJohn Forte
1312fcf3ce44SJohn Forte /*
1313fcf3ce44SJohn Forte * iscsi_cmd_state_completed -
1314fcf3ce44SJohn Forte *
1315fcf3ce44SJohn Forte */
1316fcf3ce44SJohn Forte static void
iscsi_cmd_state_completed(iscsi_cmd_t * icmdp,iscsi_cmd_event_t event,void * arg)1317fcf3ce44SJohn Forte iscsi_cmd_state_completed(iscsi_cmd_t *icmdp,
1318fcf3ce44SJohn Forte iscsi_cmd_event_t event, void *arg)
1319fcf3ce44SJohn Forte {
1320fcf3ce44SJohn Forte iscsi_sess_t *isp = (iscsi_sess_t *)arg;
1321fcf3ce44SJohn Forte
1322fcf3ce44SJohn Forte ASSERT(icmdp != NULL);
1323fcf3ce44SJohn Forte ASSERT(icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI);
1324fcf3ce44SJohn Forte ASSERT(icmdp->cmd_state == ISCSI_CMD_STATE_COMPLETED);
1325fcf3ce44SJohn Forte ASSERT(isp != NULL);
1326fcf3ce44SJohn Forte
1327fcf3ce44SJohn Forte /* switch on event change */
1328fcf3ce44SJohn Forte switch (event) {
1329fcf3ce44SJohn Forte /* -E8: */
1330fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E8:
1331fcf3ce44SJohn Forte icmdp->cmd_state = ISCSI_CMD_STATE_FREE;
1332fcf3ce44SJohn Forte
1333fcf3ce44SJohn Forte /* the caller has already remove cmd from queue */
1334fcf3ce44SJohn Forte
1335fcf3ce44SJohn Forte icmdp->cmd_next = NULL;
1336fcf3ce44SJohn Forte icmdp->cmd_prev = NULL;
1337fcf3ce44SJohn Forte iscsi_iodone(isp, icmdp);
1338fcf3ce44SJohn Forte break;
1339fcf3ce44SJohn Forte /* All other events are invalid for this state */
1340fcf3ce44SJohn Forte default:
1341fcf3ce44SJohn Forte ASSERT(FALSE);
1342fcf3ce44SJohn Forte }
1343fcf3ce44SJohn Forte }
1344fcf3ce44SJohn Forte
1345fcf3ce44SJohn Forte
1346fcf3ce44SJohn Forte /*
1347fcf3ce44SJohn Forte * iscsi_cmd_state_str -
1348fcf3ce44SJohn Forte *
1349fcf3ce44SJohn Forte */
1350fcf3ce44SJohn Forte static char *
iscsi_cmd_state_str(iscsi_cmd_state_t state)1351fcf3ce44SJohn Forte iscsi_cmd_state_str(iscsi_cmd_state_t state)
1352fcf3ce44SJohn Forte {
1353fcf3ce44SJohn Forte switch (state) {
1354fcf3ce44SJohn Forte case ISCSI_CMD_STATE_FREE:
1355fcf3ce44SJohn Forte return ("free");
1356fcf3ce44SJohn Forte case ISCSI_CMD_STATE_PENDING:
1357fcf3ce44SJohn Forte return ("pending");
1358fcf3ce44SJohn Forte case ISCSI_CMD_STATE_ACTIVE:
1359fcf3ce44SJohn Forte return ("active");
1360fcf3ce44SJohn Forte case ISCSI_CMD_STATE_ABORTING:
1361fcf3ce44SJohn Forte return ("aborting");
136230e7468fSPeter Dunlap case ISCSI_CMD_STATE_IDM_ABORTING:
136330e7468fSPeter Dunlap return ("idm-aborting");
1364fcf3ce44SJohn Forte case ISCSI_CMD_STATE_COMPLETED:
1365fcf3ce44SJohn Forte return ("completed");
1366fcf3ce44SJohn Forte default:
1367fcf3ce44SJohn Forte return ("unknown");
1368fcf3ce44SJohn Forte }
1369fcf3ce44SJohn Forte }
1370fcf3ce44SJohn Forte
1371fcf3ce44SJohn Forte
1372fcf3ce44SJohn Forte /*
1373fcf3ce44SJohn Forte * iscsi_cmd_event_str -
1374fcf3ce44SJohn Forte *
1375fcf3ce44SJohn Forte */
1376fcf3ce44SJohn Forte static char *
iscsi_cmd_event_str(iscsi_cmd_event_t event)1377fcf3ce44SJohn Forte iscsi_cmd_event_str(iscsi_cmd_event_t event)
1378fcf3ce44SJohn Forte {
1379fcf3ce44SJohn Forte switch (event) {
1380fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E1:
1381fcf3ce44SJohn Forte return ("E1");
1382fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E2:
1383fcf3ce44SJohn Forte return ("E2");
1384fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E3:
1385fcf3ce44SJohn Forte return ("E3");
1386fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E4:
1387fcf3ce44SJohn Forte return ("E4");
1388fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E6:
1389fcf3ce44SJohn Forte return ("E6");
1390fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E7:
1391fcf3ce44SJohn Forte return ("E7");
1392fcf3ce44SJohn Forte case ISCSI_CMD_EVENT_E8:
1393fcf3ce44SJohn Forte return ("E8");
139430e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E9:
139530e7468fSPeter Dunlap return ("E9");
139630e7468fSPeter Dunlap case ISCSI_CMD_EVENT_E10:
139730e7468fSPeter Dunlap return ("E10");
1398fcf3ce44SJohn Forte default:
1399fcf3ce44SJohn Forte return ("unknown");
1400fcf3ce44SJohn Forte }
1401fcf3ce44SJohn Forte }
1402fcf3ce44SJohn Forte
1403fcf3ce44SJohn Forte
1404fcf3ce44SJohn Forte /*
1405fcf3ce44SJohn Forte * iscsi_cmd_event_str -
1406fcf3ce44SJohn Forte *
1407fcf3ce44SJohn Forte */
1408fcf3ce44SJohn Forte static char *
iscsi_cmd_type_str(iscsi_cmd_type_t type)1409fcf3ce44SJohn Forte iscsi_cmd_type_str(iscsi_cmd_type_t type)
1410fcf3ce44SJohn Forte {
1411fcf3ce44SJohn Forte switch (type) {
1412fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_SCSI:
1413fcf3ce44SJohn Forte return ("scsi");
1414fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_NOP:
1415fcf3ce44SJohn Forte return ("nop");
1416fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_ABORT:
1417fcf3ce44SJohn Forte return ("abort");
1418fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_RESET:
1419fcf3ce44SJohn Forte return ("reset");
1420fcf3ce44SJohn Forte case ISCSI_CMD_TYPE_LOGOUT:
1421fcf3ce44SJohn Forte return ("logout");
1422fcf3ce44SJohn Forte default:
1423fcf3ce44SJohn Forte return ("unknown");
1424fcf3ce44SJohn Forte }
1425fcf3ce44SJohn Forte }
1426