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