]> Pileus Git - ~andy/linux/commitdiff
[SCSI] bfa: Clear LL_HALT and PSS_ERR bit when IOC crashes.
authorKrishna Gudipati <kgudipat@brocade.com>
Sat, 6 Mar 2010 03:34:44 +0000 (19:34 -0800)
committerJames Bottomley <James.Bottomley@suse.de>
Sun, 7 Mar 2010 07:23:53 +0000 (12:53 +0530)
Clear LL_HALT and PSS_ERR bit in the interrupt status register on an IOC crash.

Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/bfa/bfa_intr.c
drivers/scsi/bfa/bfa_ioc.h
drivers/scsi/bfa/bfa_ioc_cb.c
drivers/scsi/bfa/bfa_ioc_ct.c
drivers/scsi/bfa/include/bfi/bfi_cbreg.h
drivers/scsi/bfa/include/bfi/bfi_ctreg.h

index ab463db11144cfcb2fb1f246180da89c8d2879f5..c42254613f7343c816e7dcfa5fcd6e2c35196cca 100644 (file)
@@ -197,17 +197,44 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
 void
 bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
 {
-       u32 intr;
+       u32 intr, curr_value;
 
        intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
 
        if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
                bfa_msix_lpu(bfa);
 
-       if (intr & (__HFN_INT_ERR_EMC |
-                   __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 |
-                   __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT))
+       intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
+               __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
+
+       if (intr) {
+               if (intr & __HFN_INT_LL_HALT) {
+                       /**
+                        * If LL_HALT bit is set then FW Init Halt LL Port
+                        * Register needs to be cleared as well so Interrupt
+                        * Status Register will be cleared.
+                        */
+                       curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt);
+                       curr_value &= ~__FW_INIT_HALT_P;
+                       bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value);
+               }
+
+               if (intr & __HFN_INT_ERR_PSS) {
+                       /**
+                        * ERR_PSS bit needs to be cleared as well in case
+                        * interrups are shared so driver's interrupt handler is
+                        * still called eventhough it is already masked out.
+                        */
+                       curr_value = bfa_reg_read(
+                               bfa->ioc.ioc_regs.pss_err_status_reg);
+                       curr_value &= __PSS_ERR_STATUS_SET;
+                       bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg,
+                               curr_value);
+               }
+
+               bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr);
                bfa_msix_errint(bfa, intr);
+       }
 }
 
 void
index 1633a50187f7eb5bdda9d81af684c01847ae1778..853cc3136f0ee6a573eccc4c7f64026c90bf478b 100644 (file)
@@ -74,6 +74,7 @@ struct bfa_ioc_regs_s {
        bfa_os_addr_t   lpu_mbox_cmd;
        bfa_os_addr_t   lpu_mbox;
        bfa_os_addr_t   pss_ctl_reg;
+       bfa_os_addr_t   pss_err_status_reg;
        bfa_os_addr_t   app_pll_fast_ctl_reg;
        bfa_os_addr_t   app_pll_slow_ctl_reg;
        bfa_os_addr_t   ioc_sem_reg;
index d1d625bcd72170c3ef2cfb697377ca4af18d0707..1fa052ef9ce0ce6a849e25b4dbb9c5375a2219e0 100644 (file)
@@ -145,6 +145,7 @@ bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
         * PSS control registers
         */
        ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+       ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
        ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG);
        ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG);
 
index 5de9c24efacfff7395f80ed5c5a66c6da5760999..0430edd2e011c048dba16e1adbb3b0e900f78a62 100644 (file)
@@ -237,6 +237,7 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
         * PSS control registers
         */
        ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+       ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
        ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
        ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
 
index 781cefafb6595bf11f1d2bb8aa56ac5d47cdc98f..a51ee61ddb19d2b7bd59b72f250c12fbde3ead75 100644 (file)
 #define __PSS_LMEM_INIT_EN               0x00000100
 #define __PSS_LPU1_RESET                 0x00000002
 #define __PSS_LPU0_RESET                 0x00000001
+#define PSS_ERR_STATUS_REG              0x00018810
+#define __PSS_LMEM1_CORR_ERR            0x00000800
+#define __PSS_LMEM0_CORR_ERR             0x00000400
+#define __PSS_LMEM1_UNCORR_ERR           0x00000200
+#define __PSS_LMEM0_UNCORR_ERR           0x00000100
+#define __PSS_BAL_PERR                   0x00000080
+#define __PSS_DIP_IF_ERR                 0x00000040
+#define __PSS_IOH_IF_ERR                 0x00000020
+#define __PSS_TDS_IF_ERR                 0x00000010
+#define __PSS_RDS_IF_ERR                 0x00000008
+#define __PSS_SGM_IF_ERR                 0x00000004
+#define __PSS_LPU1_RAM_ERR               0x00000002
+#define __PSS_LPU0_RAM_ERR               0x00000001
 #define ERR_SET_REG                     0x00018818
 #define __PSS_ERR_STATUS_SET            0x00000fff
 
index d84ebae70cb4a0b34ba73df3134abe77b8766cf8..57a8497105af6c21c31a8d9dac97c61a5328ed85 100644 (file)
@@ -430,6 +430,29 @@ enum {
 #define __PSS_LMEM_INIT_EN               0x00000100
 #define __PSS_LPU1_RESET                 0x00000002
 #define __PSS_LPU0_RESET                 0x00000001
+#define PSS_ERR_STATUS_REG               0x00018810
+#define __PSS_LPU1_TCM_READ_ERR          0x00200000
+#define __PSS_LPU0_TCM_READ_ERR          0x00100000
+#define __PSS_LMEM5_CORR_ERR             0x00080000
+#define __PSS_LMEM4_CORR_ERR             0x00040000
+#define __PSS_LMEM3_CORR_ERR             0x00020000
+#define __PSS_LMEM2_CORR_ERR             0x00010000
+#define __PSS_LMEM1_CORR_ERR             0x00008000
+#define __PSS_LMEM0_CORR_ERR             0x00004000
+#define __PSS_LMEM5_UNCORR_ERR           0x00002000
+#define __PSS_LMEM4_UNCORR_ERR           0x00001000
+#define __PSS_LMEM3_UNCORR_ERR           0x00000800
+#define __PSS_LMEM2_UNCORR_ERR           0x00000400
+#define __PSS_LMEM1_UNCORR_ERR           0x00000200
+#define __PSS_LMEM0_UNCORR_ERR           0x00000100
+#define __PSS_BAL_PERR                   0x00000080
+#define __PSS_DIP_IF_ERR                 0x00000040
+#define __PSS_IOH_IF_ERR                 0x00000020
+#define __PSS_TDS_IF_ERR                 0x00000010
+#define __PSS_RDS_IF_ERR                 0x00000008
+#define __PSS_SGM_IF_ERR                 0x00000004
+#define __PSS_LPU1_RAM_ERR               0x00000002
+#define __PSS_LPU0_RAM_ERR               0x00000001
 #define ERR_SET_REG                     0x00018818
 #define __PSS_ERR_STATUS_SET            0x003fffff
 #define HQM_QSET0_RXQ_DRBL_P0            0x00038000