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