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 9 * http://www.opensource.org/licenses/cddl1.txt. 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 /* 23 * Copyright (c) 2004-2012 Emulex. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <emlxs.h> 28 29 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 30 EMLXS_MSG_DEF(EMLXS_FCP_C); 31 32 #define EMLXS_GET_VADDR(hba, rp, icmd) emlxs_mem_get_vaddr(hba, rp, \ 33 PADDR(icmd->un.cont64[i].addrHigh, icmd->un.cont64[i].addrLow)); 34 35 static void emlxs_sbp_abort_add(emlxs_port_t *port, emlxs_buf_t *sbp, 36 Q *abort, uint8_t *flag, emlxs_buf_t *fpkt); 37 38 #define SCSI3_PERSISTENT_RESERVE_IN 0x5e 39 #define SCSI_INQUIRY 0x12 40 #define SCSI_RX_DIAG 0x1C 41 42 43 /* 44 * emlxs_handle_fcp_event 45 * 46 * Description: Process an FCP Rsp Ring completion 47 * 48 */ 49 /* ARGSUSED */ 50 extern void 51 emlxs_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 52 { 53 emlxs_port_t *port = &PPORT; 54 emlxs_config_t *cfg = &CFG; 55 IOCB *cmd; 56 emlxs_buf_t *sbp; 57 fc_packet_t *pkt = NULL; 58 #ifdef SAN_DIAG_SUPPORT 59 NODELIST *ndlp; 60 #endif 61 uint32_t iostat; 62 uint8_t localstat; 63 fcp_rsp_t *rsp; 64 uint32_t rsp_data_resid; 65 uint32_t check_underrun; 66 uint8_t asc; 67 uint8_t ascq; 68 uint8_t scsi_status; 69 uint8_t sense; 70 uint32_t did; 71 uint32_t fix_it; 72 uint8_t *scsi_cmd; 73 uint8_t scsi_opcode; 74 uint16_t scsi_dl; 75 uint32_t data_rx; 76 uint32_t length; 77 78 cmd = &iocbq->iocb; 79 80 /* Initialize the status */ 81 iostat = cmd->ULPSTATUS; 82 localstat = 0; 83 scsi_status = 0; 84 asc = 0; 85 ascq = 0; 86 sense = 0; 87 check_underrun = 0; 88 fix_it = 0; 89 90 HBASTATS.FcpEvent++; 91 92 sbp = (emlxs_buf_t *)iocbq->sbp; 93 94 if (!sbp) { 95 /* completion with missing xmit command */ 96 HBASTATS.FcpStray++; 97 98 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_fcp_completion_msg, 99 "cmd=%x iotag=%d", cmd->ULPCOMMAND, cmd->ULPIOTAG); 100 101 return; 102 } 103 104 HBASTATS.FcpCompleted++; 105 106 #ifdef SAN_DIAG_SUPPORT 107 emlxs_update_sd_bucket(sbp); 108 #endif /* SAN_DIAG_SUPPORT */ 109 110 pkt = PRIV2PKT(sbp); 111 112 did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 113 scsi_cmd = (uint8_t *)pkt->pkt_cmd; 114 scsi_opcode = scsi_cmd[12]; 115 data_rx = 0; 116 117 /* Sync data in data buffer only on FC_PKT_FCP_READ */ 118 if (pkt->pkt_datalen && (pkt->pkt_tran_type == FC_PKT_FCP_READ)) { 119 EMLXS_MPDATA_SYNC(pkt->pkt_data_dma, 0, pkt->pkt_datalen, 120 DDI_DMA_SYNC_FORKERNEL); 121 122 #ifdef TEST_SUPPORT 123 if (hba->underrun_counter && (iostat == IOSTAT_SUCCESS) && 124 (pkt->pkt_datalen >= 512)) { 125 hba->underrun_counter--; 126 iostat = IOSTAT_FCP_RSP_ERROR; 127 128 /* Report 512 bytes missing by adapter */ 129 cmd->un.fcpi.fcpi_parm = pkt->pkt_datalen - 512; 130 131 /* Corrupt 512 bytes of Data buffer */ 132 bzero((uint8_t *)pkt->pkt_data, 512); 133 134 /* Set FCP response to STATUS_GOOD */ 135 bzero((uint8_t *)pkt->pkt_resp, pkt->pkt_rsplen); 136 } 137 #endif /* TEST_SUPPORT */ 138 } 139 140 /* Process the pkt */ 141 mutex_enter(&sbp->mtx); 142 143 /* Check for immediate return */ 144 if ((iostat == IOSTAT_SUCCESS) && 145 (pkt->pkt_comp) && 146 !(sbp->pkt_flags & 147 (PACKET_ULP_OWNED | PACKET_COMPLETED | 148 PACKET_IN_COMPLETION | PACKET_IN_TXQ | PACKET_IN_CHIPQ | 149 PACKET_IN_DONEQ | PACKET_IN_TIMEOUT | PACKET_IN_FLUSH | 150 PACKET_IN_ABORT | PACKET_POLLED))) { 151 HBASTATS.FcpGood++; 152 153 sbp->pkt_flags |= 154 (PACKET_STATE_VALID | PACKET_IN_COMPLETION | 155 PACKET_COMPLETED | PACKET_ULP_OWNED); 156 mutex_exit(&sbp->mtx); 157 158 #if (EMLXS_MODREVX == EMLXS_MODREV2X) 159 emlxs_unswap_pkt(sbp); 160 #endif /* EMLXS_MODREV2X */ 161 162 #ifdef FMA_SUPPORT 163 emlxs_check_dma(hba, sbp); 164 #endif /* FMA_SUPPORT */ 165 166 cp->ulpCmplCmd++; 167 (*pkt->pkt_comp) (pkt); 168 169 #ifdef FMA_SUPPORT 170 if (hba->flag & FC_DMA_CHECK_ERROR) { 171 emlxs_thread_spawn(hba, emlxs_restart_thread, 172 NULL, NULL); 173 } 174 #endif /* FMA_SUPPORT */ 175 176 return; 177 } 178 179 /* 180 * A response is only placed in the resp buffer if IOSTAT_FCP_RSP_ERROR 181 * is reported. 182 */ 183 184 /* Check if a response buffer was not provided */ 185 if ((iostat != IOSTAT_FCP_RSP_ERROR) || (pkt->pkt_rsplen == 0)) { 186 goto done; 187 } 188 189 EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen, 190 DDI_DMA_SYNC_FORKERNEL); 191 192 /* Get the response buffer pointer */ 193 rsp = (fcp_rsp_t *)pkt->pkt_resp; 194 195 /* Validate the response payload */ 196 if (!rsp->fcp_u.fcp_status.resid_under && 197 !rsp->fcp_u.fcp_status.resid_over) { 198 rsp->fcp_resid = 0; 199 } 200 201 if (!rsp->fcp_u.fcp_status.rsp_len_set) { 202 rsp->fcp_response_len = 0; 203 } 204 205 if (!rsp->fcp_u.fcp_status.sense_len_set) { 206 rsp->fcp_sense_len = 0; 207 } 208 209 length = sizeof (fcp_rsp_t) + LE_SWAP32(rsp->fcp_response_len) + 210 LE_SWAP32(rsp->fcp_sense_len); 211 212 if (length > pkt->pkt_rsplen) { 213 iostat = IOSTAT_RSP_INVALID; 214 pkt->pkt_data_resid = pkt->pkt_datalen; 215 goto done; 216 } 217 218 /* Set the valid response flag */ 219 sbp->pkt_flags |= PACKET_FCP_RSP_VALID; 220 221 scsi_status = rsp->fcp_u.fcp_status.scsi_status; 222 223 #ifdef SAN_DIAG_SUPPORT 224 ndlp = (NODELIST *)iocbq->node; 225 if (scsi_status == SCSI_STAT_QUE_FULL) { 226 emlxs_log_sd_scsi_event(port, SD_SCSI_SUBCATEGORY_QFULL, 227 (HBA_WWN *)&ndlp->nlp_portname, sbp->lun); 228 } else if (scsi_status == SCSI_STAT_BUSY) { 229 emlxs_log_sd_scsi_event(port, 230 SD_SCSI_SUBCATEGORY_DEVBSY, 231 (HBA_WWN *)&ndlp->nlp_portname, sbp->lun); 232 } 233 #endif 234 235 /* 236 * Convert a task abort to a check condition with no data 237 * transferred. We saw a data corruption when Solaris received 238 * a Task Abort from a tape. 239 */ 240 241 if (scsi_status == SCSI_STAT_TASK_ABORT) { 242 EMLXS_MSGF(EMLXS_CONTEXT, 243 &emlxs_fcp_completion_error_msg, 244 "Task Abort. " 245 "Fixed. did=0x%06x sbp=%p cmd=%02x dl=%d", 246 did, sbp, scsi_opcode, pkt->pkt_datalen); 247 248 rsp->fcp_u.fcp_status.scsi_status = 249 SCSI_STAT_CHECK_COND; 250 rsp->fcp_u.fcp_status.rsp_len_set = 0; 251 rsp->fcp_u.fcp_status.sense_len_set = 0; 252 rsp->fcp_u.fcp_status.resid_over = 0; 253 254 if (pkt->pkt_datalen) { 255 rsp->fcp_u.fcp_status.resid_under = 1; 256 rsp->fcp_resid = 257 LE_SWAP32(pkt->pkt_datalen); 258 } else { 259 rsp->fcp_u.fcp_status.resid_under = 0; 260 rsp->fcp_resid = 0; 261 } 262 263 scsi_status = SCSI_STAT_CHECK_COND; 264 } 265 266 /* 267 * We only need to check underrun if data could 268 * have been sent 269 */ 270 271 /* Always check underrun if status is good */ 272 if (scsi_status == SCSI_STAT_GOOD) { 273 check_underrun = 1; 274 } 275 /* Check the sense codes if this is a check condition */ 276 else if (scsi_status == SCSI_STAT_CHECK_COND) { 277 check_underrun = 1; 278 279 /* Check if sense data was provided */ 280 if (LE_SWAP32(rsp->fcp_sense_len) >= 14) { 281 sense = *((uint8_t *)rsp + 32 + 2); 282 asc = *((uint8_t *)rsp + 32 + 12); 283 ascq = *((uint8_t *)rsp + 32 + 13); 284 } 285 286 #ifdef SAN_DIAG_SUPPORT 287 emlxs_log_sd_scsi_check_event(port, 288 (HBA_WWN *)&ndlp->nlp_portname, sbp->lun, 289 scsi_opcode, sense, asc, ascq); 290 #endif 291 } 292 /* Status is not good and this is not a check condition */ 293 /* No data should have been sent */ 294 else { 295 check_underrun = 0; 296 } 297 298 /* Initialize the resids */ 299 pkt->pkt_resp_resid = 0; 300 pkt->pkt_data_resid = 0; 301 302 /* Check if no data was to be transferred */ 303 if (pkt->pkt_datalen == 0) { 304 goto done; 305 } 306 307 /* Get the residual underrun count reported by the SCSI reply */ 308 rsp_data_resid = (rsp->fcp_u.fcp_status.resid_under) ? 309 LE_SWAP32(rsp->fcp_resid) : 0; 310 311 /* Set the pkt_data_resid to what the scsi response resid */ 312 pkt->pkt_data_resid = rsp_data_resid; 313 314 /* Adjust the pkt_data_resid field if needed */ 315 if (pkt->pkt_tran_type == FC_PKT_FCP_READ) { 316 /* 317 * Get the residual underrun count reported by 318 * our adapter 319 */ 320 pkt->pkt_data_resid = cmd->un.fcpi.fcpi_parm; 321 322 #ifdef SAN_DIAG_SUPPORT 323 if ((rsp_data_resid == 0) && (pkt->pkt_data_resid)) { 324 emlxs_log_sd_fc_rdchk_event(port, 325 (HBA_WWN *)&ndlp->nlp_portname, sbp->lun, 326 scsi_opcode, pkt->pkt_data_resid); 327 } 328 #endif 329 330 /* Get the actual amount of data transferred */ 331 data_rx = pkt->pkt_datalen - pkt->pkt_data_resid; 332 333 /* 334 * If the residual being reported by the adapter is 335 * greater than the residual being reported in the 336 * reply, then we have a true underrun. 337 */ 338 if (check_underrun && (pkt->pkt_data_resid > rsp_data_resid)) { 339 switch (scsi_opcode) { 340 case SCSI_INQUIRY: 341 scsi_dl = scsi_cmd[16]; 342 break; 343 344 case SCSI_RX_DIAG: 345 scsi_dl = 346 (scsi_cmd[15] * 0x100) + 347 scsi_cmd[16]; 348 break; 349 350 default: 351 scsi_dl = pkt->pkt_datalen; 352 } 353 354 #ifdef FCP_UNDERRUN_PATCH1 355 if (cfg[CFG_ENABLE_PATCH].current & FCP_UNDERRUN_PATCH1) { 356 /* 357 * If status is not good and no data was 358 * actually transferred, then we must fix 359 * the issue 360 */ 361 if ((scsi_status != SCSI_STAT_GOOD) && (data_rx == 0)) { 362 fix_it = 1; 363 364 EMLXS_MSGF(EMLXS_CONTEXT, 365 &emlxs_fcp_completion_error_msg, 366 "Underrun(1). Fixed. " 367 "did=0x%06x sbp=%p cmd=%02x " 368 "dl=%d,%d rx=%d rsp=%d", 369 did, sbp, scsi_opcode, 370 pkt->pkt_datalen, scsi_dl, 371 (pkt->pkt_datalen - 372 pkt->pkt_data_resid), 373 rsp_data_resid); 374 375 } 376 } 377 #endif /* FCP_UNDERRUN_PATCH1 */ 378 379 380 #ifdef FCP_UNDERRUN_PATCH2 381 if (cfg[CFG_ENABLE_PATCH].current & FCP_UNDERRUN_PATCH2) { 382 if (scsi_status == SCSI_STAT_GOOD) { 383 emlxs_msg_t *msg; 384 385 msg = &emlxs_fcp_completion_error_msg; 386 /* 387 * If status is good and this is an 388 * inquiry request and the amount of 389 * data 390 */ 391 /* 392 * requested <= data received, then we 393 * must fix the issue. 394 */ 395 396 if ((scsi_opcode == SCSI_INQUIRY) && 397 (pkt->pkt_datalen >= data_rx) && 398 (scsi_dl <= data_rx)) { 399 fix_it = 1; 400 401 EMLXS_MSGF(EMLXS_CONTEXT, msg, 402 "Underrun(2). Fixed. " 403 "did=0x%06x sbp=%p " 404 "cmd=%02x dl=%d,%d " 405 "rx=%d rsp=%d", 406 did, sbp, scsi_opcode, 407 pkt->pkt_datalen, scsi_dl, 408 data_rx, rsp_data_resid); 409 410 } 411 412 /* 413 * If status is good and this is an 414 * inquiry request and the amount of 415 * data requested >= 128 bytes, but 416 * only 128 bytes were received, 417 * then we must fix the issue. 418 */ 419 else if ((scsi_opcode == SCSI_INQUIRY) && 420 (pkt->pkt_datalen >= 128) && 421 (scsi_dl >= 128) && (data_rx == 128)) { 422 fix_it = 1; 423 424 EMLXS_MSGF(EMLXS_CONTEXT, msg, 425 "Underrun(3). Fixed. " 426 "did=0x%06x sbp=%p " 427 "cmd=%02x dl=%d,%d " 428 "rx=%d rsp=%d", 429 did, sbp, scsi_opcode, 430 pkt->pkt_datalen, scsi_dl, 431 data_rx, rsp_data_resid); 432 433 } 434 } 435 } 436 #endif /* FCP_UNDERRUN_PATCH2 */ 437 438 /* 439 * Check if SCSI response payload should be 440 * fixed or if a DATA_UNDERRUN should be 441 * reported 442 */ 443 if (fix_it) { 444 /* 445 * Fix the SCSI response payload itself 446 */ 447 rsp->fcp_u.fcp_status.resid_under = 1; 448 rsp->fcp_resid = 449 LE_SWAP32(pkt->pkt_data_resid); 450 } else { 451 /* 452 * Change the status from 453 * IOSTAT_FCP_RSP_ERROR to 454 * IOSTAT_DATA_UNDERRUN 455 */ 456 iostat = IOSTAT_DATA_UNDERRUN; 457 pkt->pkt_data_resid = 458 pkt->pkt_datalen; 459 } 460 } 461 462 /* 463 * If the residual being reported by the adapter is 464 * less than the residual being reported in the reply, 465 * then we have a true overrun. Since we don't know 466 * where the extra data came from or went to then we 467 * cannot trust anything we received 468 */ 469 else if (rsp_data_resid > pkt->pkt_data_resid) { 470 /* 471 * Change the status from 472 * IOSTAT_FCP_RSP_ERROR to 473 * IOSTAT_DATA_OVERRUN 474 */ 475 iostat = IOSTAT_DATA_OVERRUN; 476 pkt->pkt_data_resid = pkt->pkt_datalen; 477 } 478 479 } else if ((hba->sli_mode == EMLXS_HBA_SLI4_MODE) && 480 (pkt->pkt_tran_type == FC_PKT_FCP_WRITE)) { 481 /* 482 * Get the residual underrun count reported by 483 * our adapter 484 */ 485 pkt->pkt_data_resid = cmd->un.fcpi.fcpi_parm; 486 487 #ifdef SAN_DIAG_SUPPORT 488 if ((rsp_data_resid == 0) && (pkt->pkt_data_resid)) { 489 emlxs_log_sd_fc_rdchk_event(port, 490 (HBA_WWN *)&ndlp->nlp_portname, sbp->lun, 491 scsi_opcode, pkt->pkt_data_resid); 492 } 493 #endif /* SAN_DIAG_SUPPORT */ 494 495 /* Get the actual amount of data transferred */ 496 data_rx = pkt->pkt_datalen - pkt->pkt_data_resid; 497 498 /* 499 * If the residual being reported by the adapter is 500 * greater than the residual being reported in the 501 * reply, then we have a true underrun. 502 */ 503 if (check_underrun && (pkt->pkt_data_resid > rsp_data_resid)) { 504 505 scsi_dl = pkt->pkt_datalen; 506 507 #ifdef FCP_UNDERRUN_PATCH1 508 if (cfg[CFG_ENABLE_PATCH].current & FCP_UNDERRUN_PATCH1) { 509 /* 510 * If status is not good and no data was 511 * actually transferred, then we must fix 512 * the issue 513 */ 514 if ((scsi_status != SCSI_STAT_GOOD) && (data_rx == 0)) { 515 fix_it = 1; 516 517 EMLXS_MSGF(EMLXS_CONTEXT, 518 &emlxs_fcp_completion_error_msg, 519 "Underrun(1). Fixed. " 520 "did=0x%06x sbp=%p cmd=%02x " 521 "dl=%d,%d rx=%d rsp=%d", 522 did, sbp, scsi_opcode, 523 pkt->pkt_datalen, scsi_dl, 524 (pkt->pkt_datalen - 525 pkt->pkt_data_resid), 526 rsp_data_resid); 527 528 } 529 } 530 #endif /* FCP_UNDERRUN_PATCH1 */ 531 532 /* 533 * Check if SCSI response payload should be 534 * fixed or if a DATA_UNDERRUN should be 535 * reported 536 */ 537 if (fix_it) { 538 /* 539 * Fix the SCSI response payload itself 540 */ 541 rsp->fcp_u.fcp_status.resid_under = 1; 542 rsp->fcp_resid = 543 LE_SWAP32(pkt->pkt_data_resid); 544 } else { 545 /* 546 * Change the status from 547 * IOSTAT_FCP_RSP_ERROR to 548 * IOSTAT_DATA_UNDERRUN 549 */ 550 iostat = IOSTAT_DATA_UNDERRUN; 551 pkt->pkt_data_resid = 552 pkt->pkt_datalen; 553 } 554 } 555 556 /* 557 * If the residual being reported by the adapter is 558 * less than the residual being reported in the reply, 559 * then we have a true overrun. Since we don't know 560 * where the extra data came from or went to then we 561 * cannot trust anything we received 562 */ 563 else if (rsp_data_resid > pkt->pkt_data_resid) { 564 /* 565 * Change the status from 566 * IOSTAT_FCP_RSP_ERROR to 567 * IOSTAT_DATA_OVERRUN 568 */ 569 iostat = IOSTAT_DATA_OVERRUN; 570 pkt->pkt_data_resid = pkt->pkt_datalen; 571 } 572 } 573 574 done: 575 576 /* Print completion message */ 577 switch (iostat) { 578 case IOSTAT_SUCCESS: 579 /* Build SCSI GOOD status */ 580 if (pkt->pkt_rsplen) { 581 bzero((uint8_t *)pkt->pkt_resp, pkt->pkt_rsplen); 582 } 583 break; 584 585 case IOSTAT_FCP_RSP_ERROR: 586 break; 587 588 case IOSTAT_REMOTE_STOP: 589 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 590 "Remote Stop. did=0x%06x sbp=%p cmd=%02x", did, sbp, 591 scsi_opcode); 592 break; 593 594 case IOSTAT_LOCAL_REJECT: 595 localstat = cmd->un.grsp.perr.statLocalError; 596 597 switch (localstat) { 598 case IOERR_SEQUENCE_TIMEOUT: 599 EMLXS_MSGF(EMLXS_CONTEXT, 600 &emlxs_fcp_completion_error_msg, 601 "Local reject. " 602 "%s did=0x%06x sbp=%p cmd=%02x tmo=%d ", 603 emlxs_error_xlate(localstat), did, sbp, 604 scsi_opcode, pkt->pkt_timeout); 605 break; 606 607 default: 608 EMLXS_MSGF(EMLXS_CONTEXT, 609 &emlxs_fcp_completion_error_msg, 610 "Local reject. %s 0x%06x %p %02x (%x)(%x)", 611 emlxs_error_xlate(localstat), did, sbp, 612 scsi_opcode, (uint16_t)cmd->ULPIOTAG, 613 (uint16_t)cmd->ULPCONTEXT); 614 } 615 616 break; 617 618 case IOSTAT_NPORT_RJT: 619 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 620 "Nport reject. did=0x%06x sbp=%p cmd=%02x", did, sbp, 621 scsi_opcode); 622 break; 623 624 case IOSTAT_FABRIC_RJT: 625 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 626 "Fabric reject. did=0x%06x sbp=%p cmd=%02x", did, sbp, 627 scsi_opcode); 628 break; 629 630 case IOSTAT_NPORT_BSY: 631 #ifdef SAN_DIAG_SUPPORT 632 ndlp = (NODELIST *)iocbq->node; 633 emlxs_log_sd_fc_bsy_event(port, (HBA_WWN *)&ndlp->nlp_portname); 634 #endif 635 636 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 637 "Nport busy. did=0x%06x sbp=%p cmd=%02x", did, sbp, 638 scsi_opcode); 639 break; 640 641 case IOSTAT_FABRIC_BSY: 642 #ifdef SAN_DIAG_SUPPORT 643 ndlp = (NODELIST *)iocbq->node; 644 emlxs_log_sd_fc_bsy_event(port, NULL); 645 #endif 646 647 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 648 "Fabric busy. did=0x%06x sbp=%p cmd=%02x", did, sbp, 649 scsi_opcode); 650 break; 651 652 case IOSTAT_INTERMED_RSP: 653 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 654 "Intermediate response. did=0x%06x sbp=%p cmd=%02x", did, 655 sbp, scsi_opcode); 656 break; 657 658 case IOSTAT_LS_RJT: 659 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 660 "LS Reject. did=0x%06x sbp=%p cmd=%02x", did, sbp, 661 scsi_opcode); 662 break; 663 664 case IOSTAT_DATA_UNDERRUN: 665 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 666 "Underrun. did=0x%06x sbp=%p cmd=%02x " 667 "dl=%d,%d rx=%d rsp=%d (%02x,%02x,%02x,%02x)", 668 did, sbp, scsi_opcode, pkt->pkt_datalen, scsi_dl, data_rx, 669 rsp_data_resid, scsi_status, sense, asc, ascq); 670 break; 671 672 case IOSTAT_DATA_OVERRUN: 673 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 674 "Overrun. did=0x%06x sbp=%p cmd=%02x " 675 "dl=%d,%d rx=%d rsp=%d (%02x,%02x,%02x,%02x)", 676 did, sbp, scsi_opcode, pkt->pkt_datalen, scsi_dl, data_rx, 677 rsp_data_resid, scsi_status, sense, asc, ascq); 678 break; 679 680 case IOSTAT_RSP_INVALID: 681 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 682 "Rsp Invalid. did=0x%06x sbp=%p cmd=%02x dl=%d rl=%d" 683 "(%d, %d, %d)", 684 did, sbp, scsi_opcode, pkt->pkt_datalen, pkt->pkt_rsplen, 685 LE_SWAP32(rsp->fcp_resid), 686 LE_SWAP32(rsp->fcp_sense_len), 687 LE_SWAP32(rsp->fcp_response_len)); 688 break; 689 690 default: 691 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg, 692 "Unknown status=%x reason=%x did=0x%06x sbp=%p cmd=%02x", 693 iostat, cmd->un.grsp.perr.statLocalError, did, sbp, 694 scsi_opcode); 695 break; 696 } 697 698 if (iostat == IOSTAT_SUCCESS) { 699 HBASTATS.FcpGood++; 700 } else { 701 HBASTATS.FcpError++; 702 } 703 704 mutex_exit(&sbp->mtx); 705 706 emlxs_pkt_complete(sbp, iostat, localstat, 0); 707 708 return; 709 710 } /* emlxs_handle_fcp_event() */ 711 712 713 /* 714 * emlxs_post_buffer 715 * 716 * This routine will post count buffers to the 717 * ring with the QUE_RING_BUF_CN command. This 718 * allows 2 buffers / command to be posted. 719 * Returns the number of buffers NOT posted. 720 */ 721 /* SLI3 */ 722 extern int 723 emlxs_post_buffer(emlxs_hba_t *hba, RING *rp, int16_t cnt) 724 { 725 emlxs_port_t *port = &PPORT; 726 IOCB *icmd; 727 IOCBQ *iocbq; 728 MATCHMAP *mp; 729 uint16_t tag; 730 uint32_t maxqbuf; 731 int32_t i; 732 int32_t j; 733 uint32_t seg; 734 uint32_t size; 735 736 mp = 0; 737 maxqbuf = 2; 738 tag = (uint16_t)cnt; 739 cnt += rp->fc_missbufcnt; 740 741 if (rp->ringno == hba->channel_els) { 742 seg = MEM_BUF; 743 size = MEM_ELSBUF_SIZE; 744 } else if (rp->ringno == hba->channel_ip) { 745 seg = MEM_IPBUF; 746 size = MEM_IPBUF_SIZE; 747 } else if (rp->ringno == hba->channel_ct) { 748 seg = MEM_CTBUF; 749 size = MEM_CTBUF_SIZE; 750 } 751 #ifdef SFCT_SUPPORT 752 else if (rp->ringno == hba->CHANNEL_FCT) { 753 seg = MEM_FCTBUF; 754 size = MEM_FCTBUF_SIZE; 755 } 756 #endif /* SFCT_SUPPORT */ 757 else { 758 return (0); 759 } 760 761 /* 762 * While there are buffers to post 763 */ 764 while (cnt) { 765 if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB)) == 0) { 766 rp->fc_missbufcnt = cnt; 767 return (cnt); 768 } 769 770 iocbq->channel = (void *)&hba->chan[rp->ringno]; 771 iocbq->port = (void *)port; 772 iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL); 773 774 icmd = &iocbq->iocb; 775 776 /* 777 * Max buffers can be posted per command 778 */ 779 for (i = 0; i < maxqbuf; i++) { 780 if (cnt <= 0) 781 break; 782 783 /* fill in BDEs for command */ 784 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, seg)) 785 == 0) { 786 icmd->ULPBDECOUNT = i; 787 for (j = 0; j < i; j++) { 788 mp = EMLXS_GET_VADDR(hba, rp, icmd); 789 if (mp) { 790 emlxs_mem_put(hba, seg, 791 (void *)mp); 792 } 793 } 794 795 rp->fc_missbufcnt = cnt + i; 796 797 emlxs_mem_put(hba, MEM_IOCB, (void *)iocbq); 798 799 return (cnt + i); 800 } 801 802 /* 803 * map that page and save the address pair for lookup 804 * later 805 */ 806 emlxs_mem_map_vaddr(hba, 807 rp, 808 mp, 809 (uint32_t *)&icmd->un.cont64[i].addrHigh, 810 (uint32_t *)&icmd->un.cont64[i].addrLow); 811 812 icmd->un.cont64[i].tus.f.bdeSize = size; 813 icmd->ULPCOMMAND = CMD_QUE_RING_BUF64_CN; 814 815 /* 816 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 817 * "UB Post: ring=%d addr=%08x%08x size=%d", 818 * rp->ringno, icmd->un.cont64[i].addrHigh, 819 * icmd->un.cont64[i].addrLow, size); 820 */ 821 822 cnt--; 823 } 824 825 icmd->ULPIOTAG = tag; 826 icmd->ULPBDECOUNT = i; 827 icmd->ULPLE = 1; 828 icmd->ULPOWNER = OWN_CHIP; 829 /* used for delimiter between commands */ 830 iocbq->bp = (void *)mp; 831 832 EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[rp->ringno], iocbq); 833 } 834 835 rp->fc_missbufcnt = 0; 836 837 return (0); 838 839 } /* emlxs_post_buffer() */ 840 841 842 static void 843 emlxs_fcp_tag_nodes(emlxs_port_t *port) 844 { 845 NODELIST *nlp; 846 int i; 847 848 /* We will process all nodes with this tag later */ 849 rw_enter(&port->node_rwlock, RW_READER); 850 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 851 nlp = port->node_table[i]; 852 while (nlp != NULL) { 853 nlp->nlp_tag = 1; 854 nlp = nlp->nlp_list_next; 855 } 856 } 857 rw_exit(&port->node_rwlock); 858 } 859 860 861 static NODELIST * 862 emlxs_find_tagged_node(emlxs_port_t *port) 863 { 864 NODELIST *nlp; 865 NODELIST *tagged; 866 int i; 867 868 /* Find first node */ 869 rw_enter(&port->node_rwlock, RW_READER); 870 tagged = 0; 871 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 872 nlp = port->node_table[i]; 873 while (nlp != NULL) { 874 if (!nlp->nlp_tag) { 875 nlp = nlp->nlp_list_next; 876 continue; 877 } 878 nlp->nlp_tag = 0; 879 880 if (nlp->nlp_Rpi == FABRIC_RPI) { 881 nlp = nlp->nlp_list_next; 882 continue; 883 } 884 tagged = nlp; 885 break; 886 } 887 if (tagged) { 888 break; 889 } 890 } 891 rw_exit(&port->node_rwlock); 892 return (tagged); 893 } 894 895 896 extern int 897 emlxs_port_offline(emlxs_port_t *port, uint32_t scope) 898 { 899 emlxs_hba_t *hba = HBA; 900 emlxs_config_t *cfg; 901 NODELIST *nlp; 902 fc_affected_id_t *aid; 903 uint32_t mask; 904 uint32_t aff_d_id; 905 uint32_t linkdown; 906 uint32_t vlinkdown; 907 uint32_t action; 908 int i; 909 uint32_t unreg_vpi; 910 uint32_t update; 911 uint32_t adisc_support; 912 uint32_t clear_all; 913 uint8_t format; 914 915 /* Target mode only uses this routine for linkdowns */ 916 if ((port->mode == MODE_TARGET) && (scope != 0xffffffff) && 917 (scope != 0xfeffffff) && (scope != 0xfdffffff)) { 918 return (0); 919 } 920 921 cfg = &CFG; 922 aid = (fc_affected_id_t *)&scope; 923 linkdown = 0; 924 vlinkdown = 0; 925 unreg_vpi = 0; 926 update = 0; 927 clear_all = 0; 928 929 if (!(port->flag & EMLXS_PORT_BOUND)) { 930 return (0); 931 } 932 933 format = aid->aff_format; 934 935 switch (format) { 936 case 0: /* Port */ 937 mask = 0x00ffffff; 938 break; 939 940 case 1: /* Area */ 941 mask = 0x00ffff00; 942 break; 943 944 case 2: /* Domain */ 945 mask = 0x00ff0000; 946 break; 947 948 case 3: /* Network */ 949 mask = 0x00000000; 950 break; 951 952 #ifdef DHCHAP_SUPPORT 953 case 0xfe: /* Virtual link down */ 954 mask = 0x00000000; 955 vlinkdown = 1; 956 break; 957 #endif /* DHCHAP_SUPPORT */ 958 959 case 0xff: /* link is down */ 960 mask = 0x00000000; 961 linkdown = 1; 962 break; 963 964 case 0xfd: /* New fabric */ 965 default: 966 mask = 0x00000000; 967 linkdown = 1; 968 clear_all = 1; 969 break; 970 } 971 972 aff_d_id = aid->aff_d_id & mask; 973 974 975 /* 976 * If link is down then this is a hard shutdown and flush 977 * If link not down then this is a soft shutdown and flush 978 * (e.g. RSCN) 979 */ 980 if (linkdown) { 981 mutex_enter(&EMLXS_PORT_LOCK); 982 983 port->flag &= EMLXS_PORT_LINKDOWN_MASK; 984 985 if (port->ulp_statec != FC_STATE_OFFLINE) { 986 port->ulp_statec = FC_STATE_OFFLINE; 987 988 port->prev_did = port->did; 989 port->did = 0; 990 port->rdid = 0; 991 992 bcopy(&port->fabric_sparam, &port->prev_fabric_sparam, 993 sizeof (SERV_PARM)); 994 bzero(&port->fabric_sparam, sizeof (SERV_PARM)); 995 996 update = 1; 997 } 998 999 mutex_exit(&EMLXS_PORT_LOCK); 1000 1001 emlxs_timer_cancel_clean_address(port); 1002 1003 /* Tell ULP about it */ 1004 if (update) { 1005 if (port->flag & EMLXS_PORT_BOUND) { 1006 if (port->vpi == 0) { 1007 EMLXS_MSGF(EMLXS_CONTEXT, 1008 &emlxs_link_down_msg, NULL); 1009 } 1010 1011 if (port->mode == MODE_INITIATOR) { 1012 emlxs_fca_link_down(port); 1013 } 1014 #ifdef SFCT_SUPPORT 1015 else if (port->mode == MODE_TARGET) { 1016 emlxs_fct_link_down(port); 1017 } 1018 #endif /* SFCT_SUPPORT */ 1019 1020 } else { 1021 if (port->vpi == 0) { 1022 EMLXS_MSGF(EMLXS_CONTEXT, 1023 &emlxs_link_down_msg, "*"); 1024 } 1025 } 1026 1027 1028 } 1029 1030 unreg_vpi = 1; 1031 1032 #ifdef DHCHAP_SUPPORT 1033 /* Stop authentication with all nodes */ 1034 emlxs_dhc_auth_stop(port, NULL); 1035 #endif /* DHCHAP_SUPPORT */ 1036 1037 /* Flush the base node */ 1038 (void) emlxs_tx_node_flush(port, &port->node_base, 0, 0, 0); 1039 (void) emlxs_chipq_node_flush(port, 0, &port->node_base, 0); 1040 1041 /* Flush any pending ub buffers */ 1042 emlxs_ub_flush(port); 1043 } 1044 #ifdef DHCHAP_SUPPORT 1045 /* virtual link down */ 1046 else if (vlinkdown) { 1047 mutex_enter(&EMLXS_PORT_LOCK); 1048 1049 if (port->ulp_statec != FC_STATE_OFFLINE) { 1050 port->ulp_statec = FC_STATE_OFFLINE; 1051 update = 1; 1052 } 1053 1054 mutex_exit(&EMLXS_PORT_LOCK); 1055 1056 emlxs_timer_cancel_clean_address(port); 1057 1058 /* Tell ULP about it */ 1059 if (update) { 1060 if (port->flag & EMLXS_PORT_BOUND) { 1061 if (port->vpi == 0) { 1062 EMLXS_MSGF(EMLXS_CONTEXT, 1063 &emlxs_link_down_msg, 1064 "Switch authentication failed."); 1065 } 1066 1067 if (port->mode == MODE_INITIATOR) { 1068 emlxs_fca_link_down(port); 1069 } 1070 #ifdef SFCT_SUPPORT 1071 else if (port->mode == MODE_TARGET) { 1072 emlxs_fct_link_down(port); 1073 } 1074 #endif /* SFCT_SUPPORT */ 1075 } else { 1076 if (port->vpi == 0) { 1077 EMLXS_MSGF(EMLXS_CONTEXT, 1078 &emlxs_link_down_msg, 1079 "Switch authentication failed. *"); 1080 } 1081 } 1082 1083 1084 } 1085 1086 /* Flush the base node */ 1087 (void) emlxs_tx_node_flush(port, &port->node_base, 0, 0, 0); 1088 (void) emlxs_chipq_node_flush(port, 0, &port->node_base, 0); 1089 } 1090 #endif /* DHCHAP_SUPPORT */ 1091 else { 1092 emlxs_timer_cancel_clean_address(port); 1093 } 1094 1095 if (port->mode == MODE_TARGET) { 1096 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1097 /* Set the node tags */ 1098 emlxs_fcp_tag_nodes(port); 1099 unreg_vpi = 0; 1100 while ((nlp = emlxs_find_tagged_node(port))) { 1101 (void) emlxs_rpi_pause_notify(port, 1102 nlp->rpip); 1103 /* 1104 * In port_online we need to resume 1105 * these RPIs before we can use them. 1106 */ 1107 } 1108 } 1109 goto done; 1110 } 1111 1112 /* Set the node tags */ 1113 emlxs_fcp_tag_nodes(port); 1114 1115 if (!clear_all && (hba->flag & FC_ONLINE_MODE)) { 1116 adisc_support = cfg[CFG_ADISC_SUPPORT].current; 1117 } else { 1118 adisc_support = 0; 1119 } 1120 1121 /* Check ADISC support level */ 1122 switch (adisc_support) { 1123 case 0: /* No support - Flush all IO to all matching nodes */ 1124 1125 for (;;) { 1126 /* 1127 * We need to hold the locks this way because 1128 * EMLXS_SLI_UNREG_NODE and the flush routines enter the 1129 * same locks. Also, when we release the lock the list 1130 * can change out from under us. 1131 */ 1132 1133 /* Find first node */ 1134 rw_enter(&port->node_rwlock, RW_READER); 1135 action = 0; 1136 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 1137 nlp = port->node_table[i]; 1138 while (nlp != NULL) { 1139 if (!nlp->nlp_tag) { 1140 nlp = nlp->nlp_list_next; 1141 continue; 1142 } 1143 nlp->nlp_tag = 0; 1144 1145 /* 1146 * Check for any device that matches 1147 * our mask 1148 */ 1149 if ((nlp->nlp_DID & mask) == aff_d_id) { 1150 if (linkdown) { 1151 action = 1; 1152 break; 1153 } else { /* Must be an RCSN */ 1154 1155 action = 2; 1156 break; 1157 } 1158 } 1159 nlp = nlp->nlp_list_next; 1160 } 1161 1162 if (action) { 1163 break; 1164 } 1165 } 1166 rw_exit(&port->node_rwlock); 1167 1168 1169 /* Check if nothing was found */ 1170 if (action == 0) { 1171 break; 1172 } else if (action == 1) { 1173 (void) EMLXS_SLI_UNREG_NODE(port, nlp, 1174 NULL, NULL, NULL); 1175 } else if (action == 2) { 1176 EMLXS_SET_DFC_STATE(nlp, NODE_LIMBO); 1177 1178 #ifdef DHCHAP_SUPPORT 1179 emlxs_dhc_auth_stop(port, nlp); 1180 #endif /* DHCHAP_SUPPORT */ 1181 1182 /* 1183 * Close the node for any further normal IO 1184 * A PLOGI with reopen the node 1185 */ 1186 emlxs_node_close(port, nlp, 1187 hba->channel_fcp, 60); 1188 emlxs_node_close(port, nlp, 1189 hba->channel_ip, 60); 1190 1191 /* Flush tx queue */ 1192 (void) emlxs_tx_node_flush(port, nlp, 0, 0, 0); 1193 1194 /* Flush chip queue */ 1195 (void) emlxs_chipq_node_flush(port, 0, nlp, 0); 1196 } 1197 1198 } 1199 1200 break; 1201 1202 case 1: /* Partial support - Flush IO for non-FCP2 matching nodes */ 1203 1204 for (;;) { 1205 1206 /* 1207 * We need to hold the locks this way because 1208 * EMLXS_SLI_UNREG_NODE and the flush routines enter the 1209 * same locks. Also, when we release the lock the list 1210 * can change out from under us. 1211 */ 1212 rw_enter(&port->node_rwlock, RW_READER); 1213 action = 0; 1214 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 1215 nlp = port->node_table[i]; 1216 while (nlp != NULL) { 1217 if (!nlp->nlp_tag) { 1218 nlp = nlp->nlp_list_next; 1219 continue; 1220 } 1221 nlp->nlp_tag = 0; 1222 1223 /* 1224 * Check for special FCP2 target device 1225 * that matches our mask 1226 */ 1227 if ((nlp->nlp_fcp_info & 1228 NLP_FCP_TGT_DEVICE) && 1229 (nlp-> nlp_fcp_info & 1230 NLP_FCP_2_DEVICE) && 1231 (nlp->nlp_DID & mask) == 1232 aff_d_id) { 1233 action = 3; 1234 break; 1235 } 1236 1237 /* 1238 * Check for any other device that 1239 * matches our mask 1240 */ 1241 else if ((nlp->nlp_DID & mask) == 1242 aff_d_id) { 1243 if (linkdown) { 1244 action = 1; 1245 break; 1246 } else { /* Must be an RSCN */ 1247 1248 action = 2; 1249 break; 1250 } 1251 } 1252 1253 nlp = nlp->nlp_list_next; 1254 } 1255 1256 if (action) { 1257 break; 1258 } 1259 } 1260 rw_exit(&port->node_rwlock); 1261 1262 /* Check if nothing was found */ 1263 if (action == 0) { 1264 break; 1265 } else if (action == 1) { 1266 (void) EMLXS_SLI_UNREG_NODE(port, nlp, 1267 NULL, NULL, NULL); 1268 } else if (action == 2) { 1269 EMLXS_SET_DFC_STATE(nlp, NODE_LIMBO); 1270 1271 #ifdef DHCHAP_SUPPORT 1272 emlxs_dhc_auth_stop(port, nlp); 1273 #endif /* DHCHAP_SUPPORT */ 1274 1275 /* 1276 * Close the node for any further normal IO 1277 * A PLOGI with reopen the node 1278 */ 1279 emlxs_node_close(port, nlp, 1280 hba->channel_fcp, 60); 1281 emlxs_node_close(port, nlp, 1282 hba->channel_ip, 60); 1283 1284 /* Flush tx queue */ 1285 (void) emlxs_tx_node_flush(port, nlp, 0, 0, 0); 1286 1287 /* Flush chip queue */ 1288 (void) emlxs_chipq_node_flush(port, 0, nlp, 0); 1289 1290 } else if (action == 3) { /* FCP2 devices */ 1291 EMLXS_SET_DFC_STATE(nlp, NODE_LIMBO); 1292 1293 unreg_vpi = 0; 1294 1295 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1296 (void) emlxs_rpi_pause_notify(port, 1297 nlp->rpip); 1298 } 1299 1300 #ifdef DHCHAP_SUPPORT 1301 emlxs_dhc_auth_stop(port, nlp); 1302 #endif /* DHCHAP_SUPPORT */ 1303 1304 /* 1305 * Close the node for any further normal IO 1306 * An ADISC or a PLOGI with reopen the node 1307 */ 1308 emlxs_node_close(port, nlp, 1309 hba->channel_fcp, -1); 1310 emlxs_node_close(port, nlp, hba->channel_ip, 1311 ((linkdown) ? 0 : 60)); 1312 1313 /* Flush tx queues except for FCP ring */ 1314 (void) emlxs_tx_node_flush(port, nlp, 1315 &hba->chan[hba->channel_ct], 0, 0); 1316 (void) emlxs_tx_node_flush(port, nlp, 1317 &hba->chan[hba->channel_els], 0, 0); 1318 (void) emlxs_tx_node_flush(port, nlp, 1319 &hba->chan[hba->channel_ip], 0, 0); 1320 1321 /* Flush chip queues except for FCP ring */ 1322 (void) emlxs_chipq_node_flush(port, 1323 &hba->chan[hba->channel_ct], nlp, 0); 1324 (void) emlxs_chipq_node_flush(port, 1325 &hba->chan[hba->channel_els], nlp, 0); 1326 (void) emlxs_chipq_node_flush(port, 1327 &hba->chan[hba->channel_ip], nlp, 0); 1328 } 1329 } 1330 break; 1331 1332 case 2: /* Full support - Hold FCP IO to FCP target matching nodes */ 1333 1334 if (!linkdown && !vlinkdown) { 1335 break; 1336 } 1337 1338 for (;;) { 1339 /* 1340 * We need to hold the locks this way because 1341 * EMLXS_SLI_UNREG_NODE and the flush routines enter the 1342 * same locks. Also, when we release the lock the list 1343 * can change out from under us. 1344 */ 1345 rw_enter(&port->node_rwlock, RW_READER); 1346 action = 0; 1347 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 1348 nlp = port->node_table[i]; 1349 while (nlp != NULL) { 1350 if (!nlp->nlp_tag) { 1351 nlp = nlp->nlp_list_next; 1352 continue; 1353 } 1354 nlp->nlp_tag = 0; 1355 1356 /* 1357 * Check for FCP target device that 1358 * matches our mask 1359 */ 1360 if ((nlp-> nlp_fcp_info & 1361 NLP_FCP_TGT_DEVICE) && 1362 (nlp->nlp_DID & mask) == 1363 aff_d_id) { 1364 action = 3; 1365 break; 1366 } 1367 1368 /* 1369 * Check for any other device that 1370 * matches our mask 1371 */ 1372 else if ((nlp->nlp_DID & mask) == 1373 aff_d_id) { 1374 if (linkdown) { 1375 action = 1; 1376 break; 1377 } else { /* Must be an RSCN */ 1378 1379 action = 2; 1380 break; 1381 } 1382 } 1383 1384 nlp = nlp->nlp_list_next; 1385 } 1386 if (action) { 1387 break; 1388 } 1389 } 1390 rw_exit(&port->node_rwlock); 1391 1392 /* Check if nothing was found */ 1393 if (action == 0) { 1394 break; 1395 } else if (action == 1) { 1396 (void) EMLXS_SLI_UNREG_NODE(port, nlp, 1397 NULL, NULL, NULL); 1398 } else if (action == 2) { 1399 EMLXS_SET_DFC_STATE(nlp, NODE_LIMBO); 1400 1401 /* 1402 * Close the node for any further normal IO 1403 * A PLOGI with reopen the node 1404 */ 1405 emlxs_node_close(port, nlp, 1406 hba->channel_fcp, 60); 1407 emlxs_node_close(port, nlp, 1408 hba->channel_ip, 60); 1409 1410 /* Flush tx queue */ 1411 (void) emlxs_tx_node_flush(port, nlp, 0, 0, 0); 1412 1413 /* Flush chip queue */ 1414 (void) emlxs_chipq_node_flush(port, 0, nlp, 0); 1415 1416 } else if (action == 3) { /* FCP2 devices */ 1417 EMLXS_SET_DFC_STATE(nlp, NODE_LIMBO); 1418 1419 unreg_vpi = 0; 1420 1421 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1422 (void) emlxs_rpi_pause_notify(port, 1423 nlp->rpip); 1424 } 1425 1426 /* 1427 * Close the node for any further normal IO 1428 * An ADISC or a PLOGI with reopen the node 1429 */ 1430 emlxs_node_close(port, nlp, 1431 hba->channel_fcp, -1); 1432 emlxs_node_close(port, nlp, hba->channel_ip, 1433 ((linkdown) ? 0 : 60)); 1434 1435 /* Flush tx queues except for FCP ring */ 1436 (void) emlxs_tx_node_flush(port, nlp, 1437 &hba->chan[hba->channel_ct], 0, 0); 1438 (void) emlxs_tx_node_flush(port, nlp, 1439 &hba->chan[hba->channel_els], 0, 0); 1440 (void) emlxs_tx_node_flush(port, nlp, 1441 &hba->chan[hba->channel_ip], 0, 0); 1442 1443 /* Flush chip queues except for FCP ring */ 1444 (void) emlxs_chipq_node_flush(port, 1445 &hba->chan[hba->channel_ct], nlp, 0); 1446 (void) emlxs_chipq_node_flush(port, 1447 &hba->chan[hba->channel_els], nlp, 0); 1448 (void) emlxs_chipq_node_flush(port, 1449 &hba->chan[hba->channel_ip], nlp, 0); 1450 } 1451 } 1452 1453 break; 1454 1455 } /* switch() */ 1456 1457 done: 1458 1459 if (unreg_vpi) { 1460 (void) emlxs_mb_unreg_vpi(port); 1461 } 1462 1463 return (0); 1464 1465 } /* emlxs_port_offline() */ 1466 1467 1468 extern void 1469 emlxs_port_online(emlxs_port_t *vport) 1470 { 1471 emlxs_hba_t *hba = vport->hba; 1472 emlxs_port_t *port = &PPORT; 1473 NODELIST *nlp; 1474 uint32_t state; 1475 uint32_t update; 1476 uint32_t npiv_linkup; 1477 char topology[32]; 1478 char linkspeed[32]; 1479 char mode[32]; 1480 1481 /* 1482 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg, 1483 * "linkup_callback. vpi=%d fc_flag=%x", vport->vpi, hba->flag); 1484 */ 1485 1486 if ((vport->vpi > 0) && 1487 (!(hba->flag & FC_NPIV_ENABLED) || 1488 !(hba->flag & FC_NPIV_SUPPORTED))) { 1489 return; 1490 } 1491 1492 if (!(vport->flag & EMLXS_PORT_BOUND) || 1493 !(vport->flag & EMLXS_PORT_ENABLED)) { 1494 return; 1495 } 1496 1497 /* Check for mode */ 1498 if (port->mode == MODE_TARGET) { 1499 (void) strlcpy(mode, ", target", sizeof (mode)); 1500 1501 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1502 /* Set the node tags */ 1503 emlxs_fcp_tag_nodes(vport); 1504 while ((nlp = emlxs_find_tagged_node(vport))) { 1505 /* The RPI was paused in port_offline */ 1506 (void) emlxs_rpi_resume_notify(vport, 1507 nlp->rpip, 0); 1508 } 1509 } 1510 } else if (port->mode == MODE_INITIATOR) { 1511 (void) strlcpy(mode, ", initiator", sizeof (mode)); 1512 } else { 1513 (void) strlcpy(mode, "unknown", sizeof (mode)); 1514 } 1515 mutex_enter(&EMLXS_PORT_LOCK); 1516 1517 /* Check for loop topology */ 1518 if (hba->topology == TOPOLOGY_LOOP) { 1519 state = FC_STATE_LOOP; 1520 (void) strlcpy(topology, ", loop", sizeof (topology)); 1521 } else { 1522 state = FC_STATE_ONLINE; 1523 (void) strlcpy(topology, ", fabric", sizeof (topology)); 1524 } 1525 1526 /* Set the link speed */ 1527 switch (hba->linkspeed) { 1528 case 0: 1529 (void) strlcpy(linkspeed, "Gb", sizeof (linkspeed)); 1530 state |= FC_STATE_1GBIT_SPEED; 1531 break; 1532 1533 case LA_1GHZ_LINK: 1534 (void) strlcpy(linkspeed, "1Gb", sizeof (linkspeed)); 1535 state |= FC_STATE_1GBIT_SPEED; 1536 break; 1537 case LA_2GHZ_LINK: 1538 (void) strlcpy(linkspeed, "2Gb", sizeof (linkspeed)); 1539 state |= FC_STATE_2GBIT_SPEED; 1540 break; 1541 case LA_4GHZ_LINK: 1542 (void) strlcpy(linkspeed, "4Gb", sizeof (linkspeed)); 1543 state |= FC_STATE_4GBIT_SPEED; 1544 break; 1545 case LA_8GHZ_LINK: 1546 (void) strlcpy(linkspeed, "8Gb", sizeof (linkspeed)); 1547 state |= FC_STATE_8GBIT_SPEED; 1548 break; 1549 case LA_10GHZ_LINK: 1550 (void) strlcpy(linkspeed, "10Gb", sizeof (linkspeed)); 1551 state |= FC_STATE_10GBIT_SPEED; 1552 break; 1553 case LA_16GHZ_LINK: 1554 (void) strlcpy(linkspeed, "16Gb", sizeof (linkspeed)); 1555 state |= FC_STATE_16GBIT_SPEED; 1556 break; 1557 default: 1558 (void) snprintf(linkspeed, sizeof (linkspeed), "unknown(0x%x)", 1559 hba->linkspeed); 1560 break; 1561 } 1562 1563 npiv_linkup = 0; 1564 update = 0; 1565 1566 if ((hba->state >= FC_LINK_UP) && 1567 !(hba->flag & FC_LOOPBACK_MODE) && (vport->ulp_statec != state)) { 1568 update = 1; 1569 vport->ulp_statec = state; 1570 1571 if ((vport->vpi > 0) && !(hba->flag & FC_NPIV_LINKUP)) { 1572 hba->flag |= FC_NPIV_LINKUP; 1573 npiv_linkup = 1; 1574 } 1575 } 1576 1577 mutex_exit(&EMLXS_PORT_LOCK); 1578 1579 if (update) { 1580 if (vport->flag & EMLXS_PORT_BOUND) { 1581 if (vport->vpi == 0) { 1582 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg, 1583 "%s%s%s", linkspeed, topology, mode); 1584 1585 } else if (npiv_linkup) { 1586 EMLXS_MSGF(EMLXS_CONTEXT, 1587 &emlxs_npiv_link_up_msg, "%s%s%s", 1588 linkspeed, topology, mode); 1589 } 1590 1591 if (vport->mode == MODE_INITIATOR) { 1592 emlxs_fca_link_up(vport); 1593 } 1594 #ifdef SFCT_SUPPORT 1595 else if (vport->mode == MODE_TARGET) { 1596 emlxs_fct_link_up(vport); 1597 } 1598 #endif /* SFCT_SUPPORT */ 1599 } else { 1600 if (vport->vpi == 0) { 1601 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_up_msg, 1602 "%s%s%s *", linkspeed, topology, mode); 1603 1604 } else if (npiv_linkup) { 1605 EMLXS_MSGF(EMLXS_CONTEXT, 1606 &emlxs_npiv_link_up_msg, "%s%s%s *", 1607 linkspeed, topology, mode); 1608 } 1609 } 1610 1611 /* Check for waiting threads */ 1612 if (vport->vpi == 0) { 1613 mutex_enter(&EMLXS_LINKUP_LOCK); 1614 if (hba->linkup_wait_flag == TRUE) { 1615 hba->linkup_wait_flag = FALSE; 1616 cv_broadcast(&EMLXS_LINKUP_CV); 1617 } 1618 mutex_exit(&EMLXS_LINKUP_LOCK); 1619 } 1620 1621 /* Flush any pending ub buffers */ 1622 emlxs_ub_flush(vport); 1623 } 1624 1625 return; 1626 1627 } /* emlxs_port_online() */ 1628 1629 1630 /* SLI3 */ 1631 extern void 1632 emlxs_linkdown(emlxs_hba_t *hba) 1633 { 1634 emlxs_port_t *port = &PPORT; 1635 int i; 1636 uint32_t scope; 1637 1638 mutex_enter(&EMLXS_PORT_LOCK); 1639 1640 if (hba->state > FC_LINK_DOWN) { 1641 HBASTATS.LinkDown++; 1642 EMLXS_STATE_CHANGE_LOCKED(hba, FC_LINK_DOWN); 1643 } 1644 1645 /* Set scope */ 1646 scope = (hba->flag & FC_NEW_FABRIC)? 0xFDFFFFFF:0xFFFFFFFF; 1647 1648 /* Filter hba flags */ 1649 hba->flag &= FC_LINKDOWN_MASK; 1650 hba->discovery_timer = 0; 1651 hba->linkup_timer = 0; 1652 1653 mutex_exit(&EMLXS_PORT_LOCK); 1654 1655 for (i = 0; i < MAX_VPORTS; i++) { 1656 port = &VPORT(i); 1657 1658 if (!(port->flag & EMLXS_PORT_BOUND)) { 1659 continue; 1660 } 1661 1662 (void) emlxs_port_offline(port, scope); 1663 1664 } 1665 1666 emlxs_log_link_event(port); 1667 1668 return; 1669 1670 } /* emlxs_linkdown() */ 1671 1672 1673 /* SLI3 */ 1674 extern void 1675 emlxs_linkup(emlxs_hba_t *hba) 1676 { 1677 emlxs_port_t *port = &PPORT; 1678 emlxs_config_t *cfg = &CFG; 1679 1680 mutex_enter(&EMLXS_PORT_LOCK); 1681 1682 /* Check for any mode changes */ 1683 emlxs_mode_set(hba); 1684 1685 HBASTATS.LinkUp++; 1686 EMLXS_STATE_CHANGE_LOCKED(hba, FC_LINK_UP); 1687 1688 #ifdef MENLO_SUPPORT 1689 if (hba->flag & FC_MENLO_MODE) { 1690 mutex_exit(&EMLXS_PORT_LOCK); 1691 1692 /* 1693 * Trigger linkup CV and don't start linkup & discovery 1694 * timers 1695 */ 1696 mutex_enter(&EMLXS_LINKUP_LOCK); 1697 cv_broadcast(&EMLXS_LINKUP_CV); 1698 mutex_exit(&EMLXS_LINKUP_LOCK); 1699 1700 emlxs_log_link_event(port); 1701 1702 return; 1703 } 1704 #endif /* MENLO_SUPPORT */ 1705 1706 /* Set the linkup & discovery timers */ 1707 hba->linkup_timer = hba->timer_tics + cfg[CFG_LINKUP_TIMEOUT].current; 1708 hba->discovery_timer = 1709 hba->timer_tics + cfg[CFG_LINKUP_TIMEOUT].current + 1710 cfg[CFG_DISC_TIMEOUT].current; 1711 1712 mutex_exit(&EMLXS_PORT_LOCK); 1713 1714 emlxs_log_link_event(port); 1715 1716 return; 1717 1718 } /* emlxs_linkup() */ 1719 1720 1721 /* 1722 * emlxs_reset_link 1723 * 1724 * Description: 1725 * Called to reset the link with an init_link 1726 * 1727 * Returns: 1728 * 1729 */ 1730 extern int 1731 emlxs_reset_link(emlxs_hba_t *hba, uint32_t linkup, uint32_t wait) 1732 { 1733 emlxs_port_t *port = &PPORT; 1734 emlxs_config_t *cfg; 1735 MAILBOXQ *mbq = NULL; 1736 MAILBOX *mb = NULL; 1737 int rval = 0; 1738 int tmo; 1739 int rc; 1740 1741 /* 1742 * Get a buffer to use for the mailbox command 1743 */ 1744 if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX)) 1745 == NULL) { 1746 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_reset_failed_msg, 1747 "Unable to allocate mailbox buffer."); 1748 rval = 1; 1749 goto reset_link_fail; 1750 } 1751 1752 if (linkup) { 1753 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_reset_msg, 1754 "Resetting link..."); 1755 } else { 1756 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_reset_msg, 1757 "Disabling link..."); 1758 } 1759 1760 mb = (MAILBOX *)mbq; 1761 1762 /* Bring link down first */ 1763 emlxs_mb_down_link(hba, mbq); 1764 1765 #define MBXERR_LINK_DOWN 0x33 1766 1767 if (wait) { 1768 wait = MBX_WAIT; 1769 } else { 1770 wait = MBX_NOWAIT; 1771 } 1772 rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, wait, 0); 1773 if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS) && 1774 (rc != MBXERR_LINK_DOWN)) { 1775 rval = 1; 1776 goto reset_link_fail; 1777 } 1778 1779 tmo = 120; 1780 do { 1781 delay(drv_usectohz(500000)); 1782 tmo--; 1783 1784 if (!tmo) { 1785 rval = 1; 1786 1787 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_reset_msg, 1788 "Linkdown timeout."); 1789 1790 goto reset_link_fail; 1791 } 1792 } while ((hba->state >= FC_LINK_UP) && (hba->state != FC_ERROR)); 1793 1794 if (linkup) { 1795 /* 1796 * Setup and issue mailbox INITIALIZE LINK command 1797 */ 1798 1799 if (wait == MBX_NOWAIT) { 1800 if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX)) 1801 == NULL) { 1802 EMLXS_MSGF(EMLXS_CONTEXT, 1803 &emlxs_link_reset_failed_msg, 1804 "Unable to allocate mailbox buffer."); 1805 rval = 1; 1806 goto reset_link_fail; 1807 } 1808 mb = (MAILBOX *)mbq; 1809 } else { 1810 /* Reuse mbq from previous mbox */ 1811 mb = (MAILBOX *)mbq; 1812 } 1813 cfg = &CFG; 1814 1815 emlxs_mb_init_link(hba, mbq, 1816 cfg[CFG_TOPOLOGY].current, cfg[CFG_LINK_SPEED].current); 1817 1818 mb->un.varInitLnk.lipsr_AL_PA = 0; 1819 1820 /* Clear the loopback mode */ 1821 mutex_enter(&EMLXS_PORT_LOCK); 1822 hba->flag &= ~FC_LOOPBACK_MODE; 1823 hba->loopback_tics = 0; 1824 mutex_exit(&EMLXS_PORT_LOCK); 1825 1826 rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, wait, 0); 1827 if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 1828 rval = 1; 1829 goto reset_link_fail; 1830 } 1831 1832 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_reset_msg, NULL); 1833 } 1834 1835 reset_link_fail: 1836 1837 if ((wait == MBX_WAIT) && mbq) { 1838 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 1839 } 1840 1841 return (rval); 1842 } /* emlxs_reset_link() */ 1843 1844 1845 extern int 1846 emlxs_online(emlxs_hba_t *hba) 1847 { 1848 emlxs_port_t *port = &PPORT; 1849 int32_t rval = 0; 1850 uint32_t i = 0; 1851 1852 /* Make sure adapter is offline or exit trying (30 seconds) */ 1853 while (i++ < 30) { 1854 /* Check if adapter is already going online */ 1855 if (hba->flag & (FC_ONLINE_MODE | FC_ONLINING_MODE)) { 1856 return (0); 1857 } 1858 1859 mutex_enter(&EMLXS_PORT_LOCK); 1860 1861 /* Check again */ 1862 if (hba->flag & (FC_ONLINE_MODE | FC_ONLINING_MODE)) { 1863 mutex_exit(&EMLXS_PORT_LOCK); 1864 return (0); 1865 } 1866 1867 /* Check if adapter is offline */ 1868 if (hba->flag & FC_OFFLINE_MODE) { 1869 /* Mark it going online */ 1870 hba->flag &= ~FC_OFFLINE_MODE; 1871 hba->flag |= FC_ONLINING_MODE; 1872 1873 /* Currently !FC_ONLINE_MODE and !FC_OFFLINE_MODE */ 1874 mutex_exit(&EMLXS_PORT_LOCK); 1875 break; 1876 } 1877 1878 mutex_exit(&EMLXS_PORT_LOCK); 1879 1880 BUSYWAIT_MS(1000); 1881 } 1882 1883 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 1884 "Going online..."); 1885 1886 if (rval = EMLXS_SLI_ONLINE(hba)) { 1887 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, "status=%x", 1888 rval); 1889 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_offline_msg, NULL); 1890 1891 /* Set FC_OFFLINE_MODE */ 1892 mutex_enter(&EMLXS_PORT_LOCK); 1893 hba->flag |= FC_OFFLINE_MODE; 1894 hba->flag &= ~FC_ONLINING_MODE; 1895 mutex_exit(&EMLXS_PORT_LOCK); 1896 1897 return (rval); 1898 } 1899 1900 /* Start the timer */ 1901 emlxs_timer_start(hba); 1902 1903 /* Set FC_ONLINE_MODE */ 1904 mutex_enter(&EMLXS_PORT_LOCK); 1905 hba->flag |= FC_ONLINE_MODE; 1906 hba->flag &= ~FC_ONLINING_MODE; 1907 mutex_exit(&EMLXS_PORT_LOCK); 1908 1909 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_online_msg, NULL); 1910 1911 #ifdef SFCT_SUPPORT 1912 if (port->flag & EMLXS_TGT_ENABLED) { 1913 (void) emlxs_fct_port_initialize(port); 1914 } 1915 #endif /* SFCT_SUPPORT */ 1916 1917 return (rval); 1918 1919 } /* emlxs_online() */ 1920 1921 1922 extern int 1923 emlxs_offline(emlxs_hba_t *hba, uint32_t reset_requested) 1924 { 1925 emlxs_port_t *port = &PPORT; 1926 uint32_t i = 0; 1927 int rval = 1; 1928 1929 /* Make sure adapter is online or exit trying (30 seconds) */ 1930 while (i++ < 30) { 1931 /* Check if adapter is already going offline */ 1932 if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) { 1933 return (0); 1934 } 1935 1936 mutex_enter(&EMLXS_PORT_LOCK); 1937 1938 /* Check again */ 1939 if (hba->flag & (FC_OFFLINE_MODE | FC_OFFLINING_MODE)) { 1940 mutex_exit(&EMLXS_PORT_LOCK); 1941 return (0); 1942 } 1943 1944 /* Check if adapter is online */ 1945 if (hba->flag & FC_ONLINE_MODE) { 1946 /* Mark it going offline */ 1947 hba->flag &= ~FC_ONLINE_MODE; 1948 hba->flag |= FC_OFFLINING_MODE; 1949 1950 /* Currently !FC_ONLINE_MODE and !FC_OFFLINE_MODE */ 1951 mutex_exit(&EMLXS_PORT_LOCK); 1952 break; 1953 } 1954 1955 mutex_exit(&EMLXS_PORT_LOCK); 1956 1957 BUSYWAIT_MS(1000); 1958 } 1959 1960 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 1961 "Going offline..."); 1962 1963 /* Declare link down */ 1964 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 1965 (void) emlxs_fcf_shutdown_notify(port, 1); 1966 } else { 1967 emlxs_linkdown(hba); 1968 } 1969 1970 #ifdef SFCT_SUPPORT 1971 if (port->flag & EMLXS_TGT_ENABLED) { 1972 (void) emlxs_fct_port_shutdown(port); 1973 } 1974 #endif /* SFCT_SUPPORT */ 1975 1976 /* Check if adapter was shutdown */ 1977 if (hba->flag & FC_HARDWARE_ERROR) { 1978 /* 1979 * Force mailbox cleanup 1980 * This will wake any sleeping or polling threads 1981 */ 1982 emlxs_mb_fini(hba, NULL, MBX_HARDWARE_ERROR); 1983 } 1984 1985 /* Pause here for the IO to settle */ 1986 delay(drv_usectohz(1000000)); /* 1 sec */ 1987 1988 /* Unregister all nodes */ 1989 emlxs_ffcleanup(hba); 1990 1991 if (hba->bus_type == SBUS_FC) { 1992 WRITE_SBUS_CSR_REG(hba, FC_SHS_REG(hba), 0x9A); 1993 #ifdef FMA_SUPPORT 1994 /* Access handle validation */ 1995 EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.sbus_csr_handle); 1996 #endif /* FMA_SUPPORT */ 1997 } 1998 1999 /* Stop the timer */ 2000 emlxs_timer_stop(hba); 2001 2002 /* For safety flush every iotag list */ 2003 if (emlxs_iotag_flush(hba)) { 2004 /* Pause here for the IO to flush */ 2005 delay(drv_usectohz(1000)); 2006 } 2007 2008 /* Wait for poll command request to settle */ 2009 while (hba->io_poll_count > 0) { 2010 delay(drv_usectohz(2000000)); /* 2 sec */ 2011 } 2012 2013 /* Shutdown the adapter interface */ 2014 EMLXS_SLI_OFFLINE(hba, reset_requested); 2015 2016 mutex_enter(&EMLXS_PORT_LOCK); 2017 hba->flag |= FC_OFFLINE_MODE; 2018 hba->flag &= ~FC_OFFLINING_MODE; 2019 mutex_exit(&EMLXS_PORT_LOCK); 2020 2021 rval = 0; 2022 2023 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_offline_msg, NULL); 2024 2025 done: 2026 2027 return (rval); 2028 2029 } /* emlxs_offline() */ 2030 2031 2032 2033 extern int 2034 emlxs_power_down(emlxs_hba_t *hba) 2035 { 2036 #ifdef FMA_SUPPORT 2037 emlxs_port_t *port = &PPORT; 2038 #endif /* FMA_SUPPORT */ 2039 int32_t rval = 0; 2040 2041 if ((rval = emlxs_offline(hba, 0))) { 2042 return (rval); 2043 } 2044 EMLXS_SLI_HBA_RESET(hba, 1, 1, 0); 2045 2046 2047 #ifdef FMA_SUPPORT 2048 if (emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle) 2049 != DDI_FM_OK) { 2050 EMLXS_MSGF(EMLXS_CONTEXT, 2051 &emlxs_invalid_access_handle_msg, NULL); 2052 return (1); 2053 } 2054 #endif /* FMA_SUPPORT */ 2055 2056 return (0); 2057 2058 } /* End emlxs_power_down */ 2059 2060 2061 extern int 2062 emlxs_power_up(emlxs_hba_t *hba) 2063 { 2064 #ifdef FMA_SUPPORT 2065 emlxs_port_t *port = &PPORT; 2066 #endif /* FMA_SUPPORT */ 2067 int32_t rval = 0; 2068 2069 2070 #ifdef FMA_SUPPORT 2071 if (emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle) 2072 != DDI_FM_OK) { 2073 EMLXS_MSGF(EMLXS_CONTEXT, 2074 &emlxs_invalid_access_handle_msg, NULL); 2075 return (1); 2076 } 2077 #endif /* FMA_SUPPORT */ 2078 2079 /* Bring adapter online */ 2080 if ((rval = emlxs_online(hba))) { 2081 if (hba->pci_cap_offset[PCI_CAP_ID_PM]) { 2082 /* Put chip in D3 state */ 2083 (void) ddi_put8(hba->pci_acc_handle, 2084 (uint8_t *)(hba->pci_addr + 2085 hba->pci_cap_offset[PCI_CAP_ID_PM] + 2086 PCI_PMCSR), 2087 (uint8_t)PCI_PMCSR_D3HOT); 2088 } 2089 return (rval); 2090 } 2091 2092 return (rval); 2093 2094 } /* emlxs_power_up() */ 2095 2096 2097 /* 2098 * 2099 * NAME: emlxs_ffcleanup 2100 * 2101 * FUNCTION: Cleanup all the Firefly resources used by configuring the adapter 2102 * 2103 * EXECUTION ENVIRONMENT: process only 2104 * 2105 * CALLED FROM: CFG_TERM 2106 * 2107 * INPUT: hba - pointer to the dev_ctl area. 2108 * 2109 * RETURNS: none 2110 */ 2111 extern void 2112 emlxs_ffcleanup(emlxs_hba_t *hba) 2113 { 2114 emlxs_port_t *port = &PPORT; 2115 uint32_t i; 2116 2117 /* Disable all but the mailbox interrupt */ 2118 EMLXS_SLI_DISABLE_INTR(hba, HC_MBINT_ENA); 2119 2120 /* Make sure all port nodes are destroyed */ 2121 for (i = 0; i < MAX_VPORTS; i++) { 2122 port = &VPORT(i); 2123 2124 if (port->node_count) { 2125 (void) EMLXS_SLI_UNREG_NODE(port, 0, 0, 0, 0); 2126 } 2127 } 2128 2129 /* Clear all interrupt enable conditions */ 2130 EMLXS_SLI_DISABLE_INTR(hba, 0); 2131 2132 return; 2133 2134 } /* emlxs_ffcleanup() */ 2135 2136 2137 extern uint16_t 2138 emlxs_register_pkt(CHANNEL *cp, emlxs_buf_t *sbp) 2139 { 2140 emlxs_hba_t *hba; 2141 emlxs_port_t *port; 2142 uint16_t iotag; 2143 uint32_t i; 2144 2145 hba = cp->hba; 2146 2147 mutex_enter(&EMLXS_FCTAB_LOCK); 2148 2149 if (sbp->iotag != 0) { 2150 port = &PPORT; 2151 2152 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2153 "Pkt already registered! channel=%d iotag=%d sbp=%p", 2154 sbp->channel, sbp->iotag, sbp); 2155 } 2156 2157 iotag = 0; 2158 for (i = 0; i < hba->max_iotag; i++) { 2159 if (!hba->fc_iotag || hba->fc_iotag >= hba->max_iotag) { 2160 hba->fc_iotag = 1; 2161 } 2162 iotag = hba->fc_iotag++; 2163 2164 if (hba->fc_table[iotag] == 0 || 2165 hba->fc_table[iotag] == STALE_PACKET) { 2166 hba->io_count++; 2167 hba->fc_table[iotag] = sbp; 2168 2169 sbp->iotag = iotag; 2170 sbp->channel = cp; 2171 2172 break; 2173 } 2174 iotag = 0; 2175 } 2176 2177 mutex_exit(&EMLXS_FCTAB_LOCK); 2178 2179 /* 2180 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2181 * "register_pkt: channel=%d iotag=%d sbp=%p", 2182 * cp->channelno, iotag, sbp); 2183 */ 2184 2185 return (iotag); 2186 2187 } /* emlxs_register_pkt() */ 2188 2189 2190 2191 extern emlxs_buf_t * 2192 emlxs_unregister_pkt(CHANNEL *cp, uint16_t iotag, uint32_t forced) 2193 { 2194 emlxs_hba_t *hba; 2195 emlxs_buf_t *sbp; 2196 2197 sbp = NULL; 2198 hba = cp->hba; 2199 2200 /* Check the iotag range */ 2201 if ((iotag == 0) || (iotag >= hba->max_iotag)) { 2202 return (NULL); 2203 } 2204 2205 /* Remove the sbp from the table */ 2206 mutex_enter(&EMLXS_FCTAB_LOCK); 2207 sbp = hba->fc_table[iotag]; 2208 2209 if (!sbp || (sbp == STALE_PACKET)) { 2210 mutex_exit(&EMLXS_FCTAB_LOCK); 2211 return (sbp); 2212 } 2213 2214 hba->fc_table[iotag] = ((forced) ? STALE_PACKET : NULL); 2215 hba->io_count--; 2216 sbp->iotag = 0; 2217 2218 mutex_exit(&EMLXS_FCTAB_LOCK); 2219 2220 2221 /* Clean up the sbp */ 2222 mutex_enter(&sbp->mtx); 2223 2224 if (sbp->pkt_flags & PACKET_IN_TXQ) { 2225 sbp->pkt_flags &= ~PACKET_IN_TXQ; 2226 hba->channel_tx_count--; 2227 } 2228 2229 if (sbp->pkt_flags & PACKET_IN_CHIPQ) { 2230 sbp->pkt_flags &= ~PACKET_IN_CHIPQ; 2231 } 2232 2233 if (sbp->bmp) { 2234 emlxs_mem_put(hba, MEM_BPL, (void *)sbp->bmp); 2235 sbp->bmp = 0; 2236 } 2237 2238 mutex_exit(&sbp->mtx); 2239 2240 return (sbp); 2241 2242 } /* emlxs_unregister_pkt() */ 2243 2244 2245 2246 /* Flush all IO's to all nodes for a given IO Channel */ 2247 extern uint32_t 2248 emlxs_tx_channel_flush(emlxs_hba_t *hba, CHANNEL *cp, emlxs_buf_t *fpkt) 2249 { 2250 emlxs_port_t *port = &PPORT; 2251 emlxs_buf_t *sbp; 2252 IOCBQ *iocbq; 2253 IOCBQ *next; 2254 IOCB *iocb; 2255 uint32_t channelno; 2256 Q abort; 2257 NODELIST *ndlp; 2258 IOCB *icmd; 2259 MATCHMAP *mp; 2260 uint32_t i; 2261 uint8_t flag[MAX_CHANNEL]; 2262 2263 channelno = cp->channelno; 2264 bzero((void *)&abort, sizeof (Q)); 2265 bzero((void *)flag, MAX_CHANNEL * sizeof (uint8_t)); 2266 2267 mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 2268 2269 /* While a node needs servicing */ 2270 while (cp->nodeq.q_first) { 2271 ndlp = (NODELIST *) cp->nodeq.q_first; 2272 2273 /* Check if priority queue is not empty */ 2274 if (ndlp->nlp_ptx[channelno].q_first) { 2275 /* Transfer all iocb's to local queue */ 2276 if (abort.q_first == 0) { 2277 abort.q_first = 2278 ndlp->nlp_ptx[channelno].q_first; 2279 } else { 2280 ((IOCBQ *)abort.q_last)->next = 2281 (IOCBQ *)ndlp->nlp_ptx[channelno].q_first; 2282 } 2283 flag[channelno] = 1; 2284 2285 abort.q_last = ndlp->nlp_ptx[channelno].q_last; 2286 abort.q_cnt += ndlp->nlp_ptx[channelno].q_cnt; 2287 } 2288 2289 /* Check if tx queue is not empty */ 2290 if (ndlp->nlp_tx[channelno].q_first) { 2291 /* Transfer all iocb's to local queue */ 2292 if (abort.q_first == 0) { 2293 abort.q_first = ndlp->nlp_tx[channelno].q_first; 2294 } else { 2295 ((IOCBQ *)abort.q_last)->next = 2296 (IOCBQ *)ndlp->nlp_tx[channelno].q_first; 2297 } 2298 2299 abort.q_last = ndlp->nlp_tx[channelno].q_last; 2300 abort.q_cnt += ndlp->nlp_tx[channelno].q_cnt; 2301 } 2302 2303 /* Clear the queue pointers */ 2304 ndlp->nlp_ptx[channelno].q_first = NULL; 2305 ndlp->nlp_ptx[channelno].q_last = NULL; 2306 ndlp->nlp_ptx[channelno].q_cnt = 0; 2307 2308 ndlp->nlp_tx[channelno].q_first = NULL; 2309 ndlp->nlp_tx[channelno].q_last = NULL; 2310 ndlp->nlp_tx[channelno].q_cnt = 0; 2311 2312 /* Remove node from service queue */ 2313 2314 /* If this is the last node on list */ 2315 if (cp->nodeq.q_last == (void *)ndlp) { 2316 cp->nodeq.q_last = NULL; 2317 cp->nodeq.q_first = NULL; 2318 cp->nodeq.q_cnt = 0; 2319 } else { 2320 /* Remove node from head */ 2321 cp->nodeq.q_first = ndlp->nlp_next[channelno]; 2322 ((NODELIST *)cp->nodeq.q_last)->nlp_next[channelno] = 2323 cp->nodeq.q_first; 2324 cp->nodeq.q_cnt--; 2325 } 2326 2327 /* Clear node */ 2328 ndlp->nlp_next[channelno] = NULL; 2329 } 2330 2331 /* First cleanup the iocb's while still holding the lock */ 2332 iocbq = (IOCBQ *) abort.q_first; 2333 while (iocbq) { 2334 /* Free the IoTag and the bmp */ 2335 iocb = &iocbq->iocb; 2336 2337 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 2338 sbp = iocbq->sbp; 2339 if (sbp) { 2340 emlxs_sli4_free_xri(port, sbp, sbp->xrip, 1); 2341 } 2342 } else { 2343 sbp = emlxs_unregister_pkt((CHANNEL *)iocbq->channel, 2344 iocb->ULPIOTAG, 0); 2345 } 2346 2347 if (sbp && (sbp != STALE_PACKET)) { 2348 mutex_enter(&sbp->mtx); 2349 2350 sbp->pkt_flags |= PACKET_IN_FLUSH; 2351 /* 2352 * If the fpkt is already set, then we will leave it 2353 * alone. This ensures that this pkt is only accounted 2354 * for on one fpkt->flush_count 2355 */ 2356 if (!sbp->fpkt && fpkt) { 2357 mutex_enter(&fpkt->mtx); 2358 sbp->fpkt = fpkt; 2359 fpkt->flush_count++; 2360 mutex_exit(&fpkt->mtx); 2361 } 2362 2363 mutex_exit(&sbp->mtx); 2364 } 2365 2366 iocbq = (IOCBQ *)iocbq->next; 2367 } /* end of while */ 2368 2369 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 2370 2371 /* Now abort the iocb's */ 2372 iocbq = (IOCBQ *)abort.q_first; 2373 while (iocbq) { 2374 /* Save the next iocbq for now */ 2375 next = (IOCBQ *)iocbq->next; 2376 2377 /* Unlink this iocbq */ 2378 iocbq->next = NULL; 2379 2380 /* Get the pkt */ 2381 sbp = (emlxs_buf_t *)iocbq->sbp; 2382 2383 if (sbp) { 2384 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flush_msg, 2385 "tx: sbp=%p node=%p", sbp, sbp->node); 2386 2387 if (hba->state >= FC_LINK_UP) { 2388 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 2389 IOERR_ABORT_REQUESTED, 1); 2390 } else { 2391 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 2392 IOERR_LINK_DOWN, 1); 2393 } 2394 2395 } 2396 /* Free the iocb and its associated buffers */ 2397 else { 2398 icmd = &iocbq->iocb; 2399 2400 /* SLI3 */ 2401 if (icmd->ULPCOMMAND == CMD_QUE_RING_BUF64_CN || 2402 icmd->ULPCOMMAND == CMD_QUE_RING_BUF_CN || 2403 icmd->ULPCOMMAND == CMD_QUE_RING_LIST64_CN) { 2404 if ((hba->flag & 2405 (FC_ONLINE_MODE | FC_ONLINING_MODE)) == 0) { 2406 /* HBA is detaching or offlining */ 2407 if (icmd->ULPCOMMAND != 2408 CMD_QUE_RING_LIST64_CN) { 2409 void *tmp; 2410 RING *rp; 2411 2412 rp = &hba->sli.sli3. 2413 ring[channelno]; 2414 for (i = 0; 2415 i < icmd->ULPBDECOUNT; 2416 i++) { 2417 mp = EMLXS_GET_VADDR( 2418 hba, rp, icmd); 2419 2420 tmp = (void *)mp; 2421 if (mp) { 2422 emlxs_mem_put( 2423 hba, MEM_BUF, tmp); 2424 } 2425 } 2426 } 2427 2428 emlxs_mem_put(hba, MEM_IOCB, 2429 (void *)iocbq); 2430 } else { 2431 /* repost the unsolicited buffer */ 2432 EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, 2433 iocbq); 2434 } 2435 } else if (icmd->ULPCOMMAND == CMD_CLOSE_XRI_CN || 2436 icmd->ULPCOMMAND == CMD_CLOSE_XRI_CX) { 2437 2438 emlxs_tx_put(iocbq, 1); 2439 } 2440 } 2441 2442 iocbq = next; 2443 2444 } /* end of while */ 2445 2446 /* Now trigger channel service */ 2447 for (channelno = 0; channelno < hba->chan_count; channelno++) { 2448 if (!flag[channelno]) { 2449 continue; 2450 } 2451 2452 EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0); 2453 } 2454 2455 return (abort.q_cnt); 2456 2457 } /* emlxs_tx_channel_flush() */ 2458 2459 2460 /* Flush all IO's on all or a given ring for a given node */ 2461 extern uint32_t 2462 emlxs_tx_node_flush(emlxs_port_t *port, NODELIST *ndlp, CHANNEL *chan, 2463 uint32_t shutdown, emlxs_buf_t *fpkt) 2464 { 2465 emlxs_hba_t *hba = HBA; 2466 emlxs_buf_t *sbp; 2467 uint32_t channelno; 2468 CHANNEL *cp; 2469 IOCB *icmd; 2470 IOCBQ *iocbq; 2471 NODELIST *prev; 2472 IOCBQ *next; 2473 IOCB *iocb; 2474 Q abort; 2475 uint32_t i; 2476 MATCHMAP *mp; 2477 uint8_t flag[MAX_CHANNEL]; 2478 2479 bzero((void *)&abort, sizeof (Q)); 2480 2481 /* Flush all I/O's on tx queue to this target */ 2482 mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 2483 2484 if (!ndlp->nlp_base && shutdown) { 2485 ndlp->nlp_active = 0; 2486 } 2487 2488 for (channelno = 0; channelno < hba->chan_count; channelno++) { 2489 cp = &hba->chan[channelno]; 2490 2491 if (chan && cp != chan) { 2492 continue; 2493 } 2494 2495 if (!ndlp->nlp_base || shutdown) { 2496 /* Check if priority queue is not empty */ 2497 if (ndlp->nlp_ptx[channelno].q_first) { 2498 /* Transfer all iocb's to local queue */ 2499 if (abort.q_first == 0) { 2500 abort.q_first = 2501 ndlp->nlp_ptx[channelno].q_first; 2502 } else { 2503 ((IOCBQ *)(abort.q_last))->next = 2504 (IOCBQ *)ndlp->nlp_ptx[channelno]. 2505 q_first; 2506 } 2507 2508 flag[channelno] = 1; 2509 2510 abort.q_last = ndlp->nlp_ptx[channelno].q_last; 2511 abort.q_cnt += ndlp->nlp_ptx[channelno].q_cnt; 2512 } 2513 } 2514 2515 /* Check if tx queue is not empty */ 2516 if (ndlp->nlp_tx[channelno].q_first) { 2517 2518 /* Transfer all iocb's to local queue */ 2519 if (abort.q_first == 0) { 2520 abort.q_first = ndlp->nlp_tx[channelno].q_first; 2521 } else { 2522 ((IOCBQ *)abort.q_last)->next = 2523 (IOCBQ *)ndlp->nlp_tx[channelno].q_first; 2524 } 2525 2526 abort.q_last = ndlp->nlp_tx[channelno].q_last; 2527 abort.q_cnt += ndlp->nlp_tx[channelno].q_cnt; 2528 } 2529 2530 /* Clear the queue pointers */ 2531 ndlp->nlp_ptx[channelno].q_first = NULL; 2532 ndlp->nlp_ptx[channelno].q_last = NULL; 2533 ndlp->nlp_ptx[channelno].q_cnt = 0; 2534 2535 ndlp->nlp_tx[channelno].q_first = NULL; 2536 ndlp->nlp_tx[channelno].q_last = NULL; 2537 ndlp->nlp_tx[channelno].q_cnt = 0; 2538 2539 /* If this node was on the channel queue, remove it */ 2540 if (ndlp->nlp_next[channelno]) { 2541 /* If this is the only node on list */ 2542 if (cp->nodeq.q_first == (void *)ndlp && 2543 cp->nodeq.q_last == (void *)ndlp) { 2544 cp->nodeq.q_last = NULL; 2545 cp->nodeq.q_first = NULL; 2546 cp->nodeq.q_cnt = 0; 2547 } else if (cp->nodeq.q_first == (void *)ndlp) { 2548 cp->nodeq.q_first = ndlp->nlp_next[channelno]; 2549 ((NODELIST *) cp->nodeq.q_last)-> 2550 nlp_next[channelno] = cp->nodeq.q_first; 2551 cp->nodeq.q_cnt--; 2552 } else { 2553 /* 2554 * This is a little more difficult find the 2555 * previous node in the circular channel queue 2556 */ 2557 prev = ndlp; 2558 while (prev->nlp_next[channelno] != ndlp) { 2559 prev = prev->nlp_next[channelno]; 2560 } 2561 2562 prev->nlp_next[channelno] = 2563 ndlp->nlp_next[channelno]; 2564 2565 if (cp->nodeq.q_last == (void *)ndlp) { 2566 cp->nodeq.q_last = (void *)prev; 2567 } 2568 cp->nodeq.q_cnt--; 2569 2570 } 2571 2572 /* Clear node */ 2573 ndlp->nlp_next[channelno] = NULL; 2574 } 2575 2576 } 2577 2578 /* First cleanup the iocb's while still holding the lock */ 2579 iocbq = (IOCBQ *) abort.q_first; 2580 while (iocbq) { 2581 /* Free the IoTag and the bmp */ 2582 iocb = &iocbq->iocb; 2583 2584 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 2585 sbp = iocbq->sbp; 2586 if (sbp) { 2587 emlxs_sli4_free_xri(port, sbp, sbp->xrip, 1); 2588 } 2589 } else { 2590 sbp = emlxs_unregister_pkt((CHANNEL *)iocbq->channel, 2591 iocb->ULPIOTAG, 0); 2592 } 2593 2594 if (sbp && (sbp != STALE_PACKET)) { 2595 mutex_enter(&sbp->mtx); 2596 sbp->pkt_flags |= PACKET_IN_FLUSH; 2597 /* 2598 * If the fpkt is already set, then we will leave it 2599 * alone. This ensures that this pkt is only accounted 2600 * for on one fpkt->flush_count 2601 */ 2602 if (!sbp->fpkt && fpkt) { 2603 mutex_enter(&fpkt->mtx); 2604 sbp->fpkt = fpkt; 2605 fpkt->flush_count++; 2606 mutex_exit(&fpkt->mtx); 2607 } 2608 2609 mutex_exit(&sbp->mtx); 2610 } 2611 2612 iocbq = (IOCBQ *) iocbq->next; 2613 2614 } /* end of while */ 2615 2616 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 2617 2618 /* Now abort the iocb's outside the locks */ 2619 iocbq = (IOCBQ *)abort.q_first; 2620 while (iocbq) { 2621 /* Save the next iocbq for now */ 2622 next = (IOCBQ *)iocbq->next; 2623 2624 /* Unlink this iocbq */ 2625 iocbq->next = NULL; 2626 2627 /* Get the pkt */ 2628 sbp = (emlxs_buf_t *)iocbq->sbp; 2629 2630 if (sbp) { 2631 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flush_msg, 2632 "tx: sbp=%p node=%p", sbp, sbp->node); 2633 2634 if (hba->state >= FC_LINK_UP) { 2635 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 2636 IOERR_ABORT_REQUESTED, 1); 2637 } else { 2638 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 2639 IOERR_LINK_DOWN, 1); 2640 } 2641 2642 } 2643 /* Free the iocb and its associated buffers */ 2644 else { 2645 /* CMD_CLOSE_XRI_CN should also free the memory */ 2646 icmd = &iocbq->iocb; 2647 2648 /* SLI3 */ 2649 if (icmd->ULPCOMMAND == CMD_QUE_RING_BUF64_CN || 2650 icmd->ULPCOMMAND == CMD_QUE_RING_BUF_CN || 2651 icmd->ULPCOMMAND == CMD_QUE_RING_LIST64_CN) { 2652 if ((hba->flag & 2653 (FC_ONLINE_MODE | FC_ONLINING_MODE)) == 0) { 2654 /* HBA is detaching or offlining */ 2655 if (icmd->ULPCOMMAND != 2656 CMD_QUE_RING_LIST64_CN) { 2657 void *tmp; 2658 RING *rp; 2659 int ch; 2660 2661 ch = ((CHANNEL *) 2662 iocbq->channel)->channelno; 2663 rp = &hba->sli.sli3.ring[ch]; 2664 for (i = 0; 2665 i < icmd->ULPBDECOUNT; 2666 i++) { 2667 mp = EMLXS_GET_VADDR( 2668 hba, rp, icmd); 2669 2670 tmp = (void *)mp; 2671 if (mp) { 2672 emlxs_mem_put( 2673 hba, MEM_BUF, tmp); 2674 } 2675 } 2676 } 2677 2678 emlxs_mem_put(hba, MEM_IOCB, 2679 (void *)iocbq); 2680 } else { 2681 /* repost the unsolicited buffer */ 2682 EMLXS_SLI_ISSUE_IOCB_CMD(hba, 2683 (CHANNEL *)iocbq->channel, iocbq); 2684 } 2685 } else if (icmd->ULPCOMMAND == CMD_CLOSE_XRI_CN || 2686 icmd->ULPCOMMAND == CMD_CLOSE_XRI_CX) { 2687 /* 2688 * Resend the abort iocbq if any 2689 */ 2690 emlxs_tx_put(iocbq, 1); 2691 } 2692 } 2693 2694 iocbq = next; 2695 2696 } /* end of while */ 2697 2698 /* Now trigger channel service */ 2699 for (channelno = 0; channelno < hba->chan_count; channelno++) { 2700 if (!flag[channelno]) { 2701 continue; 2702 } 2703 2704 EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0); 2705 } 2706 2707 return (abort.q_cnt); 2708 2709 } /* emlxs_tx_node_flush() */ 2710 2711 2712 /* Check for IO's on all or a given ring for a given node */ 2713 extern uint32_t 2714 emlxs_tx_node_check(emlxs_port_t *port, NODELIST *ndlp, CHANNEL *chan) 2715 { 2716 emlxs_hba_t *hba = HBA; 2717 uint32_t channelno; 2718 CHANNEL *cp; 2719 uint32_t count; 2720 2721 count = 0; 2722 2723 /* Flush all I/O's on tx queue to this target */ 2724 mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 2725 2726 for (channelno = 0; channelno < hba->chan_count; channelno++) { 2727 cp = &hba->chan[channelno]; 2728 2729 if (chan && cp != chan) { 2730 continue; 2731 } 2732 2733 /* Check if priority queue is not empty */ 2734 if (ndlp->nlp_ptx[channelno].q_first) { 2735 count += ndlp->nlp_ptx[channelno].q_cnt; 2736 } 2737 2738 /* Check if tx queue is not empty */ 2739 if (ndlp->nlp_tx[channelno].q_first) { 2740 count += ndlp->nlp_tx[channelno].q_cnt; 2741 } 2742 2743 } 2744 2745 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 2746 2747 return (count); 2748 2749 } /* emlxs_tx_node_check() */ 2750 2751 2752 2753 /* Flush all IO's on the any ring for a given node's lun */ 2754 extern uint32_t 2755 emlxs_tx_lun_flush(emlxs_port_t *port, NODELIST *ndlp, uint32_t lun, 2756 emlxs_buf_t *fpkt) 2757 { 2758 emlxs_hba_t *hba = HBA; 2759 emlxs_buf_t *sbp; 2760 uint32_t channelno; 2761 IOCBQ *iocbq; 2762 IOCBQ *prev; 2763 IOCBQ *next; 2764 IOCB *iocb; 2765 IOCB *icmd; 2766 Q abort; 2767 uint32_t i; 2768 MATCHMAP *mp; 2769 uint8_t flag[MAX_CHANNEL]; 2770 2771 if (lun == EMLXS_LUN_NONE) { 2772 return (0); 2773 } 2774 2775 bzero((void *)&abort, sizeof (Q)); 2776 2777 /* Flush I/O's on txQ to this target's lun */ 2778 mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 2779 2780 for (channelno = 0; channelno < hba->chan_count; channelno++) { 2781 2782 /* Scan the priority queue first */ 2783 prev = NULL; 2784 iocbq = (IOCBQ *) ndlp->nlp_ptx[channelno].q_first; 2785 2786 while (iocbq) { 2787 next = (IOCBQ *)iocbq->next; 2788 iocb = &iocbq->iocb; 2789 sbp = (emlxs_buf_t *)iocbq->sbp; 2790 2791 /* Check if this IO is for our lun */ 2792 if (sbp && (sbp->lun == lun)) { 2793 /* Remove iocb from the node's ptx queue */ 2794 if (next == 0) { 2795 ndlp->nlp_ptx[channelno].q_last = 2796 (uint8_t *)prev; 2797 } 2798 2799 if (prev == 0) { 2800 ndlp->nlp_ptx[channelno].q_first = 2801 (uint8_t *)next; 2802 } else { 2803 prev->next = next; 2804 } 2805 2806 iocbq->next = NULL; 2807 ndlp->nlp_ptx[channelno].q_cnt--; 2808 2809 /* 2810 * Add this iocb to our local abort Q 2811 */ 2812 if (abort.q_first) { 2813 ((IOCBQ *)abort.q_last)->next = iocbq; 2814 abort.q_last = (uint8_t *)iocbq; 2815 abort.q_cnt++; 2816 } else { 2817 abort.q_first = (uint8_t *)iocbq; 2818 abort.q_last = (uint8_t *)iocbq; 2819 abort.q_cnt = 1; 2820 } 2821 iocbq->next = NULL; 2822 flag[channelno] = 1; 2823 2824 } else { 2825 prev = iocbq; 2826 } 2827 2828 iocbq = next; 2829 2830 } /* while (iocbq) */ 2831 2832 2833 /* Scan the regular queue */ 2834 prev = NULL; 2835 iocbq = (IOCBQ *)ndlp->nlp_tx[channelno].q_first; 2836 2837 while (iocbq) { 2838 next = (IOCBQ *)iocbq->next; 2839 iocb = &iocbq->iocb; 2840 sbp = (emlxs_buf_t *)iocbq->sbp; 2841 2842 /* Check if this IO is for our lun */ 2843 if (sbp && (sbp->lun == lun)) { 2844 /* Remove iocb from the node's tx queue */ 2845 if (next == 0) { 2846 ndlp->nlp_tx[channelno].q_last = 2847 (uint8_t *)prev; 2848 } 2849 2850 if (prev == 0) { 2851 ndlp->nlp_tx[channelno].q_first = 2852 (uint8_t *)next; 2853 } else { 2854 prev->next = next; 2855 } 2856 2857 iocbq->next = NULL; 2858 ndlp->nlp_tx[channelno].q_cnt--; 2859 2860 /* 2861 * Add this iocb to our local abort Q 2862 */ 2863 if (abort.q_first) { 2864 ((IOCBQ *) abort.q_last)->next = iocbq; 2865 abort.q_last = (uint8_t *)iocbq; 2866 abort.q_cnt++; 2867 } else { 2868 abort.q_first = (uint8_t *)iocbq; 2869 abort.q_last = (uint8_t *)iocbq; 2870 abort.q_cnt = 1; 2871 } 2872 iocbq->next = NULL; 2873 } else { 2874 prev = iocbq; 2875 } 2876 2877 iocbq = next; 2878 2879 } /* while (iocbq) */ 2880 } /* for loop */ 2881 2882 /* First cleanup the iocb's while still holding the lock */ 2883 iocbq = (IOCBQ *)abort.q_first; 2884 while (iocbq) { 2885 /* Free the IoTag and the bmp */ 2886 iocb = &iocbq->iocb; 2887 2888 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 2889 sbp = iocbq->sbp; 2890 if (sbp) { 2891 emlxs_sli4_free_xri(port, sbp, sbp->xrip, 1); 2892 } 2893 } else { 2894 sbp = emlxs_unregister_pkt((CHANNEL *)iocbq->channel, 2895 iocb->ULPIOTAG, 0); 2896 } 2897 2898 if (sbp && (sbp != STALE_PACKET)) { 2899 mutex_enter(&sbp->mtx); 2900 sbp->pkt_flags |= PACKET_IN_FLUSH; 2901 /* 2902 * If the fpkt is already set, then we will leave it 2903 * alone. This ensures that this pkt is only accounted 2904 * for on one fpkt->flush_count 2905 */ 2906 if (!sbp->fpkt && fpkt) { 2907 mutex_enter(&fpkt->mtx); 2908 sbp->fpkt = fpkt; 2909 fpkt->flush_count++; 2910 mutex_exit(&fpkt->mtx); 2911 } 2912 2913 mutex_exit(&sbp->mtx); 2914 } 2915 2916 iocbq = (IOCBQ *) iocbq->next; 2917 2918 } /* end of while */ 2919 2920 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 2921 2922 /* Now abort the iocb's outside the locks */ 2923 iocbq = (IOCBQ *)abort.q_first; 2924 while (iocbq) { 2925 /* Save the next iocbq for now */ 2926 next = (IOCBQ *)iocbq->next; 2927 2928 /* Unlink this iocbq */ 2929 iocbq->next = NULL; 2930 2931 /* Get the pkt */ 2932 sbp = (emlxs_buf_t *)iocbq->sbp; 2933 2934 if (sbp) { 2935 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flush_msg, 2936 "tx: sbp=%p node=%p", sbp, sbp->node); 2937 2938 if (hba->state >= FC_LINK_UP) { 2939 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 2940 IOERR_ABORT_REQUESTED, 1); 2941 } else { 2942 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 2943 IOERR_LINK_DOWN, 1); 2944 } 2945 } 2946 2947 /* Free the iocb and its associated buffers */ 2948 else { 2949 /* Should never happen! */ 2950 icmd = &iocbq->iocb; 2951 2952 /* SLI3 */ 2953 if (icmd->ULPCOMMAND == CMD_QUE_RING_BUF64_CN || 2954 icmd->ULPCOMMAND == CMD_QUE_RING_BUF_CN || 2955 icmd->ULPCOMMAND == CMD_QUE_RING_LIST64_CN) { 2956 if ((hba->flag & 2957 (FC_ONLINE_MODE | FC_ONLINING_MODE)) == 0) { 2958 /* HBA is detaching or offlining */ 2959 if (icmd->ULPCOMMAND != 2960 CMD_QUE_RING_LIST64_CN) { 2961 void *tmp; 2962 RING *rp; 2963 int ch; 2964 2965 ch = ((CHANNEL *) 2966 iocbq->channel)->channelno; 2967 rp = &hba->sli.sli3.ring[ch]; 2968 for (i = 0; 2969 i < icmd->ULPBDECOUNT; 2970 i++) { 2971 mp = EMLXS_GET_VADDR( 2972 hba, rp, icmd); 2973 2974 tmp = (void *)mp; 2975 if (mp) { 2976 emlxs_mem_put( 2977 hba, MEM_BUF, tmp); 2978 } 2979 } 2980 } 2981 2982 emlxs_mem_put(hba, MEM_IOCB, 2983 (void *)iocbq); 2984 } else { 2985 /* repost the unsolicited buffer */ 2986 EMLXS_SLI_ISSUE_IOCB_CMD(hba, 2987 (CHANNEL *)iocbq->channel, iocbq); 2988 } 2989 } else if (icmd->ULPCOMMAND == CMD_CLOSE_XRI_CN || 2990 icmd->ULPCOMMAND == CMD_CLOSE_XRI_CX) { 2991 /* 2992 * Resend the abort iocbq if any 2993 */ 2994 emlxs_tx_put(iocbq, 1); 2995 } 2996 } 2997 2998 iocbq = next; 2999 3000 } /* end of while */ 3001 3002 /* Now trigger channel service */ 3003 for (channelno = 0; channelno < hba->chan_count; channelno++) { 3004 if (!flag[channelno]) { 3005 continue; 3006 } 3007 3008 EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0); 3009 } 3010 3011 return (abort.q_cnt); 3012 3013 } /* emlxs_tx_lun_flush() */ 3014 3015 3016 extern void 3017 emlxs_tx_put(IOCBQ *iocbq, uint32_t lock) 3018 { 3019 emlxs_hba_t *hba; 3020 emlxs_port_t *port; 3021 uint32_t channelno; 3022 NODELIST *nlp; 3023 CHANNEL *cp; 3024 emlxs_buf_t *sbp; 3025 3026 port = (emlxs_port_t *)iocbq->port; 3027 hba = HBA; 3028 cp = (CHANNEL *)iocbq->channel; 3029 nlp = (NODELIST *)iocbq->node; 3030 channelno = cp->channelno; 3031 sbp = (emlxs_buf_t *)iocbq->sbp; 3032 3033 if (nlp == NULL) { 3034 /* Set node to base node by default */ 3035 nlp = &port->node_base; 3036 3037 iocbq->node = (void *)nlp; 3038 3039 if (sbp) { 3040 sbp->node = (void *)nlp; 3041 } 3042 } 3043 3044 if (lock) { 3045 mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 3046 } 3047 3048 if (!nlp->nlp_active || (sbp && (sbp->pkt_flags & PACKET_IN_ABORT))) { 3049 if (sbp) { 3050 mutex_enter(&sbp->mtx); 3051 sbp->pkt_flags |= PACKET_IN_FLUSH; 3052 mutex_exit(&sbp->mtx); 3053 3054 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3055 emlxs_sli4_free_xri(port, sbp, sbp->xrip, 1); 3056 } else { 3057 (void) emlxs_unregister_pkt(cp, sbp->iotag, 0); 3058 } 3059 3060 if (lock) { 3061 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 3062 } 3063 3064 if (hba->state >= FC_LINK_UP) { 3065 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 3066 IOERR_ABORT_REQUESTED, 1); 3067 } else { 3068 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 3069 IOERR_LINK_DOWN, 1); 3070 } 3071 return; 3072 } else { 3073 if (lock) { 3074 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 3075 } 3076 3077 emlxs_mem_put(hba, MEM_IOCB, (void *)iocbq); 3078 } 3079 3080 return; 3081 } 3082 3083 if (sbp) { 3084 3085 mutex_enter(&sbp->mtx); 3086 3087 if (sbp->pkt_flags & 3088 (PACKET_IN_COMPLETION | PACKET_IN_CHIPQ | PACKET_IN_TXQ)) { 3089 mutex_exit(&sbp->mtx); 3090 if (lock) { 3091 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 3092 } 3093 return; 3094 } 3095 3096 sbp->pkt_flags |= PACKET_IN_TXQ; 3097 hba->channel_tx_count++; 3098 3099 mutex_exit(&sbp->mtx); 3100 } 3101 3102 3103 /* Check iocbq priority */ 3104 /* Some IOCB has the high priority like reset/close xri etc */ 3105 if (iocbq->flag & IOCB_PRIORITY) { 3106 /* Add the iocb to the bottom of the node's ptx queue */ 3107 if (nlp->nlp_ptx[channelno].q_first) { 3108 ((IOCBQ *)nlp->nlp_ptx[channelno].q_last)->next = iocbq; 3109 nlp->nlp_ptx[channelno].q_last = (uint8_t *)iocbq; 3110 nlp->nlp_ptx[channelno].q_cnt++; 3111 } else { 3112 nlp->nlp_ptx[channelno].q_first = (uint8_t *)iocbq; 3113 nlp->nlp_ptx[channelno].q_last = (uint8_t *)iocbq; 3114 nlp->nlp_ptx[channelno].q_cnt = 1; 3115 } 3116 3117 iocbq->next = NULL; 3118 } else { /* Normal priority */ 3119 3120 3121 /* Add the iocb to the bottom of the node's tx queue */ 3122 if (nlp->nlp_tx[channelno].q_first) { 3123 ((IOCBQ *)nlp->nlp_tx[channelno].q_last)->next = iocbq; 3124 nlp->nlp_tx[channelno].q_last = (uint8_t *)iocbq; 3125 nlp->nlp_tx[channelno].q_cnt++; 3126 } else { 3127 nlp->nlp_tx[channelno].q_first = (uint8_t *)iocbq; 3128 nlp->nlp_tx[channelno].q_last = (uint8_t *)iocbq; 3129 nlp->nlp_tx[channelno].q_cnt = 1; 3130 } 3131 3132 iocbq->next = NULL; 3133 } 3134 3135 3136 /* 3137 * Check if the node is not already on channel queue and 3138 * (is not closed or is a priority request) 3139 */ 3140 if (!nlp->nlp_next[channelno] && 3141 (!(nlp->nlp_flag[channelno] & NLP_CLOSED) || 3142 (iocbq->flag & IOCB_PRIORITY))) { 3143 /* If so, then add it to the channel queue */ 3144 if (cp->nodeq.q_first) { 3145 ((NODELIST *)cp->nodeq.q_last)->nlp_next[channelno] = 3146 (uint8_t *)nlp; 3147 nlp->nlp_next[channelno] = cp->nodeq.q_first; 3148 3149 /* 3150 * If this is not the base node then add it 3151 * to the tail 3152 */ 3153 if (!nlp->nlp_base) { 3154 cp->nodeq.q_last = (uint8_t *)nlp; 3155 } else { /* Otherwise, add it to the head */ 3156 3157 /* The command node always gets priority */ 3158 cp->nodeq.q_first = (uint8_t *)nlp; 3159 } 3160 3161 cp->nodeq.q_cnt++; 3162 } else { 3163 cp->nodeq.q_first = (uint8_t *)nlp; 3164 cp->nodeq.q_last = (uint8_t *)nlp; 3165 nlp->nlp_next[channelno] = nlp; 3166 cp->nodeq.q_cnt = 1; 3167 } 3168 } 3169 3170 HBASTATS.IocbTxPut[channelno]++; 3171 3172 /* Adjust the channel timeout timer */ 3173 cp->timeout = hba->timer_tics + 5; 3174 3175 if (lock) { 3176 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 3177 } 3178 3179 return; 3180 3181 } /* emlxs_tx_put() */ 3182 3183 3184 extern IOCBQ * 3185 emlxs_tx_get(CHANNEL *cp, uint32_t lock) 3186 { 3187 emlxs_hba_t *hba; 3188 uint32_t channelno; 3189 IOCBQ *iocbq; 3190 NODELIST *nlp; 3191 emlxs_buf_t *sbp; 3192 3193 hba = cp->hba; 3194 channelno = cp->channelno; 3195 3196 if (lock) { 3197 mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 3198 } 3199 3200 begin: 3201 3202 iocbq = NULL; 3203 3204 /* Check if a node needs servicing */ 3205 if (cp->nodeq.q_first) { 3206 nlp = (NODELIST *)cp->nodeq.q_first; 3207 3208 /* Get next iocb from node's priority queue */ 3209 3210 if (nlp->nlp_ptx[channelno].q_first) { 3211 iocbq = (IOCBQ *)nlp->nlp_ptx[channelno].q_first; 3212 3213 /* Check if this is last entry */ 3214 if (nlp->nlp_ptx[channelno].q_last == (void *)iocbq) { 3215 nlp->nlp_ptx[channelno].q_first = NULL; 3216 nlp->nlp_ptx[channelno].q_last = NULL; 3217 nlp->nlp_ptx[channelno].q_cnt = 0; 3218 } else { 3219 /* Remove iocb from head */ 3220 nlp->nlp_ptx[channelno].q_first = 3221 (void *)iocbq->next; 3222 nlp->nlp_ptx[channelno].q_cnt--; 3223 } 3224 3225 iocbq->next = NULL; 3226 } 3227 3228 /* Get next iocb from node tx queue if node not closed */ 3229 else if (nlp->nlp_tx[channelno].q_first && 3230 !(nlp->nlp_flag[channelno] & NLP_CLOSED)) { 3231 iocbq = (IOCBQ *)nlp->nlp_tx[channelno].q_first; 3232 3233 /* Check if this is last entry */ 3234 if (nlp->nlp_tx[channelno].q_last == (void *)iocbq) { 3235 nlp->nlp_tx[channelno].q_first = NULL; 3236 nlp->nlp_tx[channelno].q_last = NULL; 3237 nlp->nlp_tx[channelno].q_cnt = 0; 3238 } else { 3239 /* Remove iocb from head */ 3240 nlp->nlp_tx[channelno].q_first = 3241 (void *)iocbq->next; 3242 nlp->nlp_tx[channelno].q_cnt--; 3243 } 3244 3245 iocbq->next = NULL; 3246 } 3247 3248 /* Now deal with node itself */ 3249 3250 /* Check if node still needs servicing */ 3251 if ((nlp->nlp_ptx[channelno].q_first) || 3252 (nlp->nlp_tx[channelno].q_first && 3253 !(nlp->nlp_flag[channelno] & NLP_CLOSED))) { 3254 3255 /* 3256 * If this is the base node, then don't shift the 3257 * pointers. We want to drain the base node before 3258 * moving on 3259 */ 3260 if (!nlp->nlp_base) { 3261 /* 3262 * Just shift channel queue pointers to next 3263 * node 3264 */ 3265 cp->nodeq.q_last = (void *)nlp; 3266 cp->nodeq.q_first = nlp->nlp_next[channelno]; 3267 } 3268 } else { 3269 /* Remove node from channel queue */ 3270 3271 /* If this is the last node on list */ 3272 if (cp->nodeq.q_last == (void *)nlp) { 3273 cp->nodeq.q_last = NULL; 3274 cp->nodeq.q_first = NULL; 3275 cp->nodeq.q_cnt = 0; 3276 } else { 3277 /* Remove node from head */ 3278 cp->nodeq.q_first = nlp->nlp_next[channelno]; 3279 ((NODELIST *)cp->nodeq.q_last)-> 3280 nlp_next[channelno] = cp->nodeq.q_first; 3281 cp->nodeq.q_cnt--; 3282 3283 } 3284 3285 /* Clear node */ 3286 nlp->nlp_next[channelno] = NULL; 3287 } 3288 3289 /* 3290 * If no iocbq was found on this node, then it will have 3291 * been removed. So try again. 3292 */ 3293 if (!iocbq) { 3294 goto begin; 3295 } 3296 3297 sbp = (emlxs_buf_t *)iocbq->sbp; 3298 3299 if (sbp) { 3300 /* 3301 * Check flags before we enter mutex in case this 3302 * has been flushed and destroyed 3303 */ 3304 if ((sbp->pkt_flags & 3305 (PACKET_IN_COMPLETION | PACKET_IN_CHIPQ)) || 3306 !(sbp->pkt_flags & PACKET_IN_TXQ)) { 3307 goto begin; 3308 } 3309 3310 mutex_enter(&sbp->mtx); 3311 3312 if ((sbp->pkt_flags & 3313 (PACKET_IN_COMPLETION | PACKET_IN_CHIPQ)) || 3314 !(sbp->pkt_flags & PACKET_IN_TXQ)) { 3315 mutex_exit(&sbp->mtx); 3316 goto begin; 3317 } 3318 3319 sbp->pkt_flags &= ~PACKET_IN_TXQ; 3320 hba->channel_tx_count--; 3321 3322 mutex_exit(&sbp->mtx); 3323 } 3324 } 3325 3326 if (iocbq) { 3327 HBASTATS.IocbTxGet[channelno]++; 3328 } 3329 3330 /* Adjust the ring timeout timer */ 3331 cp->timeout = (cp->nodeq.q_first) ? (hba->timer_tics + 5) : 0; 3332 3333 if (lock) { 3334 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 3335 } 3336 3337 return (iocbq); 3338 3339 } /* emlxs_tx_get() */ 3340 3341 3342 /* 3343 * Remove all cmd from from_rp's txq to to_rp's txq for ndlp. 3344 * The old IoTag has to be released, the new one has to be 3345 * allocated. Others no change 3346 * TX_CHANNEL lock is held 3347 */ 3348 extern void 3349 emlxs_tx_move(NODELIST *ndlp, CHANNEL *from_chan, CHANNEL *to_chan, 3350 uint32_t cmd, emlxs_buf_t *fpkt, uint32_t lock) 3351 { 3352 emlxs_hba_t *hba; 3353 emlxs_port_t *port; 3354 uint32_t fchanno, tchanno, i; 3355 3356 IOCBQ *iocbq; 3357 IOCBQ *prev; 3358 IOCBQ *next; 3359 IOCB *iocb, *icmd; 3360 Q tbm; /* To Be Moved Q */ 3361 MATCHMAP *mp; 3362 3363 NODELIST *nlp = ndlp; 3364 emlxs_buf_t *sbp; 3365 3366 NODELIST *n_prev = NULL; 3367 NODELIST *n_next = NULL; 3368 uint16_t count = 0; 3369 3370 hba = from_chan->hba; 3371 port = &PPORT; 3372 cmd = cmd; /* To pass lint */ 3373 3374 fchanno = from_chan->channelno; 3375 tchanno = to_chan->channelno; 3376 3377 if (lock) { 3378 mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 3379 } 3380 3381 bzero((void *)&tbm, sizeof (Q)); 3382 3383 /* Scan the ndlp's fchanno txq to get the iocb of fcp cmd */ 3384 prev = NULL; 3385 iocbq = (IOCBQ *)nlp->nlp_tx[fchanno].q_first; 3386 3387 while (iocbq) { 3388 next = (IOCBQ *)iocbq->next; 3389 /* Check if this iocb is fcp cmd */ 3390 iocb = &iocbq->iocb; 3391 3392 switch (iocb->ULPCOMMAND) { 3393 /* FCP commands */ 3394 case CMD_FCP_ICMND_CR: 3395 case CMD_FCP_ICMND_CX: 3396 case CMD_FCP_IREAD_CR: 3397 case CMD_FCP_IREAD_CX: 3398 case CMD_FCP_IWRITE_CR: 3399 case CMD_FCP_IWRITE_CX: 3400 case CMD_FCP_ICMND64_CR: 3401 case CMD_FCP_ICMND64_CX: 3402 case CMD_FCP_IREAD64_CR: 3403 case CMD_FCP_IREAD64_CX: 3404 case CMD_FCP_IWRITE64_CR: 3405 case CMD_FCP_IWRITE64_CX: 3406 /* We found a fcp cmd */ 3407 break; 3408 default: 3409 /* this is not fcp cmd continue */ 3410 prev = iocbq; 3411 iocbq = next; 3412 continue; 3413 } 3414 3415 /* found a fcp cmd iocb in fchanno txq, now deque it */ 3416 if (next == NULL) { 3417 /* This is the last iocbq */ 3418 nlp->nlp_tx[fchanno].q_last = 3419 (uint8_t *)prev; 3420 } 3421 3422 if (prev == NULL) { 3423 /* This is the first one then remove it from head */ 3424 nlp->nlp_tx[fchanno].q_first = 3425 (uint8_t *)next; 3426 } else { 3427 prev->next = next; 3428 } 3429 3430 iocbq->next = NULL; 3431 nlp->nlp_tx[fchanno].q_cnt--; 3432 3433 /* Add this iocb to our local toberemovedq */ 3434 /* This way we donot hold the TX_CHANNEL lock too long */ 3435 3436 if (tbm.q_first) { 3437 ((IOCBQ *)tbm.q_last)->next = iocbq; 3438 tbm.q_last = (uint8_t *)iocbq; 3439 tbm.q_cnt++; 3440 } else { 3441 tbm.q_first = (uint8_t *)iocbq; 3442 tbm.q_last = (uint8_t *)iocbq; 3443 tbm.q_cnt = 1; 3444 } 3445 3446 iocbq = next; 3447 3448 } /* While (iocbq) */ 3449 3450 if ((tchanno == hba->channel_fcp) && (tbm.q_cnt != 0)) { 3451 3452 /* from_chan->nodeq.q_first must be non NULL */ 3453 if (from_chan->nodeq.q_first) { 3454 3455 /* nodeq is not empty, now deal with the node itself */ 3456 if ((nlp->nlp_tx[fchanno].q_first)) { 3457 3458 if (!nlp->nlp_base) { 3459 from_chan->nodeq.q_last = 3460 (void *)nlp; 3461 from_chan->nodeq.q_first = 3462 nlp->nlp_next[fchanno]; 3463 } 3464 3465 } else { 3466 n_prev = (NODELIST *)from_chan->nodeq.q_first; 3467 count = from_chan->nodeq.q_cnt; 3468 3469 if (n_prev == nlp) { 3470 3471 /* If this is the only node on list */ 3472 if (from_chan->nodeq.q_last == 3473 (void *)nlp) { 3474 from_chan->nodeq.q_last = 3475 NULL; 3476 from_chan->nodeq.q_first = 3477 NULL; 3478 from_chan->nodeq.q_cnt = 0; 3479 } else { 3480 from_chan->nodeq.q_first = 3481 nlp->nlp_next[fchanno]; 3482 ((NODELIST *)from_chan-> 3483 nodeq.q_last)-> 3484 nlp_next[fchanno] = 3485 from_chan->nodeq.q_first; 3486 from_chan->nodeq.q_cnt--; 3487 } 3488 /* Clear node */ 3489 nlp->nlp_next[fchanno] = NULL; 3490 } else { 3491 count--; 3492 do { 3493 n_next = 3494 n_prev->nlp_next[fchanno]; 3495 if (n_next == nlp) { 3496 break; 3497 } 3498 n_prev = n_next; 3499 } while (count--); 3500 3501 if (count != 0) { 3502 3503 if (n_next == 3504 (NODELIST *)from_chan-> 3505 nodeq.q_last) { 3506 n_prev-> 3507 nlp_next[fchanno] 3508 = 3509 ((NODELIST *) 3510 from_chan-> 3511 nodeq.q_last)-> 3512 nlp_next 3513 [fchanno]; 3514 from_chan->nodeq.q_last 3515 = (uint8_t *)n_prev; 3516 } else { 3517 3518 n_prev-> 3519 nlp_next[fchanno] 3520 = 3521 n_next-> nlp_next 3522 [fchanno]; 3523 } 3524 from_chan->nodeq.q_cnt--; 3525 /* Clear node */ 3526 nlp->nlp_next[fchanno] = 3527 NULL; 3528 } 3529 } 3530 } 3531 } 3532 } 3533 3534 /* Now cleanup the iocb's */ 3535 prev = NULL; 3536 iocbq = (IOCBQ *)tbm.q_first; 3537 3538 while (iocbq) { 3539 3540 next = (IOCBQ *)iocbq->next; 3541 3542 /* Free the IoTag and the bmp */ 3543 iocb = &iocbq->iocb; 3544 3545 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3546 sbp = iocbq->sbp; 3547 if (sbp) { 3548 emlxs_sli4_free_xri(port, sbp, sbp->xrip, 1); 3549 } 3550 } else { 3551 sbp = emlxs_unregister_pkt((CHANNEL *)iocbq->channel, 3552 iocb->ULPIOTAG, 0); 3553 } 3554 3555 if (sbp && (sbp != STALE_PACKET)) { 3556 mutex_enter(&sbp->mtx); 3557 sbp->pkt_flags |= PACKET_IN_FLUSH; 3558 3559 /* 3560 * If the fpkt is already set, then we will leave it 3561 * alone. This ensures that this pkt is only accounted 3562 * for on one fpkt->flush_count 3563 */ 3564 if (!sbp->fpkt && fpkt) { 3565 mutex_enter(&fpkt->mtx); 3566 sbp->fpkt = fpkt; 3567 fpkt->flush_count++; 3568 mutex_exit(&fpkt->mtx); 3569 } 3570 mutex_exit(&sbp->mtx); 3571 } 3572 iocbq = next; 3573 3574 } /* end of while */ 3575 3576 iocbq = (IOCBQ *)tbm.q_first; 3577 while (iocbq) { 3578 /* Save the next iocbq for now */ 3579 next = (IOCBQ *)iocbq->next; 3580 3581 /* Unlink this iocbq */ 3582 iocbq->next = NULL; 3583 3584 /* Get the pkt */ 3585 sbp = (emlxs_buf_t *)iocbq->sbp; 3586 3587 if (sbp) { 3588 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_flush_msg, 3589 "tx: sbp=%p node=%p", sbp, sbp->node); 3590 3591 if (hba->state >= FC_LINK_UP) { 3592 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 3593 IOERR_ABORT_REQUESTED, 1); 3594 } else { 3595 emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 3596 IOERR_LINK_DOWN, 1); 3597 } 3598 3599 } 3600 /* Free the iocb and its associated buffers */ 3601 else { 3602 icmd = &iocbq->iocb; 3603 3604 /* SLI3 */ 3605 if (icmd->ULPCOMMAND == CMD_QUE_RING_BUF64_CN || 3606 icmd->ULPCOMMAND == CMD_QUE_RING_BUF_CN || 3607 icmd->ULPCOMMAND == CMD_QUE_RING_LIST64_CN) { 3608 if ((hba->flag & 3609 (FC_ONLINE_MODE | FC_ONLINING_MODE)) == 0) { 3610 /* HBA is detaching or offlining */ 3611 if (icmd->ULPCOMMAND != 3612 CMD_QUE_RING_LIST64_CN) { 3613 void *tmp; 3614 RING *rp; 3615 int ch; 3616 3617 ch = from_chan->channelno; 3618 rp = &hba->sli.sli3.ring[ch]; 3619 3620 for (i = 0; 3621 i < icmd->ULPBDECOUNT; 3622 i++) { 3623 mp = EMLXS_GET_VADDR( 3624 hba, rp, icmd); 3625 3626 tmp = (void *)mp; 3627 if (mp) { 3628 emlxs_mem_put( 3629 hba, 3630 MEM_BUF, 3631 tmp); 3632 } 3633 } 3634 3635 } 3636 3637 emlxs_mem_put(hba, MEM_IOCB, 3638 (void *)iocbq); 3639 } else { 3640 /* repost the unsolicited buffer */ 3641 EMLXS_SLI_ISSUE_IOCB_CMD(hba, 3642 from_chan, iocbq); 3643 } 3644 } 3645 } 3646 3647 iocbq = next; 3648 3649 } /* end of while */ 3650 3651 /* Now flush the chipq if any */ 3652 if (!(nlp->nlp_flag[fchanno] & NLP_CLOSED)) { 3653 3654 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 3655 3656 (void) emlxs_chipq_node_flush(port, from_chan, nlp, 0); 3657 3658 mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 3659 } 3660 3661 if (lock) { 3662 mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 3663 } 3664 3665 return; 3666 3667 } /* emlxs_tx_move */ 3668 3669 3670 extern uint32_t 3671 emlxs_chipq_node_flush(emlxs_port_t *port, CHANNEL *chan, NODELIST *ndlp, 3672 emlxs_buf_t *fpkt) 3673 { 3674 emlxs_hba_t *hba = HBA; 3675 emlxs_buf_t *sbp; 3676 IOCBQ *iocbq; 3677 IOCBQ *next; 3678 Q abort; 3679 CHANNEL *cp; 3680 uint32_t channelno; 3681 uint8_t flag[MAX_CHANNEL]; 3682 uint32_t iotag; 3683 3684 bzero((void *)&abort, sizeof (Q)); 3685 bzero((void *)flag, sizeof (flag)); 3686 3687 for (channelno = 0; channelno < hba->chan_count; channelno++) { 3688 cp = &hba->chan[channelno]; 3689 3690 if (chan && cp != chan) { 3691 continue; 3692 } 3693 3694 mutex_enter(&EMLXS_FCTAB_LOCK); 3695 3696 for (iotag = 1; iotag < hba->max_iotag; iotag++) { 3697 sbp = hba->fc_table[iotag]; 3698 3699 if (sbp && (sbp != STALE_PACKET) && 3700 (sbp->pkt_flags & PACKET_IN_CHIPQ) && 3701 (sbp->node == ndlp) && 3702 (sbp->channel == cp) && 3703 !(sbp->pkt_flags & PACKET_XRI_CLOSED)) { 3704 emlxs_sbp_abort_add(port, sbp, &abort, flag, 3705 fpkt); 3706 } 3707 3708 } 3709 mutex_exit(&EMLXS_FCTAB_LOCK); 3710 3711 } /* for */ 3712 3713 /* Now put the iocb's on the tx queue */ 3714 iocbq = (IOCBQ *)abort.q_first; 3715 while (iocbq) { 3716 /* Save the next iocbq for now */ 3717 next = (IOCBQ *)iocbq->next; 3718 3719 /* Unlink this iocbq */ 3720 iocbq->next = NULL; 3721 3722 /* Send this iocbq */ 3723 emlxs_tx_put(iocbq, 1); 3724 3725 iocbq = next; 3726 } 3727 3728 /* Now trigger channel service */ 3729 for (channelno = 0; channelno < hba->chan_count; channelno++) { 3730 if (!flag[channelno]) { 3731 continue; 3732 } 3733 3734 EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0); 3735 } 3736 3737 return (abort.q_cnt); 3738 3739 } /* emlxs_chipq_node_flush() */ 3740 3741 3742 /* Flush all IO's left on all iotag lists */ 3743 extern uint32_t 3744 emlxs_iotag_flush(emlxs_hba_t *hba) 3745 { 3746 emlxs_port_t *port = &PPORT; 3747 emlxs_buf_t *sbp; 3748 IOCBQ *iocbq; 3749 IOCB *iocb; 3750 Q abort; 3751 CHANNEL *cp; 3752 uint32_t channelno; 3753 uint32_t iotag; 3754 uint32_t count; 3755 3756 count = 0; 3757 for (channelno = 0; channelno < hba->chan_count; channelno++) { 3758 cp = &hba->chan[channelno]; 3759 3760 bzero((void *)&abort, sizeof (Q)); 3761 3762 mutex_enter(&EMLXS_FCTAB_LOCK); 3763 3764 for (iotag = 1; iotag < hba->max_iotag; iotag++) { 3765 sbp = hba->fc_table[iotag]; 3766 3767 /* Check if the slot is empty */ 3768 if (!sbp || (sbp == STALE_PACKET)) { 3769 continue; 3770 } 3771 3772 /* We are building an abort list per channel */ 3773 if (sbp->channel != cp) { 3774 continue; 3775 } 3776 3777 hba->fc_table[iotag] = STALE_PACKET; 3778 hba->io_count--; 3779 3780 /* Check if IO is valid */ 3781 if (!(sbp->pkt_flags & PACKET_VALID) || 3782 (sbp->pkt_flags & (PACKET_ULP_OWNED| 3783 PACKET_COMPLETED|PACKET_IN_COMPLETION))) { 3784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 3785 "iotag_flush: Invalid IO found. iotag=%d", 3786 iotag); 3787 3788 continue; 3789 } 3790 3791 sbp->iotag = 0; 3792 3793 /* Set IOCB status */ 3794 iocbq = &sbp->iocbq; 3795 iocb = &iocbq->iocb; 3796 3797 iocb->ULPSTATUS = IOSTAT_LOCAL_REJECT; 3798 iocb->un.grsp.perr.statLocalError = IOERR_LINK_DOWN; 3799 iocb->ULPLE = 1; 3800 iocbq->next = NULL; 3801 3802 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 3803 if (sbp->xrip) { 3804 EMLXS_MSGF(EMLXS_CONTEXT, 3805 &emlxs_sli_debug_msg, 3806 "iotag_flush: iotag=%d sbp=%p " 3807 "xrip=%p state=%x flag=%x", 3808 iotag, sbp, sbp->xrip, 3809 sbp->xrip->state, sbp->xrip->flag); 3810 } else { 3811 EMLXS_MSGF(EMLXS_CONTEXT, 3812 &emlxs_sli_debug_msg, 3813 "iotag_flush: iotag=%d sbp=%p " 3814 "xrip=NULL", iotag, sbp); 3815 } 3816 3817 emlxs_sli4_free_xri(port, sbp, sbp->xrip, 0); 3818 } else { 3819 /* Clean up the sbp */ 3820 mutex_enter(&sbp->mtx); 3821 3822 if (sbp->pkt_flags & PACKET_IN_TXQ) { 3823 sbp->pkt_flags &= ~PACKET_IN_TXQ; 3824 hba->channel_tx_count --; 3825 } 3826 3827 if (sbp->pkt_flags & PACKET_IN_CHIPQ) { 3828 sbp->pkt_flags &= ~PACKET_IN_CHIPQ; 3829 } 3830 3831 if (sbp->bmp) { 3832 emlxs_mem_put(hba, MEM_BPL, 3833 (void *)sbp->bmp); 3834 sbp->bmp = 0; 3835 } 3836 3837 mutex_exit(&sbp->mtx); 3838 } 3839 3840 /* At this point all nodes are assumed destroyed */ 3841 mutex_enter(&sbp->mtx); 3842 sbp->node = 0; 3843 mutex_exit(&sbp->mtx); 3844 3845 /* Add this iocb to our local abort Q */ 3846 if (abort.q_first) { 3847 ((IOCBQ *)abort.q_last)->next = iocbq; 3848 abort.q_last = (uint8_t *)iocbq; 3849 abort.q_cnt++; 3850 } else { 3851 abort.q_first = (uint8_t *)iocbq; 3852 abort.q_last = (uint8_t *)iocbq; 3853 abort.q_cnt = 1; 3854 } 3855 } 3856 3857 mutex_exit(&EMLXS_FCTAB_LOCK); 3858 3859 /* Trigger deferred completion */ 3860 if (abort.q_first) { 3861 mutex_enter(&cp->rsp_lock); 3862 if (cp->rsp_head == NULL) { 3863 cp->rsp_head = (IOCBQ *)abort.q_first; 3864 cp->rsp_tail = (IOCBQ *)abort.q_last; 3865 } else { 3866 cp->rsp_tail->next = (IOCBQ *)abort.q_first; 3867 cp->rsp_tail = (IOCBQ *)abort.q_last; 3868 } 3869 mutex_exit(&cp->rsp_lock); 3870 3871 emlxs_thread_trigger2(&cp->intr_thread, 3872 emlxs_proc_channel, cp); 3873 3874 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 3875 "iotag_flush: channel=%d count=%d", 3876 channelno, abort.q_cnt); 3877 3878 count += abort.q_cnt; 3879 } 3880 } 3881 3882 return (count); 3883 3884 } /* emlxs_iotag_flush() */ 3885 3886 3887 3888 /* Checks for IO's on all or a given channel for a given node */ 3889 extern uint32_t 3890 emlxs_chipq_node_check(emlxs_port_t *port, CHANNEL *chan, NODELIST *ndlp) 3891 { 3892 emlxs_hba_t *hba = HBA; 3893 emlxs_buf_t *sbp; 3894 CHANNEL *cp; 3895 uint32_t channelno; 3896 uint32_t count; 3897 uint32_t iotag; 3898 3899 count = 0; 3900 3901 for (channelno = 0; channelno < hba->chan_count; channelno++) { 3902 cp = &hba->chan[channelno]; 3903 3904 if (chan && cp != chan) { 3905 continue; 3906 } 3907 3908 mutex_enter(&EMLXS_FCTAB_LOCK); 3909 3910 for (iotag = 1; iotag < hba->max_iotag; iotag++) { 3911 sbp = hba->fc_table[iotag]; 3912 3913 if (sbp && (sbp != STALE_PACKET) && 3914 (sbp->pkt_flags & PACKET_IN_CHIPQ) && 3915 (sbp->node == ndlp) && 3916 (sbp->channel == cp) && 3917 !(sbp->pkt_flags & PACKET_XRI_CLOSED)) { 3918 count++; 3919 } 3920 3921 } 3922 mutex_exit(&EMLXS_FCTAB_LOCK); 3923 3924 } /* for */ 3925 3926 return (count); 3927 3928 } /* emlxs_chipq_node_check() */ 3929 3930 3931 3932 /* Flush all IO's for a given node's lun (on any channel) */ 3933 extern uint32_t 3934 emlxs_chipq_lun_flush(emlxs_port_t *port, NODELIST *ndlp, 3935 uint32_t lun, emlxs_buf_t *fpkt) 3936 { 3937 emlxs_hba_t *hba = HBA; 3938 emlxs_buf_t *sbp; 3939 IOCBQ *iocbq; 3940 IOCBQ *next; 3941 Q abort; 3942 uint32_t iotag; 3943 uint8_t flag[MAX_CHANNEL]; 3944 uint32_t channelno; 3945 3946 if (lun == EMLXS_LUN_NONE) { 3947 return (0); 3948 } 3949 3950 bzero((void *)flag, sizeof (flag)); 3951 bzero((void *)&abort, sizeof (Q)); 3952 3953 mutex_enter(&EMLXS_FCTAB_LOCK); 3954 for (iotag = 1; iotag < hba->max_iotag; iotag++) { 3955 sbp = hba->fc_table[iotag]; 3956 3957 if (sbp && (sbp != STALE_PACKET) && 3958 sbp->pkt_flags & PACKET_IN_CHIPQ && 3959 sbp->node == ndlp && 3960 sbp->lun == lun && 3961 !(sbp->pkt_flags & PACKET_XRI_CLOSED)) { 3962 emlxs_sbp_abort_add(port, sbp, 3963 &abort, flag, fpkt); 3964 } 3965 } 3966 mutex_exit(&EMLXS_FCTAB_LOCK); 3967 3968 /* Now put the iocb's on the tx queue */ 3969 iocbq = (IOCBQ *)abort.q_first; 3970 while (iocbq) { 3971 /* Save the next iocbq for now */ 3972 next = (IOCBQ *)iocbq->next; 3973 3974 /* Unlink this iocbq */ 3975 iocbq->next = NULL; 3976 3977 /* Send this iocbq */ 3978 emlxs_tx_put(iocbq, 1); 3979 3980 iocbq = next; 3981 } 3982 3983 /* Now trigger channel service */ 3984 for (channelno = 0; channelno < hba->chan_count; channelno++) { 3985 if (!flag[channelno]) { 3986 continue; 3987 } 3988 3989 EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[channelno], 0); 3990 } 3991 3992 return (abort.q_cnt); 3993 3994 } /* emlxs_chipq_lun_flush() */ 3995 3996 3997 3998 /* 3999 * Issue an ABORT_XRI_CN iocb command to abort an FCP command already issued. 4000 * This must be called while holding the EMLXS_FCTAB_LOCK 4001 */ 4002 extern IOCBQ * 4003 emlxs_create_abort_xri_cn(emlxs_port_t *port, NODELIST *ndlp, 4004 uint16_t iotag, CHANNEL *cp, uint8_t class, int32_t flag) 4005 { 4006 emlxs_hba_t *hba = HBA; 4007 IOCBQ *iocbq; 4008 IOCB *iocb; 4009 emlxs_wqe_t *wqe; 4010 emlxs_buf_t *sbp; 4011 uint16_t abort_iotag; 4012 4013 if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB)) == NULL) { 4014 return (NULL); 4015 } 4016 4017 iocbq->channel = (void *)cp; 4018 iocbq->port = (void *)port; 4019 iocbq->node = (void *)ndlp; 4020 iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL); 4021 4022 /* 4023 * set up an iotag using special Abort iotags 4024 */ 4025 if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) { 4026 hba->fc_oor_iotag = hba->max_iotag; 4027 } 4028 abort_iotag = hba->fc_oor_iotag++; 4029 4030 4031 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4032 wqe = &iocbq->wqe; 4033 sbp = hba->fc_table[iotag]; 4034 4035 /* Try to issue abort by XRI if possible */ 4036 if (sbp == NULL || sbp == STALE_PACKET || sbp->xrip == NULL) { 4037 wqe->un.Abort.Criteria = ABORT_REQ_TAG; 4038 wqe->AbortTag = iotag; 4039 } else { 4040 wqe->un.Abort.Criteria = ABORT_XRI_TAG; 4041 wqe->AbortTag = sbp->xrip->XRI; 4042 } 4043 wqe->un.Abort.IA = 0; 4044 wqe->RequestTag = abort_iotag; 4045 wqe->Command = CMD_ABORT_XRI_CX; 4046 wqe->Class = CLASS3; 4047 wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 4048 wqe->CmdType = WQE_TYPE_ABORT; 4049 } else { 4050 iocb = &iocbq->iocb; 4051 iocb->ULPIOTAG = abort_iotag; 4052 iocb->un.acxri.abortType = flag; 4053 iocb->un.acxri.abortContextTag = ndlp->nlp_Rpi; 4054 iocb->un.acxri.abortIoTag = iotag; 4055 iocb->ULPLE = 1; 4056 iocb->ULPCLASS = class; 4057 iocb->ULPCOMMAND = CMD_ABORT_XRI_CN; 4058 iocb->ULPOWNER = OWN_CHIP; 4059 } 4060 4061 return (iocbq); 4062 4063 } /* emlxs_create_abort_xri_cn() */ 4064 4065 4066 /* This must be called while holding the EMLXS_FCTAB_LOCK */ 4067 extern IOCBQ * 4068 emlxs_create_abort_xri_cx(emlxs_port_t *port, NODELIST *ndlp, uint16_t xid, 4069 CHANNEL *cp, uint8_t class, int32_t flag) 4070 { 4071 emlxs_hba_t *hba = HBA; 4072 IOCBQ *iocbq; 4073 IOCB *iocb; 4074 emlxs_wqe_t *wqe; 4075 uint16_t abort_iotag; 4076 4077 if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB)) == NULL) { 4078 return (NULL); 4079 } 4080 4081 iocbq->channel = (void *)cp; 4082 iocbq->port = (void *)port; 4083 iocbq->node = (void *)ndlp; 4084 iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL); 4085 4086 /* 4087 * set up an iotag using special Abort iotags 4088 */ 4089 if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) { 4090 hba->fc_oor_iotag = hba->max_iotag; 4091 } 4092 abort_iotag = hba->fc_oor_iotag++; 4093 4094 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4095 wqe = &iocbq->wqe; 4096 wqe->un.Abort.Criteria = ABORT_XRI_TAG; 4097 wqe->un.Abort.IA = 0; 4098 wqe->RequestTag = abort_iotag; 4099 wqe->AbortTag = xid; 4100 wqe->Command = CMD_ABORT_XRI_CX; 4101 wqe->Class = CLASS3; 4102 wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 4103 wqe->CmdType = WQE_TYPE_ABORT; 4104 } else { 4105 iocb = &iocbq->iocb; 4106 iocb->ULPCONTEXT = xid; 4107 iocb->ULPIOTAG = abort_iotag; 4108 iocb->un.acxri.abortType = flag; 4109 iocb->ULPLE = 1; 4110 iocb->ULPCLASS = class; 4111 iocb->ULPCOMMAND = CMD_ABORT_XRI_CX; 4112 iocb->ULPOWNER = OWN_CHIP; 4113 } 4114 4115 return (iocbq); 4116 4117 } /* emlxs_create_abort_xri_cx() */ 4118 4119 4120 4121 /* This must be called while holding the EMLXS_FCTAB_LOCK */ 4122 extern IOCBQ * 4123 emlxs_create_close_xri_cn(emlxs_port_t *port, NODELIST *ndlp, 4124 uint16_t iotag, CHANNEL *cp) 4125 { 4126 emlxs_hba_t *hba = HBA; 4127 IOCBQ *iocbq; 4128 IOCB *iocb; 4129 emlxs_wqe_t *wqe; 4130 emlxs_buf_t *sbp; 4131 uint16_t abort_iotag; 4132 4133 if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB)) == NULL) { 4134 return (NULL); 4135 } 4136 4137 iocbq->channel = (void *)cp; 4138 iocbq->port = (void *)port; 4139 iocbq->node = (void *)ndlp; 4140 iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL); 4141 4142 /* 4143 * set up an iotag using special Abort iotags 4144 */ 4145 if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) { 4146 hba->fc_oor_iotag = hba->max_iotag; 4147 } 4148 abort_iotag = hba->fc_oor_iotag++; 4149 4150 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4151 wqe = &iocbq->wqe; 4152 sbp = hba->fc_table[iotag]; 4153 4154 /* Try to issue close by XRI if possible */ 4155 if (sbp == NULL || sbp == STALE_PACKET || sbp->xrip == NULL) { 4156 wqe->un.Abort.Criteria = ABORT_REQ_TAG; 4157 wqe->AbortTag = iotag; 4158 } else { 4159 wqe->un.Abort.Criteria = ABORT_XRI_TAG; 4160 wqe->AbortTag = sbp->xrip->XRI; 4161 } 4162 wqe->un.Abort.IA = 1; 4163 wqe->RequestTag = abort_iotag; 4164 wqe->Command = CMD_ABORT_XRI_CX; 4165 wqe->Class = CLASS3; 4166 wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 4167 wqe->CmdType = WQE_TYPE_ABORT; 4168 } else { 4169 iocb = &iocbq->iocb; 4170 iocb->ULPIOTAG = abort_iotag; 4171 iocb->un.acxri.abortType = 0; 4172 iocb->un.acxri.abortContextTag = ndlp->nlp_Rpi; 4173 iocb->un.acxri.abortIoTag = iotag; 4174 iocb->ULPLE = 1; 4175 iocb->ULPCLASS = 0; 4176 iocb->ULPCOMMAND = CMD_CLOSE_XRI_CN; 4177 iocb->ULPOWNER = OWN_CHIP; 4178 } 4179 4180 return (iocbq); 4181 4182 } /* emlxs_create_close_xri_cn() */ 4183 4184 4185 /* This must be called while holding the EMLXS_FCTAB_LOCK */ 4186 extern IOCBQ * 4187 emlxs_create_close_xri_cx(emlxs_port_t *port, NODELIST *ndlp, uint16_t xid, 4188 CHANNEL *cp) 4189 { 4190 emlxs_hba_t *hba = HBA; 4191 IOCBQ *iocbq; 4192 IOCB *iocb; 4193 emlxs_wqe_t *wqe; 4194 uint16_t abort_iotag; 4195 4196 if ((iocbq = (IOCBQ *)emlxs_mem_get(hba, MEM_IOCB)) == NULL) { 4197 return (NULL); 4198 } 4199 4200 iocbq->channel = (void *)cp; 4201 iocbq->port = (void *)port; 4202 iocbq->node = (void *)ndlp; 4203 iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL); 4204 4205 /* 4206 * set up an iotag using special Abort iotags 4207 */ 4208 if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) { 4209 hba->fc_oor_iotag = hba->max_iotag; 4210 } 4211 abort_iotag = hba->fc_oor_iotag++; 4212 4213 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4214 wqe = &iocbq->wqe; 4215 wqe->un.Abort.Criteria = ABORT_XRI_TAG; 4216 wqe->un.Abort.IA = 1; 4217 wqe->RequestTag = abort_iotag; 4218 wqe->AbortTag = xid; 4219 wqe->Command = CMD_ABORT_XRI_CX; 4220 wqe->Class = CLASS3; 4221 wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 4222 wqe->CmdType = WQE_TYPE_ABORT; 4223 } else { 4224 iocb = &iocbq->iocb; 4225 iocb->ULPCONTEXT = xid; 4226 iocb->ULPIOTAG = abort_iotag; 4227 iocb->ULPLE = 1; 4228 iocb->ULPCLASS = 0; 4229 iocb->ULPCOMMAND = CMD_CLOSE_XRI_CX; 4230 iocb->ULPOWNER = OWN_CHIP; 4231 } 4232 4233 return (iocbq); 4234 4235 } /* emlxs_create_close_xri_cx() */ 4236 4237 4238 void 4239 emlxs_close_els_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid) 4240 { 4241 CHANNEL *cp; 4242 IOCBQ *iocbq; 4243 IOCB *iocb; 4244 4245 if (rxid == 0 || rxid == 0xFFFF) { 4246 return; 4247 } 4248 4249 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4250 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 4251 "Closing ELS exchange: xid=%x", rxid); 4252 4253 if (emlxs_sli4_unreserve_xri(port, rxid, 1) == 0) { 4254 return; 4255 } 4256 } 4257 4258 cp = &hba->chan[hba->channel_els]; 4259 4260 mutex_enter(&EMLXS_FCTAB_LOCK); 4261 4262 /* Create the abort IOCB */ 4263 iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp); 4264 4265 mutex_exit(&EMLXS_FCTAB_LOCK); 4266 4267 if (iocbq) { 4268 iocb = &iocbq->iocb; 4269 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 4270 "Closing ELS exchange: xid=%x iotag=%d", rxid, 4271 iocb->ULPIOTAG); 4272 4273 EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq); 4274 } 4275 4276 } /* emlxs_close_els_exchange() */ 4277 4278 4279 void 4280 emlxs_abort_els_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid) 4281 { 4282 CHANNEL *cp; 4283 IOCBQ *iocbq; 4284 IOCB *iocb; 4285 4286 if (rxid == 0 || rxid == 0xFFFF) { 4287 return; 4288 } 4289 4290 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4291 4292 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 4293 "Aborting ELS exchange: xid=%x", rxid); 4294 4295 if (emlxs_sli4_unreserve_xri(port, rxid, 1) == 0) { 4296 /* We have no way to abort unsolicited exchanges */ 4297 /* that we have not responded to at this time */ 4298 /* So we will return for now */ 4299 return; 4300 } 4301 } 4302 4303 cp = &hba->chan[hba->channel_els]; 4304 4305 mutex_enter(&EMLXS_FCTAB_LOCK); 4306 4307 /* Create the abort IOCB */ 4308 if (hba->state >= FC_LINK_UP) { 4309 iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp, 4310 CLASS3, ABORT_TYPE_ABTS); 4311 } else { 4312 iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp); 4313 } 4314 4315 mutex_exit(&EMLXS_FCTAB_LOCK); 4316 4317 if (iocbq) { 4318 iocb = &iocbq->iocb; 4319 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 4320 "Aborting ELS exchange: xid=%x iotag=%d", rxid, 4321 iocb->ULPIOTAG); 4322 4323 EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq); 4324 } 4325 4326 } /* emlxs_abort_els_exchange() */ 4327 4328 4329 void 4330 emlxs_abort_ct_exchange(emlxs_hba_t *hba, emlxs_port_t *port, uint32_t rxid) 4331 { 4332 CHANNEL *cp; 4333 IOCBQ *iocbq; 4334 IOCB *iocb; 4335 4336 if (rxid == 0 || rxid == 0xFFFF) { 4337 return; 4338 } 4339 4340 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 4341 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg, 4342 "Aborting CT exchange: xid=%x", rxid); 4343 4344 if (emlxs_sli4_unreserve_xri(port, rxid, 1) == 0) { 4345 /* We have no way to abort unsolicited exchanges */ 4346 /* that we have not responded to at this time */ 4347 /* So we will return for now */ 4348 return; 4349 } 4350 } 4351 4352 cp = &hba->chan[hba->channel_ct]; 4353 4354 mutex_enter(&EMLXS_FCTAB_LOCK); 4355 4356 /* Create the abort IOCB */ 4357 if (hba->state >= FC_LINK_UP) { 4358 iocbq = emlxs_create_abort_xri_cx(port, NULL, rxid, cp, 4359 CLASS3, ABORT_TYPE_ABTS); 4360 } else { 4361 iocbq = emlxs_create_close_xri_cx(port, NULL, rxid, cp); 4362 } 4363 4364 mutex_exit(&EMLXS_FCTAB_LOCK); 4365 4366 if (iocbq) { 4367 iocb = &iocbq->iocb; 4368 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, 4369 "Aborting CT exchange: xid=%x iotag=%d", rxid, 4370 iocb->ULPIOTAG); 4371 4372 EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq); 4373 } 4374 4375 } /* emlxs_abort_ct_exchange() */ 4376 4377 4378 /* This must be called while holding the EMLXS_FCTAB_LOCK */ 4379 static void 4380 emlxs_sbp_abort_add(emlxs_port_t *port, emlxs_buf_t *sbp, Q *abort, 4381 uint8_t *flag, emlxs_buf_t *fpkt) 4382 { 4383 emlxs_hba_t *hba = HBA; 4384 IOCBQ *iocbq; 4385 CHANNEL *cp; 4386 NODELIST *ndlp; 4387 4388 cp = (CHANNEL *)sbp->channel; 4389 ndlp = sbp->node; 4390 4391 /* Create the close XRI IOCB */ 4392 if (hba->state >= FC_LINK_UP) { 4393 iocbq = emlxs_create_abort_xri_cn(port, ndlp, sbp->iotag, cp, 4394 CLASS3, ABORT_TYPE_ABTS); 4395 } else { 4396 iocbq = emlxs_create_close_xri_cn(port, ndlp, sbp->iotag, cp); 4397 } 4398 /* 4399 * Add this iocb to our local abort Q 4400 * This way we don't hold the CHIPQ lock too long 4401 */ 4402 if (iocbq) { 4403 if (abort->q_first) { 4404 ((IOCBQ *)abort->q_last)->next = iocbq; 4405 abort->q_last = (uint8_t *)iocbq; 4406 abort->q_cnt++; 4407 } else { 4408 abort->q_first = (uint8_t *)iocbq; 4409 abort->q_last = (uint8_t *)iocbq; 4410 abort->q_cnt = 1; 4411 } 4412 iocbq->next = NULL; 4413 } 4414 4415 /* set the flags */ 4416 mutex_enter(&sbp->mtx); 4417 4418 sbp->pkt_flags |= (PACKET_IN_FLUSH | PACKET_XRI_CLOSED); 4419 4420 sbp->ticks = hba->timer_tics + 10; 4421 sbp->abort_attempts++; 4422 4423 flag[cp->channelno] = 1; 4424 4425 /* 4426 * If the fpkt is already set, then we will leave it alone 4427 * This ensures that this pkt is only accounted for on one 4428 * fpkt->flush_count 4429 */ 4430 if (!sbp->fpkt && fpkt) { 4431 mutex_enter(&fpkt->mtx); 4432 sbp->fpkt = fpkt; 4433 fpkt->flush_count++; 4434 mutex_exit(&fpkt->mtx); 4435 } 4436 4437 mutex_exit(&sbp->mtx); 4438 4439 return; 4440 4441 } /* emlxs_sbp_abort_add() */ 4442