1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2000 by Cisco Systems, Inc.  All rights reserved.
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  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, iscsi_cmd_t *icmdp);
 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, icmdp);
 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    = ic->ic_handle;
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). Fire the enumeration
1440                  * to handle the change.
1441                  */
1442                 if (isp->sess_type == ISCSI_SESS_TYPE_NORMAL) {
1443                         rw_enter(&isp->sess_state_rwlock, RW_READER);
1444                         if (isp->sess_state == ISCSI_SESS_STATE_LOGGED_IN) {
1445                                 (void) iscsi_sess_enum_request(isp, B_FALSE,
1446                                     isp->sess_state_event_count);
1447                         }
1448                         rw_exit(&isp->sess_state_rwlock);
1449                 }
1450                 break;
1451 
1452         case ISCSI_ASYNC_EVENT_REQUEST_LOGOUT:
1453                 /*
1454                  * We've been asked to logout by the target --
1455                  * we need to treat this differently from a normal logout
1456                  * due to a discovery failure.  Normal logouts result in
1457                  * an N3 event to the session state machine and an offline
1458                  * of the lun.  In this case we want to put the connection
1459                  * into "failed" state and generate N5 to the session state
1460                  * machine since the initiator logged out at the target's
1461                  * request.  To track this we set a flag indicating we
1462                  * received this async logout request from the tharget
1463                  */
1464                 mutex_enter(&icp->conn_state_mutex);
1465                 icp->conn_async_logout = B_TRUE;
1466                 mutex_exit(&icp->conn_state_mutex);
1467 
1468                 /* Hold is released in iscsi_handle_logout. */
1469                 idm_conn_hold(ic);
1470 
1471                 /* Target has requested this connection to logout. */
1472                 itp = kmem_zalloc(sizeof (iscsi_task_t), KM_SLEEP);
1473                 itp->t_arg = icp;
1474                 itp->t_blocking = B_FALSE;
1475                 if (ddi_taskq_dispatch(isp->sess_login_taskq,
1476                     (void(*)())iscsi_logout_start, itp, DDI_SLEEP) !=
1477                     DDI_SUCCESS) {
1478                         idm_conn_rele(ic);
1479                         /* Disconnect if we couldn't dispatch the task */
1480                         idm_ini_conn_disconnect(ic);
1481                 }
1482                 break;
1483 
1484         case ISCSI_ASYNC_EVENT_DROPPING_CONNECTION:
1485                 /*
1486                  * Target is going to drop our connection.
1487                  *      param1 - CID which will be dropped.
1488                  *      param2 - Min time to reconnect.
1489                  *      param3 - Max time to reconnect.
1490                  *
1491                  * For now just let fail as another disconnect.
1492                  *
1493                  * MC/S Once we support > 1 connections then
1494                  * we need to check the CID and drop that
1495                  * specific connection.
1496                  */
1497                 iscsi_conn_set_login_min_max(icp, iaehp->param2,
1498                     iaehp->param3);
1499                 idm_ini_conn_disconnect(ic);
1500                 break;
1501 
1502         case ISCSI_ASYNC_EVENT_DROPPING_ALL_CONNECTIONS:
1503                 /*
1504                  * Target is going to drop ALL connections.
1505                  *      param2 - Min time to reconnect.
1506                  *      param3 - Max time to reconnect.
1507                  *
1508                  * For now just let fail as anyother disconnect.
1509                  *
1510                  * MC/S Once we support more than > 1 connections
1511                  * then we need to drop all connections on the
1512                  * session.
1513                  */
1514                 iscsi_conn_set_login_min_max(icp, iaehp->param2,
1515                     iaehp->param3);
1516                 idm_ini_conn_disconnect(ic);
1517                 break;
1518 
1519         case ISCSI_ASYNC_EVENT_PARAM_NEGOTIATION:
1520                 /*
1521                  * Target requests parameter negotiation
1522                  * on this connection.
1523                  *
1524                  * The initiator must honor this request.  For
1525                  * now we will request a logout.  We can't
1526                  * just ignore this or it might force corruption?
1527                  */
1528 
1529                 /* Hold is released in iscsi_handle_logout */
1530                 idm_conn_hold(ic);
1531                 itp = kmem_zalloc(sizeof (iscsi_task_t), KM_SLEEP);
1532                 itp->t_arg = icp;
1533                 itp->t_blocking = B_FALSE;
1534                 if (ddi_taskq_dispatch(isp->sess_login_taskq,
1535                     (void(*)())iscsi_logout_start, itp, DDI_SLEEP) !=
1536                     DDI_SUCCESS) {
1537                         /* Disconnect if we couldn't dispatch the task */
1538                         idm_conn_rele(ic);
1539                         idm_ini_conn_disconnect(ic);
1540                 }
1541                 break;
1542 
1543         case ISCSI_ASYNC_EVENT_VENDOR_SPECIFIC:
1544                 /*
1545                  * We currently don't handle any vendor
1546                  * specific async events.  So just ignore
1547                  * the request.
1548                  */
1549                 idm_ini_conn_disconnect(ic);
1550                 break;
1551         default:
1552                 rval = IDM_STATUS_PROTOCOL_ERROR;
1553         }
1554 
1555         return (rval);
1556 }
1557 
1558 /*
1559  * iscsi_rx_process_text_rsp - processes iSCSI text response.  It sets
1560  * the cmd_result field of the command data structure with the actual
1561  * status value instead of returning the status value.  The return value
1562  * is SUCCESS in order to let iscsi_handle_text control the operation of
1563  * a text request.
1564  * Text requests are a handled a little different than other types of
1565  * iSCSI commands because the initiator sends additional empty text requests
1566  * in order to obtain the remaining responses required to complete the
1567  * request.  iscsi_handle_text controls the operation of text request, while
1568  * iscsi_rx_process_text_rsp just process the current response.
1569  */
1570 static idm_status_t
1571 iscsi_rx_process_text_rsp(idm_conn_t *ic, idm_pdu_t *pdu)
1572 {
1573         iscsi_sess_t            *isp    = NULL;
1574         iscsi_text_rsp_hdr_t    *ithp   =
1575             (iscsi_text_rsp_hdr_t *)pdu->isp_hdr;
1576         iscsi_conn_t            *icp    = ic->ic_handle;
1577         iscsi_cmd_t             *icmdp  = NULL;
1578         boolean_t               final   = B_FALSE;
1579         uint32_t                data_len;
1580         uint8_t                 *data = pdu->isp_data;
1581         idm_status_t            rval;
1582 
1583         isp = icp->conn_sess;
1584 
1585         mutex_enter(&icp->conn_queue_active.mutex);
1586         if ((rval = iscsi_rx_chk(icp, isp, (iscsi_scsi_rsp_hdr_t *)ithp,
1587             &icmdp)) != IDM_STATUS_SUCCESS) {
1588                 mutex_exit(&icp->conn_queue_active.mutex);
1589                 return (rval);
1590         }
1591 
1592         /* update local final response flag */
1593         if (ithp->flags & ISCSI_FLAG_FINAL) {
1594                 final = B_TRUE;
1595         }
1596 
1597         /*
1598          * validate received TTT value.  RFC3720 specifies the following:
1599          * - F bit set to 1 MUST have a reserved TTT value 0xffffffff
1600          * - F bit set to 0 MUST have a non-reserved TTT value !0xffffffff
1601          * In addition, the received TTT value must not change between
1602          * responses of a long text response
1603          */
1604         if (((final == B_TRUE) && (ithp->ttt != ISCSI_RSVD_TASK_TAG)) ||
1605             ((final == B_FALSE) && (ithp->ttt == ISCSI_RSVD_TASK_TAG))) {
1606                 icmdp->cmd_result = ISCSI_STATUS_PROTOCOL_ERROR;
1607                 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1608                 mutex_exit(&icp->conn_queue_active.mutex);
1609                 cmn_err(CE_WARN, "iscsi connection(%u) protocol error - "
1610                     "received text response with invalid flags:0x%x or "
1611                     "ttt:0x%x", icp->conn_oid, ithp->flags, ithp->itt);
1612                 return (IDM_STATUS_PROTOCOL_ERROR);
1613         }
1614 
1615         if ((icmdp->cmd_un.text.stage == ISCSI_CMD_TEXT_INITIAL_REQ) &&
1616             (ithp->ttt == ISCSI_RSVD_TASK_TAG) &&
1617             (final == B_FALSE)) {
1618                 /* TTT should have matched reserved value */
1619                 icmdp->cmd_result = ISCSI_STATUS_PROTOCOL_ERROR;
1620                 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1621                 mutex_exit(&icp->conn_queue_active.mutex);
1622                 cmn_err(CE_WARN, "iscsi connection(%u) protocol "
1623                     "error - received text response with invalid "
1624                     "ttt:0x%x", icp->conn_oid, ithp->ttt);
1625                 return (IDM_STATUS_PROTOCOL_ERROR);
1626         }
1627 
1628         /*
1629          * If this is first response, save away TTT value for later use
1630          * in a long text request/response sequence
1631          */
1632         if (icmdp->cmd_un.text.stage == ISCSI_CMD_TEXT_INITIAL_REQ) {
1633                 icmdp->cmd_un.text.ttt = ithp->ttt;
1634         }
1635 
1636         data_len = ntoh24(ithp->dlength);
1637 
1638         /* check whether enough buffer available to copy data */
1639         if ((icmdp->cmd_un.text.total_rx_len + data_len) >
1640             icmdp->cmd_un.text.buf_len) {
1641                 icmdp->cmd_un.text.total_rx_len += data_len;
1642                 icmdp->cmd_result = ISCSI_STATUS_DATA_OVERFLOW;
1643                 /*
1644                  * DATA_OVERFLOW will result in a SUCCESS return so that
1645                  * iscsi_handle_text can continue to obtain the remaining
1646                  * text response if needed.
1647                  */
1648         } else {
1649                 char *buf_data = (icmdp->cmd_un.text.buf +
1650                     icmdp->cmd_un.text.offset);
1651 
1652                 bcopy(data, buf_data, data_len);
1653                 icmdp->cmd_un.text.offset += data_len;
1654                 icmdp->cmd_un.text.total_rx_len += data_len;
1655                 icmdp->cmd_result = ISCSI_STATUS_SUCCESS;
1656                 bcopy(ithp->rsvd4, icmdp->cmd_un.text.lun,
1657                     sizeof (icmdp->cmd_un.text.lun));
1658         }
1659 
1660         /* update stage  */
1661         if (final == B_TRUE) {
1662                 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_FINAL_RSP;
1663         } else {
1664                 icmdp->cmd_un.text.stage = ISCSI_CMD_TEXT_CONTINUATION;
1665         }
1666 
1667         iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E3, isp);
1668         mutex_exit(&icp->conn_queue_active.mutex);
1669         return (IDM_STATUS_SUCCESS);
1670 }
1671 
1672 /*
1673  * iscsi_rx_process_scsi_itt_to_icmdp - Lookup itt using IDM to find matching
1674  * icmdp.  Verify itt in hdr and icmdp are the same.
1675  */
1676 static iscsi_status_t
1677 iscsi_rx_process_scsi_itt_to_icmdp(iscsi_sess_t *isp, idm_conn_t *ic,
1678     iscsi_scsi_rsp_hdr_t *ihp, iscsi_cmd_t **icmdp)
1679 {
1680         idm_task_t *itp;
1681 
1682         ASSERT(isp != NULL);
1683         ASSERT(ihp != NULL);
1684         ASSERT(icmdp != NULL);
1685         ASSERT(mutex_owned(&isp->sess_cmdsn_mutex));
1686         itp = idm_task_find_and_complete(ic, ihp->itt, ISCSI_INI_TASK_TTT);
1687         if (itp == NULL) {
1688                 cmn_err(CE_WARN, "iscsi session(%u) protocol error - "
1689                     "received unknown itt:0x%x - protocol error",
1690                     isp->sess_oid, ihp->itt);
1691                 return (ISCSI_STATUS_INTERNAL_ERROR);
1692         }
1693         *icmdp = itp->idt_private;
1694 
1695         idm_task_rele(itp);
1696 
1697         return (ISCSI_STATUS_SUCCESS);
1698 
1699 }
1700 
1701 /*
1702  * iscsi_rx_process_itt_to_icmdp - Lookup itt in the session's
1703  * cmd table to find matching icmdp.  Verify itt in hdr and
1704  * icmdp are the same.
1705  */
1706 static iscsi_status_t
1707 iscsi_rx_process_itt_to_icmdp(iscsi_sess_t *isp, iscsi_hdr_t *ihp,
1708     iscsi_cmd_t **icmdp)
1709 {
1710         int cmd_table_idx = 0;
1711 
1712         ASSERT(isp != NULL);
1713         ASSERT(ihp != NULL);
1714         ASSERT(icmdp != NULL);
1715         ASSERT(mutex_owned(&isp->sess_cmdsn_mutex));
1716 
1717         /* try to find an associated iscsi_pkt */
1718         cmd_table_idx = (ihp->itt - IDM_TASKIDS_MAX) % ISCSI_CMD_TABLE_SIZE;
1719         if (isp->sess_cmd_table[cmd_table_idx] == NULL) {
1720                 cmn_err(CE_WARN, "iscsi session(%u) protocol error - "
1721                     "received unknown itt:0x%x - protocol error",
1722                     isp->sess_oid, ihp->itt);
1723                 return (ISCSI_STATUS_INTERNAL_ERROR);
1724         }
1725 
1726         /* verify itt */
1727         if (isp->sess_cmd_table[cmd_table_idx]->cmd_itt != ihp->itt) {
1728                 cmn_err(CE_WARN, "iscsi session(%u) received itt:0x%x "
1729                     " which is out of sync with itt:0x%x", isp->sess_oid,
1730                     ihp->itt, isp->sess_cmd_table[cmd_table_idx]->cmd_itt);
1731                 return (ISCSI_STATUS_INTERNAL_ERROR);
1732         }
1733 
1734         /* ensure that icmdp is still in Active state */
1735         if (isp->sess_cmd_table[cmd_table_idx]->cmd_state !=
1736             ISCSI_CMD_STATE_ACTIVE) {
1737                 cmn_err(CE_WARN, "iscsi session(%u) received itt:0x%x "
1738                     "but icmdp (%p) is not in active state",
1739                     isp->sess_oid, ihp->itt,
1740                     (void *)isp->sess_cmd_table[cmd_table_idx]);
1741                 return (ISCSI_STATUS_INTERNAL_ERROR);
1742         }
1743 
1744         /* make sure this is a SCSI cmd */
1745         *icmdp = isp->sess_cmd_table[cmd_table_idx];
1746 
1747         return (ISCSI_STATUS_SUCCESS);
1748 }
1749 
1750 /*
1751  * +--------------------------------------------------------------------+
1752  * | End of protocol receive routines                                   |
1753  * +--------------------------------------------------------------------+
1754  */
1755 
1756 /*
1757  * +--------------------------------------------------------------------+
1758  * | Beginning of protocol send routines                                |
1759  * +--------------------------------------------------------------------+
1760  */
1761 
1762 
1763 /*
1764  * iscsi_tx_thread - This thread is the driving point for all
1765  * iSCSI PDUs after login.  No PDUs should call idm_pdu_tx()
1766  * directly they should be funneled through iscsi_tx_thread.
1767  */
1768 void
1769 iscsi_tx_thread(iscsi_thread_t *thread, void *arg)
1770 {
1771         iscsi_conn_t    *icp    = (iscsi_conn_t *)arg;
1772         iscsi_sess_t    *isp    = NULL;
1773         iscsi_cmd_t     *icmdp  = NULL;
1774         clock_t         tout;
1775         int             ret     = 1;
1776 
1777         ASSERT(icp != NULL);
1778         isp = icp->conn_sess;
1779         ASSERT(isp != NULL);
1780         ASSERT(thread != NULL);
1781         ASSERT(thread->signature == SIG_ISCSI_THREAD);
1782 
1783         tout = SEC_TO_TICK(1);
1784         /*
1785          * Transfer icmdps until shutdown by owning session.
1786          */
1787         while (ret != 0) {
1788 
1789                 isp->sess_window_open = B_TRUE;
1790                 /*
1791                  * While the window is open, there are commands available
1792                  * to send and the session state allows those commands to
1793                  * be sent try to transfer them.
1794                  */
1795                 mutex_enter(&isp->sess_queue_pending.mutex);
1796                 while ((isp->sess_window_open == B_TRUE) &&
1797                     ((icmdp = isp->sess_queue_pending.head) != NULL)) {
1798                         if (((icmdp->cmd_type != ISCSI_CMD_TYPE_SCSI) &&
1799                             (ISCSI_CONN_STATE_FULL_FEATURE(icp->conn_state))) ||
1800                             (icp->conn_state == ISCSI_CONN_STATE_LOGGED_IN)) {
1801 
1802                                 /* update command with this connection info */
1803                                 icmdp->cmd_conn = icp;
1804                                 /* attempt to send this command */
1805                                 iscsi_cmd_state_machine(icmdp,
1806                                     ISCSI_CMD_EVENT_E2, isp);
1807 
1808                                 ASSERT(!mutex_owned(
1809                                     &isp->sess_queue_pending.mutex));
1810                                 mutex_enter(&isp->sess_queue_pending.mutex);
1811                         } else {
1812                                 while (icmdp != NULL) {
1813                                         if ((icmdp->cmd_type !=
1814                                             ISCSI_CMD_TYPE_SCSI) &&
1815                                             (ISCSI_CONN_STATE_FULL_FEATURE
1816                                             (icp->conn_state) != B_TRUE)) {
1817                                                 icmdp->cmd_misc_flags |=
1818                                                     ISCSI_CMD_MISCFLAG_STUCK;
1819                                         } else if (icp->conn_state !=
1820                                             ISCSI_CONN_STATE_LOGGED_IN) {
1821                                                 icmdp->cmd_misc_flags |=
1822                                                     ISCSI_CMD_MISCFLAG_STUCK;
1823                                         }
1824                                         icmdp = icmdp->cmd_next;
1825                                 }
1826                                 break;
1827                         }
1828                 }
1829                 mutex_exit(&isp->sess_queue_pending.mutex);
1830 
1831                 /*
1832                  * Go to sleep until there is something new
1833                  * to process (awoken via cv_boardcast).
1834                  * Or the timer goes off.
1835                  */
1836                 ret = iscsi_thread_wait(thread, tout);
1837         }
1838 
1839 }
1840 
1841 
1842 /*
1843  * iscsi_tx_cmd - transfers icmdp across wire as iscsi pdu
1844  *
1845  * Just prior to sending the command to the networking layer the
1846  * pending queue lock will be dropped.  At this point only local
1847  * resources will be used, not the icmdp.  Holding the queue lock
1848  * across the networking call can lead to a hang.  (This is due
1849  * to the the target driver and networking layers competing use
1850  * of the timeout() resources and the queue lock being held for
1851  * both sides.)  Upon the completion of this command the lock
1852  * will have been re-acquired.
1853  */
1854 iscsi_status_t
1855 iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
1856 {
1857         iscsi_status_t  rval = ISCSI_STATUS_INTERNAL_ERROR;
1858 
1859         ASSERT(isp != NULL);
1860         ASSERT(icmdp != NULL);
1861 
1862         /* transfer specific command type */
1863         switch (icmdp->cmd_type) {
1864         case ISCSI_CMD_TYPE_SCSI:
1865                 rval = iscsi_tx_scsi(isp, icmdp);
1866                 break;
1867         case ISCSI_CMD_TYPE_NOP:
1868                 rval = iscsi_tx_nop(isp, icmdp);
1869                 break;
1870         case ISCSI_CMD_TYPE_ABORT:
1871                 rval = iscsi_tx_abort(isp, icmdp);
1872                 break;
1873         case ISCSI_CMD_TYPE_RESET:
1874                 rval = iscsi_tx_reset(isp, icmdp);
1875                 break;
1876         case ISCSI_CMD_TYPE_LOGOUT:
1877                 rval = iscsi_tx_logout(isp, icmdp);
1878                 break;
1879         case ISCSI_CMD_TYPE_TEXT:
1880                 rval = iscsi_tx_text(isp, icmdp);
1881                 break;
1882         default:
1883                 cmn_err(CE_WARN, "iscsi_tx_cmd: invalid cmdtype: %d",
1884                     icmdp->cmd_type);
1885                 ASSERT(FALSE);
1886         }
1887 
1888         ASSERT(!mutex_owned(&isp->sess_queue_pending.mutex));
1889         return (rval);
1890 }
1891 
1892 /*
1893  * a variable length cdb can be up to 16K, but we obviously don't want
1894  * to put that on the stack; go with 200 bytes; if we get something
1895  * bigger than that we will kmem_alloc a buffer
1896  */
1897 #define DEF_CDB_LEN     200
1898 
1899 /*
1900  * given the size of the cdb, return how many bytes the header takes,
1901  * which is the sizeof addl_hdr_t + the CDB size, minus the 16 bytes
1902  * stored in the basic header, minus sizeof (ahs_extscb)
1903  */
1904 #define ADDLHDRSZ(x)            (sizeof (iscsi_addl_hdr_t) + (x) - \
1905                                         16 - 4)
1906 
1907 static void
1908 iscsi_tx_init_hdr(iscsi_sess_t *isp, iscsi_conn_t *icp,
1909     iscsi_text_hdr_t *ihp, int opcode, iscsi_cmd_t *icmdp)
1910 {
1911         ihp->opcode          = opcode;
1912         ihp->itt             = icmdp->cmd_itt;
1913         mutex_enter(&isp->sess_cmdsn_mutex);
1914         icmdp->cmd_sn                = isp->sess_cmdsn;
1915         ihp->cmdsn           = htonl(isp->sess_cmdsn);
1916         isp->sess_cmdsn++;
1917         mutex_exit(&isp->sess_cmdsn_mutex);
1918         ihp->expstatsn               = htonl(icp->conn_expstatsn);
1919         icp->conn_laststatsn = icp->conn_expstatsn;
1920 }
1921 
1922 
1923 static void
1924 iscsi_tx_scsi_data(iscsi_cmd_t *icmdp, iscsi_scsi_cmd_hdr_t *ihp,
1925     iscsi_conn_t *icp, idm_pdu_t *pdu)
1926 {
1927         struct buf              *bp             = NULL;
1928         size_t                  buflen          = 0;
1929         uint32_t                first_burst_length = 0;
1930         struct scsi_pkt         *pkt;
1931 
1932         pkt = icmdp->cmd_un.scsi.pkt;
1933         bp = icmdp->cmd_un.scsi.bp;
1934         if ((bp != NULL) && bp->b_bcount) {
1935                 buflen = bp->b_bcount;
1936                 first_burst_length =
1937                     icp->conn_params.first_burst_length;
1938 
1939                 if (bp->b_flags & B_READ) {
1940                         ihp->flags = ISCSI_FLAG_FINAL;
1941                         /*
1942                          * fix problem where OS sends bp (B_READ &
1943                          * b_bcount!=0) for a TUR or START_STOP.
1944                          * (comment came from cisco code.)
1945                          */
1946                         if ((pkt->pkt_cdbp[0] != SCMD_TEST_UNIT_READY) &&
1947                             (pkt->pkt_cdbp[0] != SCMD_START_STOP)) {
1948                                 ihp->flags |= ISCSI_FLAG_CMD_READ;
1949                                 ihp->data_length = htonl(buflen);
1950                         }
1951                 } else {
1952                         ihp->flags = ISCSI_FLAG_CMD_WRITE;
1953                         /*
1954                          * FinalBit on the the iSCSI PDU denotes this
1955                          * is the last PDU in the sequence.
1956                          *
1957                          * initial_r2t = true means R2T is required
1958                          * for additional PDU, so there will be no more
1959                          * unsolicited PDUs following
1960                          */
1961                         if (icp->conn_params.initial_r2t) {
1962                                 ihp->flags |= ISCSI_FLAG_FINAL;
1963                         }
1964 
1965                         /* Check if we should send ImmediateData */
1966                         if (icp->conn_params.immediate_data) {
1967                                 pdu->isp_data =
1968                                     (uint8_t *)icmdp->
1969                                     cmd_un.scsi.bp->b_un.b_addr;
1970 
1971                                 pdu->isp_datalen = MIN(MIN(buflen,
1972                                     first_burst_length),
1973                                     icmdp->cmd_conn->conn_params.
1974                                     max_xmit_data_seg_len);
1975 
1976                                 /*
1977                                  * if everything fits immediate, or
1978                                  * we can send all burst data immediate
1979                                  * (not unsol), set F
1980                                  */
1981                                 /*
1982                                  * XXX This doesn't look right -- it's not
1983                                  * clear how we can handle transmitting
1984                                  * any unsolicited data.  It looks like
1985                                  * we only support immediate data.  So what
1986                                  * happens if we don't set ISCSI_FLAG_FINAL?
1987                                  *
1988                                  * Unless there's magic code somewhere that
1989                                  * is sending the remaining PDU's we should
1990                                  * simply set ISCSI_FLAG_FINAL and forget
1991                                  * about sending unsolicited data.  The big
1992                                  * win is the immediate data anyway for small
1993                                  * PDU's.
1994                                  */
1995                                 if ((pdu->isp_datalen == buflen) ||
1996                                     (pdu->isp_datalen == first_burst_length)) {
1997                                         ihp->flags |= ISCSI_FLAG_FINAL;
1998                                 }
1999 
2000                                 hton24(ihp->dlength, pdu->isp_datalen);
2001                         }
2002                         /* total data transfer length */
2003                         ihp->data_length = htonl(buflen);
2004                 }
2005         } else {
2006                 ihp->flags = ISCSI_FLAG_FINAL;
2007         }
2008         icmdp->cmd_un.scsi.data_transferred += pdu->isp_datalen;
2009         /* XXX How is this different from the code above? */
2010         /* will idm send the next data command up to burst length? */
2011         /* send the burstlen if we haven't sent immediate data */
2012         /* CRM: should idm send difference min(buflen, first_burst) and  imm? */
2013         /*    (MIN(first_burst_length, buflen) - imdata > 0) */
2014         /* CRM_LATER: change this to generate unsolicited pdu */
2015         if ((buflen > 0) &&
2016             ((bp->b_flags & B_READ) == 0) &&
2017             (icp->conn_params.initial_r2t == 0) &&
2018             pdu->isp_datalen == 0) {
2019 
2020                 pdu->isp_datalen = MIN(first_burst_length, buflen);
2021                 if ((pdu->isp_datalen == buflen) ||
2022                     (pdu->isp_datalen == first_burst_length)) {
2023                         ihp->flags |= ISCSI_FLAG_FINAL;
2024                 }
2025                 pdu->isp_data = (uint8_t *)icmdp->cmd_un.scsi.bp->b_un.b_addr;
2026                 hton24(ihp->dlength, pdu->isp_datalen);
2027         }
2028 }
2029 
2030 static void
2031 iscsi_tx_scsi_init_pkt(iscsi_cmd_t *icmdp, iscsi_scsi_cmd_hdr_t *ihp)
2032 {
2033         struct scsi_pkt *pkt;
2034 
2035         pkt = icmdp->cmd_un.scsi.pkt;
2036         pkt->pkt_state = (STATE_GOT_BUS | STATE_GOT_TARGET);
2037         pkt->pkt_reason = CMD_INCOMPLETE;
2038 
2039         /* tagged queuing */
2040         if (pkt->pkt_flags & FLAG_HTAG) {
2041                 ihp->flags |= ISCSI_ATTR_HEAD_OF_QUEUE;
2042         } else if (pkt->pkt_flags & FLAG_OTAG) {
2043                 ihp->flags |= ISCSI_ATTR_ORDERED;
2044         } else if (pkt->pkt_flags & FLAG_STAG) {
2045                 ihp->flags |= ISCSI_ATTR_SIMPLE;
2046         } else {
2047                 /* ihp->flags |= ISCSI_ATTR_UNTAGGED; */
2048                 /* EMPTY */
2049         }
2050 
2051         /* iscsi states lun is based on spc.2 */
2052         ISCSI_LUN_BYTE_COPY(ihp->lun, icmdp->cmd_un.scsi.lun);
2053 
2054         if (icmdp->cmd_un.scsi.cmdlen <= 16) {
2055                 /* copy the SCSI Command Block into the PDU */
2056                 bcopy(pkt->pkt_cdbp, ihp->scb,
2057                     icmdp->cmd_un.scsi.cmdlen);
2058         } else {
2059                 iscsi_addl_hdr_t *iahp;
2060 
2061                 iahp = (iscsi_addl_hdr_t *)ihp;
2062 
2063                 ihp->hlength = (ADDLHDRSZ(icmdp->cmd_un.scsi.cmdlen) -
2064                     sizeof (iscsi_scsi_cmd_hdr_t) + 3) / 4;
2065                 iahp->ahs_hlen_hi = 0;
2066                 iahp->ahs_hlen_lo = (icmdp->cmd_un.scsi.cmdlen - 15);
2067                 iahp->ahs_key = 0x01;
2068                 iahp->ahs_resv = 0;
2069                 bcopy(pkt->pkt_cdbp, ihp->scb, 16);
2070                 bcopy(((char *)pkt->pkt_cdbp) + 16, &iahp->ahs_extscb[0],
2071                     icmdp->cmd_un.scsi.cmdlen);
2072         }
2073 
2074         /*
2075          * Update all values before transfering.
2076          * We should never touch the icmdp after
2077          * transfering if there is no more data
2078          * to send.  The only case the idm_pdu_tx()
2079          * will fail is a on a connection disconnect
2080          * in that case the command will be flushed.
2081          */
2082         pkt->pkt_state |= STATE_SENT_CMD;
2083 }
2084 
2085 static void
2086 iscsi_tx_scsi_init_task(iscsi_cmd_t *icmdp, iscsi_conn_t *icp,
2087     iscsi_scsi_cmd_hdr_t *ihp)
2088 {
2089         idm_task_t              *itp;
2090         struct buf              *bp             = NULL;
2091         uint32_t                data_length;
2092 
2093         bp = icmdp->cmd_un.scsi.bp;
2094 
2095         itp = icmdp->cmd_itp;
2096         ASSERT(itp != NULL);
2097         data_length = ntohl(ihp->data_length);
2098         ISCSI_IO_LOG(CE_NOTE,
2099             "DEBUG: iscsi_tx_init_task: task_start: %p idt_tt: %x cmdsn: %x "
2100             "sess_cmdsn: %x cmd: %p "
2101             "cmdtype: %d datalen: %u",
2102             (void *)itp, itp->idt_tt, ihp->cmdsn, icp->conn_sess->sess_cmdsn,
2103             (void *)icmdp, icmdp->cmd_type, data_length);
2104         if (data_length > 0) {
2105                 if (bp->b_flags & B_READ) {
2106                         icmdp->cmd_un.scsi.ibp_ibuf =
2107                             idm_buf_alloc(icp->conn_ic,
2108                             bp->b_un.b_addr, bp->b_bcount);
2109                         if (icmdp->cmd_un.scsi.ibp_ibuf)
2110                                 idm_buf_bind_in(itp,
2111                                     icmdp->cmd_un.scsi.ibp_ibuf);
2112                 } else {
2113                         icmdp->cmd_un.scsi.ibp_obuf =
2114                             idm_buf_alloc(icp->conn_ic,
2115                             bp->b_un.b_addr, bp->b_bcount);
2116                         if (icmdp->cmd_un.scsi.ibp_obuf)
2117                                 idm_buf_bind_out(itp,
2118                                     icmdp->cmd_un.scsi.ibp_obuf);
2119                 }
2120                 ISCSI_IO_LOG(CE_NOTE,
2121                     "DEBUG: pdu_tx: task_start(%s): %p ic: %p idt_tt: %x "
2122                     "cmdsn: %x sess_cmdsn: %x sess_expcmdsn: %x obuf: %p "
2123                     "cmdp: %p cmdtype: %d "
2124                     "buflen: %lu " "bpaddr: %p datalen: %u ",
2125                     bp->b_flags & B_READ ? "B_READ" : "B_WRITE",
2126                     (void *)itp, (void *)icp->conn_ic,
2127                     itp->idt_tt, ihp->cmdsn,
2128                     icp->conn_sess->sess_cmdsn,
2129                     icp->conn_sess->sess_expcmdsn,
2130                     (void *)icmdp->cmd_un.scsi.ibp_ibuf,
2131                     (void *)icmdp, icmdp->cmd_type, bp->b_bcount,
2132                     (void *)bp->b_un.b_addr,
2133                     data_length);
2134         }
2135 
2136         /*
2137          * Task is now active
2138          */
2139         idm_task_start(itp, ISCSI_INI_TASK_TTT);
2140 }
2141 
2142 /*
2143  * iscsi_tx_scsi -
2144  *
2145  */
2146 static iscsi_status_t
2147 iscsi_tx_scsi(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2148 {
2149         iscsi_status_t          rval            = ISCSI_STATUS_SUCCESS;
2150         iscsi_conn_t            *icp            = NULL;
2151         struct scsi_pkt         *pkt            = NULL;
2152         iscsi_scsi_cmd_hdr_t    *ihp            = NULL;
2153         int                     cdblen          = 0;
2154         idm_pdu_t               *pdu;
2155         int                     len;
2156 
2157         ASSERT(isp != NULL);
2158         ASSERT(icmdp != NULL);
2159 
2160         pdu = kmem_zalloc(sizeof (idm_pdu_t), KM_SLEEP);
2161 
2162         pkt = icmdp->cmd_un.scsi.pkt;
2163         ASSERT(pkt != NULL);
2164         icp = icmdp->cmd_conn;
2165         ASSERT(icp != NULL);
2166 
2167         /* Reset counts in case we are on a retry */
2168         icmdp->cmd_un.scsi.data_transferred = 0;
2169 
2170         if (icmdp->cmd_un.scsi.cmdlen > DEF_CDB_LEN) {
2171                 cdblen = icmdp->cmd_un.scsi.cmdlen;
2172                 ihp = kmem_zalloc(ADDLHDRSZ(cdblen), KM_SLEEP);
2173                 len = ADDLHDRSZ(cdblen);
2174         } else {
2175                 /*
2176                  * only bzero the basic header; the additional header
2177                  * will be set up correctly later, if needed
2178                  */
2179                 ihp = kmem_zalloc(sizeof (iscsi_scsi_cmd_hdr_t), KM_SLEEP);
2180                 len = sizeof (iscsi_scsi_cmd_hdr_t);
2181         }
2182 
2183         iscsi_tx_init_hdr(isp, icp, (iscsi_text_hdr_t *)ihp,
2184             ISCSI_OP_SCSI_CMD, icmdp);
2185 
2186         idm_pdu_init(pdu, icp->conn_ic, (void *)icmdp, &iscsi_tx_done);
2187         idm_pdu_init_hdr(pdu, (uint8_t *)ihp, len);
2188         pdu->isp_data = NULL;
2189         pdu->isp_datalen = 0;
2190 
2191         /*
2192          * Sestion 12.11 of the iSCSI specification has a good table
2193          * describing when uncolicited data and/or immediate data
2194          * should be sent.
2195          */
2196 
2197         iscsi_tx_scsi_data(icmdp, ihp, icp, pdu);
2198 
2199         iscsi_tx_scsi_init_pkt(icmdp, ihp);
2200 
2201         /* Calls idm_task_start */
2202         iscsi_tx_scsi_init_task(icmdp, icp, ihp);
2203 
2204         mutex_exit(&isp->sess_queue_pending.mutex);
2205 
2206         idm_pdu_tx(pdu);
2207 
2208         icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_SENT;
2209 
2210         return (rval);
2211 }
2212 
2213 
2214 /* ARGSUSED */
2215 static void
2216 iscsi_tx_done(idm_pdu_t *pdu, idm_status_t status)
2217 {
2218         kmem_free((iscsi_hdr_t *)pdu->isp_hdr, pdu->isp_hdrlen);
2219         kmem_free(pdu, sizeof (idm_pdu_t));
2220 }
2221 
2222 
2223 static void
2224 iscsi_tx_pdu(iscsi_conn_t *icp, int opcode, void *hdr, int hdrlen,
2225     iscsi_cmd_t *icmdp)
2226 {
2227         idm_pdu_t       *tx_pdu;
2228         iscsi_hdr_t     *ihp = (iscsi_hdr_t *)hdr;
2229 
2230         tx_pdu = kmem_zalloc(sizeof (idm_pdu_t), KM_SLEEP);
2231         ASSERT(tx_pdu != NULL);
2232 
2233         idm_pdu_init(tx_pdu, icp->conn_ic, icmdp, &iscsi_tx_done);
2234         idm_pdu_init_hdr(tx_pdu, hdr, hdrlen);
2235         if (opcode == ISCSI_OP_TEXT_CMD) {
2236                 idm_pdu_init_data(tx_pdu,
2237                     (uint8_t *)icmdp->cmd_un.text.buf,
2238                     ntoh24(ihp->dlength));
2239         }
2240 
2241         mutex_exit(&icp->conn_sess->sess_queue_pending.mutex);
2242         idm_pdu_tx(tx_pdu);
2243         icmdp->cmd_misc_flags |= ISCSI_CMD_MISCFLAG_SENT;
2244 }
2245 
2246 
2247 /*
2248  * iscsi_tx_nop -
2249  *
2250  */
2251 static iscsi_status_t
2252 iscsi_tx_nop(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2253 {
2254         iscsi_status_t          rval    = ISCSI_STATUS_SUCCESS;
2255         iscsi_conn_t            *icp    = NULL;
2256         iscsi_nop_out_hdr_t     *inohp;
2257 
2258         ASSERT(isp != NULL);
2259         ASSERT(icmdp != NULL);
2260         icp = icmdp->cmd_conn;
2261         ASSERT(icp != NULL);
2262 
2263         inohp = kmem_zalloc(sizeof (iscsi_nop_out_hdr_t), KM_SLEEP);
2264         ASSERT(inohp != NULL);
2265 
2266         inohp->opcode        = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
2267         inohp->flags = ISCSI_FLAG_FINAL;
2268         inohp->itt   = icmdp->cmd_itt;
2269         inohp->ttt   = icmdp->cmd_ttt;
2270         mutex_enter(&isp->sess_cmdsn_mutex);
2271         icmdp->cmd_sn        = isp->sess_cmdsn;
2272         inohp->cmdsn = htonl(isp->sess_cmdsn);
2273         mutex_exit(&isp->sess_cmdsn_mutex);
2274         inohp->expstatsn     = htonl(icp->conn_expstatsn);
2275         icp->conn_laststatsn = icp->conn_expstatsn;
2276         iscsi_tx_pdu(icp, ISCSI_OP_NOOP_OUT, inohp,
2277             sizeof (iscsi_nop_out_hdr_t), icmdp);
2278         return (rval);
2279 }
2280 
2281 
2282 /*
2283  * iscsi_tx_abort -
2284  *
2285  */
2286 static iscsi_status_t
2287 iscsi_tx_abort(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2288 {
2289         iscsi_status_t                  rval    = ISCSI_STATUS_SUCCESS;
2290         iscsi_conn_t                    *icp    = NULL;
2291         iscsi_scsi_task_mgt_hdr_t       *istmh;
2292 
2293         ASSERT(isp != NULL);
2294         ASSERT(icmdp != NULL);
2295         icp = icmdp->cmd_conn;
2296         ASSERT(icp != NULL);
2297 
2298         istmh = kmem_zalloc(sizeof (iscsi_scsi_task_mgt_hdr_t), KM_SLEEP);
2299         ASSERT(istmh != NULL);
2300         mutex_enter(&isp->sess_cmdsn_mutex);
2301         icmdp->cmd_sn        = isp->sess_cmdsn;
2302         istmh->cmdsn = htonl(isp->sess_cmdsn);
2303         mutex_exit(&isp->sess_cmdsn_mutex);
2304         istmh->expstatsn = htonl(icp->conn_expstatsn);
2305         icp->conn_laststatsn = icp->conn_expstatsn;
2306         istmh->itt   = icmdp->cmd_itt;
2307         istmh->opcode        = ISCSI_OP_SCSI_TASK_MGT_MSG | ISCSI_OP_IMMEDIATE;
2308         istmh->function      = ISCSI_FLAG_FINAL | ISCSI_TM_FUNC_ABORT_TASK;
2309         ISCSI_LUN_BYTE_COPY(istmh->lun,
2310             icmdp->cmd_un.abort.icmdp->cmd_un.scsi.lun);
2311         istmh->rtt   = icmdp->cmd_un.abort.icmdp->cmd_itt;
2312         iscsi_tx_pdu(icp, ISCSI_OP_SCSI_TASK_MGT_MSG, istmh,
2313             sizeof (iscsi_scsi_task_mgt_hdr_t), icmdp);
2314 
2315         return (rval);
2316 }
2317 
2318 
2319 /*
2320  * iscsi_tx_reset -
2321  *
2322  */
2323 static iscsi_status_t
2324 iscsi_tx_reset(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2325 {
2326         iscsi_status_t                  rval    = ISCSI_STATUS_SUCCESS;
2327         iscsi_conn_t                    *icp    = NULL;
2328         iscsi_scsi_task_mgt_hdr_t       *istmh;
2329 
2330         ASSERT(isp != NULL);
2331         ASSERT(icmdp != NULL);
2332         icp = icmdp->cmd_conn;
2333         ASSERT(icp != NULL);
2334 
2335         istmh = kmem_zalloc(sizeof (iscsi_scsi_task_mgt_hdr_t), KM_SLEEP);
2336         ASSERT(istmh != NULL);
2337         istmh->opcode        = ISCSI_OP_SCSI_TASK_MGT_MSG | ISCSI_OP_IMMEDIATE;
2338         mutex_enter(&isp->sess_cmdsn_mutex);
2339         icmdp->cmd_sn        = isp->sess_cmdsn;
2340         istmh->cmdsn = htonl(isp->sess_cmdsn);
2341         mutex_exit(&isp->sess_cmdsn_mutex);
2342         istmh->expstatsn     = htonl(icp->conn_expstatsn);
2343         istmh->itt   = icmdp->cmd_itt;
2344 
2345         switch (icmdp->cmd_un.reset.level) {
2346         case RESET_LUN:
2347                 istmh->function      = ISCSI_FLAG_FINAL |
2348                     ISCSI_TM_FUNC_LOGICAL_UNIT_RESET;
2349                 ISCSI_LUN_BYTE_COPY(istmh->lun, icmdp->cmd_lun->lun_num);
2350                 break;
2351         case RESET_TARGET:
2352         case RESET_BUS:
2353                 istmh->function      = ISCSI_FLAG_FINAL |
2354                     ISCSI_TM_FUNC_TARGET_WARM_RESET;
2355                 break;
2356         default:
2357                 /* unsupported / unknown level */
2358                 ASSERT(FALSE);
2359                 break;
2360         }
2361 
2362         iscsi_tx_pdu(icp, ISCSI_OP_SCSI_TASK_MGT_MSG, istmh,
2363             sizeof (iscsi_scsi_task_mgt_hdr_t), icmdp);
2364 
2365         return (rval);
2366 }
2367 
2368 
2369 /*
2370  * iscsi_tx_logout -
2371  *
2372  */
2373 static iscsi_status_t
2374 iscsi_tx_logout(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2375 {
2376         iscsi_status_t          rval    = ISCSI_STATUS_SUCCESS;
2377         iscsi_conn_t            *icp    = NULL;
2378         iscsi_logout_hdr_t      *ilh;
2379 
2380         ASSERT(isp != NULL);
2381         ASSERT(icmdp != NULL);
2382         icp = icmdp->cmd_conn;
2383         ASSERT(icp != NULL);
2384 
2385         ilh = kmem_zalloc(sizeof (iscsi_logout_hdr_t), KM_SLEEP);
2386         ilh->opcode  = ISCSI_OP_LOGOUT_CMD | ISCSI_OP_IMMEDIATE;
2387         ilh->flags   = ISCSI_FLAG_FINAL | ISCSI_LOGOUT_REASON_CLOSE_SESSION;
2388         ilh->itt             = icmdp->cmd_itt;
2389         ilh->cid             = icp->conn_cid;
2390         mutex_enter(&isp->sess_cmdsn_mutex);
2391         icmdp->cmd_sn        = isp->sess_cmdsn;
2392         ilh->cmdsn   = htonl(isp->sess_cmdsn);
2393         mutex_exit(&isp->sess_cmdsn_mutex);
2394         ilh->expstatsn       = htonl(icp->conn_expstatsn);
2395         iscsi_tx_pdu(icp, ISCSI_OP_LOGOUT_CMD, ilh,
2396             sizeof (iscsi_logout_hdr_t), icmdp);
2397 
2398         return (rval);
2399 }
2400 
2401 /*
2402  * iscsi_tx_text - setup iSCSI text request header and send PDU with
2403  * data given in the buffer attached to the command.  For a single
2404  * text request, the target may need to send its response in multiple
2405  * text response.  In this case, empty text requests are sent after
2406  * each received response to notify the target the initiator is ready
2407  * for more response.  For the initial request, the data_len field in
2408  * the text specific portion of a command is set to the amount of data
2409  * the initiator wants to send as part of the request. If additional
2410  * empty text requests are required for long responses, the data_len
2411  * field is set to 0 by the iscsi_handle_text function.
2412  */
2413 static iscsi_status_t
2414 iscsi_tx_text(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
2415 {
2416         iscsi_status_t          rval    = ISCSI_STATUS_SUCCESS;
2417         iscsi_conn_t            *icp    = NULL;
2418         iscsi_text_hdr_t        *ith;
2419 
2420         ASSERT(icmdp != NULL);
2421         icp = icmdp->cmd_conn;
2422         ASSERT(icp != NULL);
2423 
2424         ith = kmem_zalloc(sizeof (iscsi_text_hdr_t), KM_SLEEP);
2425         ASSERT(ith != NULL);
2426         ith->flags   = ISCSI_FLAG_FINAL;
2427         hton24(ith->dlength, icmdp->cmd_un.text.data_len);
2428         ith->ttt             = icmdp->cmd_un.text.ttt;
2429         iscsi_tx_init_hdr(isp, icp, (iscsi_text_hdr_t *)ith,
2430             ISCSI_OP_TEXT_CMD, icmdp);
2431         bcopy(icmdp->cmd_un.text.lun, ith->rsvd4, sizeof (ith->rsvd4));
2432 
2433         iscsi_tx_pdu(icp, ISCSI_OP_TEXT_CMD, ith, sizeof (iscsi_text_hdr_t),
2434             icmdp);
2435 
2436         return (rval);
2437 }
2438 
2439 /*
2440  * +--------------------------------------------------------------------+
2441  * | End of protocol send routines                                      |
2442  * +--------------------------------------------------------------------+
2443  */
2444 
2445 /*
2446  * iscsi_handle_abort -
2447  *
2448  */
2449 void
2450 iscsi_handle_abort(void *arg)
2451 {
2452         iscsi_sess_t    *isp            = NULL;
2453         iscsi_cmd_t     *icmdp          = (iscsi_cmd_t *)arg;
2454         iscsi_cmd_t     *new_icmdp;
2455         iscsi_conn_t    *icp;
2456 
2457         ASSERT(icmdp != NULL);
2458         icp = icmdp->cmd_conn;
2459         ASSERT(icp != NULL);
2460         isp = icp->conn_sess;
2461         ASSERT(isp != NULL);
2462 
2463         /* there should only be one abort */
2464         ASSERT(icmdp->cmd_un.scsi.abort_icmdp == NULL);
2465 
2466         new_icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2467         new_icmdp->cmd_type              = ISCSI_CMD_TYPE_ABORT;
2468         new_icmdp->cmd_lun               = icmdp->cmd_lun;
2469         new_icmdp->cmd_un.abort.icmdp            = icmdp;
2470         new_icmdp->cmd_conn              = icmdp->cmd_conn;
2471         icmdp->cmd_un.scsi.abort_icmdp           = new_icmdp;
2472 
2473         /* pending queue mutex is already held by timeout_checks */
2474         iscsi_cmd_state_machine(new_icmdp, ISCSI_CMD_EVENT_E1, isp);
2475 }
2476 
2477 /*
2478  * Callback from IDM indicating that the task has been suspended or aborted.
2479  */
2480 void
2481 iscsi_task_aborted(idm_task_t *idt, idm_status_t status)
2482 {
2483         iscsi_cmd_t *icmdp = idt->idt_private;
2484         iscsi_conn_t *icp = icmdp->cmd_conn;
2485         iscsi_sess_t *isp = icp->conn_sess;
2486 
2487         ASSERT(icmdp->cmd_conn != NULL);
2488 
2489         switch (status) {
2490         case IDM_STATUS_SUSPENDED:
2491                 /*
2492                  * If the task is suspended, it may be aborted later,
2493                  * so we can ignore this notification.
2494                  */
2495                 break;
2496 
2497         case IDM_STATUS_ABORTED:
2498                 mutex_enter(&icp->conn_queue_active.mutex);
2499                 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E9, isp);
2500                 mutex_exit(&icp->conn_queue_active.mutex);
2501                 break;
2502 
2503         default:
2504                 /*
2505                  * Unexpected status.
2506                  */
2507                 ASSERT(0);
2508         }
2509 
2510 }
2511 
2512 /*
2513  * iscsi_handle_nop -
2514  *
2515  */
2516 static void
2517 iscsi_handle_nop(iscsi_conn_t *icp, uint32_t itt, uint32_t ttt)
2518 {
2519         iscsi_sess_t    *isp    = NULL;
2520         iscsi_cmd_t     *icmdp  = NULL;
2521 
2522         ASSERT(icp != NULL);
2523         isp = icp->conn_sess;
2524         ASSERT(isp != NULL);
2525 
2526         icmdp = iscsi_cmd_alloc(icp, KM_NOSLEEP);
2527         if (icmdp == NULL) {
2528                 return;
2529         }
2530 
2531         icmdp->cmd_type              = ISCSI_CMD_TYPE_NOP;
2532         icmdp->cmd_itt               = itt;
2533         icmdp->cmd_ttt               = ttt;
2534         icmdp->cmd_lun               = NULL;
2535         icp->conn_nop_lbolt  = ddi_get_lbolt();
2536 
2537         iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2538 }
2539 
2540 /*
2541  * iscsi_handle_reset - send reset request to the target
2542  *
2543  */
2544 iscsi_status_t
2545 iscsi_handle_reset(iscsi_sess_t *isp, int level, iscsi_lun_t *ilp)
2546 {
2547         iscsi_status_t  rval    = ISCSI_STATUS_SUCCESS;
2548         iscsi_conn_t    *icp;
2549         iscsi_cmd_t     icmd;
2550 
2551         ASSERT(isp != NULL);
2552 
2553         if (level == RESET_LUN) {
2554                 rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2555                 ASSERT(ilp != NULL);
2556                 if (ilp->lun_state & ISCSI_LUN_STATE_BUSY) {
2557                         rw_exit(&isp->sess_lun_list_rwlock);
2558                         return (ISCSI_STATUS_SUCCESS);
2559                 }
2560                 ilp->lun_state |= ISCSI_LUN_STATE_BUSY;
2561                 rw_exit(&isp->sess_lun_list_rwlock);
2562         } else {
2563                 mutex_enter(&isp->sess_reset_mutex);
2564                 if (isp->sess_reset_in_progress == B_TRUE) {
2565                         /*
2566                          * If the reset is in progress, it is unnecessary
2567                          * to send reset to the target redunantly.
2568                          */
2569                         mutex_exit(&isp->sess_reset_mutex);
2570                         return (ISCSI_STATUS_SUCCESS);
2571                 }
2572                 isp->sess_reset_in_progress = B_TRUE;
2573                 mutex_exit(&isp->sess_reset_mutex);
2574         }
2575 
2576         bzero(&icmd, sizeof (iscsi_cmd_t));
2577         icmd.cmd_sig            = ISCSI_SIG_CMD;
2578         icmd.cmd_state          = ISCSI_CMD_STATE_FREE;
2579         icmd.cmd_type           = ISCSI_CMD_TYPE_RESET;
2580         icmd.cmd_lun            = ilp;
2581         icmd.cmd_un.reset.level = level;
2582         icmd.cmd_result         = ISCSI_STATUS_SUCCESS;
2583         icmd.cmd_completed      = B_FALSE;
2584         icmd.cmd_un.reset.response = SCSI_TCP_TM_RESP_COMPLETE;
2585 
2586         mutex_init(&icmd.cmd_mutex, NULL, MUTEX_DRIVER, NULL);
2587         cv_init(&icmd.cmd_completion, NULL, CV_DRIVER, NULL);
2588         /*
2589          * If we received an IO and we are not in the
2590          * LOGGED_IN state we are in the process of
2591          * failing.  Just respond that we are BUSY.
2592          */
2593         rw_enter(&isp->sess_state_rwlock, RW_READER);
2594         if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
2595                 /* We aren't connected to the target fake success */
2596                 rw_exit(&isp->sess_state_rwlock);
2597 
2598                 if (level == RESET_LUN) {
2599                         rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2600                         ilp->lun_state &= ~ISCSI_LUN_STATE_BUSY;
2601                         rw_exit(&isp->sess_lun_list_rwlock);
2602                 } else {
2603                         mutex_enter(&isp->sess_reset_mutex);
2604                         isp->sess_reset_in_progress = B_FALSE;
2605                         mutex_exit(&isp->sess_reset_mutex);
2606                 }
2607 
2608                 return (ISCSI_STATUS_SUCCESS);
2609         }
2610 
2611         mutex_enter(&isp->sess_queue_pending.mutex);
2612         iscsi_cmd_state_machine(&icmd, ISCSI_CMD_EVENT_E1, isp);
2613         mutex_exit(&isp->sess_queue_pending.mutex);
2614         rw_exit(&isp->sess_state_rwlock);
2615 
2616         /* stall until completed */
2617         mutex_enter(&icmd.cmd_mutex);
2618         while (icmd.cmd_completed == B_FALSE) {
2619                 cv_wait(&icmd.cmd_completion, &icmd.cmd_mutex);
2620         }
2621         mutex_exit(&icmd.cmd_mutex);
2622 
2623         /* copy rval */
2624         rval = icmd.cmd_result;
2625 
2626         if (rval == ISCSI_STATUS_SUCCESS) {
2627                 /*
2628                  * Reset was successful.  We need to flush
2629                  * all active IOs.
2630                  */
2631                 rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
2632                 icp = isp->sess_conn_list;
2633                 while (icp != NULL) {
2634                         iscsi_cmd_t *t_icmdp = NULL;
2635                         iscsi_cmd_t *next_icmdp = NULL;
2636 
2637                         mutex_enter(&icp->conn_queue_active.mutex);
2638                         t_icmdp = icp->conn_queue_active.head;
2639                         while (t_icmdp != NULL) {
2640                                 next_icmdp = t_icmdp->cmd_next;
2641                                 mutex_enter(&t_icmdp->cmd_mutex);
2642                                 if (!(t_icmdp->cmd_misc_flags &
2643                                     ISCSI_CMD_MISCFLAG_SENT)) {
2644                                         /*
2645                                          * Although this command is in the
2646                                          * active queue, it has not been sent.
2647                                          * Skip it.
2648                                          */
2649                                         mutex_exit(&t_icmdp->cmd_mutex);
2650                                         t_icmdp = next_icmdp;
2651                                         continue;
2652                                 }
2653                                 if (level == RESET_LUN) {
2654                                         if (icmd.cmd_lun == NULL ||
2655                                             t_icmdp->cmd_lun == NULL ||
2656                                             (icmd.cmd_lun->lun_num !=
2657                                             t_icmdp->cmd_lun->lun_num)) {
2658                                                 mutex_exit(&t_icmdp->cmd_mutex);
2659                                                 t_icmdp = next_icmdp;
2660                                                 continue;
2661                                         }
2662                                 }
2663 
2664                                 if (icmd.cmd_sn == t_icmdp->cmd_sn) {
2665                                         /*
2666                                          * This command may be replied with
2667                                          * UA sense key later. So currently
2668                                          * it is not a suitable time to flush
2669                                          * it. Mark its flag with FLUSH. There
2670                                          * is no harm to keep it for a while.
2671                                          */
2672                                         t_icmdp->cmd_misc_flags |=
2673                                             ISCSI_CMD_MISCFLAG_FLUSH;
2674                                         if (t_icmdp->cmd_type ==
2675                                             ISCSI_CMD_TYPE_SCSI) {
2676                                                 t_icmdp->cmd_un.scsi.pkt_stat |=
2677                                                     STAT_BUS_RESET;
2678                                         }
2679                                         mutex_exit(&t_icmdp->cmd_mutex);
2680                                 } else if ((icmd.cmd_sn > t_icmdp->cmd_sn) ||
2681                                     ((t_icmdp->cmd_sn - icmd.cmd_sn) >
2682                                     ISCSI_CMD_SN_WRAP)) {
2683                                         /*
2684                                          * This reset request must act on all
2685                                          * the commnds from the same session
2686                                          * having a CmdSN lower than the task
2687                                          * mangement CmdSN. So flush these
2688                                          * commands here.
2689                                          */
2690                                         if (t_icmdp->cmd_type ==
2691                                             ISCSI_CMD_TYPE_SCSI) {
2692                                                 t_icmdp->cmd_un.scsi.pkt_stat |=
2693                                                     STAT_BUS_RESET;
2694                                         }
2695                                         mutex_exit(&t_icmdp->cmd_mutex);
2696                                         iscsi_cmd_state_machine(t_icmdp,
2697                                             ISCSI_CMD_EVENT_E7, isp);
2698                                 } else {
2699                                         mutex_exit(&t_icmdp->cmd_mutex);
2700                                 }
2701 
2702                                 t_icmdp = next_icmdp;
2703                         }
2704 
2705                         mutex_exit(&icp->conn_queue_active.mutex);
2706                         icp = icp->conn_next;
2707                 }
2708                 rw_exit(&isp->sess_conn_list_rwlock);
2709         }
2710 
2711         /* clean up */
2712         cv_destroy(&icmd.cmd_completion);
2713         mutex_destroy(&icmd.cmd_mutex);
2714 
2715         if (level == RESET_LUN) {
2716                 rw_enter(&isp->sess_lun_list_rwlock, RW_WRITER);
2717                 ilp->lun_state &= ~ISCSI_LUN_STATE_BUSY;
2718                 rw_exit(&isp->sess_lun_list_rwlock);
2719         } else {
2720                 mutex_enter(&isp->sess_reset_mutex);
2721                 isp->sess_reset_in_progress = B_FALSE;
2722                 mutex_exit(&isp->sess_reset_mutex);
2723         }
2724 
2725         return (rval);
2726 }
2727 
2728 /*
2729  * iscsi_logout_start - task handler for deferred logout
2730  * Acquire a hold before call, released in iscsi_handle_logout
2731  */
2732 static void
2733 iscsi_logout_start(void *arg)
2734 {
2735         iscsi_task_t            *itp = (iscsi_task_t *)arg;
2736         iscsi_conn_t            *icp;
2737 
2738         icp = (iscsi_conn_t *)itp->t_arg;
2739 
2740         mutex_enter(&icp->conn_state_mutex);
2741         (void) iscsi_handle_logout(icp);
2742         mutex_exit(&icp->conn_state_mutex);
2743 }
2744 
2745 /*
2746  * iscsi_handle_logout - This function will issue a logout for
2747  * the session from a specific connection.
2748  * Acquire idm_conn_hold before call.  Released internally.
2749  */
2750 iscsi_status_t
2751 iscsi_handle_logout(iscsi_conn_t *icp)
2752 {
2753         iscsi_sess_t    *isp;
2754         idm_conn_t      *ic;
2755         iscsi_cmd_t     *icmdp;
2756         int             rval;
2757 
2758         ASSERT(icp != NULL);
2759         isp = icp->conn_sess;
2760         ic = icp->conn_ic;
2761         ASSERT(isp != NULL);
2762         ASSERT(isp->sess_hba != NULL);
2763         ASSERT(mutex_owned(&icp->conn_state_mutex));
2764 
2765         /*
2766          * If the connection has already gone down (e.g. if the transport
2767          * failed between when this LOGOUT was generated and now) then we
2768          * can and must skip sending the LOGOUT.  Check the same condition
2769          * we use below to determine that connection has "settled".
2770          */
2771         if ((icp->conn_state == ISCSI_CONN_STATE_FREE) ||
2772             (icp->conn_state == ISCSI_CONN_STATE_FAILED) ||
2773             (icp->conn_state == ISCSI_CONN_STATE_POLLING)) {
2774                 idm_conn_rele(ic);
2775                 return (0);
2776         }
2777 
2778         icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2779         ASSERT(icmdp != NULL);
2780         icmdp->cmd_type              = ISCSI_CMD_TYPE_LOGOUT;
2781         icmdp->cmd_result    = ISCSI_STATUS_SUCCESS;
2782         icmdp->cmd_completed = B_FALSE;
2783 
2784         mutex_enter(&isp->sess_queue_pending.mutex);
2785         iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2786         mutex_exit(&isp->sess_queue_pending.mutex);
2787 
2788         /*
2789          * release connection state mutex to avoid a deadlock.  This
2790          * function is called from within the connection state
2791          * machine with the lock held.  When the logout response is
2792          * received another call to the connection state machine
2793          * occurs which causes the deadlock
2794          */
2795         mutex_exit(&icp->conn_state_mutex);
2796 
2797         /* stall until completed */
2798         mutex_enter(&icmdp->cmd_mutex);
2799         while (icmdp->cmd_completed == B_FALSE) {
2800                 cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
2801         }
2802         mutex_exit(&icmdp->cmd_mutex);
2803         mutex_enter(&icp->conn_state_mutex);
2804 
2805         /* copy rval */
2806         rval = icmdp->cmd_result;
2807 
2808         /* clean up */
2809         iscsi_cmd_free(icmdp);
2810 
2811         if (rval != 0) {
2812                 /* If the logout failed then drop the connection */
2813                 idm_ini_conn_disconnect(icp->conn_ic);
2814         }
2815 
2816         /* stall until connection settles */
2817         while ((icp->conn_state != ISCSI_CONN_STATE_FREE) &&
2818             (icp->conn_state != ISCSI_CONN_STATE_FAILED) &&
2819             (icp->conn_state != ISCSI_CONN_STATE_POLLING)) {
2820                 /* wait for transition */
2821                 cv_wait(&icp->conn_state_change, &icp->conn_state_mutex);
2822         }
2823 
2824         idm_conn_rele(ic);
2825 
2826         /*
2827          * Return value reflects whether the logout command completed --
2828          * regardless of the return value the connection is closed and
2829          * ready for reconnection.
2830          */
2831         return (rval);
2832 }
2833 
2834 
2835 /*
2836  * iscsi_handle_text - main control function for iSCSI text requests.  This
2837  * function handles allocating the command, sending initial text request, and
2838  * handling long response sequence.
2839  * If a data overflow condition occurs, iscsi_handle_text continues to
2840  * receive responses until the all data has been recieved.  This allows
2841  * the full data length to be returned to the caller.
2842  */
2843 iscsi_status_t
2844 iscsi_handle_text(iscsi_conn_t *icp, char *buf, uint32_t buf_len,
2845     uint32_t data_len, uint32_t *rx_data_len)
2846 {
2847         iscsi_sess_t    *isp;
2848         iscsi_cmd_t     *icmdp;
2849         iscsi_status_t  rval    = ISCSI_STATUS_SUCCESS;
2850 
2851         ASSERT(icp != NULL);
2852         ASSERT(buf != NULL);
2853         ASSERT(rx_data_len != NULL);
2854 
2855         isp = icp->conn_sess;
2856         ASSERT(isp != NULL);
2857 
2858         /*
2859          * Ensure data for text request command is not greater
2860          * than the negotiated maximum receive data seqment length.
2861          *
2862          * Although iSCSI allows for long text requests (multiple
2863          * pdus), this function places a restriction on text
2864          * requests to ensure it is handled by a single PDU.
2865          */
2866         if (data_len > icp->conn_params.max_xmit_data_seg_len) {
2867                 return (ISCSI_STATUS_CMD_FAILED);
2868         }
2869 
2870         icmdp = iscsi_cmd_alloc(icp, KM_SLEEP);
2871         ASSERT(icmdp != NULL);
2872 
2873         icmdp->cmd_type              = ISCSI_CMD_TYPE_TEXT;
2874         icmdp->cmd_result    = ISCSI_STATUS_SUCCESS;
2875         icmdp->cmd_misc_flags        &= ~ISCSI_CMD_MISCFLAG_FREE;
2876         icmdp->cmd_completed = B_FALSE;
2877 
2878         icmdp->cmd_un.text.buf               = buf;
2879         icmdp->cmd_un.text.buf_len   = buf_len;
2880         icmdp->cmd_un.text.offset    = 0;
2881         icmdp->cmd_un.text.data_len  = data_len;
2882         icmdp->cmd_un.text.total_rx_len      = 0;
2883         icmdp->cmd_un.text.ttt               = ISCSI_RSVD_TASK_TAG;
2884         icmdp->cmd_un.text.stage     = ISCSI_CMD_TEXT_INITIAL_REQ;
2885 
2886 long_text_response:
2887         rw_enter(&isp->sess_state_rwlock, RW_READER);
2888         if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
2889                 iscsi_cmd_free(icmdp);
2890                 rw_exit(&isp->sess_state_rwlock);
2891                 return (ISCSI_STATUS_NO_CONN_LOGGED_IN);
2892         }
2893 
2894         mutex_enter(&isp->sess_queue_pending.mutex);
2895         iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
2896         mutex_exit(&isp->sess_queue_pending.mutex);
2897         rw_exit(&isp->sess_state_rwlock);
2898 
2899         /* stall until completed */
2900         mutex_enter(&icmdp->cmd_mutex);
2901         while (icmdp->cmd_completed == B_FALSE) {
2902                 cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
2903         }
2904         mutex_exit(&icmdp->cmd_mutex);
2905 
2906         /*
2907          * check if error occured.  If data overflow occured, continue on
2908          * to ensure we get all data so that the full data length can be
2909          * returned to the user
2910          */
2911         if ((icmdp->cmd_result != ISCSI_STATUS_SUCCESS) &&
2912             (icmdp->cmd_result != ISCSI_STATUS_DATA_OVERFLOW)) {
2913                 cmn_err(CE_NOTE, "iscsi: SendTarget discovery failed (%d)",
2914                     icmdp->cmd_result);
2915                 rval = icmdp->cmd_result;
2916                 iscsi_cmd_free(icmdp);
2917                 return (rval);
2918         }
2919 
2920         /* check if this was a partial text PDU  */
2921         if (icmdp->cmd_un.text.stage != ISCSI_CMD_TEXT_FINAL_RSP) {
2922                 /*
2923                  * If a paritial text rexponse received, send an empty
2924                  * text request.  This follows the behaviour specified
2925                  * in RFC3720 regarding long text responses.
2926                  */
2927                 icmdp->cmd_misc_flags                &= ~ISCSI_CMD_MISCFLAG_FREE;
2928                 icmdp->cmd_completed         = B_FALSE;
2929                 icmdp->cmd_un.text.data_len  = 0;
2930                 icmdp->cmd_un.text.stage     = ISCSI_CMD_TEXT_CONTINUATION;
2931                 goto long_text_response;
2932         }
2933 
2934         /*
2935          * set total received data length.  If data overflow this would be
2936          * amount of data that would have been received if buffer large
2937          * enough.
2938          */
2939         *rx_data_len = icmdp->cmd_un.text.total_rx_len;
2940 
2941         /* copy rval */
2942         rval = icmdp->cmd_result;
2943 
2944         /* clean up  */
2945         iscsi_cmd_free(icmdp);
2946 
2947         return (rval);
2948 }
2949 
2950 /*
2951  * iscsi_handle_passthru - This function is used to send a uscsi_cmd
2952  * to a specific target lun.  This routine is used for internal purposes
2953  * during enumeration and via the ISCSI_USCSICMD IOCTL.  We restrict
2954  * the CDBs that can be issued to a target/lun to INQUIRY, REPORT_LUNS,
2955  * and READ_CAPACITY for security purposes.
2956  *
2957  * The logic here is broken into three phases.
2958  * 1) Allocate and initialize a pkt/icmdp
2959  * 2) Send the pkt/icmdp
2960  * 3) cv_wait for completion
2961  */
2962 iscsi_status_t
2963 iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun, struct uscsi_cmd *ucmdp)
2964 {
2965         iscsi_status_t          rval;
2966         iscsi_cmd_t             *icmdp;
2967         struct scsi_pkt         *pkt;
2968         struct buf              *bp;
2969         struct scsi_arq_status  *arqstat;
2970         int                     statuslen;
2971 
2972         ASSERT(isp != NULL);
2973         ASSERT(ucmdp != NULL);
2974 
2975         if (ucmdp->uscsi_rqlen > SENSE_LENGTH) {
2976                 /*
2977                  * The caller provided sense buffer large enough for additional
2978                  * sense bytes. We need to allocate pkt_scbp to fit them there
2979                  * too.
2980                  */
2981                 statuslen = ucmdp->uscsi_rqlen + ISCSI_ARQ_STATUS_NOSENSE_LEN;
2982         } else {
2983                 /* The default size of pkt_scbp */
2984                 statuslen = sizeof (struct scsi_arq_status);
2985         }
2986 
2987         /*
2988          * Step 1. Setup structs - KM_SLEEP will always succeed
2989          */
2990         bp = kmem_zalloc(sizeof (struct buf), KM_SLEEP);
2991         ASSERT(bp != NULL);
2992         pkt = kmem_zalloc(sizeof (struct scsi_pkt), KM_SLEEP);
2993         ASSERT(pkt != NULL);
2994         icmdp = iscsi_cmd_alloc(NULL, KM_SLEEP);
2995         ASSERT(icmdp != NULL);
2996 
2997         /* setup bp structure */
2998         bp->b_flags          = B_READ;
2999         bp->b_bcount         = ucmdp->uscsi_buflen;
3000         bp->b_un.b_addr              = ucmdp->uscsi_bufaddr;
3001 
3002         /* setup scsi_pkt structure */
3003         pkt->pkt_ha_private  = icmdp;
3004         pkt->pkt_scbp                = kmem_zalloc(statuslen, KM_SLEEP);
3005         pkt->pkt_cdbp                = kmem_zalloc(ucmdp->uscsi_cdblen, KM_SLEEP);
3006         /* callback routine for passthru, will wake cv_wait */
3007         pkt->pkt_comp                = iscsi_handle_passthru_callback;
3008         pkt->pkt_time                = ucmdp->uscsi_timeout;
3009 
3010         /* setup iscsi_cmd structure */
3011         icmdp->cmd_lun                       = NULL;
3012         icmdp->cmd_type                      = ISCSI_CMD_TYPE_SCSI;
3013         icmdp->cmd_un.scsi.lun               = lun;
3014         icmdp->cmd_un.scsi.pkt               = pkt;
3015         icmdp->cmd_un.scsi.bp                = bp;
3016         bcopy(ucmdp->uscsi_cdb, pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
3017         icmdp->cmd_un.scsi.cmdlen    = ucmdp->uscsi_cdblen;
3018         icmdp->cmd_un.scsi.statuslen = statuslen;
3019         icmdp->cmd_crc_error_seen    = B_FALSE;
3020         icmdp->cmd_completed         = B_FALSE;
3021         icmdp->cmd_result            = ISCSI_STATUS_SUCCESS;
3022 
3023         /*
3024          * Step 2. Push IO onto pending queue.  If we aren't in
3025          * FULL_FEATURE we need to fail the IO.
3026          */
3027         rw_enter(&isp->sess_state_rwlock, RW_READER);
3028         if (!ISCSI_SESS_STATE_FULL_FEATURE(isp->sess_state)) {
3029                 rw_exit(&isp->sess_state_rwlock);
3030 
3031                 iscsi_cmd_free(icmdp);
3032                 kmem_free(pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
3033                 kmem_free(pkt->pkt_scbp, statuslen);
3034                 kmem_free(pkt, sizeof (struct scsi_pkt));
3035                 kmem_free(bp, sizeof (struct buf));
3036 
3037                 return (ISCSI_STATUS_CMD_FAILED);
3038         }
3039 
3040         mutex_enter(&isp->sess_queue_pending.mutex);
3041         iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E1, isp);
3042         mutex_exit(&isp->sess_queue_pending.mutex);
3043         rw_exit(&isp->sess_state_rwlock);
3044 
3045         /*
3046          * Step 3. Wait on cv_wait for completion routine
3047          */
3048         mutex_enter(&icmdp->cmd_mutex);
3049         while (icmdp->cmd_completed == B_FALSE) {
3050                 cv_wait(&icmdp->cmd_completion, &icmdp->cmd_mutex);
3051         }
3052         mutex_exit(&icmdp->cmd_mutex);
3053 
3054         /* copy rval */
3055         rval = icmdp->cmd_result;
3056 
3057         ucmdp->uscsi_resid = pkt->pkt_resid;
3058 
3059         /* update scsi status */
3060         arqstat = (struct scsi_arq_status *)pkt->pkt_scbp;
3061         ucmdp->uscsi_status = ((char *)&arqstat->sts_status)[0];
3062 
3063         /* copy request sense buffers if caller gave space */
3064         if ((ucmdp->uscsi_rqlen > 0) &&
3065             (ucmdp->uscsi_rqbuf != NULL)) {
3066                 ASSERT(ucmdp->uscsi_rqlen >= arqstat->sts_rqpkt_resid);
3067                 ucmdp->uscsi_rqresid = arqstat->sts_rqpkt_resid;
3068                 bcopy(&arqstat->sts_sensedata, ucmdp->uscsi_rqbuf,
3069                     ucmdp->uscsi_rqlen - arqstat->sts_rqpkt_resid);
3070         }
3071 
3072         if ((ucmdp->uscsi_status == STATUS_CHECK) &&
3073             ((icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_INTERNAL)) == B_TRUE) {
3074                 /*
3075                  * Internal SCSI commands received status
3076                  */
3077                 (void) iscsi_decode_sense(
3078                     (uint8_t *)&arqstat->sts_sensedata, icmdp);
3079         }
3080 
3081         /* clean up */
3082         iscsi_cmd_free(icmdp);
3083         kmem_free(pkt->pkt_cdbp, ucmdp->uscsi_cdblen);
3084         kmem_free(pkt->pkt_scbp, statuslen);
3085         kmem_free(pkt, sizeof (struct scsi_pkt));
3086         kmem_free(bp, sizeof (struct buf));
3087 
3088         return (rval);
3089 }
3090 
3091 
3092 /*
3093  * iscsi_handle_passthru_callback -
3094  *
3095  */
3096 static void
3097 iscsi_handle_passthru_callback(struct scsi_pkt *pkt)
3098 {
3099         iscsi_cmd_t             *icmdp  = NULL;
3100 
3101         ASSERT(pkt != NULL);
3102         icmdp = (iscsi_cmd_t *)pkt->pkt_ha_private;
3103         ASSERT(icmdp != NULL);
3104 
3105         mutex_enter(&icmdp->cmd_mutex);
3106         icmdp->cmd_completed    = B_TRUE;
3107         icmdp->cmd_result    = ISCSI_STATUS_SUCCESS;
3108         cv_broadcast(&icmdp->cmd_completion);
3109         mutex_exit(&icmdp->cmd_mutex);
3110 
3111 }
3112 
3113 /*
3114  * IDM callbacks
3115  */
3116 void
3117 iscsi_build_hdr(idm_task_t *idm_task, idm_pdu_t *pdu, uint8_t opcode)
3118 {
3119         iscsi_cmd_t *icmdp = idm_task->idt_private;
3120         iscsi_conn_t *icp = icmdp->cmd_conn;
3121         iscsi_data_hdr_t *ihp = (iscsi_data_hdr_t *)pdu->isp_hdr;
3122 
3123         mutex_enter(&icmdp->cmd_mutex);
3124         if (opcode == ISCSI_OP_SCSI_DATA) {
3125                 uint32_t        data_sn;
3126                 uint32_t        lun;
3127                 icmdp = idm_task->idt_private;
3128                 icp = icmdp->cmd_conn;
3129                 ihp->opcode  = opcode;
3130                 ihp->itt     = icmdp->cmd_itt;
3131                 ihp->ttt     = idm_task->idt_r2t_ttt;
3132                 ihp->expstatsn       = htonl(icp->conn_expstatsn);
3133                 icp->conn_laststatsn = icp->conn_expstatsn;
3134                 data_sn = ntohl(ihp->datasn);
3135                 data_sn++;
3136                 lun = icmdp->cmd_un.scsi.lun;
3137                 ISCSI_LUN_BYTE_COPY(ihp->lun, lun);
3138                 /* CRM: upate_flow_control */
3139                 ISCSI_IO_LOG(CE_NOTE, "DEBUG: iscsi_build_hdr"
3140                     "(ISCSI_OP_SCSI_DATA): task: %p icp: %p ic: %p itt: %x "
3141                     "exp: %d data_sn: %d", (void *)idm_task, (void *)icp,
3142                     (void *)icp->conn_ic, ihp->itt, icp->conn_expstatsn,
3143                     data_sn);
3144         } else {
3145                 cmn_err(CE_WARN, "iscsi_build_hdr: unprocessed build "
3146                     "header opcode: %x", opcode);
3147         }
3148         mutex_exit(&icmdp->cmd_mutex);
3149 }
3150 
3151 static void
3152 iscsi_process_rsp_status(iscsi_sess_t *isp, iscsi_conn_t *icp,
3153     idm_status_t status)
3154 {
3155         switch (status) {
3156         case IDM_STATUS_SUCCESS:
3157                 if ((isp->sess_state == ISCSI_SESS_STATE_IN_FLUSH) &&
3158                     (icp->conn_queue_active.count == 0)) {
3159                         iscsi_drop_conn_cleanup(icp);
3160                 }
3161                 break;
3162         case IDM_STATUS_PROTOCOL_ERROR:
3163                 KSTAT_INC_CONN_ERR_PROTOCOL(icp);
3164                 iscsi_drop_conn_cleanup(icp);
3165                 break;
3166         default:
3167                 break;
3168         }
3169 }
3170 
3171 static void
3172 iscsi_drop_conn_cleanup(iscsi_conn_t *icp) {
3173         mutex_enter(&icp->conn_state_mutex);
3174         idm_ini_conn_disconnect(icp->conn_ic);
3175         mutex_exit(&icp->conn_state_mutex);
3176 }
3177 
3178 void
3179 iscsi_rx_error_pdu(idm_conn_t *ic, idm_pdu_t *pdu, idm_status_t status)
3180 {
3181         iscsi_conn_t *icp = (iscsi_conn_t *)ic->ic_handle;
3182         iscsi_sess_t *isp;
3183 
3184         ASSERT(icp != NULL);
3185         isp = icp->conn_sess;
3186         ASSERT(isp != NULL);
3187         iscsi_process_rsp_status(isp, icp, status);
3188         idm_pdu_complete(pdu, status);
3189 }
3190 
3191 void
3192 iscsi_rx_misc_pdu(idm_conn_t *ic, idm_pdu_t *pdu)
3193 {
3194         iscsi_conn_t            *icp;
3195         iscsi_hdr_t             *ihp    = (iscsi_hdr_t *)pdu->isp_hdr;
3196         iscsi_sess_t            *isp;
3197         idm_status_t            status;
3198 
3199         icp = ic->ic_handle;
3200         isp = icp->conn_sess;
3201         isp->sess_rx_lbolt = icp->conn_rx_lbolt = ddi_get_lbolt();
3202         switch (ihp->opcode & ISCSI_OPCODE_MASK) {
3203         case ISCSI_OP_LOGIN_RSP:
3204                 status = iscsi_rx_process_login_pdu(ic, pdu);
3205                 idm_pdu_complete(pdu, status);
3206                 break;
3207         case ISCSI_OP_LOGOUT_RSP:
3208                 status = iscsi_rx_process_logout_rsp(ic, pdu);
3209                 idm_pdu_complete(pdu, status);
3210                 break;
3211         case ISCSI_OP_REJECT_MSG:
3212                 status = iscsi_rx_process_reject_rsp(ic, pdu);
3213                 break;
3214         case ISCSI_OP_SCSI_TASK_MGT_RSP:
3215                 status = iscsi_rx_process_task_mgt_rsp(ic, pdu);
3216                 idm_pdu_complete(pdu, status);
3217                 break;
3218         case ISCSI_OP_NOOP_IN:
3219                 status = iscsi_rx_process_nop(ic, pdu);
3220                 idm_pdu_complete(pdu, status);
3221                 break;
3222         case ISCSI_OP_ASYNC_EVENT:
3223                 status = iscsi_rx_process_async_rsp(ic, pdu);
3224                 break;
3225         case ISCSI_OP_TEXT_RSP:
3226                 status = iscsi_rx_process_text_rsp(ic, pdu);
3227                 idm_pdu_complete(pdu, status);
3228                 break;
3229         default:
3230                 cmn_err(CE_WARN, "iscsi connection(%u) protocol error "
3231                     "- received misc unsupported opcode 0x%02x",
3232                     icp->conn_oid, ihp->opcode);
3233                 status = IDM_STATUS_PROTOCOL_ERROR;
3234                 break;
3235         }
3236         iscsi_process_rsp_status(isp, icp, status);
3237 }
3238 
3239 /*
3240  * +--------------------------------------------------------------------+
3241  * | Beginning of completion routines                                   |
3242  * +--------------------------------------------------------------------+
3243  */
3244 
3245 /*
3246  * iscsi_ic_thread -
3247  */
3248 void
3249 iscsi_ic_thread(iscsi_thread_t *thread, void *arg)
3250 {
3251         iscsi_sess_t    *isp = (iscsi_sess_t *)arg;
3252         int             ret;
3253         iscsi_queue_t   q;
3254         iscsi_cmd_t     *icmdp;
3255         iscsi_cmd_t     *next_icmdp;
3256 
3257         ASSERT(isp != NULL);
3258         ASSERT(thread != NULL);
3259         ASSERT(thread->signature == SIG_ISCSI_THREAD);
3260 
3261         for (;;) {
3262 
3263                 /*
3264                  * We wait till iodone or somebody else wakes us up.
3265                  */
3266                 ret = iscsi_thread_wait(thread, -1);
3267 
3268                 /*
3269                  * The value should never be negative since we never timeout.
3270                  */
3271                 ASSERT(ret >= 0);
3272 
3273                 q.count = 0;
3274                 q.head  = NULL;
3275                 q.tail  = NULL;
3276                 mutex_enter(&isp->sess_queue_completion.mutex);
3277                 icmdp = isp->sess_queue_completion.head;
3278                 while (icmdp != NULL) {
3279                         next_icmdp = icmdp->cmd_next;
3280                         mutex_enter(&icmdp->cmd_mutex);
3281                         /*
3282                          * check if the associated r2t/abort has finished
3283                          * yet.  If not, don't complete the command.
3284                          */
3285                         if ((icmdp->cmd_un.scsi.r2t_icmdp == NULL) &&
3286                             (icmdp->cmd_un.scsi.abort_icmdp == NULL)) {
3287                                 mutex_exit(&icmdp->cmd_mutex);
3288                                 (void) iscsi_dequeue_cmd(&isp->
3289                                     sess_queue_completion.head,
3290                                     &isp->sess_queue_completion.tail,
3291                                     icmdp);
3292                                 --isp->sess_queue_completion.count;
3293                                 iscsi_enqueue_cmd_head(&q.head,
3294                                     &q.tail, icmdp);
3295                         } else {
3296                                 mutex_exit(&icmdp->cmd_mutex);
3297                         }
3298                         icmdp = next_icmdp;
3299                 }
3300                 mutex_exit(&isp->sess_queue_completion.mutex);
3301                 icmdp = q.head;
3302                 while (icmdp != NULL) {
3303                         next_icmdp = icmdp->cmd_next;
3304                         iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E8, isp);
3305                         icmdp = next_icmdp;
3306                 }
3307 
3308                 if (ret > 0)
3309                         /* Somebody woke us up to work */
3310                         continue;
3311                 else
3312                         /*
3313                          * Somebody woke us up to kill ourselves. We will
3314                          * make sure, however that the completion queue is
3315                          * empty before leaving.  After we've done that it
3316                          * is the originator of the signal that has to make
3317                          * sure no other SCSI command is posted.
3318                          */
3319                         break;
3320         }
3321 
3322 }
3323 
3324 /*
3325  * iscsi_iodone -
3326  *
3327  */
3328 void
3329 iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp)
3330 {
3331         struct scsi_pkt         *pkt    = NULL;
3332         struct buf              *bp     = icmdp->cmd_un.scsi.bp;
3333 
3334         ASSERT(isp != NULL);
3335         ASSERT(icmdp != NULL);
3336         pkt = icmdp->cmd_un.scsi.pkt;
3337         ASSERT(pkt != NULL);
3338 
3339         ASSERT(icmdp->cmd_un.scsi.abort_icmdp == NULL);
3340         ASSERT(icmdp->cmd_un.scsi.r2t_icmdp == NULL);
3341         if (pkt->pkt_reason == CMD_CMPLT) {
3342                 if (bp) {
3343                         if (bp->b_flags & B_READ) {
3344                                 KSTAT_SESS_RX_IO_DONE(isp, bp->b_bcount);
3345                         } else {
3346                                 KSTAT_SESS_TX_IO_DONE(isp, bp->b_bcount);
3347                         }
3348                 }
3349         }
3350 
3351         if (pkt->pkt_flags & FLAG_NOINTR) {
3352                 cv_broadcast(&icmdp->cmd_completion);
3353                 mutex_exit(&icmdp->cmd_mutex);
3354         } else {
3355                 /*
3356                  * Release mutex.  As soon as callback is
3357                  * issued the caller may destroy the command.
3358                  */
3359                 mutex_exit(&icmdp->cmd_mutex);
3360                 /*
3361                  * We can't just directly call the pk_comp routine.  In
3362                  * many error cases the target driver will use the calling
3363                  * thread to re-drive error handling (reset, retries...)
3364                  * back into the hba driver (iscsi).  If the target redrives
3365                  * a reset back into the iscsi driver off this thead we have
3366                  * a chance of deadlocking. So instead use the io completion
3367                  * thread.
3368                  */
3369                 (*icmdp->cmd_un.scsi.pkt->pkt_comp)(icmdp->cmd_un.scsi.pkt);
3370         }
3371 }
3372 
3373 /*
3374  * +--------------------------------------------------------------------+
3375  * | End of completion routines                                         |
3376  * +--------------------------------------------------------------------+
3377  */
3378 
3379 /*
3380  * +--------------------------------------------------------------------+
3381  * | Beginning of watchdog routines                                     |
3382  * +--------------------------------------------------------------------+
3383  */
3384 
3385 /*
3386  * iscsi_watchdog_thread -
3387  *
3388  */
3389 void
3390 iscsi_wd_thread(iscsi_thread_t *thread, void *arg)
3391 {
3392         iscsi_sess_t    *isp = (iscsi_sess_t *)arg;
3393         int             rc = 1;
3394 
3395         ASSERT(isp != NULL);
3396 
3397         while (rc != NULL) {
3398 
3399                 iscsi_timeout_checks(isp);
3400                 iscsi_nop_checks(isp);
3401 
3402                 rc = iscsi_thread_wait(thread, SEC_TO_TICK(1));
3403         }
3404 }
3405 
3406 /*
3407  * iscsi_timeout_checks -
3408  *
3409  */
3410 static void
3411 iscsi_timeout_checks(iscsi_sess_t *isp)
3412 {
3413         clock_t         now = ddi_get_lbolt();
3414         iscsi_conn_t    *icp;
3415         iscsi_cmd_t     *icmdp, *nicmdp;
3416 
3417         ASSERT(isp != NULL);
3418 
3419         /* PENDING */
3420         rw_enter(&isp->sess_state_rwlock, RW_READER);
3421         mutex_enter(&isp->sess_queue_pending.mutex);
3422         for (icmdp = isp->sess_queue_pending.head;
3423             icmdp; icmdp = nicmdp) {
3424                 nicmdp = icmdp->cmd_next;
3425 
3426                 /* Skip entries with no timeout */
3427                 if (icmdp->cmd_lbolt_timeout == 0)
3428                         continue;
3429 
3430                 /*
3431                  * Skip pending queue entries for cmd_type values that depend
3432                  * on having an open cmdsn window for successfull transition
3433                  * from pending to the active (i.e. ones that depend on
3434                  * sess_cmdsn .vs. sess_maxcmdsn). For them, the timer starts
3435                  * when they are successfully moved to the active queue by
3436                  * iscsi_cmd_state_pending() code.
3437                  */
3438                 /*
3439                  * If the cmd is stuck, at least give it a chance
3440                  * to timeout
3441                  */
3442                 if (((icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) ||
3443                     (icmdp->cmd_type == ISCSI_CMD_TYPE_TEXT)) &&
3444                     !(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_STUCK))
3445                         continue;
3446 
3447                 /* Skip if timeout still in the future */
3448                 if (now <= icmdp->cmd_lbolt_timeout)
3449                         continue;
3450 
3451                 /* timeout */
3452                 iscsi_cmd_state_machine(icmdp, ISCSI_CMD_EVENT_E6, isp);
3453         }
3454         mutex_exit(&isp->sess_queue_pending.mutex);
3455         rw_exit(&isp->sess_state_rwlock);
3456 
3457         rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
3458         icp = isp->sess_conn_list;
3459         while (icp != NULL) {
3460 
3461                 icp->conn_timeout = B_FALSE;
3462                 /* ACTIVE */
3463                 mutex_enter(&icp->conn_state_mutex);
3464                 mutex_enter(&isp->sess_queue_pending.mutex);
3465                 mutex_enter(&icp->conn_queue_active.mutex);
3466                 for (icmdp = icp->conn_queue_active.head;
3467                     icmdp; icmdp = nicmdp) {
3468                         nicmdp = icmdp->cmd_next;
3469 
3470                         if (iscsi_nop_timeout_checks(icmdp) == B_TRUE) {
3471                                 icp->conn_timeout = B_TRUE;
3472                         }
3473 
3474                         /* Skip entries with no timeout */
3475                         if (icmdp->cmd_lbolt_timeout == 0)
3476                                 continue;
3477 
3478                         /*
3479                          * Skip if command is not active or not needed
3480                          * to flush.
3481                          */
3482                         if (icmdp->cmd_state != ISCSI_CMD_STATE_ACTIVE &&
3483                             !(icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_FLUSH))
3484                                 continue;
3485 
3486                         /* Skip if timeout still in the future */
3487                         if (now <= icmdp->cmd_lbolt_timeout)
3488                                 continue;
3489 
3490                         if (icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_FLUSH) {
3491                                 /*
3492                                  * This command is left during target reset,
3493                                  * we can flush it now.
3494                                  */
3495                                 iscsi_cmd_state_machine(icmdp,
3496                                     ISCSI_CMD_EVENT_E7, isp);
3497                         } else if (icmdp->cmd_state == ISCSI_CMD_STATE_ACTIVE) {
3498                                 /* timeout */
3499                                 iscsi_cmd_state_machine(icmdp,
3500                                     ISCSI_CMD_EVENT_E6, isp);
3501                         }
3502 
3503                 }
3504                 mutex_exit(&icp->conn_queue_active.mutex);
3505                 mutex_exit(&isp->sess_queue_pending.mutex);
3506                 mutex_exit(&icp->conn_state_mutex);
3507 
3508                 icp = icp->conn_next;
3509         }
3510 
3511         icp = isp->sess_conn_list;
3512         while (icp != NULL) {
3513                 if (icp->conn_timeout == B_TRUE) {
3514                         /* timeout on this connect detected */
3515                         idm_ini_conn_disconnect(icp->conn_ic);
3516                         icp->conn_timeout = B_FALSE;
3517                 }
3518                 icp = icp->conn_next;
3519         }
3520         rw_exit(&isp->sess_conn_list_rwlock);
3521 }
3522 
3523 /*
3524  * iscsi_nop_checks - sends a NOP on idle connections
3525  *
3526  * This function walks the connections on a session and
3527  * issues NOPs on those connections that are in FULL
3528  * FEATURE mode and have not received data for the
3529  * time period specified by iscsi_nop_delay (global).
3530  */
3531 static void
3532 iscsi_nop_checks(iscsi_sess_t *isp)
3533 {
3534         iscsi_conn_t    *icp;
3535 
3536         ASSERT(isp != NULL);
3537 
3538         if (isp->sess_type == ISCSI_SESS_TYPE_DISCOVERY) {
3539                 return;
3540         }
3541 
3542         rw_enter(&isp->sess_conn_list_rwlock, RW_READER);
3543         icp = isp->sess_conn_act;
3544         if (icp != NULL) {
3545 
3546                 mutex_enter(&icp->conn_state_mutex);
3547                 if ((ISCSI_CONN_STATE_FULL_FEATURE(icp->conn_state)) &&
3548                     (ddi_get_lbolt() > isp->sess_conn_act->conn_rx_lbolt +
3549                     SEC_TO_TICK(iscsi_nop_delay)) && (ddi_get_lbolt() >
3550                     isp->sess_conn_act->conn_nop_lbolt +
3551                     SEC_TO_TICK(iscsi_nop_delay))) {
3552 
3553                         /*
3554                          * We haven't received anything from the
3555                          * target is a defined period of time,
3556                          * send NOP to see if the target is alive.
3557                          */
3558                         mutex_enter(&isp->sess_queue_pending.mutex);
3559                         iscsi_handle_nop(isp->sess_conn_act,
3560                             0, ISCSI_RSVD_TASK_TAG);
3561                         mutex_exit(&isp->sess_queue_pending.mutex);
3562                 }
3563                 mutex_exit(&icp->conn_state_mutex);
3564 
3565                 icp = icp->conn_next;
3566         }
3567         rw_exit(&isp->sess_conn_list_rwlock);
3568 }
3569 
3570 static boolean_t
3571 iscsi_nop_timeout_checks(iscsi_cmd_t *icmdp)
3572 {
3573         if (icmdp->cmd_type == ISCSI_CMD_TYPE_NOP) {
3574                 if ((ddi_get_lbolt() - icmdp->cmd_lbolt_active) >
3575                     SEC_TO_TICK(ISCSI_CONN_TIEMOUT_DETECT)) {
3576                         return (B_TRUE);
3577                 } else {
3578                         return (B_FALSE);
3579                 }
3580         }
3581         return (B_FALSE);
3582 }
3583 /*
3584  * +--------------------------------------------------------------------+
3585  * | End of wd routines                                         |
3586  * +--------------------------------------------------------------------+
3587  */
3588 
3589 /*
3590  * iscsi_flush_cmd_after_reset - flush commands after reset
3591  *
3592  * Here we will flush all the commands for a specified LUN whose cmdsn is less
3593  * than the one received with the Unit Attention.
3594  */
3595 static void
3596 iscsi_flush_cmd_after_reset(uint32_t cmd_sn, uint16_t lun_num,
3597     iscsi_conn_t *icp)
3598 {
3599         iscsi_cmd_t     *t_icmdp    = NULL;
3600         iscsi_cmd_t     *next_icmdp = NULL;
3601 
3602         ASSERT(icp != NULL);
3603 
3604         t_icmdp = icp->conn_queue_active.head;
3605         while (t_icmdp != NULL) {
3606                 next_icmdp = t_icmdp->cmd_next;
3607                 mutex_enter(&t_icmdp->cmd_mutex);
3608                 /*
3609                  * We will flush the commands whose cmdsn is less than the one
3610                  * got Unit Attention.
3611                  * Here we will check for wrap by subtracting and compare to
3612                  * 1/2 of a 32 bit number, if greater then we wrapped.
3613                  */
3614                 if ((t_icmdp->cmd_misc_flags & ISCSI_CMD_MISCFLAG_SENT) &&
3615                     ((cmd_sn > t_icmdp->cmd_sn) ||
3616                     ((t_icmdp->cmd_sn - cmd_sn) >
3617                     ISCSI_CMD_SN_WRAP))) {
3618                         /*
3619                          * Internally generated SCSI commands do not have
3620                          * t_icmdp->cmd_lun set, but the LUN can be retrieved
3621                          * from t_icmdp->cmd_un.scsi.lun.
3622                          */
3623                         if ((t_icmdp->cmd_lun != NULL &&
3624                             t_icmdp->cmd_lun->lun_num == lun_num) ||
3625                             (t_icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI &&
3626                             (t_icmdp->cmd_un.scsi.lun & ISCSI_LUN_MASK) ==
3627                             lun_num)) {
3628                                 t_icmdp->cmd_misc_flags |=
3629                                     ISCSI_CMD_MISCFLAG_FLUSH;
3630                                 if (t_icmdp->cmd_type == ISCSI_CMD_TYPE_SCSI) {
3631                                         t_icmdp->cmd_un.scsi.pkt_stat |=
3632                                             STAT_BUS_RESET;
3633                                 }
3634                         }
3635                 }
3636                 mutex_exit(&t_icmdp->cmd_mutex);
3637                 t_icmdp = next_icmdp;
3638         }
3639 }
3640 
3641 /*
3642  * iscsi_decode_sense - decode the sense data in the cmd response
3643  * and take proper actions
3644  */
3645 static boolean_t
3646 iscsi_decode_sense(uint8_t *sense_data, iscsi_cmd_t *icmdp)
3647 {
3648         uint8_t         sense_key       = 0;
3649         uint8_t         asc             = 0;
3650         uint8_t         ascq            = 0;
3651         boolean_t       flush_io        = B_FALSE;
3652         boolean_t       reconfig_lun    = B_FALSE;
3653         iscsi_sess_t    *isp            = NULL;
3654 
3655         ASSERT(sense_data != NULL);
3656 
3657         isp = icmdp->cmd_conn->conn_sess;
3658 
3659         sense_key = scsi_sense_key(sense_data);
3660         switch (sense_key) {
3661                 case KEY_UNIT_ATTENTION:
3662                         asc = scsi_sense_asc(sense_data);
3663                         switch (asc) {
3664                                 case ISCSI_SCSI_RESET_SENSE_CODE:
3665                                         /*
3666                                          * POWER ON, RESET, OR BUS_DEVICE RESET
3667                                          * OCCURRED
3668                                          */
3669                                         flush_io = B_TRUE;
3670                                         break;
3671                                 case ISCSI_SCSI_LUNCHANGED_CODE:
3672                                         ascq = scsi_sense_ascq(sense_data);
3673                                         if (ascq == ISCSI_SCSI_LUNCHANGED_ASCQ)
3674                                                 reconfig_lun = B_TRUE;
3675                                 default:
3676                                         break;
3677                         }
3678                         break;
3679                 default:
3680                         /*
3681                          * Currently we don't care
3682                          * about other sense key.
3683                          */
3684                         break;
3685         }
3686 
3687         if (reconfig_lun == B_TRUE) {
3688                 rw_enter(&isp->sess_state_rwlock, RW_READER);
3689                 if ((isp->sess_state == ISCSI_SESS_STATE_LOGGED_IN) &&
3690                     (iscsi_sess_enum_request(isp, B_FALSE,
3691                     isp->sess_state_event_count) !=
3692                     ISCSI_SESS_ENUM_SUBMITTED)) {
3693                         cmn_err(CE_WARN, "Unable to commit re-enumeration for"
3694                             " session(%u) %s", isp->sess_oid, isp->sess_name);
3695                 }
3696                 rw_exit(&isp->sess_state_rwlock);
3697         }
3698 
3699         return (flush_io);
3700 }