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