1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2000 by Cisco Systems, Inc.  All rights reserved.
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * iSCSI Pseudo HBA Driver
27  */
28 
29 #include <sys/socket.h>		/* networking stuff */
30 #include <sys/t_kuser.h>	/* networking stuff */
31 #include <sys/tihdr.h>		/* networking stuff */
32 #include <sys/strsubr.h>	/* networking stuff */
33 #include <netinet/tcp.h>	/* TCP_NODELAY */
34 #include <sys/socketvar.h>	/* _ALLOC_SLEEP */
35 #include <sys/strsun.h>		/* DB_TYPE() */
36 #include <sys/scsi/generic/sense.h>
37 
38 #include "iscsi.h"		/* iscsi driver */
39 #include <sys/iscsi_protocol.h>	/* iscsi protocol */
40 
41 #define	ISCSI_INI_TASK_TTT	0xffffffff
42 #define	ISCSI_CONN_TIEMOUT_DETECT	20
43 
44 boolean_t iscsi_io_logging = B_FALSE;
45 
46 #define	ISCSI_CHECK_SCSI_READ(ICHK_CMD, ICHK_HDR, ICHK_LEN, ICHK_TYPE)	\
47 	if (idm_pattern_checking)  {					\
48 		struct scsi_pkt *pkt = (ICHK_CMD)->cmd_un.scsi.pkt;	\
49 		if (((ICHK_HDR)->response == 0) && 			\
50 		    ((ICHK_HDR)->cmd_status == 0) &&			\
51 		    ((pkt->pkt_cdbp[0] == SCMD_READ_G1) ||		\
52 		    (pkt->pkt_cdbp[0] == SCMD_READ_G4) || 		\
53 		    (pkt->pkt_cdbp[0] == SCMD_READ) || 			\
54 		    (pkt->pkt_cdbp[0] == SCMD_READ_G5))) {		\
55 			idm_buf_t *idb = (ICHK_CMD)->cmd_un.scsi.ibp_ibuf; \
56 			IDM_BUFPAT_CHECK(idb, ICHK_LEN, ICHK_TYPE); \
57 		}						\
58 	}
59 
60 /* generic io helpers */
61 static uint32_t n2h24(uchar_t *ptr);
62 static int iscsi_sna_lt(uint32_t n1, uint32_t n2);
63 void iscsi_update_flow_control(iscsi_sess_t *isp,
64     uint32_t max, uint32_t exp);
65 static iscsi_status_t iscsi_rx_process_scsi_itt_to_icmdp(iscsi_sess_t *isp,
66     idm_conn_t *ic, iscsi_scsi_rsp_hdr_t *ihp, iscsi_cmd_t **icmdp);
67 static iscsi_status_t iscsi_rx_process_itt_to_icmdp(iscsi_sess_t *isp,
68     iscsi_hdr_t *ihp, iscsi_cmd_t **icmdp);
69 static void iscsi_process_rsp_status(iscsi_sess_t *isp, iscsi_conn_t *icp,
70     idm_status_t status);
71 static void iscsi_drop_conn_cleanup(iscsi_conn_t *icp);
72 static boolean_t iscsi_nop_timeout_checks(iscsi_cmd_t *icmdp);
73 /* callbacks from idm */
74 static idm_pdu_cb_t iscsi_tx_done;
75 
76 /* receivers */
77 static idm_status_t iscsi_rx_process_nop(idm_conn_t *ic, idm_pdu_t *pdu);
78 static idm_status_t iscsi_rx_process_data_rsp(idm_conn_t *ic,
79     idm_pdu_t *pdu);
80 static idm_status_t iscsi_rx_process_cmd_rsp(idm_conn_t *ic, idm_pdu_t *pdu);
81 static idm_status_t iscsi_rx_process_reject_rsp(idm_conn_t *ic,
82     idm_pdu_t *pdu);
83 
84 static idm_status_t iscsi_rx_process_rejected_tsk_mgt(idm_conn_t *ic,
85     iscsi_hdr_t *old_ihp);
86 static idm_status_t iscsi_rx_process_task_mgt_rsp(idm_conn_t *ic,
87     idm_pdu_t *pdu);
88 static idm_status_t iscsi_rx_process_logout_rsp(idm_conn_t *ic,
89     idm_pdu_t *pdu);
90 static idm_status_t iscsi_rx_process_async_rsp(idm_conn_t *ic,
91     idm_pdu_t *pdu);
92 static idm_status_t iscsi_rx_process_text_rsp(idm_conn_t *ic,
93     idm_pdu_t *pdu);
94 
95 /* senders */
96 static iscsi_status_t iscsi_tx_scsi(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
97 static iscsi_status_t iscsi_tx_nop(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
98 static iscsi_status_t iscsi_tx_abort(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
99 static iscsi_status_t iscsi_tx_reset(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
100 static iscsi_status_t iscsi_tx_logout(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
101 static iscsi_status_t iscsi_tx_text(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
102 
103 
104 /* helpers */
105 static void iscsi_logout_start(void *arg);
106 static void iscsi_handle_passthru_callback(struct scsi_pkt *pkt);
107 static void iscsi_handle_nop(iscsi_conn_t *icp, uint32_t itt, uint32_t ttt);
108 
109 static void iscsi_timeout_checks(iscsi_sess_t *isp);
110 static void iscsi_nop_checks(iscsi_sess_t *isp);
111 static boolean_t iscsi_decode_sense(uint8_t *sense_data);
112 static void iscsi_flush_cmd_after_reset(uint32_t cmd_sn, uint16_t lun_num,
113     iscsi_conn_t *icp);
114 
115 /*
116  * This file contains the main guts of the iSCSI protocol layer.
117  * It's broken into 5 sections; Basic helper functions, RX IO path,
118  * TX IO path, Completion (IC) IO path, and watchdog (WD) routines.
119  *
120  * The IO flow model is similiar to the below diagram.  The
121  * iscsi session, connection and command state machines are used
122  * to drive IO through this flow diagram.  Reference those files
123  * to get a detailed description of their respective state models
124  * prior to their xxx_state_machine_function().
125  *
126  * tran_start() -> CMD_E1     TX_THREAD                   RX_THREAD
127  *                   |            T                           T
128  *                   V            T                           T
129  *                PENDING_Q  --CMD_E2--> ACTIVE_Q -      --CMD_E3--+
130  *                                T                \ C        T    |
131  *                                T                 \M        T    |
132  *                                                   D        T    |
133  *                                       WD_THREAD TT|TT      T    |
134  *                                                  /E        T    |
135  *                                                 / 6        T    |
136  *                                     ABORTING_Q<-      --CMD_E3--+
137  *                                                            T    |
138  *                                T                           T    |
139  *                                T                                |
140  *               callback()  <--CMD_E#-- COMPLETION_Q <------------+
141  *                                T
142  *                                T
143  *                            IC_THREAD
144  *
145  * External and internal command are ran thru this same state
146  * machine.  All commands enter the state machine by receiving an
147  * ISCSI_CMD_EVENT_E1.  This event places the command into the
148  * PENDING_Q.  Next when resources are available the TX_THREAD
149  * issues a E2 event on the command.  This sends the command
150  * to the TCP stack and places the command on the ACTIVE_Q.  While
151  * on the PENDIING_Q and ACTIVE_Q, the command is monitored via the
152  * WD_THREAD to ensure the pkt_time has not elapsed.  If elapsed the
153  * command is issued an E6(timeout) event which moves either (if pending)
154  * completed the command or (if active) moves the command to the
155  * aborting queue and issues a SCSI TASK MANAGEMENT ABORT command
156  * to cancel the IO request.  If the original command is completed
157  * or the TASK MANAGEMENT command completes the command is moved
158  * to the COMPLETION_Q via a E3 event.  The IC_THREAD then processes
159  * the COMPLETION_Q and issues the scsi_pkt callback.  This
160  * callback can not be processed directly from the RX_THREAD
161  * because the callback might call back into the iscsi driver
162  * causing a deadlock condition.
163  *
164  * For more details on the complete CMD state machine reference
165  * the state machine diagram in iscsi_cmd.c.  The connection state
166  * machine is driven via IO events in this file.  Then session
167  * events are driven by the connection events.  For complete
168  * details on these state machines reference iscsi_sess.c and
169  * iscsi_conn.c
170  */
171 
172 
173 /*
174  * +--------------------------------------------------------------------+
175  * | io helper routines							|
176  * +--------------------------------------------------------------------+
177  */
178 
179 /*
180  * n2h24 - native to host 24 bit integer translation.
181  */
182 static uint32_t
183 n2h24(uchar_t *ptr)
184 {
185 	uint32_t idx;
186 	bcopy(ptr, &idx, 3);
187 	return (ntohl(idx) >> 8);
188 }
189 
190 /*
191  * iscsi_sna_lt - Serial Number Arithmetic, 32 bits, less than, RFC1982
192  */
193 static int
194 iscsi_sna_lt(uint32_t n1, uint32_t n2)
195 {
196 	return ((n1 != n2) &&
197 	    (((n1 < n2) && ((n2 - n1) < ISCSI_SNA32_CHECK)) ||
198 	    ((n1 > n2) && ((n1 - n2) > ISCSI_SNA32_CHECK))));
199 }
200 
201 /*
202  * iscsi_sna_lte - Serial Number Arithmetic, 32 bits, less than or equal,
203  * RFC1982
204  */
205 int
206 iscsi_sna_lte(uint32_t n1, uint32_t n2)
207 {
208 	return ((n1 == n2) ||
209 	    (((n1 < n2) && ((n2 - n1) < ISCSI_SNA32_CHECK)) ||
210 	    ((n1 > n2) && ((n1 - n2) > ISCSI_SNA32_CHECK))));
211 }
212 
213 /*
214  * iscsi_update_flow_control - Update expcmdsn and maxcmdsn iSCSI
215  * flow control information for a session
216  */
217 void
218 iscsi_update_flow_control(iscsi_sess_t *isp, uint32_t max, uint32_t exp)
219 {
220 	ASSERT(isp != NULL);
221 	ASSERT(mutex_owned(&isp->sess_cmdsn_mutex));
222 
223 	if (!iscsi_sna_lt(max, (exp - 1))) {
224 
225 		if (!iscsi_sna_lte(exp, isp->sess_expcmdsn)) {
226 			isp->sess_expcmdsn = exp;
227 		}
228 
229 		if (!iscsi_sna_lte(max, isp->sess_maxcmdsn)) {
230 			isp->sess_maxcmdsn = max;
231 			if (iscsi_sna_lte(isp->sess_cmdsn,
232 			    isp->sess_maxcmdsn)) {
233 				/*
234 				 * the window is open again - schedule
235 				 * to send any held tasks soon
236 				 */
237 				iscsi_sess_redrive_io(isp);
238 			}
239 		}
240 	}
241 }
242 
243 
244 /*
245  * +--------------------------------------------------------------------+
246  * | io receive and processing routines					|
247  * +--------------------------------------------------------------------+
248  */
249 
250 /*
251  * iscsi_rx_scsi_rsp - called from idm
252  * For each opcode type fan out the processing.
253  */
254 void
255 iscsi_rx_scsi_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
256 {
257 	iscsi_conn_t	*icp;
258 	iscsi_sess_t	*isp;
259 	iscsi_hdr_t	*ihp;
260 	idm_status_t	status;
261 
262 	ASSERT(ic != NULL);
263 	ASSERT(pdu != NULL);
264 	icp		= ic->ic_handle;
265 	ASSERT(icp != NULL);
266 	ihp		= (iscsi_hdr_t *)pdu->isp_hdr;
267 	ASSERT(ihp != NULL);
268 	isp		= icp->conn_sess;
269 	ASSERT(isp != NULL);
270 
271 	/* reset the session timer when we receive the response */
272 	isp->sess_rx_lbolt = icp->conn_rx_lbolt = ddi_get_lbolt();
273 
274 	/* fan out the hdr processing */
275 	switch (ihp->opcode & ISCSI_OPCODE_MASK) {
276 	case ISCSI_OP_SCSI_DATA_RSP:
277 		status = iscsi_rx_process_data_rsp(ic, pdu);
278 		break;
279 	case ISCSI_OP_SCSI_RSP:
280 		status = iscsi_rx_process_cmd_rsp(ic, pdu);
281 		idm_pdu_complete(pdu, status);
282 		break;
283 	default:
284 		cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
285 		    "received pdu with unsupported opcode 0x%02x",
286 		    icp->conn_oid, ihp->opcode);
287 		status = IDM_STATUS_PROTOCOL_ERROR;
288 	}
289 	iscsi_process_rsp_status(isp, icp, status);
290 }
291 
292 void
293 iscsi_task_cleanup(int opcode, iscsi_cmd_t *icmdp)
294 {
295 	struct buf 	*bp;
296 	idm_buf_t	*ibp, *obp;
297 	idm_task_t	*itp;
298 
299 	itp = icmdp->cmd_itp;
300 	ASSERT(itp != NULL);
301 	ASSERT((opcode == ISCSI_OP_SCSI_DATA_RSP) ||
302 	    (opcode == ISCSI_OP_SCSI_RSP));
303 
304 	bp = icmdp->cmd_un.scsi.bp;
305 	ibp = icmdp->cmd_un.scsi.ibp_ibuf;
306 	obp = icmdp->cmd_un.scsi.ibp_obuf;
307 	ISCSI_IO_LOG(CE_NOTE, "DEBUG: task_cleanup: itp: %p opcode: %d "
308 	    "icmdp: %p bp: %p ibp: %p", (void *)itp, opcode,
309 	    (void *)icmdp, (void *)bp, (void *)ibp);
310 	if (bp && bp->b_bcount) {
311 		if (ibp != NULL && bp->b_flags & B_READ) {
312 			idm_buf_unbind_in(itp, ibp);
313 			idm_buf_free(ibp);
314 			icmdp->cmd_un.scsi.ibp_ibuf = NULL;
315 		} else if (obp != NULL && !(bp->b_flags & B_READ)) {
316 			idm_buf_unbind_out(itp, obp);
317 			idm_buf_free(obp);
318 			icmdp->cmd_un.scsi.ibp_obuf = NULL;
319 		}
320 	}
321 
322 	idm_task_done(itp);
323 }
324 
325 idm_status_t
326 iscsi_rx_chk(iscsi_conn_t *icp, iscsi_sess_t *isp,
327     iscsi_scsi_rsp_hdr_t *irhp, iscsi_cmd_t **icmdp)
328 {
329 	iscsi_status_t rval;
330 
331 	mutex_enter(&isp->sess_cmdsn_mutex);
332 
333 	if (icp->conn_expstatsn == ntohl(irhp->statsn)) {
334 		icp->conn_expstatsn++;
335 	} else {
336 		cmn_err(CE_WARN, "iscsi connection(%u/%x) protocol error - "
337 		    "received status out of order itt:0x%x statsn:0x%x "
338 		    "expstatsn:0x%x", icp->conn_oid, irhp->opcode,
339 		    irhp->itt, ntohl(irhp->statsn), icp->conn_expstatsn);
340 		mutex_exit(&isp->sess_cmdsn_mutex);
341 		return (IDM_STATUS_PROTOCOL_ERROR);
342 	}
343 
344 	/* get icmdp so we can cleanup on error */
345 	if ((irhp->opcode == ISCSI_OP_SCSI_DATA_RSP) ||
346 	    (irhp->opcode == ISCSI_OP_SCSI_RSP)) {
347 		rval = iscsi_rx_process_scsi_itt_to_icmdp(isp, icp->conn_ic,
348 		    irhp, icmdp);
349 	} else {
350 		rval = iscsi_rx_process_itt_to_icmdp(isp,
351 		    (iscsi_hdr_t *)irhp, icmdp);
352 	}
353 
354 	if (!ISCSI_SUCCESS(rval)) {
355 		mutex_exit(&isp->sess_cmdsn_mutex);
356 		return (IDM_STATUS_PROTOCOL_ERROR);
357 	}
358 
359 	/* update expcmdsn and maxcmdsn */
360 	iscsi_update_flow_control(isp, ntohl(irhp->maxcmdsn),
361 	    ntohl(irhp->expcmdsn));
362 	mutex_exit(&isp->sess_cmdsn_mutex);
363 	return (IDM_STATUS_SUCCESS);
364 }
365 
366 static void
367 iscsi_cmd_rsp_chk(iscsi_cmd_t *icmdp, iscsi_scsi_rsp_hdr_t *issrhp)
368 {
369 	struct scsi_pkt *pkt;
370 	size_t data_transferred;
371 
372 	pkt = icmdp->cmd_un.scsi.pkt;
373 	pkt->pkt_resid = 0;
374 	data_transferred = icmdp->cmd_un.scsi.data_transferred;
375 	/* Check the residual count */
376 	if ((icmdp->cmd_un.scsi.bp) &&
377 	    (data_transferred != icmdp->cmd_un.scsi.bp->b_bcount)) {
378 		/*
379 		 * We didn't xfer the expected amount of data -
380 		 * the residual_count in the header is only
381 		 * valid if the underflow flag is set.
382 		 */
383 		if (issrhp->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
384 			pkt->pkt_resid = ntohl(issrhp->residual_count);
385 		} else {
386 			if (icmdp->cmd_un.scsi.bp->b_bcount >
387 			    data_transferred) {
388 				/*
389 				 * Some data fell on the floor
390 				 * somehow - probably a CRC error
391 				 */
392 				pkt->pkt_resid =
393 				    icmdp->cmd_un.scsi.bp->b_bcount -
394 				    data_transferred;
395 			}
396 		}
397 		ISCSI_IO_LOG(CE_NOTE,
398 		    "DEBUG: iscsi_rx_cmd_rsp_chk: itt: %u"
399 		    "data_trans != b_count data_transferred: %lu "
400 		    "b_count: %lu cmd_status: %d flags: %d resid: %lu",
401 		    issrhp->itt, data_transferred,
402 		    icmdp->cmd_un.scsi.bp->b_bcount,
403 		    issrhp->cmd_status & STATUS_MASK,
404 		    issrhp->flags, pkt->pkt_resid);
405 	}
406 	/* set flags that tell SCSA that the command is complete */
407 	if (icmdp->cmd_crc_error_seen == B_FALSE) {
408 		/* Set successful completion */
409 		pkt->pkt_reason = CMD_CMPLT;
410 		if (icmdp->cmd_un.scsi.bp) {
411 			pkt->pkt_state |= (STATE_XFERRED_DATA |
412 			    STATE_GOT_STATUS);
413 		} else {
414 			pkt->pkt_state |= STATE_GOT_STATUS;
415 		}
416 	} else {
417 		/*
418 		 * Some of the data was found to have an incorrect
419 		 * error at the protocol error.
420 		 */
421 		pkt->pkt_reason = CMD_PER_FAIL;
422 		pkt->pkt_statistics |= STAT_PERR;
423 		if (icmdp->cmd_un.scsi.bp) {
424 			pkt->pkt_resid =
425 			    icmdp->cmd_un.scsi.bp->b_bcount;
426 		} else {
427 			pkt->pkt_resid = 0;
428 		}
429 	}
430 }
431 
432 static boolean_t
433 iscsi_cmd_rsp_cmd_status(iscsi_cmd_t *icmdp, iscsi_scsi_rsp_hdr_t *issrhp,
434     uint8_t *data)
435 {
436 	int32_t			dlength		= 0;
437 	struct scsi_arq_status	*arqstat	= NULL;
438 	size_t			senselen	= 0;
439 	int32_t			statuslen	= 0;
440 	int32_t			senselen_to	= 0;
441 	struct scsi_pkt		*pkt;
442 	boolean_t		affect		= B_FALSE;
443 
444 	pkt = icmdp->cmd_un.scsi.pkt;
445 	dlength = n2h24(issrhp->dlength);
446 
447 	/*
448 	 * Process iSCSI Cmd Response Status
449 	 * RFC 3720 Sectionn 10.4.2.
450 	 */
451 	switch (issrhp->cmd_status & STATUS_MASK) {
452 	case STATUS_GOOD:
453 		/* pass SCSI status up stack */
454 		if (pkt->pkt_scbp) {
455 			pkt->pkt_scbp[0] = issrhp->cmd_status;
456 		}
457 		break;
458 	case STATUS_CHECK:
459 		/*
460 		 * Verify we received a sense buffer and
461 		 * that there is the correct amount of
462 		 * request sense space to copy it to.
463 		 */
464 		if ((dlength > 1) &&
465 		    (pkt->pkt_scbp != NULL) &&
466 		    (icmdp->cmd_un.scsi.statuslen >=
467 		    sizeof (struct scsi_arq_status))) {
468 			/*
469 			 * If a bad command status is received we
470 			 * need to reset the pkt_resid to zero.
471 			 * The target driver compares its value
472 			 * before checking other error flags.
473 			 * (ex. check conditions)
474 			 */
475 			pkt->pkt_resid = 0;
476 
477 			/* get sense length from first 2 bytes */
478 			senselen = ((data[0] << 8) | data[1]) &
479 			    (size_t)0xFFFF;
480 			ISCSI_IO_LOG(CE_NOTE,
481 			    "DEBUG: iscsi_rx_cmd_rsp_cmd_status status_check: "
482 			    "dlen: %d scbp: %p statuslen: %d arq: %d senselen:"
483 			    " %lu", dlength, (void *)pkt->pkt_scbp,
484 			    icmdp->cmd_un.scsi.statuslen,
485 			    (int)sizeof (struct scsi_arq_status),
486 			    senselen);
487 
488 			/* Sanity-check on the sense length */
489 			if ((senselen + 2) > dlength) {
490 				senselen = dlength - 2;
491 			}
492 
493 			/*
494 			 * If there was a Data Digest error then
495 			 * the sense data cannot be trusted.
496 			 */
497 			if (icmdp->cmd_crc_error_seen) {
498 				senselen = 0;
499 			}
500 
501 			/* automatic request sense */
502 			arqstat =
503 			    (struct scsi_arq_status *)pkt->pkt_scbp;
504 
505 			/* pass SCSI status up stack */
506 			*((uchar_t *)&arqstat->sts_status) =
507 			    issrhp->cmd_status;
508 
509 			/*
510 			 * Set the status for the automatic
511 			 * request sense command
512 			 */
513 			arqstat->sts_rqpkt_state = (STATE_GOT_BUS |
514 			    STATE_GOT_TARGET | STATE_SENT_CMD |
515 			    STATE_XFERRED_DATA | STATE_GOT_STATUS |
516 			    STATE_ARQ_DONE);
517 
518 			*((uchar_t *)&arqstat->sts_rqpkt_status) =
519 			    STATUS_GOOD;
520 
521 			arqstat->sts_rqpkt_reason = CMD_CMPLT;
522 			statuslen = icmdp->cmd_un.scsi.statuslen;
523 
524 			if (senselen == 0) {
525 				/* auto request sense failed */
526 				arqstat->sts_rqpkt_status.sts_chk = 1;
527 				arqstat->sts_rqpkt_resid = statuslen;
528 			} else if (senselen < statuslen) {
529 				/* auto request sense short */
530 				arqstat->sts_rqpkt_resid = statuslen - senselen;
531 			} else {
532 				/* auto request sense complete */
533 				arqstat->sts_rqpkt_resid = 0;
534 			}
535 			arqstat->sts_rqpkt_statistics = 0;
536 			pkt->pkt_state |= STATE_ARQ_DONE;
537 
538 			if (icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_XARQ) {
539 				pkt->pkt_state |= STATE_XARQ_DONE;
540 			}
541 
542 			senselen_to =  pkt->pkt_scblen -
543 			    sizeof (struct scsi_arq_status) +
544 			    sizeof (struct scsi_extended_sense);
545 
546 			/* copy auto request sense */
547 			dlength = min(senselen, senselen_to);
548 			if (dlength > 0) {
549 				bcopy(&data[2], (uchar_t *)&arqstat->
550 				    sts_sensedata, dlength);
551 
552 				affect = iscsi_decode_sense(
553 				    (uint8_t *)&arqstat->sts_sensedata);
554 			}
555 			break;
556 		}
557 		/* FALLTHRU */
558 	case STATUS_BUSY:
559 	case STATUS_RESERVATION_CONFLICT:
560 	case STATUS_QFULL:
561 	case STATUS_ACA_ACTIVE:
562 	default:
563 		/*
564 		 * If a bad command status is received we need to
565 		 * reset the pkt_resid to zero.  The target driver
566 		 * compares its value before checking other error
567 		 * flags. (ex. check conditions)
568 		 */
569 		ISCSI_IO_LOG(CE_NOTE,
570 		    "DEBUG: iscsi_rx_cmd_rsp_cmd_status: status: "
571 		    "%d cmd_status: %d dlen: %u scbp: %p statuslen: %d "
572 		    "arg_len: %d", issrhp->cmd_status & STATUS_MASK,
573 		    issrhp->cmd_status, dlength, (void *)pkt->pkt_scbp,
574 		    icmdp->cmd_un.scsi.statuslen,
575 		    (int)sizeof (struct scsi_arq_status));
576 		pkt->pkt_resid = 0;
577 		/* pass SCSI status up stack */
578 		if (pkt->pkt_scbp) {
579 			pkt->pkt_scbp[0] = issrhp->cmd_status;
580 		}
581 	}
582 
583 	return (affect);
584 }
585 
586 /*
587  * iscsi_rx_process_login_pdup - Process login response PDU.  This function
588  * copies the data into the connection context so that the login code can
589  * interpret it.
590  */
591 
592 idm_status_t
593 iscsi_rx_process_login_pdu(idm_conn_t *ic, idm_pdu_t *pdu)
594 {
595 	iscsi_conn_t 		*icp;
596 
597 	icp = ic->ic_handle;
598 
599 	/*
600 	 * Copy header and data into connection structure so iscsi_login()
601 	 * can process it.
602 	 */
603 	mutex_enter(&icp->conn_login_mutex);
604 	/*
605 	 * If conn_login_state != LOGIN_TX then we are not ready to handle
606 	 * this login response and we should just  drop it.
607 	 */
608 	if (icp->conn_login_state == LOGIN_TX) {
609 		icp->conn_login_datalen = pdu->isp_datalen;
610 		bcopy(pdu->isp_hdr, &icp->conn_login_resp_hdr,
611 		    sizeof (iscsi_hdr_t));
612 		/*
613 		 * Login code is sloppy with it's NULL handling so make sure
614 		 * we don't leave any stale data in there.
615 		 */
616 		bzero(icp->conn_login_data, icp->conn_login_max_data_length);
617 		bcopy(pdu->isp_data, icp->conn_login_data,
618 		    MIN(pdu->isp_datalen, icp->conn_login_max_data_length));
619 		iscsi_login_update_state_locked(icp, LOGIN_RX);
620 	}
621 	mutex_exit(&icp->conn_login_mutex);
622 
623 	return (IDM_STATUS_SUCCESS);
624 }
625 
626 /*
627  * iscsi_rx_process_cmd_rsp - Process received scsi command response.  This
628  * will contain sense data if the command was not successful.  This data needs
629  * to be copied into the scsi_pkt.  Otherwise we just complete the IO.
630  */
631 static idm_status_t
632 iscsi_rx_process_cmd_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
633 {
634 	iscsi_conn_t		*icp	= ic->ic_handle;
635 	iscsi_sess_t		*isp	= icp->conn_sess;
636 	iscsi_scsi_rsp_hdr_t	*issrhp	= (iscsi_scsi_rsp_hdr_t *)pdu->isp_hdr;
637 	uint8_t			*data	= pdu->isp_data;
638 	iscsi_cmd_t		*icmdp	= NULL;
639 	struct scsi_pkt		*pkt	= NULL;
640 	idm_status_t		rval;
641 	struct buf		*bp;
642 	boolean_t		flush	= B_FALSE;
643 	uint32_t		cmd_sn	= 0;
644 	uint16_t		lun_num = 0;
645 
646 	/* make sure we get status in order */
647 	mutex_enter(&icp->conn_queue_active.mutex);
648 
649 	if ((rval = iscsi_rx_chk(icp, isp, issrhp,
650 	    &icmdp)) != IDM_STATUS_SUCCESS) {
651 		if (icmdp != NULL) {
652 			iscsi_task_cleanup(issrhp->opcode, icmdp);
653 		}
654 		mutex_exit(&icp->conn_queue_active.mutex);
655 		return (rval);
656 	}
657 
658 	/*
659 	 * If we are in "idm aborting" state then we shouldn't continue
660 	 * to process this command.  By definition this command is no longer
661 	 * on the active queue so we shouldn't try to remove it either.
662 	 */
663 	mutex_enter(&icmdp->cmd_mutex);
664 	if (icmdp->cmd_state == ISCSI_CMD_STATE_IDM_ABORTING) {
665 		mutex_exit(&icmdp->cmd_mutex);
666 		mutex_exit(&icp->conn_queue_active.mutex);
667 		return (IDM_STATUS_SUCCESS);
668 	}
669 	mutex_exit(&icmdp->cmd_mutex);
670 
671 	/* Get the IDM buffer and bytes transferred */
672 	bp = icmdp->cmd_un.scsi.bp;
673 	if (ic->ic_conn_flags & IDM_CONN_USE_SCOREBOARD) {
674 		/* Transport tracks bytes transferred so use those counts */
675 		if (bp && (bp->b_flags & B_READ)) {
676 			icmdp->cmd_un.scsi.data_transferred +=
677 			    icmdp->cmd_itp->idt_rx_bytes;
678 		} else {
679 			icmdp->cmd_un.scsi.data_transferred +=
680 			    icmdp->cmd_itp->idt_tx_bytes;
681 		}
682 	} else {
683 		/*
684 		 * Some transports cannot track the bytes transferred on
685 		 * the initiator side (like iSER) so we have to use the
686 		 * status info.  If the response field indicates that
687 		 * the command actually completed then we will assume
688 		 * the data_transferred value represents the entire buffer
689 		 * unless the resid field says otherwise.  This is a bit
690 		 * unintuitive but it's really impossible to know what
691 		 * has been transferred without detailed consideration
692 		 * of the SCSI status and sense key and that is outside
693 		 * the scope of the transport.  Instead the target/class driver
694 		 * can consider these values along with the resid and figure
695 		 * it out.  The data_transferred concept is just belt and
696 		 * suspenders anyway -- RFC 3720 actually explicitly rejects
697 		 * scoreboarding ("Initiators SHOULD NOT keep track of the
698 		 * data transferred to or from the target (scoreboarding)")
699 		 * perhaps for this very reason.
700 		 */
701 		if (issrhp->response != 0) {
702 			icmdp->cmd_un.scsi.data_transferred = 0;
703 		} else {
704 			icmdp->cmd_un.scsi.data_transferred =
705 			    (bp == NULL) ? 0 : bp->b_bcount;
706 			if (issrhp->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
707 				icmdp->cmd_un.scsi.data_transferred -=
708 				    ntohl(issrhp->residual_count);
709 			}
710 		}
711 	}
712 
713 	ISCSI_CHECK_SCSI_READ(icmdp, issrhp,
714 	    icmdp->cmd_un.scsi.data_transferred,
715 	    BP_CHECK_THOROUGH);
716 
717 	ISCSI_IO_LOG(CE_NOTE, "DEBUG: rx_process_cmd_rsp: ic: %p pdu: %p itt:"
718 	    " %x expcmdsn: %x sess_cmd: %x sess_expcmdsn: %x data_transfered:"
719 	    " %lu ibp: %p obp: %p", (void *)ic, (void *)pdu, issrhp->itt,
720 	    issrhp->expcmdsn, isp->sess_cmdsn, isp->sess_expcmdsn,
721 	    icmdp->cmd_un.scsi.data_transferred,
722 	    (void *)icmdp->cmd_un.scsi.ibp_ibuf,
723 	    (void *)icmdp->cmd_un.scsi.ibp_obuf);
724 
725 	iscsi_task_cleanup(issrhp->opcode, icmdp);
726 
727 	if (issrhp->response) {
728 		/* The target failed the command. */
729 		ISCSI_IO_LOG(CE_NOTE, "DEBUG: rx_process_cmd_rsp: ic: %p pdu:"
730 		    " %p response: %d bcount: %lu", (void *)ic, (void *)pdu,
731 		    issrhp->response, icmdp->cmd_un.scsi.bp->b_bcount);
732 		pkt = icmdp->cmd_un.scsi.pkt;
733 		pkt->pkt_reason = CMD_TRAN_ERR;
734 		if (icmdp->cmd_un.scsi.bp) {
735 			pkt->pkt_resid = icmdp->cmd_un.scsi.bp->b_bcount;
736 		} else {
737 			pkt->pkt_resid = 0;
738 		}
739 	} else {
740 		/* success */
741 		iscsi_cmd_rsp_chk(icmdp, issrhp);
742 		flush = iscsi_cmd_rsp_cmd_status(icmdp, issrhp, data);
743 		if (flush == B_TRUE) {
744 			cmd_sn = icmdp->cmd_sn;
745 			ASSERT(icmdp->cmd_lun != NULL);
746 			lun_num = icmdp->cmd_lun->lun_num;
747 		}
748 	}
749 
750 	iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
751 	if (flush == B_TRUE) {
752 		iscsi_flush_cmd_after_reset(cmd_sn, lun_num, icp);
753 	}
754 	mutex_exit(&icp->conn_queue_active.mutex);
755 	return (IDM_STATUS_SUCCESS);
756 }
757 
758 static void
759 iscsi_data_rsp_pkt(iscsi_cmd_t *icmdp, iscsi_data_rsp_hdr_t *idrhp)
760 {
761 	struct buf		*bp	= NULL;
762 	size_t			data_transferred;
763 	struct scsi_pkt		*pkt;
764 
765 	bp = icmdp->cmd_un.scsi.bp;
766 	pkt = icmdp->cmd_un.scsi.pkt;
767 	data_transferred = icmdp->cmd_un.scsi.data_transferred;
768 	/*
769 	 * The command* must be completed now, since we won't get a command
770 	 * response PDU. The cmd_status and residual_count are
771 	 * not meaningful unless status_present is set.
772 	 */
773 	pkt->pkt_resid = 0;
774 	/* Check the residual count */
775 	if (bp && (data_transferred != bp->b_bcount)) {
776 		/*
777 		 * We didn't xfer the expected amount of data -
778 		 * the residual_count in the header is only valid
779 		 * if the underflow flag is set.
780 		 */
781 		if (idrhp->flags & ISCSI_FLAG_DATA_UNDERFLOW) {
782 			pkt->pkt_resid = ntohl(idrhp->residual_count);
783 			ISCSI_IO_LOG(CE_NOTE, "DEBUG: iscsi_data_rsp_pkt: "
784 			    "underflow: itt: %d "
785 			    "transferred: %lu count: %lu", idrhp->itt,
786 			    data_transferred, bp->b_bcount);
787 		} else {
788 			if (bp->b_bcount > data_transferred) {
789 				/* Some data fell on the floor somehw */
790 				ISCSI_IO_LOG(CE_NOTE, "DEBUG: "
791 				    "iscsi_data_rsp_pkt: data fell: itt: %d "
792 				    "transferred: %lu count: %lu", idrhp->itt,
793 				    data_transferred, bp->b_bcount);
794 				pkt->pkt_resid =
795 				    bp->b_bcount - data_transferred;
796 			}
797 		}
798 	}
799 
800 	pkt->pkt_reason = CMD_CMPLT;
801 	pkt->pkt_state |= (STATE_XFERRED_DATA | STATE_GOT_STATUS);
802 
803 	if (((idrhp->cmd_status & STATUS_MASK) != STATUS_GOOD) &&
804 	    (icmdp->cmd_un.scsi.statuslen >=
805 	    sizeof (struct scsi_arq_status)) && pkt->pkt_scbp) {
806 
807 		/*
808 		 * Not supposed to get exception status here!
809 		 * We have no request sense data so just do the
810 		 * best we can
811 		 */
812 		struct scsi_arq_status *arqstat =
813 		    (struct scsi_arq_status *)pkt->pkt_scbp;
814 
815 
816 		bzero(arqstat, sizeof (struct scsi_arq_status));
817 
818 		*((uchar_t *)&arqstat->sts_status) =
819 		    idrhp->cmd_status;
820 
821 		arqstat->sts_rqpkt_resid =
822 		    sizeof (struct scsi_extended_sense);
823 		ISCSI_IO_LOG(CE_NOTE, "DEBUG: iscsi_data_rsp_pkt: "
824 		    "exception status: itt: %d resid: %d",
825 		    idrhp->itt, arqstat->sts_rqpkt_resid);
826 
827 	} else if (pkt->pkt_scbp) {
828 		/* just pass along the status we got */
829 		pkt->pkt_scbp[0] = idrhp->cmd_status;
830 	}
831 }
832 
833 /*
834  * iscsi_rx_process_data_rsp -
835  * This currently processes the final data sequence denoted by the data response
836  * PDU Status bit being set.  We will not receive the SCSI response.
837  * This bit denotes that the PDU is the successful completion of the
838  * command.
839  */
840 static idm_status_t
841 iscsi_rx_process_data_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
842 {
843 	iscsi_sess_t		*isp	= NULL;
844 	iscsi_data_rsp_hdr_t	*idrhp	= (iscsi_data_rsp_hdr_t *)pdu->isp_hdr;
845 	iscsi_cmd_t		*icmdp	= NULL;
846 	struct buf		*bp	= NULL;
847 	iscsi_conn_t		*icp	= ic->ic_handle;
848 	idm_buf_t		*ibp;
849 	idm_status_t		rval;
850 
851 
852 	/* should only call this when the data rsp contains final rsp */
853 	ASSERT(idrhp->flags & ISCSI_FLAG_DATA_STATUS);
854 	isp = icp->conn_sess;
855 
856 	mutex_enter(&icp->conn_queue_active.mutex);
857 	if ((rval = iscsi_rx_chk(icp, isp, (iscsi_scsi_rsp_hdr_t *)idrhp,
858 	    &icmdp)) != IDM_STATUS_SUCCESS) {
859 		if (icmdp != NULL) {
860 			iscsi_task_cleanup(idrhp->opcode, icmdp);
861 		}
862 		mutex_exit(&icp->conn_queue_active.mutex);
863 		return (rval);
864 	}
865 
866 	/*
867 	 * If we are in "idm aborting" state then we shouldn't continue
868 	 * to process this command.  By definition this command is no longer
869 	 * on the active queue so we shouldn't try to remove it either.
870 	 */
871 	mutex_enter(&icmdp->cmd_mutex);
872 	if (icmdp->cmd_state == ISCSI_CMD_STATE_IDM_ABORTING) {
873 		mutex_exit(&icmdp->cmd_mutex);
874 		mutex_exit(&icp->conn_queue_active.mutex);
875 		return (IDM_STATUS_SUCCESS);
876 	}
877 	mutex_exit(&icmdp->cmd_mutex);
878 
879 	/*
880 	 * Holding the pending/active queue locks across the
881 	 * iscsi_rx_data call later in this function may cause
882 	 * deadlock during fault injections.  Instead remove
883 	 * the cmd from the active queue and release the locks.
884 	 * Then before returning or completing the command
885 	 * return the cmd to the active queue and reacquire
886 	 * the locks.
887 	 */
888 	iscsi_dequeue_active_cmd(icp, icmdp);
889 
890 	mutex_exit(&icp->conn_queue_active.mutex);
891 
892 	/* shorthand some values */
893 	bp = icmdp->cmd_un.scsi.bp;
894 
895 	/*
896 	 * some poorly behaved targets have been observed
897 	 * sending data-in pdu's during a write operation
898 	 */
899 	if (bp != NULL) {
900 		if (!(bp->b_flags & B_READ)) {
901 			cmn_err(CE_WARN,
902 			    "iscsi connection(%u) protocol error - "
903 			    "received data response during write operation "
904 			    "itt:0x%x",
905 			    icp->conn_oid, idrhp->itt);
906 			mutex_enter(&icp->conn_queue_active.mutex);
907 			iscsi_enqueue_active_cmd(icp, icmdp);
908 			mutex_exit(&icp->conn_queue_active.mutex);
909 			return (IDM_STATUS_PROTOCOL_ERROR);
910 		}
911 	}
912 
913 	ibp = icmdp->cmd_un.scsi.ibp_ibuf;
914 	if (ibp == NULL) {
915 		/*
916 		 * After the check of bp above we *should* have a corresponding
917 		 * idm_buf_t (ibp).  It's possible that the original call
918 		 * to idm_buf_alloc failed due to a pending connection state
919 		 * transition in which case this value can be NULL.  It's
920 		 * highly unlikely that the connection would be shutting down
921 		 * *and* we manage to process a data response and get to this
922 		 * point in the code but just in case we should check for it.
923 		 * This isn't really a protocol error -- we are almost certainly
924 		 * closing the connection anyway so just return a generic error.
925 		 */
926 		mutex_enter(&icp->conn_queue_active.mutex);
927 		iscsi_enqueue_active_cmd(icp, icmdp);
928 		mutex_exit(&icp->conn_queue_active.mutex);
929 		return (IDM_STATUS_FAIL);
930 	}
931 
932 	if (ic->ic_conn_flags & IDM_CONN_USE_SCOREBOARD) {
933 		icmdp->cmd_un.scsi.data_transferred =
934 		    icmdp->cmd_itp->idt_rx_bytes;
935 	} else {
936 		icmdp->cmd_un.scsi.data_transferred = bp->b_bcount;
937 		if (idrhp->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
938 			icmdp->cmd_un.scsi.data_transferred -=
939 			    ntohl(idrhp->residual_count);
940 		}
941 	}
942 
943 	ISCSI_IO_LOG(CE_NOTE, "DEBUG: rx_process_data_rsp: icp: %p pdu: %p "
944 	    "itt: %d ibp: %p icmdp: %p xfer_len: %lu transferred: %lu dlen: %u",
945 	    (void *)icp, (void *)pdu, idrhp->itt, (void *)bp, (void *)icmdp,
946 	    (ibp == NULL) ? 0 : ibp->idb_xfer_len,
947 	    icmdp->cmd_un.scsi.data_transferred,
948 	    n2h24(idrhp->dlength));
949 
950 	iscsi_task_cleanup(idrhp->opcode, icmdp);
951 
952 	iscsi_data_rsp_pkt(icmdp, idrhp);
953 
954 	mutex_enter(&icp->conn_queue_active.mutex);
955 	iscsi_enqueue_active_cmd(icp, icmdp);
956 	iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
957 	mutex_exit(&icp->conn_queue_active.mutex);
958 
959 	return (IDM_STATUS_SUCCESS);
960 }
961 
962 /*
963  * iscsi_rx_process_nop - Process a received nop.  If nop is in response
964  * to a ping we sent update stats.  If initiated by the target we need
965  * to response back to the target with a nop.  Schedule the response.
966  */
967 /* ARGSUSED */
968 static idm_status_t
969 iscsi_rx_process_nop(idm_conn_t *ic, idm_pdu_t *pdu)
970 {
971 	iscsi_sess_t		*isp	= NULL;
972 	iscsi_nop_in_hdr_t	*inihp	= (iscsi_nop_in_hdr_t *)pdu->isp_hdr;
973 	iscsi_cmd_t		*icmdp	= NULL;
974 	iscsi_conn_t		*icp	= ic->ic_handle;
975 
976 	if (icp->conn_expstatsn != ntohl(inihp->statsn)) {
977 		cmn_err(CE_WARN, "iscsi connection(%u/%x) protocol error - "
978 		    "received status out of order itt:0x%x statsn:0x%x "
979 		    "expstatsn:0x%x", icp->conn_oid, inihp->opcode, inihp->itt,
980 		    ntohl(inihp->statsn), icp->conn_expstatsn);
981 		return (IDM_STATUS_PROTOCOL_ERROR);
982 	}
983 	isp = icp->conn_sess;
984 	ASSERT(isp != NULL);
985 	mutex_enter(&isp->sess_queue_pending.mutex);
986 	mutex_enter(&icp->conn_queue_active.mutex);
987 	mutex_enter(&isp->sess_cmdsn_mutex);
988 	if (inihp->itt != ISCSI_RSVD_TASK_TAG) {
989 		if (!ISCSI_SUCCESS(iscsi_rx_process_itt_to_icmdp(
990 		    isp, (iscsi_hdr_t *)inihp, &icmdp))) {
991 			cmn_err(CE_WARN, "iscsi connection(%u) protocol error "
992 			    "- can not find cmd for itt:0x%x",
993 			    icp->conn_oid, inihp->itt);
994 			mutex_exit(&isp->sess_cmdsn_mutex);
995 			mutex_exit(&icp->conn_queue_active.mutex);
996 			mutex_exit(&isp->sess_queue_pending.mutex);
997 			return (IDM_STATUS_PROTOCOL_ERROR);
998 		}
999 	}
1000 
1001 	/* update expcmdsn and maxcmdsn */
1002 	iscsi_update_flow_control(isp, ntohl(inihp->maxcmdsn),
1003 	    ntohl(inihp->expcmdsn));
1004 	mutex_exit(&isp->sess_cmdsn_mutex);
1005 
1006 	if ((inihp->itt != ISCSI_RSVD_TASK_TAG) &&
1007 	    (inihp->ttt == ISCSI_RSVD_TASK_TAG)) {
1008 		/* This is the only type of nop that incs. the expstatsn */
1009 		icp->conn_expstatsn++;
1010 
1011 		/*
1012 		 * This is a targets response to our nop
1013 		 */
1014 		iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
1015 	} else if (inihp->ttt != ISCSI_RSVD_TASK_TAG) {
1016 		/*
1017 		 * Target requested a nop.  Send one.
1018 		 */
1019 		iscsi_handle_nop(icp, ISCSI_RSVD_TASK_TAG, inihp->ttt);
1020 	} else {
1021 		/*
1022 		 * This is a target-initiated ping that doesn't expect
1023 		 * a response; nothing to do except update our flow control
1024 		 * (which we do in all cases above).
1025 		 */
1026 		/* EMPTY */
1027 	}
1028 	mutex_exit(&icp->conn_queue_active.mutex);
1029 	mutex_exit(&isp->sess_queue_pending.mutex);
1030 
1031 	return (IDM_STATUS_SUCCESS);
1032 }
1033 
1034 
1035 /*
1036  * iscsi_rx_process_reject_rsp - The server rejected a PDU
1037  */
1038 static idm_status_t
1039 iscsi_rx_process_reject_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1040 {
1041 	iscsi_reject_rsp_hdr_t	*irrhp = (iscsi_reject_rsp_hdr_t *)pdu->isp_hdr;
1042 	iscsi_sess_t		*isp		= NULL;
1043 	uint32_t		dlength		= 0;
1044 	iscsi_hdr_t		*old_ihp	= NULL;
1045 	iscsi_conn_t		*icp		= ic->ic_handle;
1046 	uint8_t			*data 		= pdu->isp_data;
1047 	idm_status_t		status		= IDM_STATUS_SUCCESS;
1048 	int			i		= 0;
1049 
1050 	ASSERT(data != NULL);
1051 	isp = icp->conn_sess;
1052 	ASSERT(isp != NULL);
1053 
1054 	/*
1055 	 * In RFC3720 section 10.17, this 4 bytes should be all 0xff.
1056 	 */
1057 	for (i = 0; i < 4; i++) {
1058 		if (irrhp->must_be_ff[i] != 0xff) {
1059 			return (IDM_STATUS_PROTOCOL_ERROR);
1060 		}
1061 	}
1062 	mutex_enter(&isp->sess_cmdsn_mutex);
1063 
1064 	if (icp->conn_expstatsn == ntohl(irrhp->statsn)) {
1065 		icp->conn_expstatsn++;
1066 	} else {
1067 		cmn_err(CE_WARN, "iscsi connection(%u/%x) protocol error - "
1068 		    "received status out of order statsn:0x%x "
1069 		    "expstatsn:0x%x", icp->conn_oid, irrhp->opcode,
1070 		    ntohl(irrhp->statsn), icp->conn_expstatsn);
1071 		mutex_exit(&isp->sess_cmdsn_mutex);
1072 		return (IDM_STATUS_PROTOCOL_ERROR);
1073 	}
1074 	/* update expcmdsn and maxcmdsn */
1075 	iscsi_update_flow_control(isp, ntohl(irrhp->maxcmdsn),
1076 	    ntohl(irrhp->expcmdsn));
1077 
1078 	mutex_exit(&isp->sess_cmdsn_mutex);
1079 
1080 	/* If we don't have the rejected header we can't do anything */
1081 	dlength = n2h24(irrhp->dlength);
1082 	if (dlength < sizeof (iscsi_hdr_t)) {
1083 		return (IDM_STATUS_PROTOCOL_ERROR);
1084 	}
1085 
1086 	/* map old ihp */
1087 	old_ihp = (iscsi_hdr_t *)data;
1088 
1089 	switch (irrhp->reason) {
1090 	/*
1091 	 * ISCSI_REJECT_IMM_CMD_REJECT - Immediate Command Reject
1092 	 * too many immediate commands (original cmd can be resent)
1093 	 */
1094 	case ISCSI_REJECT_IMM_CMD_REJECT:
1095 		/*
1096 		 * We have exceeded the server's capacity for outstanding
1097 		 * immediate commands.   This must be a task management
1098 		 * command so try to find it in the abortingqueue and
1099 		 * complete it.
1100 		 */
1101 		if (!(old_ihp->opcode & ISCSI_OP_IMMEDIATE)) {
1102 			/* Rejecting IMM but old old_hdr wasn't IMM */
1103 			return (IDM_STATUS_PROTOCOL_ERROR);
1104 		}
1105 
1106 		/*
1107 		 * We only send NOP and TASK_MGT as IMM.  All other
1108 		 * cases should be considered as a protocol error.
1109 		 */
1110 		switch (old_ihp->opcode & ISCSI_OPCODE_MASK) {
1111 		case ISCSI_OP_NOOP_OUT:
1112 			/*
1113 			 * A ping was rejected - treat this like
1114 			 * ping response.  The down side is we
1115 			 * didn't get an updated MaxCmdSn.
1116 			 */
1117 			break;
1118 		case ISCSI_OP_SCSI_TASK_MGT_MSG:
1119 			status =
1120 			    iscsi_rx_process_rejected_tsk_mgt(ic, old_ihp);
1121 			break;
1122 		default:
1123 			cmn_err(CE_WARN, "iscsi connection(%u) protocol error "
1124 			    "- received a reject for a command(0x%02x) not "
1125 			    "sent as an immediate", icp->conn_oid,
1126 			    old_ihp->opcode);
1127 			status = IDM_STATUS_PROTOCOL_ERROR;
1128 			break;
1129 		}
1130 		break;
1131 
1132 	/*
1133 	 * For the rest of the reject cases just use the general
1134 	 * hammer of dis/reconnecting.  This will resolve all
1135 	 * noted issues although could be more graceful.
1136 	 */
1137 	case ISCSI_REJECT_DATA_DIGEST_ERROR:
1138 	case ISCSI_REJECT_CMD_BEFORE_LOGIN:
1139 	case ISCSI_REJECT_SNACK_REJECT:
1140 	case ISCSI_REJECT_PROTOCOL_ERROR:
1141 	case ISCSI_REJECT_CMD_NOT_SUPPORTED:
1142 	case ISCSI_REJECT_TASK_IN_PROGRESS:
1143 	case ISCSI_REJECT_INVALID_DATA_ACK:
1144 	case ISCSI_REJECT_INVALID_PDU_FIELD:
1145 	case ISCSI_REJECT_LONG_OPERATION_REJECT:
1146 	case ISCSI_REJECT_NEGOTIATION_RESET:
1147 	default:
1148 		cmn_err(CE_WARN, "iscsi connection(%u/%x) closing connection - "
1149 		    "target requested reason:0x%x",
1150 		    icp->conn_oid, irrhp->opcode, irrhp->reason);
1151 		status = IDM_STATUS_PROTOCOL_ERROR;
1152 		break;
1153 	}
1154 
1155 	return (status);
1156 }
1157 
1158 
1159 /*
1160  * iscsi_rx_process_rejected_tsk_mgt -
1161  */
1162 /* ARGSUSED */
1163 static idm_status_t
1164 iscsi_rx_process_rejected_tsk_mgt(idm_conn_t *ic, iscsi_hdr_t *old_ihp)
1165 {
1166 	iscsi_sess_t		*isp	= NULL;
1167 	iscsi_cmd_t		*icmdp	= NULL;
1168 	iscsi_conn_t		*icp 	= NULL;
1169 
1170 	isp = icp->conn_sess;
1171 	ASSERT(old_ihp != NULL);
1172 	ASSERT(isp != NULL);
1173 
1174 	mutex_enter(&icp->conn_queue_active.mutex);
1175 	mutex_enter(&isp->sess_cmdsn_mutex);
1176 	if (!ISCSI_SUCCESS(iscsi_rx_process_itt_to_icmdp(
1177 	    isp, old_ihp, &icmdp))) {
1178 		mutex_exit(&isp->sess_cmdsn_mutex);
1179 		mutex_exit(&icp->conn_queue_active.mutex);
1180 		return (IDM_STATUS_PROTOCOL_ERROR);
1181 	}
1182 	mutex_exit(&isp->sess_cmdsn_mutex);
1183 
1184 	switch (icmdp->cmd_type) {
1185 	case ISCSI_CMD_TYPE_ABORT:
1186 	case ISCSI_CMD_TYPE_RESET:
1187 		iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E4,
1188 		    icp->conn_sess);
1189 		break;
1190 	/* We don't send any other task mgr types */
1191 	default:
1192 		ASSERT(B_FALSE);
1193 		break;
1194 	}
1195 	mutex_exit(&icp->conn_queue_active.mutex);
1196 
1197 	return (IDM_STATUS_SUCCESS);
1198 }
1199 
1200 
1201 /*
1202  * iscsi_rx_process_task_mgt_rsp -
1203  */
1204 /* ARGSUSED */
1205 static idm_status_t
1206 iscsi_rx_process_task_mgt_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1207 {
1208 	iscsi_sess_t			*isp		= NULL;
1209 	iscsi_scsi_task_mgt_rsp_hdr_t	*istmrhp	= NULL;
1210 	iscsi_cmd_t			*icmdp		= NULL;
1211 	iscsi_conn_t			*icp		= ic->ic_handle;
1212 	idm_status_t			status = IDM_STATUS_SUCCESS;
1213 
1214 	isp = icp->conn_sess;
1215 	istmrhp = (iscsi_scsi_task_mgt_rsp_hdr_t *)pdu->isp_hdr;
1216 
1217 	mutex_enter(&icp->conn_queue_active.mutex);
1218 	if ((status = iscsi_rx_chk(icp, isp, (iscsi_scsi_rsp_hdr_t *)istmrhp,
1219 	    &icmdp)) != IDM_STATUS_SUCCESS) {
1220 		mutex_exit(&icp->conn_queue_active.mutex);
1221 		return (status);
1222 	}
1223 
1224 	switch (icmdp->cmd_type) {
1225 	case ISCSI_CMD_TYPE_ABORT:
1226 	case ISCSI_CMD_TYPE_RESET:
1227 		switch (istmrhp->response) {
1228 		case SCSI_TCP_TM_RESP_COMPLETE:
1229 			/* success */
1230 			iscsi_cmd_state_machine(icmdp,
1231 			    ISCSI_CMD_EVENT_E3, isp);
1232 			break;
1233 		case SCSI_TCP_TM_RESP_NO_TASK:
1234 			/*
1235 			 * If the array no longer knows about
1236 			 * an ABORT RTT and we no longer have
1237 			 * a parent SCSI command it was just
1238 			 * completed, free this ABORT resource.
1239 			 * Otherwise FALLTHRU this will flag a
1240 			 * protocol problem.
1241 			 */
1242 			if ((icmdp->cmd_type == ISCSI_CMD_TYPE_ABORT) &&
1243 			    (icmdp->cmd_un.abort.icmdp == NULL)) {
1244 				iscsi_cmd_state_machine(icmdp,
1245 				    ISCSI_CMD_EVENT_E4, isp);
1246 				break;
1247 			}
1248 			/* FALLTHRU */
1249 		case SCSI_TCP_TM_RESP_REJECTED:
1250 			/*
1251 			 * If the target rejects our reset task,
1252 			 * we should record the response and complete
1253 			 * this command with the result.
1254 			 */
1255 			if (icmdp->cmd_type == ISCSI_CMD_TYPE_RESET) {
1256 				icmdp->cmd_un.reset.response =
1257 				    istmrhp->response;
1258 				iscsi_cmd_state_machine(icmdp,
1259 				    ISCSI_CMD_EVENT_E3, isp);
1260 				break;
1261 			}
1262 			/* FALLTHRU */
1263 		case SCSI_TCP_TM_RESP_NO_LUN:
1264 		case SCSI_TCP_TM_RESP_TASK_ALLEGIANT:
1265 		case SCSI_TCP_TM_RESP_NO_FAILOVER:
1266 		case SCSI_TCP_TM_RESP_IN_PRGRESS:
1267 		default:
1268 			/*
1269 			 * Something is out of sync.  Flush
1270 			 * active queues and resync the
1271 			 * the connection to try and recover
1272 			 * to a known state.
1273 			 */
1274 			status = IDM_STATUS_PROTOCOL_ERROR;
1275 		}
1276 		break;
1277 
1278 	default:
1279 		cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
1280 		    "received a task mgt response for a non-task mgt "
1281 		    "cmd itt:0x%x type:%d", icp->conn_oid, istmrhp->itt,
1282 		    icmdp->cmd_type);
1283 		status = IDM_STATUS_PROTOCOL_ERROR;
1284 		break;
1285 	}
1286 
1287 	mutex_exit(&icp->conn_queue_active.mutex);
1288 	return (status);
1289 }
1290 
1291 
1292 /*
1293  * iscsi_rx_process_logout_rsp -
1294  *
1295  */
1296 /* ARGSUSED */
1297 idm_status_t
1298 iscsi_rx_process_logout_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1299 {
1300 	iscsi_conn_t		*icp	= ic->ic_handle;
1301 	iscsi_logout_rsp_hdr_t	*ilrhp	=
1302 	    (iscsi_logout_rsp_hdr_t *)pdu->isp_hdr;
1303 	iscsi_cmd_t		*icmdp	= NULL;
1304 	iscsi_sess_t		*isp;
1305 	idm_status_t		status = IDM_STATUS_SUCCESS;
1306 
1307 	isp = icp->conn_sess;
1308 
1309 	if (icp->conn_expstatsn != ntohl(ilrhp->statsn)) {
1310 		cmn_err(CE_WARN, "iscsi connection(%u/%x) protocol error - "
1311 		    "received status out of order itt:0x%x statsn:0x%x "
1312 		    "expstatsn:0x%x", icp->conn_oid, ilrhp->opcode, ilrhp->itt,
1313 		    ntohl(ilrhp->statsn), icp->conn_expstatsn);
1314 		return (IDM_STATUS_PROTOCOL_ERROR);
1315 	}
1316 
1317 	mutex_enter(&icp->conn_queue_active.mutex);
1318 	mutex_enter(&isp->sess_cmdsn_mutex);
1319 	if (ilrhp->itt != ISCSI_RSVD_TASK_TAG) {
1320 		if (!ISCSI_SUCCESS(iscsi_rx_process_itt_to_icmdp(
1321 		    isp, (iscsi_hdr_t *)ilrhp, &icmdp))) {
1322 			mutex_exit(&isp->sess_cmdsn_mutex);
1323 			mutex_exit(&icp->conn_queue_active.mutex);
1324 			return (IDM_STATUS_PROTOCOL_ERROR);
1325 		}
1326 	}
1327 
1328 	/* update expcmdsn and maxcmdsn */
1329 	iscsi_update_flow_control(isp, ntohl(ilrhp->maxcmdsn),
1330 	    ntohl(ilrhp->expcmdsn));
1331 	mutex_exit(&isp->sess_cmdsn_mutex);
1332 
1333 	ISCSI_IO_LOG(CE_NOTE,
1334 	    "DEBUG: iscsi_rx_process_logout_rsp: response: %d",
1335 	    ilrhp->response);
1336 	switch (ilrhp->response) {
1337 	case ISCSI_LOGOUT_CID_NOT_FOUND:
1338 		/*
1339 		 * If the target doesn't know about our connection
1340 		 * then we can consider our self disconnected.
1341 		 */
1342 		/* FALLTHRU */
1343 	case ISCSI_LOGOUT_RECOVERY_UNSUPPORTED:
1344 		/*
1345 		 * We don't support ErrorRecovery levels above 0
1346 		 * currently so consider this success.
1347 		 */
1348 		/* FALLTHRU */
1349 	case ISCSI_LOGOUT_CLEANUP_FAILED:
1350 		/*
1351 		 * per spec. "cleanup failed for various reasons."
1352 		 * Although those various reasons are undefined.
1353 		 * Not sure what to do here.  So fake success,
1354 		 * which will disconnect the connection.
1355 		 */
1356 		/* FALLTHRU */
1357 	case ISCSI_LOGOUT_SUCCESS:
1358 		iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
1359 		mutex_exit(&icp->conn_queue_active.mutex);
1360 		iscsi_drop_conn_cleanup(icp);
1361 		break;
1362 	default:
1363 		mutex_exit(&icp->conn_queue_active.mutex);
1364 		status = IDM_STATUS_PROTOCOL_ERROR;
1365 		break;
1366 
1367 	}
1368 	return (status);
1369 }
1370 
1371 /*
1372  * iscsi_rx_process_async_rsp
1373  *
1374  */
1375 /* ARGSUSED */
1376 static idm_status_t
1377 iscsi_rx_process_async_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1378 {
1379 	iscsi_conn_t		*icp	= ic->ic_handle;
1380 	iscsi_sess_t		*isp	= icp->conn_sess;
1381 	idm_status_t		rval	= IDM_STATUS_SUCCESS;
1382 	iscsi_task_t		*itp;
1383 	iscsi_async_evt_hdr_t	*iaehp	=
1384 	    (iscsi_async_evt_hdr_t *)pdu->isp_hdr;
1385 
1386 	ASSERT(icp != NULL);
1387 	ASSERT(pdu != NULL);
1388 	ASSERT(isp != NULL);
1389 
1390 	mutex_enter(&isp->sess_cmdsn_mutex);
1391 	if (icp->conn_expstatsn == ntohl(iaehp->statsn)) {
1392 		icp->conn_expstatsn++;
1393 	} else {
1394 		cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
1395 		    "received status out of order statsn:0x%x "
1396 		    "expstatsn:0x%x", icp->conn_oid,
1397 		    ntohl(iaehp->statsn), icp->conn_expstatsn);
1398 		mutex_exit(&isp->sess_cmdsn_mutex);
1399 		return (IDM_STATUS_PROTOCOL_ERROR);
1400 	}
1401 	mutex_exit(&isp->sess_cmdsn_mutex);
1402 
1403 	switch (iaehp->async_event) {
1404 	case ISCSI_ASYNC_EVENT_SCSI_EVENT:
1405 		/*
1406 		 * SCSI asynchronous event is reported in
1407 		 * the sense data.  Sense data that accompanies
1408 		 * the report in the data segment identifies the
1409 		 * condition.  If the target supports SCSI
1410 		 * asynchronous events reporting (see [SAM2])
1411 		 * as indicated in the stardard INQUIRY data
1412 		 * (see [SPC3]), its use may be enabled by
1413 		 * parameters in the SCSI control mode page
1414 		 * (see [SPC3]).
1415 		 *
1416 		 * T-10 has removed SCSI asunchronous events
1417 		 * from the standard.  Although we have seen
1418 		 * a couple targets still spending these requests.
1419 		 * Those targets were specifically sending them
1420 		 * for notification of a LUN/Volume change
1421 		 * (ex. LUN addition/removal).  Take a general
1422 		 * action to these events of dis/reconnecting.
1423 		 * Once reconnected we perform a reenumeration.
1424 		 */
1425 		idm_ini_conn_disconnect(ic);
1426 		break;
1427 
1428 	case ISCSI_ASYNC_EVENT_REQUEST_LOGOUT:
1429 		/*
1430 		 * We've been asked to logout by the target --
1431 		 * we need to treat this differently from a normal logout
1432 		 * due to a discovery failure.  Normal logouts result in
1433 		 * an N3 event to the session state machine and an offline
1434 		 * of the lun.  In this case we want to put the connection
1435 		 * into "failed" state and generate N5 to the session state
1436 		 * machine since the initiator logged out at the target's
1437 		 * request.  To track this we set a flag indicating we
1438 		 * received this async logout request from the tharget
1439 		 */
1440 		mutex_enter(&icp->conn_state_mutex);
1441 		icp->conn_async_logout = B_TRUE;
1442 		mutex_exit(&icp->conn_state_mutex);
1443 
1444 		/* Hold is released in iscsi_handle_logout. */
1445 		idm_conn_hold(ic);
1446 
1447 		/* Target has requested this connection to logout. */
1448 		itp = kmem_zalloc(sizeof (iscsi_task_t), KM_SLEEP);
1449 		itp->t_arg = icp;
1450 		itp->t_blocking = B_FALSE;
1451 		if (ddi_taskq_dispatch(isp->sess_taskq,
1452 		    (void(*)())iscsi_logout_start, itp, DDI_SLEEP) !=
1453 		    DDI_SUCCESS) {
1454 			idm_conn_rele(ic);
1455 			/* Disconnect if we couldn't dispatch the task */
1456 			idm_ini_conn_disconnect(ic);
1457 		}
1458 		break;
1459 
1460 	case ISCSI_ASYNC_EVENT_DROPPING_CONNECTION:
1461 		/*
1462 		 * Target is going to drop our connection.
1463 		 *	param1 - CID which will be dropped.
1464 		 *	param2 - Min time to reconnect.
1465 		 *	param3 - Max time to reconnect.
1466 		 *
1467 		 * For now just let fail as another disconnect.
1468 		 *
1469 		 * MC/S Once we support > 1 connections then
1470 		 * we need to check the CID and drop that
1471 		 * specific connection.
1472 		 */
1473 		iscsi_conn_set_login_min_max(icp, iaehp->param2,
1474 		    iaehp->param3);
1475 		idm_ini_conn_disconnect(ic);
1476 		break;
1477 
1478 	case ISCSI_ASYNC_EVENT_DROPPING_ALL_CONNECTIONS:
1479 		/*
1480 		 * Target is going to drop ALL connections.
1481 		 *	param2 - Min time to reconnect.
1482 		 *	param3 - Max time to reconnect.
1483 		 *
1484 		 * For now just let fail as anyother disconnect.
1485 		 *
1486 		 * MC/S Once we support more than > 1 connections
1487 		 * then we need to drop all connections on the
1488 		 * session.
1489 		 */
1490 		iscsi_conn_set_login_min_max(icp, iaehp->param2,
1491 		    iaehp->param3);
1492 		idm_ini_conn_disconnect(ic);
1493 		break;
1494 
1495 	case ISCSI_ASYNC_EVENT_PARAM_NEGOTIATION:
1496 		/*
1497 		 * Target requests parameter negotiation
1498 		 * on this connection.
1499 		 *
1500 		 * The initiator must honor this request.  For
1501 		 * now we will request a logout.  We can't
1502 		 * just ignore this or it might force corruption?
1503 		 */
1504 
1505 		/* Hold is released in iscsi_handle_logout */
1506 		idm_conn_hold(ic);
1507 		itp = kmem_zalloc(sizeof (iscsi_task_t), KM_SLEEP);
1508 		itp->t_arg = icp;
1509 		itp->t_blocking = B_FALSE;
1510 		if (ddi_taskq_dispatch(isp->sess_taskq,
1511 		    (void(*)())iscsi_logout_start, itp, DDI_SLEEP) !=
1512 		    DDI_SUCCESS) {
1513 			/* Disconnect if we couldn't dispatch the task */
1514 			idm_conn_rele(ic);
1515 			idm_ini_conn_disconnect(ic);
1516 		}
1517 		break;
1518 
1519 	case ISCSI_ASYNC_EVENT_VENDOR_SPECIFIC:
1520 		/*
1521 		 * We currently don't handle any vendor
1522 		 * specific async events.  So just ignore
1523 		 * the request.
1524 		 */
1525 		idm_ini_conn_disconnect(ic);
1526 		break;
1527 	default:
1528 		rval = IDM_STATUS_PROTOCOL_ERROR;
1529 	}
1530 
1531 	return (rval);
1532 }
1533 
1534 /*
1535  * iscsi_rx_process_text_rsp - processes iSCSI text response.  It sets
1536  * the cmd_result field of the command data structure with the actual
1537  * status value instead of returning the status value.  The return value
1538  * is SUCCESS in order to let iscsi_handle_text control the operation of
1539  * a text request.
1540  * Text requests are a handled a little different than other types of
1541  * iSCSI commands because the initiator sends additional empty text requests
1542  * in order to obtain the remaining responses required to complete the
1543  * request.  iscsi_handle_text controls the operation of text request, while
1544  * iscsi_rx_process_text_rsp just process the current response.
1545  */
1546 static idm_status_t
1547 iscsi_rx_process_text_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1548 {
1549 	iscsi_sess_t		*isp	= NULL;
1550 	iscsi_text_rsp_hdr_t	*ithp	=
1551 	    (iscsi_text_rsp_hdr_t *)pdu->isp_hdr;
1552 	iscsi_conn_t		*icp	= ic->ic_handle;
1553 	iscsi_cmd_t		*icmdp	= NULL;
1554 	boolean_t		final	= B_FALSE;
1555 	uint32_t		data_len;
1556 	uint8_t			*data = pdu->isp_data;
1557 	idm_status_t		rval;
1558 
1559 	isp = icp->conn_sess;
1560 
1561 	mutex_enter(&icp->conn_queue_active.mutex);
1562 	if ((rval = iscsi_rx_chk(icp, isp, (iscsi_scsi_rsp_hdr_t *)ithp,
1563 	    &icmdp)) != IDM_STATUS_SUCCESS) {
1564 		mutex_exit(&icp->conn_queue_active.mutex);
1565 		return (rval);
1566 	}
1567 
1568 	/* update local final response flag */
1569 	if (ithp->flags & ISCSI_FLAG_FINAL) {
1570 		final = B_TRUE;
1571 	}
1572 
1573 	/*
1574 	 * validate received TTT value.  RFC3720 specifies the following:
1575 	 * - F bit set to 1 MUST have a reserved TTT value 0xffffffff
1576 	 * - F bit set to 0 MUST have a non-reserved TTT value !0xffffffff
1577 	 * In addition, the received TTT value must not change between
1578 	 * responses of a long text response
1579 	 */
1580 	if (((final == B_TRUE) && (ithp->ttt != ISCSI_RSVD_TASK_TAG)) ||
1581 	    ((final == B_FALSE) && (ithp->ttt == ISCSI_RSVD_TASK_TAG))) {
1582 		icmdp->cmd_result = ISCSI_STATUS_PROTOCOL_ERROR;
1583 		icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1584 		mutex_exit(&icp->conn_queue_active.mutex);
1585 		cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
1586 		    "received text response with invalid flags:0x%x or "
1587 		    "ttt:0x%x", icp->conn_oid, ithp->flags, ithp->itt);
1588 		return (IDM_STATUS_PROTOCOL_ERROR);
1589 	}
1590 
1591 	if ((icmdp->cmd_un.text.stage == ISCSI_CMD_TEXT_INITIAL_REQ) &&
1592 	    (ithp->ttt == ISCSI_RSVD_TASK_TAG) &&
1593 	    (final == B_FALSE)) {
1594 		/* TTT should have matched reserved value */
1595 		icmdp->cmd_result = ISCSI_STATUS_PROTOCOL_ERROR;
1596 		icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1597 		mutex_exit(&icp->conn_queue_active.mutex);
1598 		cmn_err(CE_WARN, "iscsi connection(%u) protocol "
1599 		    "error - received text response with invalid "
1600 		    "ttt:0x%x", icp->conn_oid, ithp->ttt);
1601 		return (IDM_STATUS_PROTOCOL_ERROR);
1602 	}
1603 
1604 	/*
1605 	 * If this is first response, save away TTT value for later use
1606 	 * in a long text request/response sequence
1607 	 */
1608 	if (icmdp->cmd_un.text.stage == ISCSI_CMD_TEXT_INITIAL_REQ) {
1609 		icmdp->cmd_un.text.ttt = ithp->ttt;
1610 	}
1611 
1612 	data_len = ntoh24(ithp->dlength);
1613 
1614 	/* check whether enough buffer available to copy data */
1615 	if ((icmdp->cmd_un.text.total_rx_len + data_len) >
1616 	    icmdp->cmd_un.text.buf_len) {
1617 		icmdp->cmd_un.text.total_rx_len += data_len;
1618 		icmdp->cmd_result = ISCSI_STATUS_DATA_OVERFLOW;
1619 		/*
1620 		 * DATA_OVERFLOW will result in a SUCCESS return so that
1621 		 * iscsi_handle_text can continue to obtain the remaining
1622 		 * text response if needed.
1623 		 */
1624 	} else {
1625 		char *buf_data = (icmdp->cmd_un.text.buf +
1626 		    icmdp->cmd_un.text.offset);
1627 
1628 		bcopy(data, buf_data, data_len);
1629 		icmdp->cmd_un.text.offset += data_len;
1630 		icmdp->cmd_un.text.total_rx_len += data_len;
1631 		icmdp->cmd_result = ISCSI_STATUS_SUCCESS;
1632 		bcopy(ithp->rsvd4, icmdp->cmd_un.text.lun,
1633 		    sizeof (icmdp->cmd_un.text.lun));
1634 	}
1635 
1636 	/* update stage  */
1637 	if (final == B_TRUE) {
1638 		icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1639 	} else {
1640 		icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_CONTINUATION;
1641 	}
1642 
1643 	iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
1644 	mutex_exit(&icp->conn_queue_active.mutex);
1645 	return (IDM_STATUS_SUCCESS);
1646 }
1647 
1648 /*
1649  * iscsi_rx_process_scsi_itt_to_icmdp - Lookup itt using IDM to find matching
1650  * icmdp.  Verify itt in hdr and icmdp are the same.
1651  */
1652 static iscsi_status_t
1653 iscsi_rx_process_scsi_itt_to_icmdp(iscsi_sess_t *isp, idm_conn_t *ic,
1654     iscsi_scsi_rsp_hdr_t *ihp, iscsi_cmd_t **icmdp)
1655 {
1656 	idm_task_t *itp;
1657 
1658 	ASSERT(isp != NULL);
1659 	ASSERT(ihp != NULL);
1660 	ASSERT(icmdp != NULL);
1661 	ASSERT(mutex_owned(&isp->sess_cmdsn_mutex));
1662 	itp = idm_task_find_and_complete(ic, ihp->itt, ISCSI_INI_TASK_TTT);
1663 	if (itp == NULL) {
1664 		cmn_err(CE_WARN, "iscsi session(%u) protocol error - "
1665 		    "received unknown itt:0x%x - protocol error",
1666 		    isp->sess_oid, ihp->itt);
1667 		return (ISCSI_STATUS_INTERNAL_ERROR);
1668 	}
1669 	*icmdp = itp->idt_private;
1670 
1671 	idm_task_rele(itp);
1672 
1673 	return (ISCSI_STATUS_SUCCESS);
1674 
1675 }
1676 
1677 /*
1678  * iscsi_rx_process_itt_to_icmdp - Lookup itt in the session's
1679  * cmd table to find matching icmdp.  Verify itt in hdr and
1680  * icmdp are the same.
1681  */
1682 static iscsi_status_t
1683 iscsi_rx_process_itt_to_icmdp(iscsi_sess_t *isp, iscsi_hdr_t *ihp,
1684     iscsi_cmd_t **icmdp)
1685 {
1686 	int cmd_table_idx = 0;
1687 
1688 	ASSERT(isp != NULL);
1689 	ASSERT(ihp != NULL);
1690 	ASSERT(icmdp != NULL);
1691 	ASSERT(mutex_owned(&isp->sess_cmdsn_mutex));
1692 
1693 	/* try to find an associated iscsi_pkt */
1694 	cmd_table_idx = (ihp->itt - IDM_TASKIDS_MAX) % ISCSI_CMD_TABLE_SIZE;
1695 	if (isp->sess_cmd_table[cmd_table_idx] == NULL) {
1696 		cmn_err(CE_WARN, "iscsi session(%u) protocol error - "
1697 		    "received unknown itt:0x%x - protocol error",
1698 		    isp->sess_oid, ihp->itt);
1699 		return (ISCSI_STATUS_INTERNAL_ERROR);
1700 	}
1701 
1702 	/* verify itt */
1703 	if (isp->sess_cmd_table[cmd_table_idx]->cmd_itt != ihp->itt) {
1704 		cmn_err(CE_WARN, "iscsi session(%u) received itt:0x%x "
1705 		    " which is out of sync with itt:0x%x", isp->sess_oid,
1706 		    ihp->itt, isp->sess_cmd_table[cmd_table_idx]->cmd_itt);
1707 		return (ISCSI_STATUS_INTERNAL_ERROR);
1708 	}
1709 
1710 	/* ensure that icmdp is still in Active state */
1711 	if (isp->sess_cmd_table[cmd_table_idx]->cmd_state !=
1712 	    ISCSI_CMD_STATE_ACTIVE) {
1713 		cmn_err(CE_WARN, "iscsi session(%u) received itt:0x%x "
1714 		    "but icmdp (%p) is not in active state",
1715 		    isp->sess_oid, ihp->itt,
1716 		    (void *)isp->sess_cmd_table[cmd_table_idx]);
1717 		return (ISCSI_STATUS_INTERNAL_ERROR);
1718 	}
1719 
1720 	/* make sure this is a SCSI cmd */
1721 	*icmdp = isp->sess_cmd_table[cmd_table_idx];
1722 
1723 	return (ISCSI_STATUS_SUCCESS);
1724 }
1725 
1726 /*
1727  * +--------------------------------------------------------------------+
1728  * | End of protocol receive routines					|
1729  * +--------------------------------------------------------------------+
1730  */
1731 
1732 /*
1733  * +--------------------------------------------------------------------+
1734  * | Beginning of protocol send routines				|
1735  * +--------------------------------------------------------------------+
1736  */
1737 
1738 
1739 /*
1740  * iscsi_tx_thread - This thread is the driving point for all
1741  * iSCSI PDUs after login.  No PDUs should call idm_pdu_tx()
1742  * directly they should be funneled through iscsi_tx_thread.
1743  */
1744 void
1745 iscsi_tx_thread(iscsi_thread_t *thread, void *arg)
1746 {
1747 	iscsi_conn_t	*icp	= (iscsi_conn_t *)arg;
1748 	iscsi_sess_t	*isp	= NULL;
1749 	iscsi_cmd_t	*icmdp	= NULL;
1750 	clock_t		tout;
1751 	int		ret	= 1;
1752 
1753 	ASSERT(icp != NULL);
1754 	isp = icp->conn_sess;
1755 	ASSERT(isp != NULL);
1756 	ASSERT(thread != NULL);
1757 	ASSERT(thread->signature == SIG_ISCSI_THREAD);
1758 
1759 	tout = SEC_TO_TICK(1);
1760 	/*
1761 	 * Transfer icmdps until shutdown by owning session.
1762 	 */
1763 	while (ret != 0) {
1764 
1765 		isp->sess_window_open = B_TRUE;
1766 		/*
1767 		 * While the window is open, there are commands available
1768 		 * to send and the session state allows those commands to
1769 		 * be sent try to transfer them.
1770 		 */
1771 		mutex_enter(&isp->sess_queue_pending.mutex);
1772 		while ((isp->sess_window_open == B_TRUE) &&
1773 		    ((icmdp = isp->sess_queue_pending.head) != NULL) &&
1774 		    (((icmdp->cmd_type != ISCSI_CMD_TYPE_SCSI) &&
1775 		    (ISCSI_CONN_STATE_FULL_FEATURE(icp->conn_state))) ||
1776 		    (icp->conn_state == ISCSI_CONN_STATE_LOGGED_IN))) {
1777 
1778 			/* update command with this connection info */
1779 			icmdp->cmd_conn = icp;
1780 			/* attempt to send this command */
1781 			iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E2, isp);
1782 
1783 			ASSERT(!mutex_owned(&isp->sess_queue_pending.mutex));
1784 			mutex_enter(&isp->sess_queue_pending.mutex);
1785 		}
1786 		mutex_exit(&isp->sess_queue_pending.mutex);
1787 
1788 		/*
1789 		 * Go to sleep until there is something new
1790 		 * to process (awoken via cv_boardcast).
1791 		 * Or the timer goes off.
1792 		 */
1793 		ret = iscsi_thread_wait(thread, tout);
1794 	}
1795 
1796 }
1797 
1798 
1799 /*
1800  * iscsi_tx_cmd - transfers icmdp across wire as iscsi pdu
1801  *
1802  * Just prior to sending the command to the networking layer the
1803  * pending queue lock will be dropped.  At this point only local
1804  * resources will be used, not the icmdp.  Holding the queue lock
1805  * across the networking call can lead to a hang.  (This is due
1806  * to the the target driver and networking layers competing use
1807  * of the timeout() resources and the queue lock being held for
1808  * both sides.)  Upon the completion of this command the lock
1809  * will have been re-acquired.
1810  */
1811 iscsi_status_t
1812 iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
1813 {
1814 	iscsi_status_t	rval = ISCSI_STATUS_INTERNAL_ERROR;
1815 
1816 	ASSERT(isp != NULL);
1817 	ASSERT(icmdp != NULL);
1818 
1819 	/* transfer specific command type */
1820 	switch (icmdp->cmd_type) {
1821 	case ISCSI_CMD_TYPE_SCSI:
1822 		rval = iscsi_tx_scsi(isp, icmdp);
1823 		break;
1824 	case ISCSI_CMD_TYPE_NOP:
1825 		rval = iscsi_tx_nop(isp, icmdp);
1826 		break;
1827 	case ISCSI_CMD_TYPE_ABORT:
1828 		rval = iscsi_tx_abort(isp, icmdp);
1829 		break;
1830 	case ISCSI_CMD_TYPE_RESET:
1831 		rval = iscsi_tx_reset(isp, icmdp);
1832 		break;
1833 	case ISCSI_CMD_TYPE_LOGOUT:
1834 		rval = iscsi_tx_logout(isp, icmdp);
1835 		break;
1836 	case ISCSI_CMD_TYPE_TEXT:
1837 		rval = iscsi_tx_text(isp, icmdp);
1838 		break;
1839 	default:
1840 		cmn_err(CE_WARN, "iscsi_tx_cmd: invalid cmdtype: %d",
1841 		    icmdp->cmd_type);
1842 		ASSERT(FALSE);
1843 	}
1844 
1845 	ASSERT(!mutex_owned(&isp->sess_queue_pending.mutex));
1846 	return (rval);
1847 }
1848 
1849 /*
1850  * a variable length cdb can be up to 16K, but we obviously don't want
1851  * to put that on the stack; go with 200 bytes; if we get something
1852  * bigger than that we will kmem_alloc a buffer
1853  */
1854 #define	DEF_CDB_LEN	200
1855 
1856 /*
1857  * given the size of the cdb, return how many bytes the header takes,
1858  * which is the sizeof addl_hdr_t + the CDB size, minus the 16 bytes
1859  * stored in the basic header, minus sizeof (ahs_extscb)
1860  */
1861 #define	ADDLHDRSZ(x)		(sizeof (iscsi_addl_hdr_t) + (x) - \
1862 					16 - 4)
1863 
1864 static void
1865 iscsi_tx_init_hdr(iscsi_sess_t *isp, iscsi_conn_t *icp,
1866     iscsi_text_hdr_t *ihp, int opcode, iscsi_cmd_t *icmdp)
1867 {
1868 	ihp->opcode		= opcode;
1869 	ihp->itt		= icmdp->cmd_itt;
1870 	mutex_enter(&isp->sess_cmdsn_mutex);
1871 	icmdp->cmd_sn		= isp->sess_cmdsn;
1872 	ihp->cmdsn		= htonl(isp->sess_cmdsn);
1873 	isp->sess_cmdsn++;
1874 	mutex_exit(&isp->sess_cmdsn_mutex);
1875 	ihp->expstatsn		= htonl(icp->conn_expstatsn);
1876 	icp->conn_laststatsn = icp->conn_expstatsn;
1877 }
1878 
1879 
1880 static void
1881 iscsi_tx_scsi_data(iscsi_cmd_t *icmdp, iscsi_scsi_cmd_hdr_t *ihp,
1882     iscsi_conn_t *icp, idm_pdu_t *pdu)
1883 {
1884 	struct buf		*bp		= NULL;
1885 	size_t			buflen		= 0;
1886 	uint32_t		first_burst_length = 0;
1887 	struct scsi_pkt		*pkt;
1888 
1889 	pkt = icmdp->cmd_un.scsi.pkt;
1890 	bp = icmdp->cmd_un.scsi.bp;
1891 	if ((bp != NULL) && bp->b_bcount) {
1892 		buflen = bp->b_bcount;
1893 		first_burst_length =
1894 		    icp->conn_params.first_burst_length;
1895 
1896 		if (bp->b_flags & B_READ) {
1897 			ihp->flags = ISCSI_FLAG_FINAL;
1898 			/*
1899 			 * fix problem where OS sends bp (B_READ &
1900 			 * b_bcount!=0) for a TUR or START_STOP.
1901 			 * (comment came from cisco code.)
1902 			 */
1903 			if ((pkt->pkt_cdbp[0] != SCMD_TEST_UNIT_READY) &&
1904 			    (pkt->pkt_cdbp[0] != SCMD_START_STOP)) {
1905 				ihp->flags |= ISCSI_FLAG_CMD_READ;
1906 				ihp->data_length = htonl(buflen);
1907 			}
1908 		} else {
1909 			ihp->flags = ISCSI_FLAG_CMD_WRITE;
1910 			/*
1911 			 * FinalBit on the the iSCSI PDU denotes this
1912 			 * is the last PDU in the sequence.
1913 			 *
1914 			 * initial_r2t = true means R2T is required
1915 			 * for additional PDU, so there will be no more
1916 			 * unsolicited PDUs following
1917 			 */
1918 			if (icp->conn_params.initial_r2t) {
1919 				ihp->flags |= ISCSI_FLAG_FINAL;
1920 			}
1921 
1922 			/* Check if we should send ImmediateData */
1923 			if (icp->conn_params.immediate_data) {
1924 				pdu->isp_data =
1925 				    (uint8_t *)icmdp->
1926 				    cmd_un.scsi.bp->b_un.b_addr;
1927 
1928 				pdu->isp_datalen = MIN(MIN(buflen,
1929 				    first_burst_length),
1930 				    icmdp->cmd_conn->conn_params.
1931 				    max_xmit_data_seg_len);
1932 
1933 				/*
1934 				 * if everything fits immediate, or
1935 				 * we can send all burst data immediate
1936 				 * (not unsol), set F
1937 				 */
1938 				/*
1939 				 * XXX This doesn't look right -- it's not
1940 				 * clear how we can handle transmitting
1941 				 * any unsolicited data.  It looks like
1942 				 * we only support immediate data.  So what
1943 				 * happens if we don't set ISCSI_FLAG_FINAL?
1944 				 *
1945 				 * Unless there's magic code somewhere that
1946 				 * is sending the remaining PDU's we should
1947 				 * simply set ISCSI_FLAG_FINAL and forget
1948 				 * about sending unsolicited data.  The big
1949 				 * win is the immediate data anyway for small
1950 				 * PDU's.
1951 				 */
1952 				if ((pdu->isp_datalen == buflen) ||
1953 				    (pdu->isp_datalen == first_burst_length)) {
1954 					ihp->flags |= ISCSI_FLAG_FINAL;
1955 				}
1956 
1957 				hton24(ihp->dlength, pdu->isp_datalen);
1958 			}
1959 			/* total data transfer length */
1960 			ihp->data_length = htonl(buflen);
1961 		}
1962 	} else {
1963 		ihp->flags = ISCSI_FLAG_FINAL;
1964 	}
1965 	icmdp->cmd_un.scsi.data_transferred += pdu->isp_datalen;
1966 	/* XXX How is this different from the code above? */
1967 	/* will idm send the next data command up to burst length? */
1968 	/* send the burstlen if we haven't sent immediate data */
1969 	/* CRM: should idm send difference min(buflen, first_burst) and  imm? */
1970 	/*    (MIN(first_burst_length, buflen) - imdata > 0) */
1971 	/* CRM_LATER: change this to generate unsolicited pdu */
1972 	if ((buflen > 0) &&
1973 	    ((bp->b_flags & B_READ) == 0) &&
1974 	    (icp->conn_params.initial_r2t == 0) &&
1975 	    pdu->isp_datalen == 0) {
1976 
1977 		pdu->isp_datalen = MIN(first_burst_length, buflen);
1978 		if ((pdu->isp_datalen == buflen) ||
1979 		    (pdu->isp_datalen == first_burst_length)) {
1980 			ihp->flags |= ISCSI_FLAG_FINAL;
1981 		}
1982 		pdu->isp_data = (uint8_t *)icmdp->cmd_un.scsi.bp->b_un.b_addr;
1983 		hton24(ihp->dlength, pdu->isp_datalen);
1984 	}
1985 }
1986 
1987 static void
1988 iscsi_tx_scsi_init_pkt(iscsi_cmd_t *icmdp, iscsi_scsi_cmd_hdr_t *ihp)
1989 {
1990 	struct scsi_pkt *pkt;
1991 
1992 	pkt = icmdp->cmd_un.scsi.pkt;
1993 	pkt->pkt_state = (STATE_GOT_BUS | STATE_GOT_TARGET);
1994 	pkt->pkt_reason = CMD_INCOMPLETE;
1995 
1996 	/* tagged queuing */
1997 	if (pkt->pkt_flags & FLAG_HTAG) {
1998 		ihp->flags |= ISCSI_ATTR_HEAD_OF_QUEUE;
1999 	} else if (pkt->pkt_flags & FLAG_OTAG) {
2000 		ihp->flags |= ISCSI_ATTR_ORDERED;
2001 	} else if (pkt->pkt_flags & FLAG_STAG) {
2002 		ihp->flags |= ISCSI_ATTR_SIMPLE;
2003 	} else {
2004 		/* ihp->flags |= ISCSI_ATTR_UNTAGGED; */
2005 		/* EMPTY */
2006 	}
2007 
2008 	/* iscsi states lun is based on spc.2 */
2009 	ISCSI_LUN_BYTE_COPY(ihp->lun, icmdp->cmd_un.scsi.lun);
2010 
2011 	if (icmdp->cmd_un.scsi.cmdlen <= 16) {
2012 		/* copy the SCSI Command Block into the PDU */
2013 		bcopy(pkt->pkt_cdbp, ihp->scb,
2014 		    icmdp->cmd_un.scsi.cmdlen);
2015 	} else {
2016 		iscsi_addl_hdr_t *iahp;
2017 
2018 		iahp = (iscsi_addl_hdr_t *)ihp;
2019 
2020 		ihp->hlength = (ADDLHDRSZ(icmdp->cmd_un.scsi.cmdlen) -
2021 		    sizeof (iscsi_scsi_cmd_hdr_t) + 3) / 4;
2022 		iahp->ahs_hlen_hi = 0;
2023 		iahp->ahs_hlen_lo = (icmdp->cmd_un.scsi.cmdlen - 15);
2024 		iahp->ahs_key = 0x01;
2025 		iahp->ahs_resv = 0;
2026 		bcopy(pkt->pkt_cdbp, ihp->scb, 16);
2027 		bcopy(((char *)pkt->pkt_cdbp) + 16, &iahp->ahs_extscb[0],
2028 		    icmdp->cmd_un.scsi.cmdlen);
2029 	}
2030 
2031 	/*
2032 	 * Update all values before transfering.
2033 	 * We should never touch the icmdp after
2034 	 * transfering if there is no more data
2035 	 * to send.  The only case the idm_pdu_tx()
2036 	 * will fail is a on a connection disconnect
2037 	 * in that case the command will be flushed.
2038 	 */
2039 	pkt->pkt_state |= STATE_SENT_CMD;
2040 }
2041 
2042 static void
2043 iscsi_tx_scsi_init_task(iscsi_cmd_t *icmdp, iscsi_conn_t *icp,
2044     iscsi_scsi_cmd_hdr_t *ihp)
2045 {
2046 	idm_task_t		*itp;
2047 	struct buf		*bp		= NULL;
2048 	uint32_t		data_length;
2049 
2050 	bp = icmdp->cmd_un.scsi.bp;
2051 
2052 	itp = icmdp->cmd_itp;
2053 	ASSERT(itp != NULL);
2054 	data_length = ntohl(ihp->data_length);
2055 	ISCSI_IO_LOG(CE_NOTE,
2056 	    "DEBUG: iscsi_tx_init_task: task_start: %p idt_tt: %x cmdsn: %x "
2057 	    "sess_cmdsn: %x cmd: %p "
2058 	    "cmdtype: %d datalen: %u",
2059 	    (void *)itp, itp->idt_tt, ihp->cmdsn, icp->conn_sess->sess_cmdsn,
2060 	    (void *)icmdp, icmdp->cmd_type, data_length);
2061 	if (data_length > 0) {
2062 		if (bp->b_flags & B_READ) {
2063 			icmdp->cmd_un.scsi.ibp_ibuf =
2064 			    idm_buf_alloc(icp->conn_ic,
2065 			    bp->b_un.b_addr, bp->b_bcount);
2066 			if (icmdp->cmd_un.scsi.ibp_ibuf)
2067 				idm_buf_bind_in(itp,
2068 				    icmdp->cmd_un.scsi.ibp_ibuf);
2069 		} else {
2070 			icmdp->cmd_un.scsi.ibp_obuf =
2071 			    idm_buf_alloc(icp->conn_ic,
2072 			    bp->b_un.b_addr, bp->b_bcount);
2073 			if (icmdp->cmd_un.scsi.ibp_obuf)
2074 				idm_buf_bind_out(itp,
2075 				    icmdp->cmd_un.scsi.ibp_obuf);
2076 		}
2077 		ISCSI_IO_LOG(CE_NOTE,
2078 		    "DEBUG: pdu_tx: task_start(%s): %p ic: %p idt_tt: %x "
2079 		    "cmdsn: %x sess_cmdsn: %x sess_expcmdsn: %x obuf: %p "
2080 		    "cmdp: %p cmdtype: %d "
2081 		    "buflen: %lu " "bpaddr: %p datalen: %u ",
2082 		    bp->b_flags & B_READ ? "B_READ" : "B_WRITE",
2083 		    (void *)itp, (void *)icp->conn_ic,
2084 		    itp->idt_tt, ihp->cmdsn,
2085 		    icp->conn_sess->sess_cmdsn,
2086 		    icp->conn_sess->sess_expcmdsn,
2087 		    (void *)icmdp->cmd_un.scsi.ibp_ibuf,
2088 		    (void *)icmdp, icmdp->cmd_type, bp->b_bcount,
2089 		    (void *)bp->b_un.b_addr,
2090 		    data_length);
2091 	}
2092 
2093 	/*
2094 	 * Task is now active
2095 	 */
2096 	idm_task_start(itp, ISCSI_INI_TASK_TTT);
2097 }
2098 
2099 /*
2100  * iscsi_tx_scsi -
2101  *
2102  */
2103 static iscsi_status_t
2104 iscsi_tx_scsi(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2105 {
2106 	iscsi_status_t		rval		= ISCSI_STATUS_SUCCESS;
2107 	iscsi_conn_t		*icp		= NULL;
2108 	struct scsi_pkt		*pkt		= NULL;
2109 	iscsi_scsi_cmd_hdr_t	*ihp		= NULL;
2110 	int			cdblen		= 0;
2111 	idm_pdu_t		*pdu;
2112 	int			len;
2113 
2114 	ASSERT(isp != NULL);
2115 	ASSERT(icmdp != NULL);
2116 
2117 	pdu = kmem_zalloc(sizeof (idm_pdu_t), KM_SLEEP);
2118 
2119 	pkt = icmdp->cmd_un.scsi.pkt;
2120 	ASSERT(pkt != NULL);
2121 	icp = icmdp->cmd_conn;
2122 	ASSERT(icp != NULL);
2123 
2124 	/* Reset counts in case we are on a retry */
2125 	icmdp->cmd_un.scsi.data_transferred = 0;
2126 
2127 	if (icmdp->cmd_un.scsi.cmdlen > DEF_CDB_LEN) {
2128 		cdblen = icmdp->cmd_un.scsi.cmdlen;
2129 		ihp = kmem_zalloc(ADDLHDRSZ(cdblen), KM_SLEEP);
2130 		len = ADDLHDRSZ(cdblen);
2131 	} else {
2132 		/*
2133 		 * only bzero the basic header; the additional header
2134 		 * will be set up correctly later, if needed
2135 		 */
2136 		ihp = kmem_zalloc(sizeof (iscsi_scsi_cmd_hdr_t), KM_SLEEP);
2137 		len = sizeof (iscsi_scsi_cmd_hdr_t);
2138 	}
2139 
2140 	iscsi_tx_init_hdr(isp, icp, (iscsi_text_hdr_t *)ihp,
2141 	    ISCSI_OP_SCSI_CMD, icmdp);
2142 
2143 	idm_pdu_init(pdu, icp->conn_ic, (void *)icmdp, &iscsi_tx_done);
2144 	idm_pdu_init_hdr(pdu, (uint8_t *)ihp, len);
2145 	pdu->isp_data = NULL;
2146 	pdu->isp_datalen = 0;
2147 
2148 	/*
2149 	 * Sestion 12.11 of the iSCSI specification has a good table
2150 	 * describing when uncolicited data and/or immediate data
2151 	 * should be sent.
2152 	 */
2153 
2154 	iscsi_tx_scsi_data(icmdp, ihp, icp, pdu);
2155 
2156 	iscsi_tx_scsi_init_pkt(icmdp, ihp);
2157 
2158 	/* Calls idm_task_start */
2159 	iscsi_tx_scsi_init_task(icmdp, icp, ihp);
2160 
2161 	mutex_exit(&isp->sess_queue_pending.mutex);
2162 
2163 	idm_pdu_tx(pdu);
2164 
2165 	icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_SENT;
2166 
2167 	return (rval);
2168 }
2169 
2170 
2171 /* ARGSUSED */
2172 static void
2173 iscsi_tx_done(idm_pdu_t *pdu, idm_status_t status)
2174 {
2175 	kmem_free((iscsi_hdr_t *)pdu->isp_hdr, pdu->isp_hdrlen);
2176 	kmem_free(pdu, sizeof (idm_pdu_t));
2177 }
2178 
2179 
2180 static void
2181 iscsi_tx_pdu(iscsi_conn_t *icp, int opcode, void *hdr, int hdrlen,
2182     iscsi_cmd_t *icmdp)
2183 {
2184 	idm_pdu_t	*tx_pdu;
2185 	iscsi_hdr_t	*ihp = (iscsi_hdr_t *)hdr;
2186 
2187 	tx_pdu = kmem_zalloc(sizeof (idm_pdu_t), KM_SLEEP);
2188 	ASSERT(tx_pdu != NULL);
2189 
2190 	idm_pdu_init(tx_pdu, icp->conn_ic, icmdp, &iscsi_tx_done);
2191 	idm_pdu_init_hdr(tx_pdu, hdr, hdrlen);
2192 	if (opcode == ISCSI_OP_TEXT_CMD) {
2193 		idm_pdu_init_data(tx_pdu,
2194 		    (uint8_t *)icmdp->cmd_un.text.buf,
2195 		    ntoh24(ihp->dlength));
2196 	}
2197 
2198 	mutex_exit(&icp->conn_sess->sess_queue_pending.mutex);
2199 	idm_pdu_tx(tx_pdu);
2200 	icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_SENT;
2201 }
2202 
2203 
2204 /*
2205  * iscsi_tx_nop -
2206  *
2207  */
2208 static iscsi_status_t
2209 iscsi_tx_nop(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2210 {
2211 	iscsi_status_t		rval	= ISCSI_STATUS_SUCCESS;
2212 	iscsi_conn_t		*icp	= NULL;
2213 	iscsi_nop_out_hdr_t	*inohp;
2214 
2215 	ASSERT(isp != NULL);
2216 	ASSERT(icmdp != NULL);
2217 	icp = icmdp->cmd_conn;
2218 	ASSERT(icp != NULL);
2219 
2220 	inohp = kmem_zalloc(sizeof (iscsi_nop_out_hdr_t), KM_SLEEP);
2221 	ASSERT(inohp != NULL);
2222 
2223 	inohp->opcode	= ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
2224 	inohp->flags	= ISCSI_FLAG_FINAL;
2225 	inohp->itt	= icmdp->cmd_itt;
2226 	inohp->ttt	= icmdp->cmd_ttt;
2227 	mutex_enter(&isp->sess_cmdsn_mutex);
2228 	icmdp->cmd_sn	= isp->sess_cmdsn;
2229 	inohp->cmdsn	= htonl(isp->sess_cmdsn);
2230 	mutex_exit(&isp->sess_cmdsn_mutex);
2231 	inohp->expstatsn	= htonl(icp->conn_expstatsn);
2232 	icp->conn_laststatsn = icp->conn_expstatsn;
2233 	iscsi_tx_pdu(icp, ISCSI_OP_NOOP_OUT, inohp,
2234 	    sizeof (iscsi_nop_out_hdr_t), icmdp);
2235 	return (rval);
2236 }
2237 
2238 
2239 /*
2240  * iscsi_tx_abort -
2241  *
2242  */
2243 static iscsi_status_t
2244 iscsi_tx_abort(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2245 {
2246 	iscsi_status_t			rval	= ISCSI_STATUS_SUCCESS;
2247 	iscsi_conn_t			*icp	= NULL;
2248 	iscsi_scsi_task_mgt_hdr_t	*istmh;
2249 
2250 	ASSERT(isp != NULL);
2251 	ASSERT(icmdp != NULL);
2252 	icp = icmdp->cmd_conn;
2253 	ASSERT(icp != NULL);
2254 
2255 	istmh = kmem_zalloc(sizeof (iscsi_scsi_task_mgt_hdr_t), KM_SLEEP);
2256 	ASSERT(istmh != NULL);
2257 	mutex_enter(&isp->sess_cmdsn_mutex);
2258 	icmdp->cmd_sn	= isp->sess_cmdsn;
2259 	istmh->cmdsn	= htonl(isp->sess_cmdsn);
2260 	mutex_exit(&isp->sess_cmdsn_mutex);
2261 	istmh->expstatsn = htonl(icp->conn_expstatsn);
2262 	icp->conn_laststatsn = icp->conn_expstatsn;
2263 	istmh->itt	= icmdp->cmd_itt;
2264 	istmh->opcode	= ISCSI_OP_SCSI_TASK_MGT_MSG | ISCSI_OP_IMMEDIATE;
2265 	istmh->function	= ISCSI_FLAG_FINAL | ISCSI_TM_FUNC_ABORT_TASK;
2266 	ISCSI_LUN_BYTE_COPY(istmh->lun,
2267 	    icmdp->cmd_un.abort.icmdp->cmd_un.scsi.lun);
2268 	istmh->rtt	= icmdp->cmd_un.abort.icmdp->cmd_itt;
2269 	iscsi_tx_pdu(icp, ISCSI_OP_SCSI_TASK_MGT_MSG, istmh,
2270 	    sizeof (iscsi_scsi_task_mgt_hdr_t), icmdp);
2271 
2272 	return (rval);
2273 }
2274 
2275 
2276 /*
2277  * iscsi_tx_reset -
2278  *
2279  */
2280 static iscsi_status_t
2281 iscsi_tx_reset(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2282 {
2283 	iscsi_status_t			rval	= ISCSI_STATUS_SUCCESS;
2284 	iscsi_conn_t			*icp	= NULL;
2285 	iscsi_scsi_task_mgt_hdr_t	*istmh;
2286 
2287 	ASSERT(isp != NULL);
2288 	ASSERT(icmdp != NULL);
2289 	icp = icmdp->cmd_conn;
2290 	ASSERT(icp != NULL);
2291 
2292 	istmh = kmem_zalloc(sizeof (iscsi_scsi_task_mgt_hdr_t), KM_SLEEP);
2293 	ASSERT(istmh != NULL);
2294 	istmh->opcode	= ISCSI_OP_SCSI_TASK_MGT_MSG | ISCSI_OP_IMMEDIATE;
2295 	mutex_enter(&isp->sess_cmdsn_mutex);
2296 	icmdp->cmd_sn	= isp->sess_cmdsn;
2297 	istmh->cmdsn	= htonl(isp->sess_cmdsn);
2298 	mutex_exit(&isp->sess_cmdsn_mutex);
2299 	istmh->expstatsn	= htonl(icp->conn_expstatsn);
2300 	istmh->itt	= icmdp->cmd_itt;
2301 
2302 	switch (icmdp->cmd_un.reset.level) {
2303 	case RESET_LUN:
2304 		istmh->function	= ISCSI_FLAG_FINAL |
2305 		    ISCSI_TM_FUNC_LOGICAL_UNIT_RESET;
2306 		ISCSI_LUN_BYTE_COPY(istmh->lun, icmdp->cmd_lun->lun_num);
2307 		break;
2308 	case RESET_TARGET:
2309 	case RESET_BUS:
2310 		istmh->function	= ISCSI_FLAG_FINAL |
2311 		    ISCSI_TM_FUNC_TARGET_WARM_RESET;
2312 		break;
2313 	default:
2314 		/* unsupported / unknown level */
2315 		ASSERT(FALSE);
2316 		break;
2317 	}
2318 
2319 	iscsi_tx_pdu(icp, ISCSI_OP_SCSI_TASK_MGT_MSG, istmh,
2320 	    sizeof (iscsi_scsi_task_mgt_hdr_t), icmdp);
2321 
2322 	return (rval);
2323 }
2324 
2325 
2326 /*
2327  * iscsi_tx_logout -
2328  *
2329  */
2330 static iscsi_status_t
2331 iscsi_tx_logout(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2332 {
2333 	iscsi_status_t		rval	= ISCSI_STATUS_SUCCESS;
2334 	iscsi_conn_t		*icp	= NULL;
2335 	iscsi_logout_hdr_t	*ilh;
2336 
2337 	ASSERT(isp != NULL);
2338 	ASSERT(icmdp != NULL);
2339 	icp = icmdp->cmd_conn;
2340 	ASSERT(icp != NULL);
2341 
2342 	ilh = kmem_zalloc(sizeof (iscsi_logout_hdr_t), KM_SLEEP);
2343 	ilh->opcode	= ISCSI_OP_LOGOUT_CMD | ISCSI_OP_IMMEDIATE;
2344 	ilh->flags	= ISCSI_FLAG_FINAL | ISCSI_LOGOUT_REASON_CLOSE_SESSION;
2345 	ilh->itt		= icmdp->cmd_itt;
2346 	ilh->cid		= icp->conn_cid;
2347 	mutex_enter(&isp->sess_cmdsn_mutex);
2348 	icmdp->cmd_sn	= isp->sess_cmdsn;
2349 	ilh->cmdsn	= htonl(isp->sess_cmdsn);
2350 	mutex_exit(&isp->sess_cmdsn_mutex);
2351 	ilh->expstatsn	= htonl(icp->conn_expstatsn);
2352 	iscsi_tx_pdu(icp, ISCSI_OP_LOGOUT_CMD, ilh,
2353 	    sizeof (iscsi_logout_hdr_t), icmdp);
2354 
2355 	return (rval);
2356 }
2357 
2358 /*
2359  * iscsi_tx_text - setup iSCSI text request header and send PDU with
2360  * data given in the buffer attached to the command.  For a single
2361  * text request, the target may need to send its response in multiple
2362  * text response.  In this case, empty text requests are sent after
2363  * each received response to notify the target the initiator is ready
2364  * for more response.  For the initial request, the data_len field in
2365  * the text specific portion of a command is set to the amount of data
2366  * the initiator wants to send as part of the request. If additional
2367  * empty text requests are required for long responses, the data_len
2368  * field is set to 0 by the iscsi_handle_text function.
2369  */
2370 static iscsi_status_t
2371 iscsi_tx_text(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2372 {
2373 	iscsi_status_t		rval	= ISCSI_STATUS_SUCCESS;
2374 	iscsi_conn_t		*icp	= NULL;
2375 	iscsi_text_hdr_t	*ith;
2376 
2377 	ASSERT(icmdp != NULL);
2378 	icp = icmdp->cmd_conn;
2379 	ASSERT(icp != NULL);
2380 
2381 	ith = kmem_zalloc(sizeof (iscsi_text_hdr_t), KM_SLEEP);
2382 	ASSERT(ith != NULL);
2383 	ith->flags	= ISCSI_FLAG_FINAL;
2384 	hton24(ith->dlength, icmdp->cmd_un.text.data_len);
2385 	ith->ttt		= icmdp->cmd_un.text.ttt;
2386 	iscsi_tx_init_hdr(isp, icp, (iscsi_text_hdr_t *)ith,
2387 	    ISCSI_OP_TEXT_CMD, icmdp);
2388 	bcopy(icmdp->cmd_un.text.lun, ith->rsvd4, sizeof (ith->rsvd4));
2389 
2390 	iscsi_tx_pdu(icp, ISCSI_OP_TEXT_CMD, ith, sizeof (iscsi_text_hdr_t),
2391 	    icmdp);
2392 
2393 	return (rval);
2394 }
2395 
2396 /*
2397  * +--------------------------------------------------------------------+
2398  * | End of protocol send routines					|
2399  * +--------------------------------------------------------------------+
2400  */
2401 
2402 /*
2403  * iscsi_handle_abort -
2404  *
2405  */
2406 void
2407 iscsi_handle_abort(void *arg)
2408 {
2409 	iscsi_sess_t	*isp		= NULL;
2410 	iscsi_cmd_t	*icmdp		= (iscsi_cmd_t *)arg;
2411 	iscsi_cmd_t	*new_icmdp;
2412 	iscsi_conn_t	*icp;
2413 
2414 	ASSERT(icmdp != NULL);
2415 	icp = icmdp->cmd_conn;
2416 	ASSERT(icp != NULL);
2417 	isp = icp->conn_sess;
2418 	ASSERT(isp != NULL);
2419 
2420 	/* there should only be one abort */
2421 	ASSERT(icmdp->cmd_un.scsi.abort_icmdp == NULL);
2422 
2423 	new_icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2424 	new_icmdp->cmd_type		    = ISCSI_CMD_TYPE_ABORT;
2425 	new_icmdp->cmd_lun		    = icmdp->cmd_lun;
2426 	new_icmdp->cmd_un.abort.icmdp	    = icmdp;
2427 	new_icmdp->cmd_conn		    = icmdp->cmd_conn;
2428 	icmdp->cmd_un.scsi.abort_icmdp	    = new_icmdp;
2429 
2430 	/* pending queue mutex is already held by timeout_checks */
2431 	iscsi_cmd_state_machine(new_icmdp, ISCSI_CMD_EVENT_E1, isp);
2432 }
2433 
2434 /*
2435  * Callback from IDM indicating that the task has been suspended or aborted.
2436  */
2437 void
2438 iscsi_task_aborted(idm_task_t *idt, idm_status_t status)
2439 {
2440 	iscsi_cmd_t *icmdp = idt->idt_private;
2441 	iscsi_conn_t *icp = icmdp->cmd_conn;
2442 	iscsi_sess_t *isp = icp->conn_sess;
2443 
2444 	ASSERT(icmdp->cmd_conn != NULL);
2445 
2446 	switch (status) {
2447 	case IDM_STATUS_SUSPENDED:
2448 		/*
2449 		 * If the task is suspended, it may be aborted later,
2450 		 * so we can ignore this notification.
2451 		 */
2452 		break;
2453 
2454 	case IDM_STATUS_ABORTED:
2455 		mutex_enter(&icp->conn_queue_active.mutex);
2456 		iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E9, isp);
2457 		mutex_exit(&icp->conn_queue_active.mutex);
2458 		break;
2459 
2460 	default:
2461 		/*
2462 		 * Unexpected status.
2463 		 */
2464 		ASSERT(0);
2465 	}
2466 
2467 }
2468 
2469 /*
2470  * iscsi_handle_nop -
2471  *
2472  */
2473 static void
2474 iscsi_handle_nop(iscsi_conn_t *icp, uint32_t itt, uint32_t ttt)
2475 {
2476 	iscsi_sess_t	*isp	= NULL;
2477 	iscsi_cmd_t	*icmdp	= NULL;
2478 
2479 	ASSERT(icp != NULL);
2480 	isp = icp->conn_sess;
2481 	ASSERT(isp != NULL);
2482 
2483 	icmdp = iscsi_cmd_alloc(icp, KM_NOSLEEP);
2484 	if (icmdp == NULL) {
2485 		return;
2486 	}
2487 
2488 	icmdp->cmd_type		= ISCSI_CMD_TYPE_NOP;
2489 	icmdp->cmd_itt		= itt;
2490 	icmdp->cmd_ttt		= ttt;
2491 	icmdp->cmd_lun		= NULL;
2492 	icp->conn_nop_lbolt	= ddi_get_lbolt();
2493 
2494 	iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2495 }
2496 
2497 /*
2498  * iscsi_handle_reset - send reset request to the target
2499  *
2500  */
2501 iscsi_status_t
2502 iscsi_handle_reset(iscsi_sess_t *isp, int level, iscsi_lun_t *ilp)
2503 {
2504 	iscsi_status_t	rval	= ISCSI_STATUS_SUCCESS;
2505 	iscsi_conn_t	*icp;
2506 	iscsi_cmd_t	icmd;
2507 
2508 	ASSERT(isp != NULL);
2509 
2510 	if (level == RESET_LUN) {
2511 		rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2512 		ASSERT(ilp != NULL);
2513 		if (ilp->lun_state & ISCSI_LUN_STATE_BUSY) {
2514 			rw_exit(&isp->sess_lun_list_rwlock);
2515 			return (ISCSI_STATUS_SUCCESS);
2516 		}
2517 		ilp->lun_state |= ISCSI_LUN_STATE_BUSY;
2518 		rw_exit(&isp->sess_lun_list_rwlock);
2519 	} else {
2520 		mutex_enter(&isp->sess_reset_mutex);
2521 		if (isp->sess_reset_in_progress == B_TRUE) {
2522 			/*
2523 			 * If the reset is in progress, it is unnecessary
2524 			 * to send reset to the target redunantly.
2525 			 */
2526 			mutex_exit(&isp->sess_reset_mutex);
2527 			return (ISCSI_STATUS_SUCCESS);
2528 		}
2529 		isp->sess_reset_in_progress = B_TRUE;
2530 		mutex_exit(&isp->sess_reset_mutex);
2531 	}
2532 
2533 	bzero(&icmd, sizeof (iscsi_cmd_t));
2534 	icmd.cmd_sig		= ISCSI_SIG_CMD;
2535 	icmd.cmd_state		= ISCSI_CMD_STATE_FREE;
2536 	icmd.cmd_type		= ISCSI_CMD_TYPE_RESET;
2537 	icmd.cmd_lun		= ilp;
2538 	icmd.cmd_un.reset.level	= level;
2539 	icmd.cmd_result		= ISCSI_STATUS_SUCCESS;
2540 	icmd.cmd_completed	= B_FALSE;
2541 	icmd.cmd_un.reset.response = SCSI_TCP_TM_RESP_COMPLETE;
2542 
2543 	mutex_init(&icmd.cmd_mutex, NULL, MUTEX_DRIVER, NULL);
2544 	cv_init(&icmd.cmd_completion, NULL, CV_DRIVER, NULL);
2545 	/*
2546 	 * If we received an IO and we are not in the
2547 	 * LOGGED_IN state we are in the process of
2548 	 * failing.  Just respond that we are BUSY.
2549 	 */
2550 	mutex_enter(&isp->sess_state_mutex);
2551 	if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
2552 		/* We aren't connected to the target fake success */
2553 		mutex_exit(&isp->sess_state_mutex);
2554 
2555 		if (level == RESET_LUN) {
2556 			rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2557 			ilp->lun_state &= ~ISCSI_LUN_STATE_BUSY;
2558 			rw_exit(&isp->sess_lun_list_rwlock);
2559 		} else {
2560 			mutex_enter(&isp->sess_reset_mutex);
2561 			isp->sess_reset_in_progress = B_FALSE;
2562 			mutex_exit(&isp->sess_reset_mutex);
2563 		}
2564 
2565 		return (ISCSI_STATUS_SUCCESS);
2566 	}
2567 
2568 	mutex_enter(&isp->sess_queue_pending.mutex);
2569 	iscsi_cmd_state_machine(&icmd, ISCSI_CMD_EVENT_E1, isp);
2570 	mutex_exit(&isp->sess_queue_pending.mutex);
2571 	mutex_exit(&isp->sess_state_mutex);
2572 
2573 	/* stall until completed */
2574 	mutex_enter(&icmd.cmd_mutex);
2575 	while (icmd.cmd_completed == B_FALSE) {
2576 		cv_wait(&icmd.cmd_completion, &icmd.cmd_mutex);
2577 	}
2578 	mutex_exit(&icmd.cmd_mutex);
2579 
2580 	/* copy rval */
2581 	rval = icmd.cmd_result;
2582 
2583 	if (rval == ISCSI_STATUS_SUCCESS) {
2584 		/*
2585 		 * Reset was successful.  We need to flush
2586 		 * all active IOs.
2587 		 */
2588 		rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
2589 		icp = isp->sess_conn_list;
2590 		while (icp != NULL) {
2591 			iscsi_cmd_t *t_icmdp = NULL;
2592 			iscsi_cmd_t *next_icmdp = NULL;
2593 
2594 			mutex_enter(&icp->conn_queue_active.mutex);
2595 			t_icmdp = icp->conn_queue_active.head;
2596 			while (t_icmdp != NULL) {
2597 				next_icmdp = t_icmdp->cmd_next;
2598 				mutex_enter(&t_icmdp->cmd_mutex);
2599 				if (!(t_icmdp->cmd_misc_flags &
2600 				    ISCSI_CMD_MISCFLAG_SENT)) {
2601 					/*
2602 					 * Although this command is in the
2603 					 * active queue, it has not been sent.
2604 					 * Skip it.
2605 					 */
2606 					mutex_exit(&t_icmdp->cmd_mutex);
2607 					t_icmdp = next_icmdp;
2608 					continue;
2609 				}
2610 				if (level == RESET_LUN) {
2611 					if (icmd.cmd_lun == NULL ||
2612 					    t_icmdp->cmd_lun == NULL ||
2613 					    (icmd.cmd_lun->lun_num !=
2614 					    t_icmdp->cmd_lun->lun_num)) {
2615 						mutex_exit(&t_icmdp->cmd_mutex);
2616 						t_icmdp = next_icmdp;
2617 						continue;
2618 					}
2619 				}
2620 
2621 				if (icmd.cmd_sn == t_icmdp->cmd_sn) {
2622 					/*
2623 					 * This command may be replied with
2624 					 * UA sense key later. So currently
2625 					 * it is not a suitable time to flush
2626 					 * it. Mark its flag with FLUSH. There
2627 					 * is no harm to keep it for a while.
2628 					 */
2629 					t_icmdp->cmd_misc_flags |=
2630 					    ISCSI_CMD_MISCFLAG_FLUSH;
2631 					if (t_icmdp->cmd_type ==
2632 					    ISCSI_CMD_TYPE_SCSI) {
2633 						t_icmdp->cmd_un.scsi.pkt_stat |=
2634 						    STAT_BUS_RESET;
2635 					}
2636 					mutex_exit(&t_icmdp->cmd_mutex);
2637 				} else if ((icmd.cmd_sn > t_icmdp->cmd_sn) ||
2638 				    ((t_icmdp->cmd_sn - icmd.cmd_sn) >
2639 				    ISCSI_CMD_SN_WRAP)) {
2640 					/*
2641 					 * This reset request must act on all
2642 					 * the commnds from the same session
2643 					 * having a CmdSN lower than the task
2644 					 * mangement CmdSN. So flush these
2645 					 * commands here.
2646 					 */
2647 					if (t_icmdp->cmd_type ==
2648 					    ISCSI_CMD_TYPE_SCSI) {
2649 						t_icmdp->cmd_un.scsi.pkt_stat |=
2650 						    STAT_BUS_RESET;
2651 					}
2652 					mutex_exit(&t_icmdp->cmd_mutex);
2653 					iscsi_cmd_state_machine(t_icmdp,
2654 					    ISCSI_CMD_EVENT_E7, isp);
2655 				} else {
2656 					mutex_exit(&t_icmdp->cmd_mutex);
2657 				}
2658 
2659 				t_icmdp = next_icmdp;
2660 			}
2661 
2662 			mutex_exit(&icp->conn_queue_active.mutex);
2663 			icp = icp->conn_next;
2664 		}
2665 		rw_exit(&isp->sess_conn_list_rwlock);
2666 	}
2667 
2668 	/* clean up */
2669 	cv_destroy(&icmd.cmd_completion);
2670 	mutex_destroy(&icmd.cmd_mutex);
2671 
2672 	if (level == RESET_LUN) {
2673 		rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2674 		ilp->lun_state &= ~ISCSI_LUN_STATE_BUSY;
2675 		rw_exit(&isp->sess_lun_list_rwlock);
2676 	} else {
2677 		mutex_enter(&isp->sess_reset_mutex);
2678 		isp->sess_reset_in_progress = B_FALSE;
2679 		mutex_exit(&isp->sess_reset_mutex);
2680 	}
2681 
2682 	return (rval);
2683 }
2684 
2685 /*
2686  * iscsi_logout_start - task handler for deferred logout
2687  * Acquire a hold before call, released in iscsi_handle_logout
2688  */
2689 static void
2690 iscsi_logout_start(void *arg)
2691 {
2692 	iscsi_task_t		*itp = (iscsi_task_t *)arg;
2693 	iscsi_conn_t		*icp;
2694 
2695 	icp = (iscsi_conn_t *)itp->t_arg;
2696 
2697 	mutex_enter(&icp->conn_state_mutex);
2698 	(void) iscsi_handle_logout(icp);
2699 	mutex_exit(&icp->conn_state_mutex);
2700 }
2701 
2702 /*
2703  * iscsi_handle_logout - This function will issue a logout for
2704  * the session from a specific connection.
2705  * Acquire idm_conn_hold before call.  Released internally.
2706  */
2707 iscsi_status_t
2708 iscsi_handle_logout(iscsi_conn_t *icp)
2709 {
2710 	iscsi_sess_t	*isp;
2711 	idm_conn_t	*ic;
2712 	iscsi_cmd_t	*icmdp;
2713 	int		rval;
2714 
2715 	ASSERT(icp != NULL);
2716 	isp = icp->conn_sess;
2717 	ic = icp->conn_ic;
2718 	ASSERT(isp != NULL);
2719 	ASSERT(isp->sess_hba != NULL);
2720 	ASSERT(mutex_owned(&icp->conn_state_mutex));
2721 
2722 	/*
2723 	 * If the connection has already gone down (e.g. if the transport
2724 	 * failed between when this LOGOUT was generated and now) then we
2725 	 * can and must skip sending the LOGOUT.  Check the same condition
2726 	 * we use below to determine that connection has "settled".
2727 	 */
2728 	if ((icp->conn_state == ISCSI_CONN_STATE_FREE) ||
2729 	    (icp->conn_state == ISCSI_CONN_STATE_FAILED) ||
2730 	    (icp->conn_state == ISCSI_CONN_STATE_POLLING)) {
2731 		idm_conn_rele(ic);
2732 		return (0);
2733 	}
2734 
2735 	icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2736 	ASSERT(icmdp != NULL);
2737 	icmdp->cmd_type		= ISCSI_CMD_TYPE_LOGOUT;
2738 	icmdp->cmd_result	= ISCSI_STATUS_SUCCESS;
2739 	icmdp->cmd_completed	= B_FALSE;
2740 
2741 	mutex_enter(&isp->sess_queue_pending.mutex);
2742 	iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2743 	mutex_exit(&isp->sess_queue_pending.mutex);
2744 
2745 	/*
2746 	 * release connection state mutex to avoid a deadlock.  This
2747 	 * function is called from within the connection state
2748 	 * machine with the lock held.  When the logout response is
2749 	 * received another call to the connection state machine
2750 	 * occurs which causes the deadlock
2751 	 */
2752 	mutex_exit(&icp->conn_state_mutex);
2753 
2754 	/* stall until completed */
2755 	mutex_enter(&icmdp->cmd_mutex);
2756 	while (icmdp->cmd_completed == B_FALSE) {
2757 		cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
2758 	}
2759 	mutex_exit(&icmdp->cmd_mutex);
2760 	mutex_enter(&icp->conn_state_mutex);
2761 
2762 	/* copy rval */
2763 	rval = icmdp->cmd_result;
2764 
2765 	/* clean up */
2766 	iscsi_cmd_free(icmdp);
2767 
2768 	if (rval != 0) {
2769 		/* If the logout failed then drop the connection */
2770 		idm_ini_conn_disconnect(icp->conn_ic);
2771 	}
2772 
2773 	/* stall until connection settles */
2774 	while ((icp->conn_state != ISCSI_CONN_STATE_FREE) &&
2775 	    (icp->conn_state != ISCSI_CONN_STATE_FAILED) &&
2776 	    (icp->conn_state != ISCSI_CONN_STATE_POLLING)) {
2777 		/* wait for transition */
2778 		cv_wait(&icp->conn_state_change, &icp->conn_state_mutex);
2779 	}
2780 
2781 	idm_conn_rele(ic);
2782 
2783 	/*
2784 	 * Return value reflects whether the logout command completed --
2785 	 * regardless of the return value the connection is closed and
2786 	 * ready for reconnection.
2787 	 */
2788 	return (rval);
2789 }
2790 
2791 
2792 /*
2793  * iscsi_handle_text - main control function for iSCSI text requests.  This
2794  * function handles allocating the command, sending initial text request, and
2795  * handling long response sequence.
2796  * If a data overflow condition occurs, iscsi_handle_text continues to
2797  * receive responses until the all data has been recieved.  This allows
2798  * the full data length to be returned to the caller.
2799  */
2800 iscsi_status_t
2801 iscsi_handle_text(iscsi_conn_t *icp, char *buf, uint32_t buf_len,
2802     uint32_t data_len, uint32_t *rx_data_len)
2803 {
2804 	iscsi_sess_t	*isp;
2805 	iscsi_cmd_t	*icmdp;
2806 	iscsi_status_t	rval	= ISCSI_STATUS_SUCCESS;
2807 
2808 	ASSERT(icp != NULL);
2809 	ASSERT(buf != NULL);
2810 	ASSERT(rx_data_len != NULL);
2811 
2812 	isp = icp->conn_sess;
2813 	ASSERT(isp != NULL);
2814 
2815 	/*
2816 	 * Ensure data for text request command is not greater
2817 	 * than the negotiated maximum receive data seqment length.
2818 	 *
2819 	 * Although iSCSI allows for long text requests (multiple
2820 	 * pdus), this function places a restriction on text
2821 	 * requests to ensure it is handled by a single PDU.
2822 	 */
2823 	if (data_len > icp->conn_params.max_xmit_data_seg_len) {
2824 		return (ISCSI_STATUS_CMD_FAILED);
2825 	}
2826 
2827 	icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2828 	ASSERT(icmdp != NULL);
2829 
2830 	icmdp->cmd_type		= ISCSI_CMD_TYPE_TEXT;
2831 	icmdp->cmd_result	= ISCSI_STATUS_SUCCESS;
2832 	icmdp->cmd_misc_flags	&= ~ISCSI_CMD_MISCFLAG_FREE;
2833 	icmdp->cmd_completed	= B_FALSE;
2834 
2835 	icmdp->cmd_un.text.buf		= buf;
2836 	icmdp->cmd_un.text.buf_len	= buf_len;
2837 	icmdp->cmd_un.text.offset	= 0;
2838 	icmdp->cmd_un.text.data_len	= data_len;
2839 	icmdp->cmd_un.text.total_rx_len	= 0;
2840 	icmdp->cmd_un.text.ttt		= ISCSI_RSVD_TASK_TAG;
2841 	icmdp->cmd_un.text.stage	= ISCSI_CMD_TEXT_INITIAL_REQ;
2842 
2843 long_text_response:
2844 	mutex_enter(&isp->sess_state_mutex);
2845 	if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
2846 		iscsi_cmd_free(icmdp);
2847 		mutex_exit(&isp->sess_state_mutex);
2848 		return (ISCSI_STATUS_NO_CONN_LOGGED_IN);
2849 	}
2850 
2851 	mutex_enter(&isp->sess_queue_pending.mutex);
2852 	iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2853 	mutex_exit(&isp->sess_queue_pending.mutex);
2854 	mutex_exit(&isp->sess_state_mutex);
2855 
2856 	/* stall until completed */
2857 	mutex_enter(&icmdp->cmd_mutex);
2858 	while (icmdp->cmd_completed == B_FALSE) {
2859 		cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
2860 	}
2861 	mutex_exit(&icmdp->cmd_mutex);
2862 
2863 	/*
2864 	 * check if error occured.  If data overflow occured, continue on
2865 	 * to ensure we get all data so that the full data length can be
2866 	 * returned to the user
2867 	 */
2868 	if ((icmdp->cmd_result != ISCSI_STATUS_SUCCESS) &&
2869 	    (icmdp->cmd_result != ISCSI_STATUS_DATA_OVERFLOW)) {
2870 		cmn_err(CE_NOTE, "iscsi: SendTarget discovery failed (%d)",
2871 		    icmdp->cmd_result);
2872 		rval = icmdp->cmd_result;
2873 		iscsi_cmd_free(icmdp);
2874 		return (rval);
2875 	}
2876 
2877 	/* check if this was a partial text PDU  */
2878 	if (icmdp->cmd_un.text.stage != ISCSI_CMD_TEXT_FINAL_RSP) {
2879 		/*
2880 		 * If a paritial text rexponse received, send an empty
2881 		 * text request.  This follows the behaviour specified
2882 		 * in RFC3720 regarding long text responses.
2883 		 */
2884 		icmdp->cmd_misc_flags		&= ~ISCSI_CMD_MISCFLAG_FREE;
2885 		icmdp->cmd_completed		= B_FALSE;
2886 		icmdp->cmd_un.text.data_len	= 0;
2887 		icmdp->cmd_un.text.stage	= ISCSI_CMD_TEXT_CONTINUATION;
2888 		goto long_text_response;
2889 	}
2890 
2891 	/*
2892 	 * set total received data length.  If data overflow this would be
2893 	 * amount of data that would have been received if buffer large
2894 	 * enough.
2895 	 */
2896 	*rx_data_len = icmdp->cmd_un.text.total_rx_len;
2897 
2898 	/* copy rval */
2899 	rval = icmdp->cmd_result;
2900 
2901 	/* clean up  */
2902 	iscsi_cmd_free(icmdp);
2903 
2904 	return (rval);
2905 }
2906 
2907 /*
2908  * iscsi_handle_passthru - This function is used to send a uscsi_cmd
2909  * to a specific target lun.  This routine is used for internal purposes
2910  * during enumeration and via the ISCSI_USCSICMD IOCTL.  We restrict
2911  * the CDBs that can be issued to a target/lun to INQUIRY, REPORT_LUNS,
2912  * and READ_CAPACITY for security purposes.
2913  *
2914  * The logic here is broken into three phases.
2915  * 1) Allocate and initialize a pkt/icmdp
2916  * 2) Send the pkt/icmdp
2917  * 3) cv_wait for completion
2918  */
2919 iscsi_status_t
2920 iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun, struct uscsi_cmd *ucmdp)
2921 {
2922 	iscsi_status_t		rval		= ISCSI_STATUS_SUCCESS;
2923 	iscsi_cmd_t		*icmdp		= NULL;
2924 	struct scsi_pkt		*pkt		= NULL;
2925 	struct buf		*bp		= NULL;
2926 	struct scsi_arq_status  *arqstat	= NULL;
2927 	int			rqlen		= SENSE_LENGTH;
2928 
2929 	ASSERT(isp != NULL);
2930 	ASSERT(ucmdp != NULL);
2931 
2932 	/*
2933 	 * If the caller didn't provide a sense buffer we need
2934 	 * to allocation one to get the scsi status.
2935 	 */
2936 	if (ucmdp->uscsi_rqlen > SENSE_LENGTH) {
2937 		rqlen = ucmdp->uscsi_rqlen;
2938 	}
2939 
2940 	/*
2941 	 * Step 1. Setup structs - KM_SLEEP will always succeed
2942 	 */
2943 	bp = kmem_zalloc(sizeof (struct buf), KM_SLEEP);
2944 	ASSERT(bp != NULL);
2945 	pkt = kmem_zalloc(sizeof (struct scsi_pkt), KM_SLEEP);
2946 	ASSERT(pkt != NULL);
2947 	icmdp = iscsi_cmd_alloc(NULL, KM_SLEEP);
2948 	ASSERT(icmdp != NULL);
2949 
2950 	/* setup bp structure */
2951 	bp->b_flags		= B_READ;
2952 	bp->b_bcount		= ucmdp->uscsi_buflen;
2953 	bp->b_un.b_addr		= ucmdp->uscsi_bufaddr;
2954 
2955 	/* setup scsi_pkt structure */
2956 	pkt->pkt_ha_private	= icmdp;
2957 	pkt->pkt_scbp		= kmem_zalloc(rqlen, KM_SLEEP);
2958 	pkt->pkt_cdbp		= kmem_zalloc(ucmdp->uscsi_cdblen, KM_SLEEP);
2959 	/* callback routine for passthru, will wake cv_wait */
2960 	pkt->pkt_comp		= iscsi_handle_passthru_callback;
2961 	pkt->pkt_time		= ucmdp->uscsi_timeout;
2962 
2963 	/* setup iscsi_cmd structure */
2964 	icmdp->cmd_lun			= NULL;
2965 	icmdp->cmd_type			= ISCSI_CMD_TYPE_SCSI;
2966 	icmdp->cmd_un.scsi.lun		= lun;
2967 	icmdp->cmd_un.scsi.pkt		= pkt;
2968 	icmdp->cmd_un.scsi.bp		= bp;
2969 	bcopy(ucmdp->uscsi_cdb, pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
2970 	icmdp->cmd_un.scsi.cmdlen	= ucmdp->uscsi_cdblen;
2971 	icmdp->cmd_un.scsi.statuslen	= rqlen;
2972 	icmdp->cmd_crc_error_seen	= B_FALSE;
2973 	icmdp->cmd_completed		= B_FALSE;
2974 	icmdp->cmd_result		= ISCSI_STATUS_SUCCESS;
2975 
2976 	/*
2977 	 * Step 2. Push IO onto pending queue.  If we aren't in
2978 	 * FULL_FEATURE we need to fail the IO.
2979 	 */
2980 	mutex_enter(&isp->sess_state_mutex);
2981 	if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
2982 		mutex_exit(&isp->sess_state_mutex);
2983 
2984 		iscsi_cmd_free(icmdp);
2985 		kmem_free(pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
2986 		kmem_free(pkt->pkt_scbp, rqlen);
2987 		kmem_free(pkt, sizeof (struct scsi_pkt));
2988 		kmem_free(bp, sizeof (struct buf));
2989 
2990 		return (ISCSI_STATUS_CMD_FAILED);
2991 	}
2992 
2993 	mutex_enter(&isp->sess_queue_pending.mutex);
2994 	iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2995 	mutex_exit(&isp->sess_queue_pending.mutex);
2996 	mutex_exit(&isp->sess_state_mutex);
2997 
2998 	/*
2999 	 * Step 3. Wait on cv_wait for completion routine
3000 	 */
3001 	mutex_enter(&icmdp->cmd_mutex);
3002 	while (icmdp->cmd_completed == B_FALSE) {
3003 		cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
3004 	}
3005 	mutex_exit(&icmdp->cmd_mutex);
3006 
3007 	/* copy rval */
3008 	rval = icmdp->cmd_result;
3009 
3010 	ucmdp->uscsi_resid = pkt->pkt_resid;
3011 
3012 	/* update scsi status */
3013 	arqstat = (struct scsi_arq_status *)pkt->pkt_scbp;
3014 	ucmdp->uscsi_status = ((char *)&arqstat->sts_status)[0];
3015 
3016 	/* copy request sense buffers if caller gave space */
3017 	if ((ucmdp->uscsi_rqlen > 0) &&
3018 	    (ucmdp->uscsi_rqbuf != NULL)) {
3019 		bcopy(arqstat, ucmdp->uscsi_rqbuf,
3020 		    MIN(sizeof (struct scsi_arq_status), rqlen));
3021 	}
3022 
3023 	/* clean up */
3024 	iscsi_cmd_free(icmdp);
3025 	kmem_free(pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
3026 	kmem_free(pkt->pkt_scbp, rqlen);
3027 	kmem_free(pkt, sizeof (struct scsi_pkt));
3028 	kmem_free(bp, sizeof (struct buf));
3029 
3030 	return (rval);
3031 }
3032 
3033 
3034 /*
3035  * iscsi_handle_passthru_callback -
3036  *
3037  */
3038 static void
3039 iscsi_handle_passthru_callback(struct scsi_pkt *pkt)
3040 {
3041 	iscsi_cmd_t		*icmdp  = NULL;
3042 
3043 	ASSERT(pkt != NULL);
3044 	icmdp = (iscsi_cmd_t *)pkt->pkt_ha_private;
3045 	ASSERT(icmdp != NULL);
3046 
3047 	mutex_enter(&icmdp->cmd_mutex);
3048 	icmdp->cmd_completed    = B_TRUE;
3049 	icmdp->cmd_result	= ISCSI_STATUS_SUCCESS;
3050 	cv_broadcast(&icmdp->cmd_completion);
3051 	mutex_exit(&icmdp->cmd_mutex);
3052 
3053 }
3054 
3055 /*
3056  * IDM callbacks
3057  */
3058 void
3059 iscsi_build_hdr(idm_task_t *idm_task, idm_pdu_t *pdu, uint8_t opcode)
3060 {
3061 	iscsi_cmd_t *icmdp = idm_task->idt_private;
3062 	iscsi_conn_t *icp = icmdp->cmd_conn;
3063 	iscsi_data_hdr_t *ihp = (iscsi_data_hdr_t *)pdu->isp_hdr;
3064 
3065 	mutex_enter(&icmdp->cmd_mutex);
3066 	if (opcode == ISCSI_OP_SCSI_DATA) {
3067 		uint32_t	data_sn;
3068 		uint32_t	lun;
3069 		icmdp = idm_task->idt_private;
3070 		icp = icmdp->cmd_conn;
3071 		ihp->opcode	= opcode;
3072 		ihp->itt	= icmdp->cmd_itt;
3073 		ihp->ttt	= idm_task->idt_r2t_ttt;
3074 		ihp->expstatsn	= htonl(icp->conn_expstatsn);
3075 		icp->conn_laststatsn = icp->conn_expstatsn;
3076 		data_sn = ntohl(ihp->datasn);
3077 		data_sn++;
3078 		lun = icmdp->cmd_un.scsi.lun;
3079 		ISCSI_LUN_BYTE_COPY(ihp->lun, lun);
3080 		/* CRM: upate_flow_control */
3081 		ISCSI_IO_LOG(CE_NOTE, "DEBUG: iscsi_build_hdr"
3082 		    "(ISCSI_OP_SCSI_DATA): task: %p icp: %p ic: %p itt: %x "
3083 		    "exp: %d data_sn: %d", (void *)idm_task, (void *)icp,
3084 		    (void *)icp->conn_ic, ihp->itt, icp->conn_expstatsn,
3085 		    data_sn);
3086 	} else {
3087 		cmn_err(CE_WARN, "iscsi_build_hdr: unprocessed build "
3088 		    "header opcode: %x", opcode);
3089 	}
3090 	mutex_exit(&icmdp->cmd_mutex);
3091 }
3092 
3093 static void
3094 iscsi_process_rsp_status(iscsi_sess_t *isp, iscsi_conn_t *icp,
3095     idm_status_t status)
3096 {
3097 	switch (status) {
3098 	case IDM_STATUS_SUCCESS:
3099 		if ((isp->sess_state == ISCSI_SESS_STATE_IN_FLUSH) &&
3100 		    (icp->conn_queue_active.count == 0)) {
3101 			iscsi_drop_conn_cleanup(icp);
3102 		}
3103 		break;
3104 	case IDM_STATUS_PROTOCOL_ERROR:
3105 		KSTAT_INC_CONN_ERR_PROTOCOL(icp);
3106 		iscsi_drop_conn_cleanup(icp);
3107 		break;
3108 	default:
3109 		break;
3110 	}
3111 }
3112 
3113 static void
3114 iscsi_drop_conn_cleanup(iscsi_conn_t *icp) {
3115 	mutex_enter(&icp->conn_state_mutex);
3116 	idm_ini_conn_disconnect(icp->conn_ic);
3117 	mutex_exit(&icp->conn_state_mutex);
3118 }
3119 
3120 void
3121 iscsi_rx_error_pdu(idm_conn_t *ic, idm_pdu_t *pdu, idm_status_t status)
3122 {
3123 	iscsi_conn_t *icp = (iscsi_conn_t *)ic->ic_handle;
3124 	iscsi_sess_t *isp;
3125 
3126 	ASSERT(icp != NULL);
3127 	isp = icp->conn_sess;
3128 	ASSERT(isp != NULL);
3129 	iscsi_process_rsp_status(isp, icp, status);
3130 	idm_pdu_complete(pdu, status);
3131 }
3132 
3133 void
3134 iscsi_rx_misc_pdu(idm_conn_t *ic, idm_pdu_t *pdu)
3135 {
3136 	iscsi_conn_t 		*icp;
3137 	iscsi_hdr_t		*ihp	= (iscsi_hdr_t *)pdu->isp_hdr;
3138 	iscsi_sess_t		*isp;
3139 	idm_status_t		status;
3140 
3141 	icp = ic->ic_handle;
3142 	isp = icp->conn_sess;
3143 	isp->sess_rx_lbolt = icp->conn_rx_lbolt = ddi_get_lbolt();
3144 	switch (ihp->opcode & ISCSI_OPCODE_MASK) {
3145 	case ISCSI_OP_LOGIN_RSP:
3146 		status = iscsi_rx_process_login_pdu(ic, pdu);
3147 		idm_pdu_complete(pdu, status);
3148 		break;
3149 	case ISCSI_OP_LOGOUT_RSP:
3150 		status = iscsi_rx_process_logout_rsp(ic, pdu);
3151 		idm_pdu_complete(pdu, status);
3152 		break;
3153 	case ISCSI_OP_REJECT_MSG:
3154 		status = iscsi_rx_process_reject_rsp(ic, pdu);
3155 		break;
3156 	case ISCSI_OP_SCSI_TASK_MGT_RSP:
3157 		status = iscsi_rx_process_task_mgt_rsp(ic, pdu);
3158 		idm_pdu_complete(pdu, status);
3159 		break;
3160 	case ISCSI_OP_NOOP_IN:
3161 		status = iscsi_rx_process_nop(ic, pdu);
3162 		idm_pdu_complete(pdu, status);
3163 		break;
3164 	case ISCSI_OP_ASYNC_EVENT:
3165 		status = iscsi_rx_process_async_rsp(ic, pdu);
3166 		break;
3167 	case ISCSI_OP_TEXT_RSP:
3168 		status = iscsi_rx_process_text_rsp(ic, pdu);
3169 		idm_pdu_complete(pdu, status);
3170 		break;
3171 	default:
3172 		cmn_err(CE_WARN, "iscsi connection(%u) protocol error "
3173 		    "- received misc unsupported opcode 0x%02x",
3174 		    icp->conn_oid, ihp->opcode);
3175 		status = IDM_STATUS_PROTOCOL_ERROR;
3176 		break;
3177 	}
3178 	iscsi_process_rsp_status(isp, icp, status);
3179 }
3180 
3181 /*
3182  * +--------------------------------------------------------------------+
3183  * | Beginning of completion routines					|
3184  * +--------------------------------------------------------------------+
3185  */
3186 
3187 /*
3188  * iscsi_ic_thread -
3189  */
3190 void
3191 iscsi_ic_thread(iscsi_thread_t *thread, void *arg)
3192 {
3193 	iscsi_sess_t	*isp = (iscsi_sess_t *)arg;
3194 	int		ret;
3195 	iscsi_queue_t	q;
3196 	iscsi_cmd_t	*icmdp;
3197 	iscsi_cmd_t	*next_icmdp;
3198 
3199 	ASSERT(isp != NULL);
3200 	ASSERT(thread != NULL);
3201 	ASSERT(thread->signature == SIG_ISCSI_THREAD);
3202 
3203 	for (;;) {
3204 
3205 		/*
3206 		 * We wait till iodone or somebody else wakes us up.
3207 		 */
3208 		ret = iscsi_thread_wait(thread, -1);
3209 
3210 		/*
3211 		 * The value should never be negative since we never timeout.
3212 		 */
3213 		ASSERT(ret >= 0);
3214 
3215 		q.count = 0;
3216 		q.head  = NULL;
3217 		q.tail  = NULL;
3218 		mutex_enter(&isp->sess_queue_completion.mutex);
3219 		icmdp = isp->sess_queue_completion.head;
3220 		while (icmdp != NULL) {
3221 			next_icmdp = icmdp->cmd_next;
3222 			mutex_enter(&icmdp->cmd_mutex);
3223 			/*
3224 			 * check if the associated r2t/abort has finished
3225 			 * yet.  If not, don't complete the command.
3226 			 */
3227 			if ((icmdp->cmd_un.scsi.r2t_icmdp == NULL) &&
3228 			    (icmdp->cmd_un.scsi.abort_icmdp == NULL)) {
3229 				mutex_exit(&icmdp->cmd_mutex);
3230 				(void) iscsi_dequeue_cmd(&isp->
3231 				    sess_queue_completion.head,
3232 				    &isp->sess_queue_completion.tail,
3233 				    icmdp);
3234 				--isp->sess_queue_completion.count;
3235 				iscsi_enqueue_cmd_head(&q.head,
3236 				    &q.tail, icmdp);
3237 			} else {
3238 				mutex_exit(&icmdp->cmd_mutex);
3239 			}
3240 			icmdp = next_icmdp;
3241 		}
3242 		mutex_exit(&isp->sess_queue_completion.mutex);
3243 		icmdp = q.head;
3244 		while (icmdp != NULL) {
3245 			next_icmdp = icmdp->cmd_next;
3246 			iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E8, isp);
3247 			icmdp = next_icmdp;
3248 		}
3249 
3250 		if (ret > 0)
3251 			/* Somebody woke us up to work */
3252 			continue;
3253 		else
3254 			/*
3255 			 * Somebody woke us up to kill ourselves. We will
3256 			 * make sure, however that the completion queue is
3257 			 * empty before leaving.  After we've done that it
3258 			 * is the originator of the signal that has to make
3259 			 * sure no other SCSI command is posted.
3260 			 */
3261 			break;
3262 	}
3263 
3264 }
3265 
3266 /*
3267  * iscsi_iodone -
3268  *
3269  */
3270 void
3271 iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
3272 {
3273 	struct scsi_pkt		*pkt	= NULL;
3274 	struct buf		*bp	= icmdp->cmd_un.scsi.bp;
3275 
3276 	ASSERT(isp != NULL);
3277 	ASSERT(icmdp != NULL);
3278 	pkt = icmdp->cmd_un.scsi.pkt;
3279 	ASSERT(pkt != NULL);
3280 
3281 	ASSERT(icmdp->cmd_un.scsi.abort_icmdp == NULL);
3282 	ASSERT(icmdp->cmd_un.scsi.r2t_icmdp == NULL);
3283 	if (pkt->pkt_reason == CMD_CMPLT) {
3284 		if (bp) {
3285 			if (bp->b_flags & B_READ) {
3286 				KSTAT_SESS_RX_IO_DONE(isp, bp->b_bcount);
3287 			} else {
3288 				KSTAT_SESS_TX_IO_DONE(isp, bp->b_bcount);
3289 			}
3290 		}
3291 	}
3292 
3293 	if (pkt->pkt_flags & FLAG_NOINTR) {
3294 		cv_broadcast(&icmdp->cmd_completion);
3295 		mutex_exit(&icmdp->cmd_mutex);
3296 	} else {
3297 		/*
3298 		 * Release mutex.  As soon as callback is
3299 		 * issued the caller may destroy the command.
3300 		 */
3301 		mutex_exit(&icmdp->cmd_mutex);
3302 		/*
3303 		 * We can't just directly call the pk_comp routine.  In
3304 		 * many error cases the target driver will use the calling
3305 		 * thread to re-drive error handling (reset, retries...)
3306 		 * back into the hba driver (iscsi).  If the target redrives
3307 		 * a reset back into the iscsi driver off this thead we have
3308 		 * a chance of deadlocking. So instead use the io completion
3309 		 * thread.
3310 		 */
3311 		(*icmdp->cmd_un.scsi.pkt->pkt_comp)(icmdp->cmd_un.scsi.pkt);
3312 	}
3313 }
3314 
3315 /*
3316  * +--------------------------------------------------------------------+
3317  * | End of completion routines						|
3318  * +--------------------------------------------------------------------+
3319  */
3320 
3321 /*
3322  * +--------------------------------------------------------------------+
3323  * | Beginning of watchdog routines					|
3324  * +--------------------------------------------------------------------+
3325  */
3326 
3327 /*
3328  * iscsi_watchdog_thread -
3329  *
3330  */
3331 void
3332 iscsi_wd_thread(iscsi_thread_t *thread, void *arg)
3333 {
3334 	iscsi_sess_t	*isp = (iscsi_sess_t *)arg;
3335 	int		rc = 1;
3336 
3337 	ASSERT(isp != NULL);
3338 
3339 	while (rc != NULL) {
3340 
3341 		iscsi_timeout_checks(isp);
3342 		iscsi_nop_checks(isp);
3343 
3344 		rc = iscsi_thread_wait(thread, SEC_TO_TICK(1));
3345 	}
3346 }
3347 
3348 /*
3349  * iscsi_timeout_checks -
3350  *
3351  */
3352 static void
3353 iscsi_timeout_checks(iscsi_sess_t *isp)
3354 {
3355 	clock_t		now = ddi_get_lbolt();
3356 	iscsi_conn_t	*icp;
3357 	iscsi_cmd_t	*icmdp, *nicmdp;
3358 
3359 	ASSERT(isp != NULL);
3360 
3361 	/* PENDING */
3362 	mutex_enter(&isp->sess_state_mutex);
3363 	mutex_enter(&isp->sess_queue_pending.mutex);
3364 	for (icmdp = isp->sess_queue_pending.head;
3365 	    icmdp; icmdp = nicmdp) {
3366 		nicmdp = icmdp->cmd_next;
3367 
3368 		/* Skip entries with no timeout */
3369 		if (icmdp->cmd_lbolt_timeout == 0)
3370 			continue;
3371 
3372 		/*
3373 		 * Skip pending queue entries for cmd_type values that depend
3374 		 * on having an open cmdsn window for successfull transition
3375 		 * from pending to the active (i.e. ones that depend on
3376 		 * sess_cmdsn .vs. sess_maxcmdsn). For them, the timer starts
3377 		 * when they are successfully moved to the active queue by
3378 		 * iscsi_cmd_state_pending() code.
3379 		 */
3380 		/*
3381 		 * If the cmd is stuck, at least give it a chance
3382 		 * to timeout
3383 		 */
3384 		if (((icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) ||
3385 		    (icmdp->cmd_type == ISCSI_CMD_TYPE_TEXT)) &&
3386 		    !(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_STUCK))
3387 			continue;
3388 
3389 		/* Skip if timeout still in the future */
3390 		if (now <= icmdp->cmd_lbolt_timeout)
3391 			continue;
3392 
3393 		/* timeout */
3394 		iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E6, isp);
3395 	}
3396 	mutex_exit(&isp->sess_queue_pending.mutex);
3397 	mutex_exit(&isp->sess_state_mutex);
3398 
3399 	rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
3400 	icp = isp->sess_conn_list;
3401 	while (icp != NULL) {
3402 
3403 		icp->conn_timeout = B_FALSE;
3404 		/* ACTIVE */
3405 		mutex_enter(&icp->conn_state_mutex);
3406 		mutex_enter(&isp->sess_queue_pending.mutex);
3407 		mutex_enter(&icp->conn_queue_active.mutex);
3408 		for (icmdp = icp->conn_queue_active.head;
3409 		    icmdp; icmdp = nicmdp) {
3410 			nicmdp = icmdp->cmd_next;
3411 
3412 			if (iscsi_nop_timeout_checks(icmdp) == B_TRUE) {
3413 				icp->conn_timeout = B_TRUE;
3414 			}
3415 
3416 			/* Skip entries with no timeout */
3417 			if (icmdp->cmd_lbolt_timeout == 0)
3418 				continue;
3419 
3420 			/*
3421 			 * Skip if command is not active or not needed
3422 			 * to flush.
3423 			 */
3424 			if (icmdp->cmd_state != ISCSI_CMD_STATE_ACTIVE &&
3425 			    !(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_FLUSH))
3426 				continue;
3427 
3428 			/* Skip if timeout still in the future */
3429 			if (now <= icmdp->cmd_lbolt_timeout)
3430 				continue;
3431 
3432 			if (icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_FLUSH) {
3433 				/*
3434 				 * This command is left during target reset,
3435 				 * we can flush it now.
3436 				 */
3437 				iscsi_cmd_state_machine(icmdp,
3438 				    ISCSI_CMD_EVENT_E7, isp);
3439 			} else if (icmdp->cmd_state == ISCSI_CMD_STATE_ACTIVE) {
3440 				/* timeout */
3441 				iscsi_cmd_state_machine(icmdp,
3442 				    ISCSI_CMD_EVENT_E6, isp);
3443 			}
3444 
3445 		}
3446 		mutex_exit(&icp->conn_queue_active.mutex);
3447 		mutex_exit(&isp->sess_queue_pending.mutex);
3448 		mutex_exit(&icp->conn_state_mutex);
3449 
3450 		icp = icp->conn_next;
3451 	}
3452 
3453 	icp = isp->sess_conn_list;
3454 	while (icp != NULL) {
3455 		if (icp->conn_timeout == B_TRUE) {
3456 			/* timeout on this connect detected */
3457 			idm_ini_conn_disconnect(icp->conn_ic);
3458 			icp->conn_timeout = B_FALSE;
3459 		}
3460 		icp = icp->conn_next;
3461 	}
3462 	rw_exit(&isp->sess_conn_list_rwlock);
3463 }
3464 
3465 /*
3466  * iscsi_nop_checks - sends a NOP on idle connections
3467  *
3468  * This function walks the connections on a session and
3469  * issues NOPs on those connections that are in FULL
3470  * FEATURE mode and have not received data for the
3471  * time period specified by iscsi_nop_delay (global).
3472  */
3473 static void
3474 iscsi_nop_checks(iscsi_sess_t *isp)
3475 {
3476 	iscsi_conn_t	*icp;
3477 
3478 	ASSERT(isp != NULL);
3479 
3480 	if (isp->sess_type == ISCSI_SESS_TYPE_DISCOVERY) {
3481 		return;
3482 	}
3483 
3484 	rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
3485 	icp = isp->sess_conn_act;
3486 	if (icp != NULL) {
3487 
3488 		mutex_enter(&icp->conn_state_mutex);
3489 		if ((ISCSI_CONN_STATE_FULL_FEATURE(icp->conn_state)) &&
3490 		    (ddi_get_lbolt() > isp->sess_conn_act->conn_rx_lbolt +
3491 		    SEC_TO_TICK(iscsi_nop_delay)) && (ddi_get_lbolt() >
3492 		    isp->sess_conn_act->conn_nop_lbolt +
3493 		    SEC_TO_TICK(iscsi_nop_delay))) {
3494 
3495 			/*
3496 			 * We haven't received anything from the
3497 			 * target is a defined period of time,
3498 			 * send NOP to see if the target is alive.
3499 			 */
3500 			mutex_enter(&isp->sess_queue_pending.mutex);
3501 			iscsi_handle_nop(isp->sess_conn_act,
3502 			    0, ISCSI_RSVD_TASK_TAG);
3503 			mutex_exit(&isp->sess_queue_pending.mutex);
3504 		}
3505 		mutex_exit(&icp->conn_state_mutex);
3506 
3507 		icp = icp->conn_next;
3508 	}
3509 	rw_exit(&isp->sess_conn_list_rwlock);
3510 }
3511 
3512 static boolean_t
3513 iscsi_nop_timeout_checks(iscsi_cmd_t *icmdp)
3514 {
3515 	if (icmdp->cmd_type == ISCSI_CMD_TYPE_NOP) {
3516 		if ((ddi_get_lbolt() - icmdp->cmd_lbolt_active) >
3517 		    SEC_TO_TICK(ISCSI_CONN_TIEMOUT_DETECT)) {
3518 			return (B_TRUE);
3519 		} else {
3520 			return (B_FALSE);
3521 		}
3522 	}
3523 	return (B_FALSE);
3524 }
3525 /*
3526  * +--------------------------------------------------------------------+
3527  * | End of wd routines						|
3528  * +--------------------------------------------------------------------+
3529  */
3530 
3531 /*
3532  * iscsi_flush_cmd_after_reset - flush commands after reset
3533  *
3534  * Here we will flush all the commands in the same connection whose cmdsn is
3535  * less than the one received with the Unit Attention.
3536  */
3537 static void
3538 iscsi_flush_cmd_after_reset(uint32_t cmd_sn, uint16_t lun_num,
3539     iscsi_conn_t *icp)
3540 {
3541 	iscsi_cmd_t	*t_icmdp    = NULL;
3542 	iscsi_cmd_t	*next_icmdp = NULL;
3543 
3544 	ASSERT(icp != NULL);
3545 
3546 	t_icmdp = icp->conn_queue_active.head;
3547 	while (t_icmdp != NULL) {
3548 		next_icmdp = t_icmdp->cmd_next;
3549 		mutex_enter(&t_icmdp->cmd_mutex);
3550 		/*
3551 		 * We will flush the commands whose cmdsn is less than the one
3552 		 * got Unit Attention.
3553 		 * Here we will check for wrap by subtracting and compare to
3554 		 * 1/2 of a 32 bit number, if greater then we wrapped.
3555 		 */
3556 		if ((t_icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_SENT) &&
3557 		    ((cmd_sn > t_icmdp->cmd_sn) ||
3558 		    ((t_icmdp->cmd_sn - cmd_sn) >
3559 		    ISCSI_CMD_SN_WRAP))) {
3560 			if (t_icmdp->cmd_lun != NULL &&
3561 			    t_icmdp->cmd_lun->lun_num == lun_num) {
3562 				t_icmdp->cmd_misc_flags |=
3563 				    ISCSI_CMD_MISCFLAG_FLUSH;
3564 				if (t_icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) {
3565 					t_icmdp->cmd_un.scsi.pkt_stat |=
3566 					    STAT_BUS_RESET;
3567 				}
3568 			}
3569 		}
3570 		mutex_exit(&t_icmdp->cmd_mutex);
3571 		t_icmdp = next_icmdp;
3572 	}
3573 }
3574 
3575 /*
3576  * iscsi_decode_sense - decode the sense data in the cmd response
3577  *
3578  * Here we only care about Unit Attention with 0x29.
3579  */
3580 static boolean_t
3581 iscsi_decode_sense(uint8_t *sense_data)
3582 {
3583 	uint8_t	sense_key   = 0;
3584 	uint8_t	asc	    = 0;
3585 	boolean_t affect    = B_FALSE;
3586 
3587 	ASSERT(sense_data != NULL);
3588 
3589 	sense_key = scsi_sense_key(sense_data);
3590 	switch (sense_key) {
3591 		case KEY_UNIT_ATTENTION:
3592 			asc = scsi_sense_asc(sense_data);
3593 			switch (asc) {
3594 				case ISCSI_SCSI_RESET_SENSE_CODE:
3595 					/*
3596 					 * POWER ON, RESET, OR BUS_DEVICE RESET
3597 					 * OCCURRED
3598 					 */
3599 					affect = B_TRUE;
3600 					break;
3601 				default:
3602 					/*
3603 					 * Currently we don't care
3604 					 * about other sense key.
3605 					 */
3606 					break;
3607 			}
3608 			break;
3609 		default:
3610 			/*
3611 			 * Currently we don't care
3612 			 * about other sense key.
3613 			 */
3614 			break;
3615 	}
3616 	return (affect);
3617 }
3618