aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfa_ioc.c
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2012-03-13 20:38:56 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-03-28 04:53:45 -0400
commit8919678eaaa2988000ff79341e42b656d5ca009b (patch)
tree8503168181cd438360e9811fd48bcc48ac0061dc /drivers/scsi/bfa/bfa_ioc.c
parent1f67096ca5299ab67d06abeb4180c988960f9280 (diff)
[SCSI] bfa: Serialize the IOC hw semaphore unlock logic.
Made changes to ensure only the function that comes first will execute the IOC hw semaphore unlock logic. Used IOC init sem register to serialize execution of the unlock logic. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc.c')
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c58
1 files changed, 46 insertions, 12 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index eca7ab78085b..3164f7bec475 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -97,7 +97,6 @@ static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc);
97static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc); 97static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc);
98static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc); 98static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
99 99
100
101/* 100/*
102 * IOC state machine definitions/declarations 101 * IOC state machine definitions/declarations
103 */ 102 */
@@ -738,26 +737,60 @@ static void
738bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) 737bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf)
739{ 738{
740 struct bfi_ioc_image_hdr_s fwhdr; 739 struct bfi_ioc_image_hdr_s fwhdr;
741 u32 fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate); 740 u32 r32, fwstate, pgnum, pgoff, loff = 0;
741 int i;
742
743 /*
744 * Spin on init semaphore to serialize.
745 */
746 r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg);
747 while (r32 & 0x1) {
748 udelay(20);
749 r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg);
750 }
742 751
743 /* h/w sem init */ 752 /* h/w sem init */
744 if (fwstate == BFI_IOC_UNINIT) 753 fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate);
754 if (fwstate == BFI_IOC_UNINIT) {
755 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
745 goto sem_get; 756 goto sem_get;
757 }
746 758
747 bfa_ioc_fwver_get(iocpf->ioc, &fwhdr); 759 bfa_ioc_fwver_get(iocpf->ioc, &fwhdr);
748 760
749 if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) 761 if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) {
762 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
750 goto sem_get; 763 goto sem_get;
764 }
765
766 /*
767 * Clear fwver hdr
768 */
769 pgnum = PSS_SMEM_PGNUM(iocpf->ioc->ioc_regs.smem_pg0, loff);
770 pgoff = PSS_SMEM_PGOFF(loff);
771 writel(pgnum, iocpf->ioc->ioc_regs.host_page_num_fn);
772
773 for (i = 0; i < sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32); i++) {
774 bfa_mem_write(iocpf->ioc->ioc_regs.smem_page_start, loff, 0);
775 loff += sizeof(u32);
776 }
751 777
752 bfa_trc(iocpf->ioc, fwstate); 778 bfa_trc(iocpf->ioc, fwstate);
753 bfa_trc(iocpf->ioc, fwhdr.exec); 779 bfa_trc(iocpf->ioc, swab32(fwhdr.exec));
754 writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.ioc_fwstate); 780 writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.ioc_fwstate);
781 writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.alt_ioc_fwstate);
755 782
756 /* 783 /*
757 * Try to lock and then unlock the semaphore. 784 * Unlock the hw semaphore. Should be here only once per boot.
758 */ 785 */
759 readl(iocpf->ioc->ioc_regs.ioc_sem_reg); 786 readl(iocpf->ioc->ioc_regs.ioc_sem_reg);
760 writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg); 787 writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg);
788
789 /*
790 * unlock init semaphore.
791 */
792 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
793
761sem_get: 794sem_get:
762 bfa_ioc_hw_sem_get(iocpf->ioc); 795 bfa_ioc_hw_sem_get(iocpf->ioc);
763} 796}
@@ -1707,11 +1740,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1707 u32 i; 1740 u32 i;
1708 u32 asicmode; 1741 u32 asicmode;
1709 1742
1710 /*
1711 * Initialize LMEM first before code download
1712 */
1713 bfa_ioc_lmem_init(ioc);
1714
1715 bfa_trc(ioc, bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc))); 1743 bfa_trc(ioc, bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)));
1716 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno); 1744 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
1717 1745
@@ -1999,6 +2027,12 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
1999 bfa_ioc_pll_init_asic(ioc); 2027 bfa_ioc_pll_init_asic(ioc);
2000 2028
2001 ioc->pllinit = BFA_TRUE; 2029 ioc->pllinit = BFA_TRUE;
2030
2031 /*
2032 * Initialize LMEM
2033 */
2034 bfa_ioc_lmem_init(ioc);
2035
2002 /* 2036 /*
2003 * release semaphore. 2037 * release semaphore.
2004 */ 2038 */
@@ -4772,7 +4806,7 @@ diag_ledtest_send(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest)
4772} 4806}
4773 4807
4774static void 4808static void
4775diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s * msg) 4809diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s *msg)
4776{ 4810{
4777 bfa_trc(diag, diag->ledtest.lock); 4811 bfa_trc(diag, diag->ledtest.lock);
4778 diag->ledtest.lock = BFA_FALSE; 4812 diag->ledtest.lock = BFA_FALSE;