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