diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-24 23:22:56 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 17:57:52 -0400 |
commit | 5a0adaedffce91100d03fc1036dde024c8589295 (patch) | |
tree | 672bba0f2dd33eea68a492dc4567f42d16a53c4d /drivers | |
parent | 1a4d8e1bd81c018f7b8c7622066d5cfead59b38a (diff) |
[SCSI] bfa: IOC bug fixes.
- Add logic to handle the case where PCI mapping goes away when
IOCPF state machine is waiting for semaphore.
- Added logic to unlock hw semaphore if the previos FW boot was
from flash based and the current FW initialization attempt is from OS.
- Added fix to update hbfails and hb_count stats during hwerror event.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/bfa/bfa_defs.h | 2 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.c | 116 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_cb.c | 15 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_ct.c | 23 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi.h | 3 |
5 files changed, 125 insertions, 34 deletions
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index cced5874cb55..c675e65c77a4 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h | |||
@@ -274,6 +274,7 @@ enum bfa_ioc_state { | |||
274 | BFA_IOC_DISABLED = 10, /* IOC is disabled */ | 274 | BFA_IOC_DISABLED = 10, /* IOC is disabled */ |
275 | BFA_IOC_FWMISMATCH = 11, /* IOC f/w different from drivers */ | 275 | BFA_IOC_FWMISMATCH = 11, /* IOC f/w different from drivers */ |
276 | BFA_IOC_ENABLING = 12, /* IOC is being enabled */ | 276 | BFA_IOC_ENABLING = 12, /* IOC is being enabled */ |
277 | BFA_IOC_HWFAIL = 13, /* PCI mapping doesn't exist */ | ||
277 | }; | 278 | }; |
278 | 279 | ||
279 | /* | 280 | /* |
@@ -303,6 +304,7 @@ struct bfa_ioc_drv_stats_s { | |||
303 | u32 enable_reqs; | 304 | u32 enable_reqs; |
304 | u32 disable_replies; | 305 | u32 disable_replies; |
305 | u32 enable_replies; | 306 | u32 enable_replies; |
307 | u32 rsvd; | ||
306 | }; | 308 | }; |
307 | 309 | ||
308 | /* | 310 | /* |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 2c575f5dea04..931bf9769ff2 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -112,6 +112,7 @@ enum ioc_event { | |||
112 | IOC_E_HBFAIL = 9, /* heartbeat failure */ | 112 | IOC_E_HBFAIL = 9, /* heartbeat failure */ |
113 | IOC_E_HWERROR = 10, /* hardware error interrupt */ | 113 | IOC_E_HWERROR = 10, /* hardware error interrupt */ |
114 | IOC_E_TIMEOUT = 11, /* timeout */ | 114 | IOC_E_TIMEOUT = 11, /* timeout */ |
115 | IOC_E_HWFAILED = 12, /* PCI mapping failure notice */ | ||
115 | }; | 116 | }; |
116 | 117 | ||
117 | bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); | 118 | bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); |
@@ -123,6 +124,7 @@ bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event); | |||
123 | bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event); | 124 | bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event); |
124 | bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); | 125 | bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); |
125 | bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); | 126 | bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); |
127 | bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event); | ||
126 | 128 | ||
127 | static struct bfa_sm_table_s ioc_sm_table[] = { | 129 | static struct bfa_sm_table_s ioc_sm_table[] = { |
128 | {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, | 130 | {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, |
@@ -134,6 +136,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = { | |||
134 | {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, | 136 | {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, |
135 | {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, | 137 | {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, |
136 | {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, | 138 | {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, |
139 | {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL}, | ||
137 | }; | 140 | }; |
138 | 141 | ||
139 | /* | 142 | /* |
@@ -176,6 +179,7 @@ enum iocpf_event { | |||
176 | IOCPF_E_GETATTRFAIL = 9, /* init fail notice by ioc sm */ | 179 | IOCPF_E_GETATTRFAIL = 9, /* init fail notice by ioc sm */ |
177 | IOCPF_E_SEMLOCKED = 10, /* h/w semaphore is locked */ | 180 | IOCPF_E_SEMLOCKED = 10, /* h/w semaphore is locked */ |
178 | IOCPF_E_TIMEOUT = 11, /* f/w response timeout */ | 181 | IOCPF_E_TIMEOUT = 11, /* f/w response timeout */ |
182 | IOCPF_E_SEM_ERROR = 12, /* h/w sem mapping error */ | ||
179 | }; | 183 | }; |
180 | 184 | ||
181 | /* | 185 | /* |
@@ -322,6 +326,11 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
322 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); | 326 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); |
323 | break; | 327 | break; |
324 | 328 | ||
329 | case IOC_E_HWFAILED: | ||
330 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); | ||
331 | bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); | ||
332 | break; | ||
333 | |||
325 | case IOC_E_DISABLE: | 334 | case IOC_E_DISABLE: |
326 | bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); | 335 | bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); |
327 | break; | 336 | break; |
@@ -465,6 +474,11 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
465 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); | 474 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); |
466 | break; | 475 | break; |
467 | 476 | ||
477 | case IOC_E_HWFAILED: | ||
478 | bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); | ||
479 | bfa_ioc_disable_comp(ioc); | ||
480 | break; | ||
481 | |||
468 | default: | 482 | default: |
469 | bfa_sm_fault(ioc, event); | 483 | bfa_sm_fault(ioc, event); |
470 | } | 484 | } |
@@ -534,6 +548,11 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
534 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); | 548 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); |
535 | break; | 549 | break; |
536 | 550 | ||
551 | case IOC_E_HWFAILED: | ||
552 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); | ||
553 | bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); | ||
554 | break; | ||
555 | |||
537 | case IOC_E_ENABLE: | 556 | case IOC_E_ENABLE: |
538 | break; | 557 | break; |
539 | 558 | ||
@@ -591,6 +610,35 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
591 | } | 610 | } |
592 | } | 611 | } |
593 | 612 | ||
613 | static void | ||
614 | bfa_ioc_sm_hwfail_entry(struct bfa_ioc_s *ioc) | ||
615 | { | ||
616 | bfa_trc(ioc, 0); | ||
617 | } | ||
618 | |||
619 | static void | ||
620 | bfa_ioc_sm_hwfail(struct bfa_ioc_s *ioc, enum ioc_event event) | ||
621 | { | ||
622 | bfa_trc(ioc, event); | ||
623 | |||
624 | switch (event) { | ||
625 | case IOC_E_ENABLE: | ||
626 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); | ||
627 | break; | ||
628 | |||
629 | case IOC_E_DISABLE: | ||
630 | ioc->cbfn->disable_cbfn(ioc->bfa); | ||
631 | break; | ||
632 | |||
633 | case IOC_E_DETACH: | ||
634 | bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); | ||
635 | break; | ||
636 | |||
637 | default: | ||
638 | bfa_sm_fault(ioc, event); | ||
639 | } | ||
640 | } | ||
641 | |||
594 | /* | 642 | /* |
595 | * IOCPF State Machine | 643 | * IOCPF State Machine |
596 | */ | 644 | */ |
@@ -634,6 +682,28 @@ bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
634 | static void | 682 | static void |
635 | bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) | 683 | bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) |
636 | { | 684 | { |
685 | struct bfi_ioc_image_hdr_s fwhdr; | ||
686 | u32 fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate); | ||
687 | |||
688 | /* h/w sem init */ | ||
689 | if (fwstate == BFI_IOC_UNINIT) | ||
690 | goto sem_get; | ||
691 | |||
692 | bfa_ioc_fwver_get(iocpf->ioc, &fwhdr); | ||
693 | |||
694 | if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) | ||
695 | goto sem_get; | ||
696 | |||
697 | bfa_trc(iocpf->ioc, fwstate); | ||
698 | bfa_trc(iocpf->ioc, fwhdr.exec); | ||
699 | writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.ioc_fwstate); | ||
700 | |||
701 | /* | ||
702 | * Try to lock and then unlock the semaphore. | ||
703 | */ | ||
704 | readl(iocpf->ioc->ioc_regs.ioc_sem_reg); | ||
705 | writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg); | ||
706 | sem_get: | ||
637 | bfa_ioc_hw_sem_get(iocpf->ioc); | 707 | bfa_ioc_hw_sem_get(iocpf->ioc); |
638 | } | 708 | } |
639 | 709 | ||
@@ -664,6 +734,11 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
664 | } | 734 | } |
665 | break; | 735 | break; |
666 | 736 | ||
737 | case IOCPF_E_SEM_ERROR: | ||
738 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); | ||
739 | bfa_fsm_send_event(ioc, IOC_E_HWFAILED); | ||
740 | break; | ||
741 | |||
667 | case IOCPF_E_DISABLE: | 742 | case IOCPF_E_DISABLE: |
668 | bfa_sem_timer_stop(ioc); | 743 | bfa_sem_timer_stop(ioc); |
669 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); | 744 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); |
@@ -757,6 +832,11 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
757 | } | 832 | } |
758 | break; | 833 | break; |
759 | 834 | ||
835 | case IOCPF_E_SEM_ERROR: | ||
836 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); | ||
837 | bfa_fsm_send_event(ioc, IOC_E_HWFAILED); | ||
838 | break; | ||
839 | |||
760 | case IOCPF_E_DISABLE: | 840 | case IOCPF_E_DISABLE: |
761 | bfa_sem_timer_stop(ioc); | 841 | bfa_sem_timer_stop(ioc); |
762 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); | 842 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); |
@@ -957,6 +1037,11 @@ bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
957 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); | 1037 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); |
958 | break; | 1038 | break; |
959 | 1039 | ||
1040 | case IOCPF_E_SEM_ERROR: | ||
1041 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); | ||
1042 | bfa_fsm_send_event(ioc, IOC_E_HWFAILED); | ||
1043 | break; | ||
1044 | |||
960 | case IOCPF_E_FAIL: | 1045 | case IOCPF_E_FAIL: |
961 | break; | 1046 | break; |
962 | 1047 | ||
@@ -1000,6 +1085,7 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1000 | static void | 1085 | static void |
1001 | bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf) | 1086 | bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf) |
1002 | { | 1087 | { |
1088 | bfa_ioc_debug_save_ftrc(iocpf->ioc); | ||
1003 | bfa_ioc_hw_sem_get(iocpf->ioc); | 1089 | bfa_ioc_hw_sem_get(iocpf->ioc); |
1004 | } | 1090 | } |
1005 | 1091 | ||
@@ -1022,6 +1108,11 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1022 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); | 1108 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); |
1023 | break; | 1109 | break; |
1024 | 1110 | ||
1111 | case IOCPF_E_SEM_ERROR: | ||
1112 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); | ||
1113 | bfa_fsm_send_event(ioc, IOC_E_HWFAILED); | ||
1114 | break; | ||
1115 | |||
1025 | case IOCPF_E_DISABLE: | 1116 | case IOCPF_E_DISABLE: |
1026 | bfa_sem_timer_stop(ioc); | 1117 | bfa_sem_timer_stop(ioc); |
1027 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); | 1118 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); |
@@ -1044,6 +1135,7 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1044 | static void | 1135 | static void |
1045 | bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf) | 1136 | bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf) |
1046 | { | 1137 | { |
1138 | bfa_trc(iocpf->ioc, 0); | ||
1047 | } | 1139 | } |
1048 | 1140 | ||
1049 | /* | 1141 | /* |
@@ -1113,6 +1205,11 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1113 | } | 1205 | } |
1114 | break; | 1206 | break; |
1115 | 1207 | ||
1208 | case IOCPF_E_SEM_ERROR: | ||
1209 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); | ||
1210 | bfa_fsm_send_event(ioc, IOC_E_HWFAILED); | ||
1211 | break; | ||
1212 | |||
1116 | case IOCPF_E_DISABLE: | 1213 | case IOCPF_E_DISABLE: |
1117 | bfa_sem_timer_stop(ioc); | 1214 | bfa_sem_timer_stop(ioc); |
1118 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); | 1215 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); |
@@ -1129,6 +1226,7 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) | |||
1129 | static void | 1226 | static void |
1130 | bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf) | 1227 | bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf) |
1131 | { | 1228 | { |
1229 | bfa_trc(iocpf->ioc, 0); | ||
1132 | } | 1230 | } |
1133 | 1231 | ||
1134 | /* | 1232 | /* |
@@ -1195,7 +1293,6 @@ bfa_ioc_sem_get(void __iomem *sem_reg) | |||
1195 | if (!(r32 & 1)) | 1293 | if (!(r32 & 1)) |
1196 | return BFA_TRUE; | 1294 | return BFA_TRUE; |
1197 | 1295 | ||
1198 | WARN_ON(cnt >= BFA_SEM_SPINCNT); | ||
1199 | return BFA_FALSE; | 1296 | return BFA_FALSE; |
1200 | } | 1297 | } |
1201 | 1298 | ||
@@ -1209,6 +1306,11 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) | |||
1209 | * will return 1. Semaphore is released by writing 1 to the register | 1306 | * will return 1. Semaphore is released by writing 1 to the register |
1210 | */ | 1307 | */ |
1211 | r32 = readl(ioc->ioc_regs.ioc_sem_reg); | 1308 | r32 = readl(ioc->ioc_regs.ioc_sem_reg); |
1309 | if (r32 == ~0) { | ||
1310 | WARN_ON(r32 == ~0); | ||
1311 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR); | ||
1312 | return; | ||
1313 | } | ||
1212 | if (!(r32 & 1)) { | 1314 | if (!(r32 & 1)) { |
1213 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); | 1315 | bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); |
1214 | return; | 1316 | return; |
@@ -1617,6 +1719,7 @@ bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc) | |||
1617 | attr->adapter_prop = be32_to_cpu(attr->adapter_prop); | 1719 | attr->adapter_prop = be32_to_cpu(attr->adapter_prop); |
1618 | attr->card_type = be32_to_cpu(attr->card_type); | 1720 | attr->card_type = be32_to_cpu(attr->card_type); |
1619 | attr->maxfrsize = be16_to_cpu(attr->maxfrsize); | 1721 | attr->maxfrsize = be16_to_cpu(attr->maxfrsize); |
1722 | ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC); | ||
1620 | 1723 | ||
1621 | bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); | 1724 | bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); |
1622 | } | 1725 | } |
@@ -1733,6 +1836,7 @@ bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz) | |||
1733 | /* | 1836 | /* |
1734 | * release semaphore. | 1837 | * release semaphore. |
1735 | */ | 1838 | */ |
1839 | readl(ioc->ioc_regs.ioc_init_sem_reg); | ||
1736 | writel(1, ioc->ioc_regs.ioc_init_sem_reg); | 1840 | writel(1, ioc->ioc_regs.ioc_init_sem_reg); |
1737 | 1841 | ||
1738 | bfa_trc(ioc, pgnum); | 1842 | bfa_trc(ioc, pgnum); |
@@ -1789,6 +1893,7 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz) | |||
1789 | /* | 1893 | /* |
1790 | * release semaphore. | 1894 | * release semaphore. |
1791 | */ | 1895 | */ |
1896 | readl(ioc->ioc_regs.ioc_init_sem_reg); | ||
1792 | writel(1, ioc->ioc_regs.ioc_init_sem_reg); | 1897 | writel(1, ioc->ioc_regs.ioc_init_sem_reg); |
1793 | bfa_trc(ioc, pgnum); | 1898 | bfa_trc(ioc, pgnum); |
1794 | return BFA_STATUS_OK; | 1899 | return BFA_STATUS_OK; |
@@ -1840,6 +1945,7 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc) | |||
1840 | /* | 1945 | /* |
1841 | * release semaphore. | 1946 | * release semaphore. |
1842 | */ | 1947 | */ |
1948 | readl(ioc->ioc_regs.ioc_init_sem_reg); | ||
1843 | writel(1, ioc->ioc_regs.ioc_init_sem_reg); | 1949 | writel(1, ioc->ioc_regs.ioc_init_sem_reg); |
1844 | 1950 | ||
1845 | return BFA_STATUS_OK; | 1951 | return BFA_STATUS_OK; |
@@ -2232,6 +2338,8 @@ bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc) | |||
2232 | void | 2338 | void |
2233 | bfa_ioc_error_isr(struct bfa_ioc_s *ioc) | 2339 | bfa_ioc_error_isr(struct bfa_ioc_s *ioc) |
2234 | { | 2340 | { |
2341 | bfa_ioc_stats(ioc, ioc_hbfails); | ||
2342 | ioc->stats.hb_count = ioc->hb_count; | ||
2235 | bfa_fsm_send_event(ioc, IOC_E_HWERROR); | 2343 | bfa_fsm_send_event(ioc, IOC_E_HWERROR); |
2236 | } | 2344 | } |
2237 | 2345 | ||
@@ -2354,15 +2462,12 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, | |||
2354 | enum bfa_ioc_type_e | 2462 | enum bfa_ioc_type_e |
2355 | bfa_ioc_get_type(struct bfa_ioc_s *ioc) | 2463 | bfa_ioc_get_type(struct bfa_ioc_s *ioc) |
2356 | { | 2464 | { |
2357 | enum bfi_port_mode mode; | ||
2358 | |||
2359 | if (ioc->clscode == BFI_PCIFN_CLASS_ETH) | 2465 | if (ioc->clscode == BFI_PCIFN_CLASS_ETH) |
2360 | return BFA_IOC_TYPE_LL; | 2466 | return BFA_IOC_TYPE_LL; |
2361 | 2467 | ||
2362 | WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC); | 2468 | WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC); |
2363 | 2469 | ||
2364 | mode = (ioc->port_id == 0) ? ioc->port0_mode : ioc->port1_mode; | 2470 | return (ioc->attr->port_mode == BFI_PORT_MODE_FC) |
2365 | return (mode == BFI_PORT_MODE_FC) | ||
2366 | ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE; | 2471 | ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE; |
2367 | } | 2472 | } |
2368 | 2473 | ||
@@ -2739,6 +2844,7 @@ static void | |||
2739 | bfa_ioc_recover(struct bfa_ioc_s *ioc) | 2844 | bfa_ioc_recover(struct bfa_ioc_s *ioc) |
2740 | { | 2845 | { |
2741 | bfa_ioc_stats(ioc, ioc_hbfails); | 2846 | bfa_ioc_stats(ioc, ioc_hbfails); |
2847 | ioc->stats.hb_count = ioc->hb_count; | ||
2742 | bfa_fsm_send_event(ioc, IOC_E_HBFAIL); | 2848 | bfa_fsm_send_event(ioc, IOC_E_HBFAIL); |
2743 | } | 2849 | } |
2744 | 2850 | ||
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index e858bc0c48d0..30df8a284715 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c | |||
@@ -69,21 +69,6 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc) | |||
69 | static bfa_boolean_t | 69 | static bfa_boolean_t |
70 | bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc) | 70 | bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc) |
71 | { | 71 | { |
72 | struct bfi_ioc_image_hdr_s fwhdr; | ||
73 | uint32_t fwstate = readl(ioc->ioc_regs.ioc_fwstate); | ||
74 | |||
75 | if (fwstate == BFI_IOC_UNINIT) | ||
76 | return BFA_TRUE; | ||
77 | |||
78 | bfa_ioc_fwver_get(ioc, &fwhdr); | ||
79 | |||
80 | if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) | ||
81 | return BFA_TRUE; | ||
82 | |||
83 | bfa_trc(ioc, fwstate); | ||
84 | bfa_trc(ioc, fwhdr.exec); | ||
85 | writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); | ||
86 | |||
87 | return BFA_TRUE; | 72 | return BFA_TRUE; |
88 | } | 73 | } |
89 | 74 | ||
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 5b5579401d43..216016c50d11 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c | |||
@@ -58,12 +58,6 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) | |||
58 | struct bfi_ioc_image_hdr_s fwhdr; | 58 | struct bfi_ioc_image_hdr_s fwhdr; |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Firmware match check is relevant only for CNA. | ||
62 | */ | ||
63 | if (!bfa_ioc_is_cna(ioc)) | ||
64 | return BFA_TRUE; | ||
65 | |||
66 | /* | ||
67 | * If bios boot (flash based) -- do not increment usage count | 61 | * If bios boot (flash based) -- do not increment usage count |
68 | */ | 62 | */ |
69 | if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) < | 63 | if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) < |
@@ -78,6 +72,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) | |||
78 | */ | 72 | */ |
79 | if (usecnt == 0) { | 73 | if (usecnt == 0) { |
80 | writel(1, ioc->ioc_regs.ioc_usage_reg); | 74 | writel(1, ioc->ioc_regs.ioc_usage_reg); |
75 | readl(ioc->ioc_regs.ioc_usage_sem_reg); | ||
81 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); | 76 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); |
82 | writel(0, ioc->ioc_regs.ioc_fail_sync); | 77 | writel(0, ioc->ioc_regs.ioc_fail_sync); |
83 | bfa_trc(ioc, usecnt); | 78 | bfa_trc(ioc, usecnt); |
@@ -97,6 +92,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) | |||
97 | */ | 92 | */ |
98 | bfa_ioc_fwver_get(ioc, &fwhdr); | 93 | bfa_ioc_fwver_get(ioc, &fwhdr); |
99 | if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { | 94 | if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { |
95 | readl(ioc->ioc_regs.ioc_usage_sem_reg); | ||
100 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); | 96 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); |
101 | bfa_trc(ioc, usecnt); | 97 | bfa_trc(ioc, usecnt); |
102 | return BFA_FALSE; | 98 | return BFA_FALSE; |
@@ -107,6 +103,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) | |||
107 | */ | 103 | */ |
108 | usecnt++; | 104 | usecnt++; |
109 | writel(usecnt, ioc->ioc_regs.ioc_usage_reg); | 105 | writel(usecnt, ioc->ioc_regs.ioc_usage_reg); |
106 | readl(ioc->ioc_regs.ioc_usage_sem_reg); | ||
110 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); | 107 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); |
111 | bfa_trc(ioc, usecnt); | 108 | bfa_trc(ioc, usecnt); |
112 | return BFA_TRUE; | 109 | return BFA_TRUE; |
@@ -118,12 +115,6 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) | |||
118 | u32 usecnt; | 115 | u32 usecnt; |
119 | 116 | ||
120 | /* | 117 | /* |
121 | * Firmware lock is relevant only for CNA. | ||
122 | */ | ||
123 | if (!bfa_ioc_is_cna(ioc)) | ||
124 | return; | ||
125 | |||
126 | /* | ||
127 | * If bios boot (flash based) -- do not decrement usage count | 118 | * If bios boot (flash based) -- do not decrement usage count |
128 | */ | 119 | */ |
129 | if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) < | 120 | if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) < |
@@ -141,6 +132,7 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) | |||
141 | writel(usecnt, ioc->ioc_regs.ioc_usage_reg); | 132 | writel(usecnt, ioc->ioc_regs.ioc_usage_reg); |
142 | bfa_trc(ioc, usecnt); | 133 | bfa_trc(ioc, usecnt); |
143 | 134 | ||
135 | readl(ioc->ioc_regs.ioc_usage_sem_reg); | ||
144 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); | 136 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); |
145 | } | 137 | } |
146 | 138 | ||
@@ -344,7 +336,11 @@ bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc) | |||
344 | static void | 336 | static void |
345 | bfa_ioc_ct2_map_port(struct bfa_ioc_s *ioc) | 337 | bfa_ioc_ct2_map_port(struct bfa_ioc_s *ioc) |
346 | { | 338 | { |
347 | ioc->port_id = bfa_ioc_pcifn(ioc) % 2; | 339 | void __iomem *rb = ioc->pcidev.pci_bar_kva; |
340 | u32 r32; | ||
341 | |||
342 | r32 = readl(rb + CT2_HOSTFN_PERSONALITY0); | ||
343 | ioc->port_id = ((r32 & __FC_LL_PORT_MAP__MK) >> __FC_LL_PORT_MAP__SH); | ||
348 | 344 | ||
349 | bfa_trc(ioc, bfa_ioc_pcifn(ioc)); | 345 | bfa_trc(ioc, bfa_ioc_pcifn(ioc)); |
350 | bfa_trc(ioc, ioc->port_id); | 346 | bfa_trc(ioc, ioc->port_id); |
@@ -407,6 +403,7 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) | |||
407 | if (bfa_ioc_is_cna(ioc)) { | 403 | if (bfa_ioc_is_cna(ioc)) { |
408 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | 404 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); |
409 | writel(0, ioc->ioc_regs.ioc_usage_reg); | 405 | writel(0, ioc->ioc_regs.ioc_usage_reg); |
406 | readl(ioc->ioc_regs.ioc_usage_sem_reg); | ||
410 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); | 407 | writel(1, ioc->ioc_regs.ioc_usage_sem_reg); |
411 | } | 408 | } |
412 | 409 | ||
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index d28c7c55a60c..02e445612546 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h | |||
@@ -236,7 +236,8 @@ struct bfi_ioc_attr_s { | |||
236 | wwn_t mfg_pwwn; /* Mfg port wwn */ | 236 | wwn_t mfg_pwwn; /* Mfg port wwn */ |
237 | wwn_t mfg_nwwn; /* Mfg node wwn */ | 237 | wwn_t mfg_nwwn; /* Mfg node wwn */ |
238 | mac_t mfg_mac; /* Mfg mac */ | 238 | mac_t mfg_mac; /* Mfg mac */ |
239 | u16 rsvd_a; | 239 | u8 port_mode; /* bfi_port_mode */ |
240 | u8 rsvd_a; | ||
240 | wwn_t pwwn; | 241 | wwn_t pwwn; |
241 | wwn_t nwwn; | 242 | wwn_t nwwn; |
242 | mac_t mac; /* PBC or Mfg mac */ | 243 | mac_t mac; /* PBC or Mfg mac */ |