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