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