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