diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 534 |
1 files changed, 358 insertions, 176 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ce348c5c706c..fdd01e384e36 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -106,7 +106,7 @@ lpfc_sli_get_iocbq(struct lpfc_hba *phba) | |||
106 | return iocbq; | 106 | return iocbq; |
107 | } | 107 | } |
108 | 108 | ||
109 | void | 109 | static void |
110 | __lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | 110 | __lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) |
111 | { | 111 | { |
112 | size_t start_clean = offsetof(struct lpfc_iocbq, iocb); | 112 | size_t start_clean = offsetof(struct lpfc_iocbq, iocb); |
@@ -199,6 +199,7 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) | |||
199 | case CMD_RCV_ELS_REQ_CX: | 199 | case CMD_RCV_ELS_REQ_CX: |
200 | case CMD_RCV_SEQUENCE64_CX: | 200 | case CMD_RCV_SEQUENCE64_CX: |
201 | case CMD_RCV_ELS_REQ64_CX: | 201 | case CMD_RCV_ELS_REQ64_CX: |
202 | case CMD_ASYNC_STATUS: | ||
202 | case CMD_IOCB_RCV_SEQ64_CX: | 203 | case CMD_IOCB_RCV_SEQ64_CX: |
203 | case CMD_IOCB_RCV_ELS64_CX: | 204 | case CMD_IOCB_RCV_ELS64_CX: |
204 | case CMD_IOCB_RCV_CONT64_CX: | 205 | case CMD_IOCB_RCV_CONT64_CX: |
@@ -473,8 +474,7 @@ lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
473 | if (pring->txq_cnt && | 474 | if (pring->txq_cnt && |
474 | lpfc_is_link_up(phba) && | 475 | lpfc_is_link_up(phba) && |
475 | (pring->ringno != phba->sli.fcp_ring || | 476 | (pring->ringno != phba->sli.fcp_ring || |
476 | phba->sli.sli_flag & LPFC_PROCESS_LA) && | 477 | phba->sli.sli_flag & LPFC_PROCESS_LA)) { |
477 | !(pring->flag & LPFC_STOP_IOCB_MBX)) { | ||
478 | 478 | ||
479 | while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && | 479 | while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) && |
480 | (nextiocb = lpfc_sli_ringtx_get(phba, pring))) | 480 | (nextiocb = lpfc_sli_ringtx_get(phba, pring))) |
@@ -489,32 +489,7 @@ lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
489 | return; | 489 | return; |
490 | } | 490 | } |
491 | 491 | ||
492 | /* lpfc_sli_turn_on_ring is only called by lpfc_sli_handle_mb_event below */ | 492 | static struct lpfc_hbq_entry * |
493 | static void | ||
494 | lpfc_sli_turn_on_ring(struct lpfc_hba *phba, int ringno) | ||
495 | { | ||
496 | struct lpfc_pgp *pgp = (phba->sli_rev == 3) ? | ||
497 | &phba->slim2p->mbx.us.s3_pgp.port[ringno] : | ||
498 | &phba->slim2p->mbx.us.s2.port[ringno]; | ||
499 | unsigned long iflags; | ||
500 | |||
501 | /* If the ring is active, flag it */ | ||
502 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
503 | if (phba->sli.ring[ringno].cmdringaddr) { | ||
504 | if (phba->sli.ring[ringno].flag & LPFC_STOP_IOCB_MBX) { | ||
505 | phba->sli.ring[ringno].flag &= ~LPFC_STOP_IOCB_MBX; | ||
506 | /* | ||
507 | * Force update of the local copy of cmdGetInx | ||
508 | */ | ||
509 | phba->sli.ring[ringno].local_getidx | ||
510 | = le32_to_cpu(pgp->cmdGetInx); | ||
511 | lpfc_sli_resume_iocb(phba, &phba->sli.ring[ringno]); | ||
512 | } | ||
513 | } | ||
514 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
515 | } | ||
516 | |||
517 | struct lpfc_hbq_entry * | ||
518 | lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno) | 493 | lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno) |
519 | { | 494 | { |
520 | struct hbq_s *hbqp = &phba->hbqs[hbqno]; | 495 | struct hbq_s *hbqp = &phba->hbqs[hbqno]; |
@@ -565,6 +540,7 @@ lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba) | |||
565 | list_del(&hbq_buf->dbuf.list); | 540 | list_del(&hbq_buf->dbuf.list); |
566 | (phba->hbqs[i].hbq_free_buffer)(phba, hbq_buf); | 541 | (phba->hbqs[i].hbq_free_buffer)(phba, hbq_buf); |
567 | } | 542 | } |
543 | phba->hbqs[i].buffer_count = 0; | ||
568 | } | 544 | } |
569 | } | 545 | } |
570 | 546 | ||
@@ -633,8 +609,8 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) | |||
633 | return 0; | 609 | return 0; |
634 | } | 610 | } |
635 | 611 | ||
636 | start = lpfc_hbq_defs[hbqno]->buffer_count; | 612 | start = phba->hbqs[hbqno].buffer_count; |
637 | end = count + lpfc_hbq_defs[hbqno]->buffer_count; | 613 | end = count + start; |
638 | if (end > lpfc_hbq_defs[hbqno]->entry_count) { | 614 | if (end > lpfc_hbq_defs[hbqno]->entry_count) { |
639 | end = lpfc_hbq_defs[hbqno]->entry_count; | 615 | end = lpfc_hbq_defs[hbqno]->entry_count; |
640 | } | 616 | } |
@@ -646,7 +622,7 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) | |||
646 | return 1; | 622 | return 1; |
647 | hbq_buffer->tag = (i | (hbqno << 16)); | 623 | hbq_buffer->tag = (i | (hbqno << 16)); |
648 | if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) | 624 | if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) |
649 | lpfc_hbq_defs[hbqno]->buffer_count++; | 625 | phba->hbqs[hbqno].buffer_count++; |
650 | else | 626 | else |
651 | (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); | 627 | (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); |
652 | } | 628 | } |
@@ -660,14 +636,14 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) | |||
660 | lpfc_hbq_defs[qno]->add_count)); | 636 | lpfc_hbq_defs[qno]->add_count)); |
661 | } | 637 | } |
662 | 638 | ||
663 | int | 639 | static int |
664 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) | 640 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) |
665 | { | 641 | { |
666 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | 642 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, |
667 | lpfc_hbq_defs[qno]->init_count)); | 643 | lpfc_hbq_defs[qno]->init_count)); |
668 | } | 644 | } |
669 | 645 | ||
670 | struct hbq_dmabuf * | 646 | static struct hbq_dmabuf * |
671 | lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) | 647 | lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) |
672 | { | 648 | { |
673 | struct lpfc_dmabuf *d_buf; | 649 | struct lpfc_dmabuf *d_buf; |
@@ -686,7 +662,7 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) | |||
686 | } | 662 | } |
687 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, | 663 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT, |
688 | "1803 Bad hbq tag. Data: x%x x%x\n", | 664 | "1803 Bad hbq tag. Data: x%x x%x\n", |
689 | tag, lpfc_hbq_defs[tag >> 16]->buffer_count); | 665 | tag, phba->hbqs[tag >> 16].buffer_count); |
690 | return NULL; | 666 | return NULL; |
691 | } | 667 | } |
692 | 668 | ||
@@ -712,6 +688,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
712 | case MBX_LOAD_SM: | 688 | case MBX_LOAD_SM: |
713 | case MBX_READ_NV: | 689 | case MBX_READ_NV: |
714 | case MBX_WRITE_NV: | 690 | case MBX_WRITE_NV: |
691 | case MBX_WRITE_VPARMS: | ||
715 | case MBX_RUN_BIU_DIAG: | 692 | case MBX_RUN_BIU_DIAG: |
716 | case MBX_INIT_LINK: | 693 | case MBX_INIT_LINK: |
717 | case MBX_DOWN_LINK: | 694 | case MBX_DOWN_LINK: |
@@ -739,7 +716,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
739 | case MBX_DEL_LD_ENTRY: | 716 | case MBX_DEL_LD_ENTRY: |
740 | case MBX_RUN_PROGRAM: | 717 | case MBX_RUN_PROGRAM: |
741 | case MBX_SET_MASK: | 718 | case MBX_SET_MASK: |
742 | case MBX_SET_SLIM: | 719 | case MBX_SET_VARIABLE: |
743 | case MBX_UNREG_D_ID: | 720 | case MBX_UNREG_D_ID: |
744 | case MBX_KILL_BOARD: | 721 | case MBX_KILL_BOARD: |
745 | case MBX_CONFIG_FARP: | 722 | case MBX_CONFIG_FARP: |
@@ -751,9 +728,10 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
751 | case MBX_READ_RPI64: | 728 | case MBX_READ_RPI64: |
752 | case MBX_REG_LOGIN64: | 729 | case MBX_REG_LOGIN64: |
753 | case MBX_READ_LA64: | 730 | case MBX_READ_LA64: |
754 | case MBX_FLASH_WR_ULA: | 731 | case MBX_WRITE_WWN: |
755 | case MBX_SET_DEBUG: | 732 | case MBX_SET_DEBUG: |
756 | case MBX_LOAD_EXP_ROM: | 733 | case MBX_LOAD_EXP_ROM: |
734 | case MBX_ASYNCEVT_ENABLE: | ||
757 | case MBX_REG_VPI: | 735 | case MBX_REG_VPI: |
758 | case MBX_UNREG_VPI: | 736 | case MBX_UNREG_VPI: |
759 | case MBX_HEARTBEAT: | 737 | case MBX_HEARTBEAT: |
@@ -953,6 +931,17 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) | |||
953 | return &new_hbq_entry->dbuf; | 931 | return &new_hbq_entry->dbuf; |
954 | } | 932 | } |
955 | 933 | ||
934 | static struct lpfc_dmabuf * | ||
935 | lpfc_sli_get_buff(struct lpfc_hba *phba, | ||
936 | struct lpfc_sli_ring *pring, | ||
937 | uint32_t tag) | ||
938 | { | ||
939 | if (tag & QUE_BUFTAG_BIT) | ||
940 | return lpfc_sli_ring_taggedbuf_get(phba, pring, tag); | ||
941 | else | ||
942 | return lpfc_sli_replace_hbqbuff(phba, tag); | ||
943 | } | ||
944 | |||
956 | static int | 945 | static int |
957 | lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 946 | lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
958 | struct lpfc_iocbq *saveq) | 947 | struct lpfc_iocbq *saveq) |
@@ -961,19 +950,112 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
961 | WORD5 * w5p; | 950 | WORD5 * w5p; |
962 | uint32_t Rctl, Type; | 951 | uint32_t Rctl, Type; |
963 | uint32_t match, i; | 952 | uint32_t match, i; |
953 | struct lpfc_iocbq *iocbq; | ||
964 | 954 | ||
965 | match = 0; | 955 | match = 0; |
966 | irsp = &(saveq->iocb); | 956 | irsp = &(saveq->iocb); |
967 | if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) | 957 | |
968 | || (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) | 958 | if (irsp->ulpStatus == IOSTAT_NEED_BUFFER) |
969 | || (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX) | 959 | return 1; |
970 | || (irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX)) { | 960 | if (irsp->ulpCommand == CMD_ASYNC_STATUS) { |
961 | if (pring->lpfc_sli_rcv_async_status) | ||
962 | pring->lpfc_sli_rcv_async_status(phba, pring, saveq); | ||
963 | else | ||
964 | lpfc_printf_log(phba, | ||
965 | KERN_WARNING, | ||
966 | LOG_SLI, | ||
967 | "0316 Ring %d handler: unexpected " | ||
968 | "ASYNC_STATUS iocb received evt_code " | ||
969 | "0x%x\n", | ||
970 | pring->ringno, | ||
971 | irsp->un.asyncstat.evt_code); | ||
972 | return 1; | ||
973 | } | ||
974 | |||
975 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | ||
976 | if (irsp->ulpBdeCount != 0) { | ||
977 | saveq->context2 = lpfc_sli_get_buff(phba, pring, | ||
978 | irsp->un.ulpWord[3]); | ||
979 | if (!saveq->context2) | ||
980 | lpfc_printf_log(phba, | ||
981 | KERN_ERR, | ||
982 | LOG_SLI, | ||
983 | "0341 Ring %d Cannot find buffer for " | ||
984 | "an unsolicited iocb. tag 0x%x\n", | ||
985 | pring->ringno, | ||
986 | irsp->un.ulpWord[3]); | ||
987 | } | ||
988 | if (irsp->ulpBdeCount == 2) { | ||
989 | saveq->context3 = lpfc_sli_get_buff(phba, pring, | ||
990 | irsp->unsli3.sli3Words[7]); | ||
991 | if (!saveq->context3) | ||
992 | lpfc_printf_log(phba, | ||
993 | KERN_ERR, | ||
994 | LOG_SLI, | ||
995 | "0342 Ring %d Cannot find buffer for an" | ||
996 | " unsolicited iocb. tag 0x%x\n", | ||
997 | pring->ringno, | ||
998 | irsp->unsli3.sli3Words[7]); | ||
999 | } | ||
1000 | list_for_each_entry(iocbq, &saveq->list, list) { | ||
1001 | irsp = &(iocbq->iocb); | ||
1002 | if (irsp->ulpBdeCount != 0) { | ||
1003 | iocbq->context2 = lpfc_sli_get_buff(phba, pring, | ||
1004 | irsp->un.ulpWord[3]); | ||
1005 | if (!iocbq->context2) | ||
1006 | lpfc_printf_log(phba, | ||
1007 | KERN_ERR, | ||
1008 | LOG_SLI, | ||
1009 | "0343 Ring %d Cannot find " | ||
1010 | "buffer for an unsolicited iocb" | ||
1011 | ". tag 0x%x\n", pring->ringno, | ||
1012 | irsp->un.ulpWord[3]); | ||
1013 | } | ||
1014 | if (irsp->ulpBdeCount == 2) { | ||
1015 | iocbq->context3 = lpfc_sli_get_buff(phba, pring, | ||
1016 | irsp->unsli3.sli3Words[7]); | ||
1017 | if (!iocbq->context3) | ||
1018 | lpfc_printf_log(phba, | ||
1019 | KERN_ERR, | ||
1020 | LOG_SLI, | ||
1021 | "0344 Ring %d Cannot find " | ||
1022 | "buffer for an unsolicited " | ||
1023 | "iocb. tag 0x%x\n", | ||
1024 | pring->ringno, | ||
1025 | irsp->unsli3.sli3Words[7]); | ||
1026 | } | ||
1027 | } | ||
1028 | } | ||
1029 | if (irsp->ulpBdeCount != 0 && | ||
1030 | (irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX || | ||
1031 | irsp->ulpStatus == IOSTAT_INTERMED_RSP)) { | ||
1032 | int found = 0; | ||
1033 | |||
1034 | /* search continue save q for same XRI */ | ||
1035 | list_for_each_entry(iocbq, &pring->iocb_continue_saveq, clist) { | ||
1036 | if (iocbq->iocb.ulpContext == saveq->iocb.ulpContext) { | ||
1037 | list_add_tail(&saveq->list, &iocbq->list); | ||
1038 | found = 1; | ||
1039 | break; | ||
1040 | } | ||
1041 | } | ||
1042 | if (!found) | ||
1043 | list_add_tail(&saveq->clist, | ||
1044 | &pring->iocb_continue_saveq); | ||
1045 | if (saveq->iocb.ulpStatus != IOSTAT_INTERMED_RSP) { | ||
1046 | list_del_init(&iocbq->clist); | ||
1047 | saveq = iocbq; | ||
1048 | irsp = &(saveq->iocb); | ||
1049 | } else | ||
1050 | return 0; | ||
1051 | } | ||
1052 | if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) || | ||
1053 | (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) || | ||
1054 | (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX)) { | ||
971 | Rctl = FC_ELS_REQ; | 1055 | Rctl = FC_ELS_REQ; |
972 | Type = FC_ELS_DATA; | 1056 | Type = FC_ELS_DATA; |
973 | } else { | 1057 | } else { |
974 | w5p = | 1058 | w5p = (WORD5 *)&(saveq->iocb.un.ulpWord[5]); |
975 | (WORD5 *) & (saveq->iocb.un. | ||
976 | ulpWord[5]); | ||
977 | Rctl = w5p->hcsw.Rctl; | 1059 | Rctl = w5p->hcsw.Rctl; |
978 | Type = w5p->hcsw.Type; | 1060 | Type = w5p->hcsw.Type; |
979 | 1061 | ||
@@ -988,15 +1070,6 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
988 | } | 1070 | } |
989 | } | 1071 | } |
990 | 1072 | ||
991 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | ||
992 | if (irsp->ulpBdeCount != 0) | ||
993 | saveq->context2 = lpfc_sli_replace_hbqbuff(phba, | ||
994 | irsp->un.ulpWord[3]); | ||
995 | if (irsp->ulpBdeCount == 2) | ||
996 | saveq->context3 = lpfc_sli_replace_hbqbuff(phba, | ||
997 | irsp->unsli3.sli3Words[7]); | ||
998 | } | ||
999 | |||
1000 | /* unSolicited Responses */ | 1073 | /* unSolicited Responses */ |
1001 | if (pring->prt[0].profile) { | 1074 | if (pring->prt[0].profile) { |
1002 | if (pring->prt[0].lpfc_sli_rcv_unsol_event) | 1075 | if (pring->prt[0].lpfc_sli_rcv_unsol_event) |
@@ -1006,12 +1079,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
1006 | } else { | 1079 | } else { |
1007 | /* We must search, based on rctl / type | 1080 | /* We must search, based on rctl / type |
1008 | for the right routine */ | 1081 | for the right routine */ |
1009 | for (i = 0; i < pring->num_mask; | 1082 | for (i = 0; i < pring->num_mask; i++) { |
1010 | i++) { | 1083 | if ((pring->prt[i].rctl == Rctl) |
1011 | if ((pring->prt[i].rctl == | 1084 | && (pring->prt[i].type == Type)) { |
1012 | Rctl) | ||
1013 | && (pring->prt[i]. | ||
1014 | type == Type)) { | ||
1015 | if (pring->prt[i].lpfc_sli_rcv_unsol_event) | 1085 | if (pring->prt[i].lpfc_sli_rcv_unsol_event) |
1016 | (pring->prt[i].lpfc_sli_rcv_unsol_event) | 1086 | (pring->prt[i].lpfc_sli_rcv_unsol_event) |
1017 | (phba, pring, saveq); | 1087 | (phba, pring, saveq); |
@@ -1084,6 +1154,12 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
1084 | IOSTAT_LOCAL_REJECT; | 1154 | IOSTAT_LOCAL_REJECT; |
1085 | saveq->iocb.un.ulpWord[4] = | 1155 | saveq->iocb.un.ulpWord[4] = |
1086 | IOERR_SLI_ABORTED; | 1156 | IOERR_SLI_ABORTED; |
1157 | |||
1158 | /* Firmware could still be in progress | ||
1159 | * of DMAing payload, so don't free data | ||
1160 | * buffer till after a hbeat. | ||
1161 | */ | ||
1162 | saveq->iocb_flag |= LPFC_DELAY_MEM_FREE; | ||
1087 | } | 1163 | } |
1088 | } | 1164 | } |
1089 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | 1165 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); |
@@ -1572,12 +1648,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, | |||
1572 | 1648 | ||
1573 | writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx); | 1649 | writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx); |
1574 | 1650 | ||
1575 | if (list_empty(&(pring->iocb_continueq))) { | 1651 | list_add_tail(&rspiocbp->list, &(pring->iocb_continueq)); |
1576 | list_add(&rspiocbp->list, &(pring->iocb_continueq)); | ||
1577 | } else { | ||
1578 | list_add_tail(&rspiocbp->list, | ||
1579 | &(pring->iocb_continueq)); | ||
1580 | } | ||
1581 | 1652 | ||
1582 | pring->iocb_continueq_cnt++; | 1653 | pring->iocb_continueq_cnt++; |
1583 | if (irsp->ulpLe) { | 1654 | if (irsp->ulpLe) { |
@@ -1642,17 +1713,17 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, | |||
1642 | iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK; | 1713 | iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK; |
1643 | type = lpfc_sli_iocb_cmd_type(iocb_cmd_type); | 1714 | type = lpfc_sli_iocb_cmd_type(iocb_cmd_type); |
1644 | if (type == LPFC_SOL_IOCB) { | 1715 | if (type == LPFC_SOL_IOCB) { |
1645 | spin_unlock_irqrestore(&phba->hbalock, | 1716 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1646 | iflag); | ||
1647 | rc = lpfc_sli_process_sol_iocb(phba, pring, | 1717 | rc = lpfc_sli_process_sol_iocb(phba, pring, |
1648 | saveq); | 1718 | saveq); |
1649 | spin_lock_irqsave(&phba->hbalock, iflag); | 1719 | spin_lock_irqsave(&phba->hbalock, iflag); |
1650 | } else if (type == LPFC_UNSOL_IOCB) { | 1720 | } else if (type == LPFC_UNSOL_IOCB) { |
1651 | spin_unlock_irqrestore(&phba->hbalock, | 1721 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1652 | iflag); | ||
1653 | rc = lpfc_sli_process_unsol_iocb(phba, pring, | 1722 | rc = lpfc_sli_process_unsol_iocb(phba, pring, |
1654 | saveq); | 1723 | saveq); |
1655 | spin_lock_irqsave(&phba->hbalock, iflag); | 1724 | spin_lock_irqsave(&phba->hbalock, iflag); |
1725 | if (!rc) | ||
1726 | free_saveq = 0; | ||
1656 | } else if (type == LPFC_ABORT_IOCB) { | 1727 | } else if (type == LPFC_ABORT_IOCB) { |
1657 | if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && | 1728 | if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && |
1658 | ((cmdiocbp = | 1729 | ((cmdiocbp = |
@@ -1921,8 +1992,8 @@ lpfc_sli_brdkill(struct lpfc_hba *phba) | |||
1921 | "0329 Kill HBA Data: x%x x%x\n", | 1992 | "0329 Kill HBA Data: x%x x%x\n", |
1922 | phba->pport->port_state, psli->sli_flag); | 1993 | phba->pport->port_state, psli->sli_flag); |
1923 | 1994 | ||
1924 | if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, | 1995 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1925 | GFP_KERNEL)) == 0) | 1996 | if (!pmb) |
1926 | return 1; | 1997 | return 1; |
1927 | 1998 | ||
1928 | /* Disable the error attention */ | 1999 | /* Disable the error attention */ |
@@ -2113,7 +2184,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2113 | <status> */ | 2184 | <status> */ |
2114 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2185 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2115 | "0436 Adapter failed to init, " | 2186 | "0436 Adapter failed to init, " |
2116 | "timeout, status reg x%x\n", status); | 2187 | "timeout, status reg x%x, " |
2188 | "FW Data: A8 x%x AC x%x\n", status, | ||
2189 | readl(phba->MBslimaddr + 0xa8), | ||
2190 | readl(phba->MBslimaddr + 0xac)); | ||
2117 | phba->link_state = LPFC_HBA_ERROR; | 2191 | phba->link_state = LPFC_HBA_ERROR; |
2118 | return -ETIMEDOUT; | 2192 | return -ETIMEDOUT; |
2119 | } | 2193 | } |
@@ -2125,7 +2199,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2125 | <status> */ | 2199 | <status> */ |
2126 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2200 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2127 | "0437 Adapter failed to init, " | 2201 | "0437 Adapter failed to init, " |
2128 | "chipset, status reg x%x\n", status); | 2202 | "chipset, status reg x%x, " |
2203 | "FW Data: A8 x%x AC x%x\n", status, | ||
2204 | readl(phba->MBslimaddr + 0xa8), | ||
2205 | readl(phba->MBslimaddr + 0xac)); | ||
2129 | phba->link_state = LPFC_HBA_ERROR; | 2206 | phba->link_state = LPFC_HBA_ERROR; |
2130 | return -EIO; | 2207 | return -EIO; |
2131 | } | 2208 | } |
@@ -2153,7 +2230,10 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) | |||
2153 | /* Adapter failed to init, chipset, status reg <status> */ | 2230 | /* Adapter failed to init, chipset, status reg <status> */ |
2154 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2231 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
2155 | "0438 Adapter failed to init, chipset, " | 2232 | "0438 Adapter failed to init, chipset, " |
2156 | "status reg x%x\n", status); | 2233 | "status reg x%x, " |
2234 | "FW Data: A8 x%x AC x%x\n", status, | ||
2235 | readl(phba->MBslimaddr + 0xa8), | ||
2236 | readl(phba->MBslimaddr + 0xac)); | ||
2157 | phba->link_state = LPFC_HBA_ERROR; | 2237 | phba->link_state = LPFC_HBA_ERROR; |
2158 | return -EIO; | 2238 | return -EIO; |
2159 | } | 2239 | } |
@@ -2485,11 +2565,16 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2485 | lpfc_sli_abort_iocb_ring(phba, pring); | 2565 | lpfc_sli_abort_iocb_ring(phba, pring); |
2486 | 2566 | ||
2487 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 2567 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
2488 | "0316 Resetting board due to mailbox timeout\n"); | 2568 | "0345 Resetting board due to mailbox timeout\n"); |
2489 | /* | 2569 | /* |
2490 | * lpfc_offline calls lpfc_sli_hba_down which will clean up | 2570 | * lpfc_offline calls lpfc_sli_hba_down which will clean up |
2491 | * on oustanding mailbox commands. | 2571 | * on oustanding mailbox commands. |
2492 | */ | 2572 | */ |
2573 | /* If resets are disabled then set error state and return. */ | ||
2574 | if (!phba->cfg_enable_hba_reset) { | ||
2575 | phba->link_state = LPFC_HBA_ERROR; | ||
2576 | return; | ||
2577 | } | ||
2493 | lpfc_offline_prep(phba); | 2578 | lpfc_offline_prep(phba); |
2494 | lpfc_offline(phba); | 2579 | lpfc_offline(phba); |
2495 | lpfc_sli_brdrestart(phba); | 2580 | lpfc_sli_brdrestart(phba); |
@@ -2507,6 +2592,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2507 | uint32_t status, evtctr; | 2592 | uint32_t status, evtctr; |
2508 | uint32_t ha_copy; | 2593 | uint32_t ha_copy; |
2509 | int i; | 2594 | int i; |
2595 | unsigned long timeout; | ||
2510 | unsigned long drvr_flag = 0; | 2596 | unsigned long drvr_flag = 0; |
2511 | volatile uint32_t word0, ldata; | 2597 | volatile uint32_t word0, ldata; |
2512 | void __iomem *to_slim; | 2598 | void __iomem *to_slim; |
@@ -2519,7 +2605,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2519 | "1806 Mbox x%x failed. No vport\n", | 2605 | "1806 Mbox x%x failed. No vport\n", |
2520 | pmbox->mb.mbxCommand); | 2606 | pmbox->mb.mbxCommand); |
2521 | dump_stack(); | 2607 | dump_stack(); |
2522 | return MBXERR_ERROR; | 2608 | return MBX_NOT_FINISHED; |
2523 | } | 2609 | } |
2524 | } | 2610 | } |
2525 | 2611 | ||
@@ -2571,21 +2657,6 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2571 | return MBX_NOT_FINISHED; | 2657 | return MBX_NOT_FINISHED; |
2572 | } | 2658 | } |
2573 | 2659 | ||
2574 | /* Handle STOP IOCB processing flag. This is only meaningful | ||
2575 | * if we are not polling for mbox completion. | ||
2576 | */ | ||
2577 | if (flag & MBX_STOP_IOCB) { | ||
2578 | flag &= ~MBX_STOP_IOCB; | ||
2579 | /* Now flag each ring */ | ||
2580 | for (i = 0; i < psli->num_rings; i++) { | ||
2581 | /* If the ring is active, flag it */ | ||
2582 | if (psli->ring[i].cmdringaddr) { | ||
2583 | psli->ring[i].flag |= | ||
2584 | LPFC_STOP_IOCB_MBX; | ||
2585 | } | ||
2586 | } | ||
2587 | } | ||
2588 | |||
2589 | /* Another mailbox command is still being processed, queue this | 2660 | /* Another mailbox command is still being processed, queue this |
2590 | * command to be processed later. | 2661 | * command to be processed later. |
2591 | */ | 2662 | */ |
@@ -2620,23 +2691,6 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2620 | return MBX_BUSY; | 2691 | return MBX_BUSY; |
2621 | } | 2692 | } |
2622 | 2693 | ||
2623 | /* Handle STOP IOCB processing flag. This is only meaningful | ||
2624 | * if we are not polling for mbox completion. | ||
2625 | */ | ||
2626 | if (flag & MBX_STOP_IOCB) { | ||
2627 | flag &= ~MBX_STOP_IOCB; | ||
2628 | if (flag == MBX_NOWAIT) { | ||
2629 | /* Now flag each ring */ | ||
2630 | for (i = 0; i < psli->num_rings; i++) { | ||
2631 | /* If the ring is active, flag it */ | ||
2632 | if (psli->ring[i].cmdringaddr) { | ||
2633 | psli->ring[i].flag |= | ||
2634 | LPFC_STOP_IOCB_MBX; | ||
2635 | } | ||
2636 | } | ||
2637 | } | ||
2638 | } | ||
2639 | |||
2640 | psli->sli_flag |= LPFC_SLI_MBOX_ACTIVE; | 2694 | psli->sli_flag |= LPFC_SLI_MBOX_ACTIVE; |
2641 | 2695 | ||
2642 | /* If we are not polling, we MUST be in SLI2 mode */ | 2696 | /* If we are not polling, we MUST be in SLI2 mode */ |
@@ -2714,18 +2768,24 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2714 | } | 2768 | } |
2715 | 2769 | ||
2716 | wmb(); | 2770 | wmb(); |
2717 | /* interrupt board to doit right away */ | ||
2718 | writel(CA_MBATT, phba->CAregaddr); | ||
2719 | readl(phba->CAregaddr); /* flush */ | ||
2720 | 2771 | ||
2721 | switch (flag) { | 2772 | switch (flag) { |
2722 | case MBX_NOWAIT: | 2773 | case MBX_NOWAIT: |
2723 | /* Don't wait for it to finish, just return */ | 2774 | /* Set up reference to mailbox command */ |
2724 | psli->mbox_active = pmbox; | 2775 | psli->mbox_active = pmbox; |
2776 | /* Interrupt board to do it */ | ||
2777 | writel(CA_MBATT, phba->CAregaddr); | ||
2778 | readl(phba->CAregaddr); /* flush */ | ||
2779 | /* Don't wait for it to finish, just return */ | ||
2725 | break; | 2780 | break; |
2726 | 2781 | ||
2727 | case MBX_POLL: | 2782 | case MBX_POLL: |
2783 | /* Set up null reference to mailbox command */ | ||
2728 | psli->mbox_active = NULL; | 2784 | psli->mbox_active = NULL; |
2785 | /* Interrupt board to do it */ | ||
2786 | writel(CA_MBATT, phba->CAregaddr); | ||
2787 | readl(phba->CAregaddr); /* flush */ | ||
2788 | |||
2729 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2789 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2730 | /* First read mbox status word */ | 2790 | /* First read mbox status word */ |
2731 | word0 = *((volatile uint32_t *)&phba->slim2p->mbx); | 2791 | word0 = *((volatile uint32_t *)&phba->slim2p->mbx); |
@@ -2737,15 +2797,15 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2737 | 2797 | ||
2738 | /* Read the HBA Host Attention Register */ | 2798 | /* Read the HBA Host Attention Register */ |
2739 | ha_copy = readl(phba->HAregaddr); | 2799 | ha_copy = readl(phba->HAregaddr); |
2740 | 2800 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, | |
2741 | i = lpfc_mbox_tmo_val(phba, mb->mbxCommand); | 2801 | mb->mbxCommand) * |
2742 | i *= 1000; /* Convert to ms */ | 2802 | 1000) + jiffies; |
2743 | 2803 | i = 0; | |
2744 | /* Wait for command to complete */ | 2804 | /* Wait for command to complete */ |
2745 | while (((word0 & OWN_CHIP) == OWN_CHIP) || | 2805 | while (((word0 & OWN_CHIP) == OWN_CHIP) || |
2746 | (!(ha_copy & HA_MBATT) && | 2806 | (!(ha_copy & HA_MBATT) && |
2747 | (phba->link_state > LPFC_WARM_START))) { | 2807 | (phba->link_state > LPFC_WARM_START))) { |
2748 | if (i-- <= 0) { | 2808 | if (time_after(jiffies, timeout)) { |
2749 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2809 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2750 | spin_unlock_irqrestore(&phba->hbalock, | 2810 | spin_unlock_irqrestore(&phba->hbalock, |
2751 | drvr_flag); | 2811 | drvr_flag); |
@@ -2758,12 +2818,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2758 | && (evtctr != psli->slistat.mbox_event)) | 2818 | && (evtctr != psli->slistat.mbox_event)) |
2759 | break; | 2819 | break; |
2760 | 2820 | ||
2761 | spin_unlock_irqrestore(&phba->hbalock, | 2821 | if (i++ > 10) { |
2762 | drvr_flag); | 2822 | spin_unlock_irqrestore(&phba->hbalock, |
2763 | 2823 | drvr_flag); | |
2764 | msleep(1); | 2824 | msleep(1); |
2765 | 2825 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | |
2766 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | 2826 | } |
2767 | 2827 | ||
2768 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { | 2828 | if (psli->sli_flag & LPFC_SLI2_ACTIVE) { |
2769 | /* First copy command data */ | 2829 | /* First copy command data */ |
@@ -2848,7 +2908,7 @@ lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2848 | /* | 2908 | /* |
2849 | * Lockless version of lpfc_sli_issue_iocb. | 2909 | * Lockless version of lpfc_sli_issue_iocb. |
2850 | */ | 2910 | */ |
2851 | int | 2911 | static int |
2852 | __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 2912 | __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
2853 | struct lpfc_iocbq *piocb, uint32_t flag) | 2913 | struct lpfc_iocbq *piocb, uint32_t flag) |
2854 | { | 2914 | { |
@@ -2879,9 +2939,9 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2879 | 2939 | ||
2880 | /* | 2940 | /* |
2881 | * Check to see if we are blocking IOCB processing because of a | 2941 | * Check to see if we are blocking IOCB processing because of a |
2882 | * outstanding mbox command. | 2942 | * outstanding event. |
2883 | */ | 2943 | */ |
2884 | if (unlikely(pring->flag & LPFC_STOP_IOCB_MBX)) | 2944 | if (unlikely(pring->flag & LPFC_STOP_IOCB_EVENT)) |
2885 | goto iocb_busy; | 2945 | goto iocb_busy; |
2886 | 2946 | ||
2887 | if (unlikely(phba->link_state == LPFC_LINK_DOWN)) { | 2947 | if (unlikely(phba->link_state == LPFC_LINK_DOWN)) { |
@@ -2993,6 +3053,61 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) | |||
2993 | return 0; | 3053 | return 0; |
2994 | } | 3054 | } |
2995 | 3055 | ||
3056 | static void | ||
3057 | lpfc_sli_async_event_handler(struct lpfc_hba * phba, | ||
3058 | struct lpfc_sli_ring * pring, struct lpfc_iocbq * iocbq) | ||
3059 | { | ||
3060 | IOCB_t *icmd; | ||
3061 | uint16_t evt_code; | ||
3062 | uint16_t temp; | ||
3063 | struct temp_event temp_event_data; | ||
3064 | struct Scsi_Host *shost; | ||
3065 | |||
3066 | icmd = &iocbq->iocb; | ||
3067 | evt_code = icmd->un.asyncstat.evt_code; | ||
3068 | temp = icmd->ulpContext; | ||
3069 | |||
3070 | if ((evt_code != ASYNC_TEMP_WARN) && | ||
3071 | (evt_code != ASYNC_TEMP_SAFE)) { | ||
3072 | lpfc_printf_log(phba, | ||
3073 | KERN_ERR, | ||
3074 | LOG_SLI, | ||
3075 | "0346 Ring %d handler: unexpected ASYNC_STATUS" | ||
3076 | " evt_code 0x%x\n", | ||
3077 | pring->ringno, | ||
3078 | icmd->un.asyncstat.evt_code); | ||
3079 | return; | ||
3080 | } | ||
3081 | temp_event_data.data = (uint32_t)temp; | ||
3082 | temp_event_data.event_type = FC_REG_TEMPERATURE_EVENT; | ||
3083 | if (evt_code == ASYNC_TEMP_WARN) { | ||
3084 | temp_event_data.event_code = LPFC_THRESHOLD_TEMP; | ||
3085 | lpfc_printf_log(phba, | ||
3086 | KERN_ERR, | ||
3087 | LOG_TEMP, | ||
3088 | "0347 Adapter is very hot, please take " | ||
3089 | "corrective action. temperature : %d Celsius\n", | ||
3090 | temp); | ||
3091 | } | ||
3092 | if (evt_code == ASYNC_TEMP_SAFE) { | ||
3093 | temp_event_data.event_code = LPFC_NORMAL_TEMP; | ||
3094 | lpfc_printf_log(phba, | ||
3095 | KERN_ERR, | ||
3096 | LOG_TEMP, | ||
3097 | "0340 Adapter temperature is OK now. " | ||
3098 | "temperature : %d Celsius\n", | ||
3099 | temp); | ||
3100 | } | ||
3101 | |||
3102 | /* Send temperature change event to applications */ | ||
3103 | shost = lpfc_shost_from_vport(phba->pport); | ||
3104 | fc_host_post_vendor_event(shost, fc_get_event_number(), | ||
3105 | sizeof(temp_event_data), (char *) &temp_event_data, | ||
3106 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | ||
3107 | |||
3108 | } | ||
3109 | |||
3110 | |||
2996 | int | 3111 | int |
2997 | lpfc_sli_setup(struct lpfc_hba *phba) | 3112 | lpfc_sli_setup(struct lpfc_hba *phba) |
2998 | { | 3113 | { |
@@ -3059,6 +3174,8 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
3059 | pring->fast_iotag = 0; | 3174 | pring->fast_iotag = 0; |
3060 | pring->iotag_ctr = 0; | 3175 | pring->iotag_ctr = 0; |
3061 | pring->iotag_max = 4096; | 3176 | pring->iotag_max = 4096; |
3177 | pring->lpfc_sli_rcv_async_status = | ||
3178 | lpfc_sli_async_event_handler; | ||
3062 | pring->num_mask = 4; | 3179 | pring->num_mask = 4; |
3063 | pring->prt[0].profile = 0; /* Mask 0 */ | 3180 | pring->prt[0].profile = 0; /* Mask 0 */ |
3064 | pring->prt[0].rctl = FC_ELS_REQ; | 3181 | pring->prt[0].rctl = FC_ELS_REQ; |
@@ -3123,6 +3240,7 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba) | |||
3123 | INIT_LIST_HEAD(&pring->txq); | 3240 | INIT_LIST_HEAD(&pring->txq); |
3124 | INIT_LIST_HEAD(&pring->txcmplq); | 3241 | INIT_LIST_HEAD(&pring->txcmplq); |
3125 | INIT_LIST_HEAD(&pring->iocb_continueq); | 3242 | INIT_LIST_HEAD(&pring->iocb_continueq); |
3243 | INIT_LIST_HEAD(&pring->iocb_continue_saveq); | ||
3126 | INIT_LIST_HEAD(&pring->postbufq); | 3244 | INIT_LIST_HEAD(&pring->postbufq); |
3127 | } | 3245 | } |
3128 | spin_unlock_irq(&phba->hbalock); | 3246 | spin_unlock_irq(&phba->hbalock); |
@@ -3193,6 +3311,7 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3193 | LIST_HEAD(completions); | 3311 | LIST_HEAD(completions); |
3194 | struct lpfc_sli *psli = &phba->sli; | 3312 | struct lpfc_sli *psli = &phba->sli; |
3195 | struct lpfc_sli_ring *pring; | 3313 | struct lpfc_sli_ring *pring; |
3314 | struct lpfc_dmabuf *buf_ptr; | ||
3196 | LPFC_MBOXQ_t *pmb; | 3315 | LPFC_MBOXQ_t *pmb; |
3197 | struct lpfc_iocbq *iocb; | 3316 | struct lpfc_iocbq *iocb; |
3198 | IOCB_t *cmd = NULL; | 3317 | IOCB_t *cmd = NULL; |
@@ -3232,6 +3351,19 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3232 | } | 3351 | } |
3233 | } | 3352 | } |
3234 | 3353 | ||
3354 | spin_lock_irqsave(&phba->hbalock, flags); | ||
3355 | list_splice_init(&phba->elsbuf, &completions); | ||
3356 | phba->elsbuf_cnt = 0; | ||
3357 | phba->elsbuf_prev_cnt = 0; | ||
3358 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
3359 | |||
3360 | while (!list_empty(&completions)) { | ||
3361 | list_remove_head(&completions, buf_ptr, | ||
3362 | struct lpfc_dmabuf, list); | ||
3363 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
3364 | kfree(buf_ptr); | ||
3365 | } | ||
3366 | |||
3235 | /* Return any active mbox cmds */ | 3367 | /* Return any active mbox cmds */ |
3236 | del_timer_sync(&psli->mbox_tmo); | 3368 | del_timer_sync(&psli->mbox_tmo); |
3237 | spin_lock_irqsave(&phba->hbalock, flags); | 3369 | spin_lock_irqsave(&phba->hbalock, flags); |
@@ -3294,6 +3426,47 @@ lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3294 | return 0; | 3426 | return 0; |
3295 | } | 3427 | } |
3296 | 3428 | ||
3429 | uint32_t | ||
3430 | lpfc_sli_get_buffer_tag(struct lpfc_hba *phba) | ||
3431 | { | ||
3432 | spin_lock_irq(&phba->hbalock); | ||
3433 | phba->buffer_tag_count++; | ||
3434 | /* | ||
3435 | * Always set the QUE_BUFTAG_BIT to distiguish between | ||
3436 | * a tag assigned by HBQ. | ||
3437 | */ | ||
3438 | phba->buffer_tag_count |= QUE_BUFTAG_BIT; | ||
3439 | spin_unlock_irq(&phba->hbalock); | ||
3440 | return phba->buffer_tag_count; | ||
3441 | } | ||
3442 | |||
3443 | struct lpfc_dmabuf * | ||
3444 | lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | ||
3445 | uint32_t tag) | ||
3446 | { | ||
3447 | struct lpfc_dmabuf *mp, *next_mp; | ||
3448 | struct list_head *slp = &pring->postbufq; | ||
3449 | |||
3450 | /* Search postbufq, from the begining, looking for a match on tag */ | ||
3451 | spin_lock_irq(&phba->hbalock); | ||
3452 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { | ||
3453 | if (mp->buffer_tag == tag) { | ||
3454 | list_del_init(&mp->list); | ||
3455 | pring->postbufq_cnt--; | ||
3456 | spin_unlock_irq(&phba->hbalock); | ||
3457 | return mp; | ||
3458 | } | ||
3459 | } | ||
3460 | |||
3461 | spin_unlock_irq(&phba->hbalock); | ||
3462 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
3463 | "0410 Cannot find virtual addr for buffer tag on " | ||
3464 | "ring %d Data x%lx x%p x%p x%x\n", | ||
3465 | pring->ringno, (unsigned long) tag, | ||
3466 | slp->next, slp->prev, pring->postbufq_cnt); | ||
3467 | |||
3468 | return NULL; | ||
3469 | } | ||
3297 | 3470 | ||
3298 | struct lpfc_dmabuf * | 3471 | struct lpfc_dmabuf * |
3299 | lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 3472 | lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
@@ -3361,6 +3534,12 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3361 | pring->txcmplq_cnt--; | 3534 | pring->txcmplq_cnt--; |
3362 | spin_unlock_irq(&phba->hbalock); | 3535 | spin_unlock_irq(&phba->hbalock); |
3363 | 3536 | ||
3537 | /* Firmware could still be in progress of DMAing | ||
3538 | * payload, so don't free data buffer till after | ||
3539 | * a hbeat. | ||
3540 | */ | ||
3541 | abort_iocb->iocb_flag |= LPFC_DELAY_MEM_FREE; | ||
3542 | |||
3364 | abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; | 3543 | abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; |
3365 | abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; | 3544 | abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; |
3366 | abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED; | 3545 | abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED; |
@@ -3699,7 +3878,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, | |||
3699 | unsigned long flag; | 3878 | unsigned long flag; |
3700 | 3879 | ||
3701 | /* The caller must leave context1 empty. */ | 3880 | /* The caller must leave context1 empty. */ |
3702 | if (pmboxq->context1 != 0) | 3881 | if (pmboxq->context1) |
3703 | return MBX_NOT_FINISHED; | 3882 | return MBX_NOT_FINISHED; |
3704 | 3883 | ||
3705 | /* setup wake call as IOCB callback */ | 3884 | /* setup wake call as IOCB callback */ |
@@ -3771,7 +3950,6 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3771 | uint32_t ha_copy; | 3950 | uint32_t ha_copy; |
3772 | uint32_t work_ha_copy; | 3951 | uint32_t work_ha_copy; |
3773 | unsigned long status; | 3952 | unsigned long status; |
3774 | int i; | ||
3775 | uint32_t control; | 3953 | uint32_t control; |
3776 | 3954 | ||
3777 | MAILBOX_t *mbox, *pmbox; | 3955 | MAILBOX_t *mbox, *pmbox; |
@@ -3888,7 +4066,6 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3888 | } | 4066 | } |
3889 | 4067 | ||
3890 | if (work_ha_copy & HA_ERATT) { | 4068 | if (work_ha_copy & HA_ERATT) { |
3891 | phba->link_state = LPFC_HBA_ERROR; | ||
3892 | /* | 4069 | /* |
3893 | * There was a link/board error. Read the | 4070 | * There was a link/board error. Read the |
3894 | * status register to retrieve the error event | 4071 | * status register to retrieve the error event |
@@ -3920,7 +4097,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3920 | * Stray Mailbox Interrupt, mbxCommand <cmd> | 4097 | * Stray Mailbox Interrupt, mbxCommand <cmd> |
3921 | * mbxStatus <status> | 4098 | * mbxStatus <status> |
3922 | */ | 4099 | */ |
3923 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | | 4100 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | |
3924 | LOG_SLI, | 4101 | LOG_SLI, |
3925 | "(%d):0304 Stray Mailbox " | 4102 | "(%d):0304 Stray Mailbox " |
3926 | "Interrupt mbxCommand x%x " | 4103 | "Interrupt mbxCommand x%x " |
@@ -3928,51 +4105,60 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3928 | (vport ? vport->vpi : 0), | 4105 | (vport ? vport->vpi : 0), |
3929 | pmbox->mbxCommand, | 4106 | pmbox->mbxCommand, |
3930 | pmbox->mbxStatus); | 4107 | pmbox->mbxStatus); |
3931 | } | 4108 | /* clear mailbox attention bit */ |
3932 | phba->last_completion_time = jiffies; | 4109 | work_ha_copy &= ~HA_MBATT; |
3933 | del_timer_sync(&phba->sli.mbox_tmo); | 4110 | } else { |
3934 | 4111 | phba->last_completion_time = jiffies; | |
3935 | phba->sli.mbox_active = NULL; | 4112 | del_timer(&phba->sli.mbox_tmo); |
3936 | if (pmb->mbox_cmpl) { | ||
3937 | lpfc_sli_pcimem_bcopy(mbox, pmbox, | ||
3938 | MAILBOX_CMD_SIZE); | ||
3939 | } | ||
3940 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | ||
3941 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; | ||
3942 | 4113 | ||
3943 | lpfc_debugfs_disc_trc(vport, | 4114 | phba->sli.mbox_active = NULL; |
3944 | LPFC_DISC_TRC_MBOX_VPORT, | 4115 | if (pmb->mbox_cmpl) { |
3945 | "MBOX dflt rpi: : status:x%x rpi:x%x", | 4116 | lpfc_sli_pcimem_bcopy(mbox, pmbox, |
3946 | (uint32_t)pmbox->mbxStatus, | 4117 | MAILBOX_CMD_SIZE); |
3947 | pmbox->un.varWords[0], 0); | 4118 | } |
3948 | 4119 | if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { | |
3949 | if ( !pmbox->mbxStatus) { | 4120 | pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; |
3950 | mp = (struct lpfc_dmabuf *) | 4121 | |
3951 | (pmb->context1); | 4122 | lpfc_debugfs_disc_trc(vport, |
3952 | ndlp = (struct lpfc_nodelist *) | 4123 | LPFC_DISC_TRC_MBOX_VPORT, |
3953 | pmb->context2; | 4124 | "MBOX dflt rpi: : " |
3954 | 4125 | "status:x%x rpi:x%x", | |
3955 | /* Reg_LOGIN of dflt RPI was successful. | 4126 | (uint32_t)pmbox->mbxStatus, |
3956 | * new lets get rid of the RPI using the | 4127 | pmbox->un.varWords[0], 0); |
3957 | * same mbox buffer. | 4128 | |
3958 | */ | 4129 | if (!pmbox->mbxStatus) { |
3959 | lpfc_unreg_login(phba, vport->vpi, | 4130 | mp = (struct lpfc_dmabuf *) |
3960 | pmbox->un.varWords[0], pmb); | 4131 | (pmb->context1); |
3961 | pmb->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | 4132 | ndlp = (struct lpfc_nodelist *) |
3962 | pmb->context1 = mp; | 4133 | pmb->context2; |
3963 | pmb->context2 = ndlp; | 4134 | |
3964 | pmb->vport = vport; | 4135 | /* Reg_LOGIN of dflt RPI was |
3965 | spin_lock(&phba->hbalock); | 4136 | * successful. new lets get |
3966 | phba->sli.sli_flag &= | 4137 | * rid of the RPI using the |
3967 | ~LPFC_SLI_MBOX_ACTIVE; | 4138 | * same mbox buffer. |
3968 | spin_unlock(&phba->hbalock); | 4139 | */ |
3969 | goto send_current_mbox; | 4140 | lpfc_unreg_login(phba, |
4141 | vport->vpi, | ||
4142 | pmbox->un.varWords[0], | ||
4143 | pmb); | ||
4144 | pmb->mbox_cmpl = | ||
4145 | lpfc_mbx_cmpl_dflt_rpi; | ||
4146 | pmb->context1 = mp; | ||
4147 | pmb->context2 = ndlp; | ||
4148 | pmb->vport = vport; | ||
4149 | spin_lock(&phba->hbalock); | ||
4150 | phba->sli.sli_flag &= | ||
4151 | ~LPFC_SLI_MBOX_ACTIVE; | ||
4152 | spin_unlock(&phba->hbalock); | ||
4153 | goto send_current_mbox; | ||
4154 | } | ||
3970 | } | 4155 | } |
4156 | spin_lock(&phba->pport->work_port_lock); | ||
4157 | phba->pport->work_port_events &= | ||
4158 | ~WORKER_MBOX_TMO; | ||
4159 | spin_unlock(&phba->pport->work_port_lock); | ||
4160 | lpfc_mbox_cmpl_put(phba, pmb); | ||
3971 | } | 4161 | } |
3972 | spin_lock(&phba->pport->work_port_lock); | ||
3973 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | ||
3974 | spin_unlock(&phba->pport->work_port_lock); | ||
3975 | lpfc_mbox_cmpl_put(phba, pmb); | ||
3976 | } | 4162 | } |
3977 | if ((work_ha_copy & HA_MBATT) && | 4163 | if ((work_ha_copy & HA_MBATT) && |
3978 | (phba->sli.mbox_active == NULL)) { | 4164 | (phba->sli.mbox_active == NULL)) { |
@@ -3990,10 +4176,6 @@ send_current_mbox: | |||
3990 | lpfc_mbox_cmpl_put(phba, pmb); | 4176 | lpfc_mbox_cmpl_put(phba, pmb); |
3991 | goto send_next_mbox; | 4177 | goto send_next_mbox; |
3992 | } | 4178 | } |
3993 | } else { | ||
3994 | /* Turn on IOCB processing */ | ||
3995 | for (i = 0; i < phba->sli.num_rings; i++) | ||
3996 | lpfc_sli_turn_on_ring(phba, i); | ||
3997 | } | 4179 | } |
3998 | 4180 | ||
3999 | } | 4181 | } |