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