[IA64-SGI] Altix BTE error handling fixes
Russ Anderson [Fri, 16 Dec 2005 23:19:01 +0000 (17:19 -0600)]
Altix (shub2) pushes the BTE clean-up into SAL.
This patch correctly interfaces with the now implemented SAL call.
It also fixes a bug when delaying clean-up to allow busy BTEs to
complete (or error out).

Signed-off-by: Russ Anderson <rja@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>

arch/ia64/sn/kernel/bte_error.c
arch/ia64/sn/kernel/huberror.c
include/asm-ia64/sn/sn_sal.h

index fcbc748..f1ec137 100644 (file)
@@ -33,7 +33,7 @@ void bte_error_handler(unsigned long);
  * Wait until all BTE related CRBs are completed
  * and then reset the interfaces.
  */
-void shub1_bte_error_handler(unsigned long _nodepda)
+int shub1_bte_error_handler(unsigned long _nodepda)
 {
        struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
        struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
@@ -53,7 +53,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
            (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) {
                BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda,
                            smp_processor_id()));
-               return;
+               return 1;
        }
 
        /* Determine information about our hub */
@@ -81,7 +81,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
                mod_timer(recovery_timer, HZ * 5);
                BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
                            smp_processor_id()));
-               return;
+               return 1;
        }
        if (icmr.ii_icmr_fld_s.i_crb_vld != 0) {
 
@@ -99,7 +99,7 @@ void shub1_bte_error_handler(unsigned long _nodepda)
                                BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
                                            err_nodepda, smp_processor_id(),
                                            i));
-                               return;
+                               return 1;
                        }
                }
        }
@@ -124,6 +124,42 @@ void shub1_bte_error_handler(unsigned long _nodepda)
        REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval);
 
        del_timer(recovery_timer);
+       return 0;
+}
+
+/*
+ * Wait until all BTE related CRBs are completed
+ * and then reset the interfaces.
+ */
+int shub2_bte_error_handler(unsigned long _nodepda)
+{
+       struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
+       struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
+       struct bteinfo_s *bte;
+       nasid_t nasid;
+       u64 status;
+       int i;
+
+       nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
+
+       /*
+        * Verify that all the BTEs are complete
+        */
+       for (i = 0; i < BTES_PER_NODE; i++) {
+               bte = &err_nodepda->bte_if[i];
+               status = BTE_LNSTAT_LOAD(bte);
+               if ((status & IBLS_ERROR) || !(status & IBLS_BUSY))
+                       continue;
+               mod_timer(recovery_timer, HZ * 5);
+               BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
+                           smp_processor_id()));
+               return 1;
+       }
+       if (ia64_sn_bte_recovery(nasid))
+               panic("bte_error_handler(): Fatal BTE Error");
+
+       del_timer(recovery_timer);
+       return 0;
 }
 
 /*
@@ -135,7 +171,6 @@ void bte_error_handler(unsigned long _nodepda)
        struct nodepda_s *err_nodepda = (struct nodepda_s *)_nodepda;
        spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock;
        int i;
-       nasid_t nasid;
        unsigned long irq_flags;
        volatile u64 *notify;
        bte_result_t bh_error;
@@ -160,12 +195,15 @@ void bte_error_handler(unsigned long _nodepda)
        }
 
        if (is_shub1()) {
-               shub1_bte_error_handler(_nodepda);
+               if (shub1_bte_error_handler(_nodepda)) {
+                       spin_unlock_irqrestore(recovery_lock, irq_flags);
+                       return;
+               }
        } else {
-               nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
-
-               if (ia64_sn_bte_recovery(nasid))
-                       panic("bte_error_handler(): Fatal BTE Error");
+               if (shub2_bte_error_handler(_nodepda)) {
+                       spin_unlock_irqrestore(recovery_lock, irq_flags);
+                       return;
+               }
        }
 
        for (i = 0; i < BTES_PER_NODE; i++) {
index 5c5eb01..56ab6ba 100644 (file)
@@ -32,13 +32,14 @@ static irqreturn_t hub_eint_handler(int irq, void *arg, struct pt_regs *ep)
        ret_stuff.v0 = 0;
        hubdev_info = (struct hubdev_info *)arg;
        nasid = hubdev_info->hdi_nasid;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
+
+       if (is_shub1()) {
+               SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
                        (u64) nasid, 0, 0, 0, 0, 0, 0);
 
-       if ((int)ret_stuff.v0)
-               panic("hubii_eint_handler(): Fatal TIO Error");
+               if ((int)ret_stuff.v0)
+                       panic("hubii_eint_handler(): Fatal TIO Error");
 
-       if (is_shub1()) {
                if (!(nasid & 1)) /* Not a TIO, handle CRB errors */
                        (void)hubiio_crb_error_handler(hubdev_info);
        } else 
index 2a8b0d9..4363ed3 100644 (file)
@@ -1100,7 +1100,7 @@ ia64_sn_bte_recovery(nasid_t nasid)
        struct ia64_sal_retval rv;
 
        rv.status = 0;
-       SAL_CALL_NOLOCK(rv, SN_SAL_BTE_RECOVER, 0, 0, 0, 0, 0, 0, 0);
+       SAL_CALL_NOLOCK(rv, SN_SAL_BTE_RECOVER, (u64)nasid, 0, 0, 0, 0, 0, 0);
        if (rv.status == SALRET_NOT_IMPLEMENTED)
                return 0;
        return (int) rv.status;