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