diff options
Diffstat (limited to 'arch/ia64/sn/kernel/bte_error.c')
| -rw-r--r-- | arch/ia64/sn/kernel/bte_error.c | 72 |
1 files changed, 57 insertions, 15 deletions
diff --git a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c index fcbc748ae43..4cb09f3f1ef 100644 --- a/arch/ia64/sn/kernel/bte_error.c +++ b/arch/ia64/sn/kernel/bte_error.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2007 Silicon Graphics, Inc. All Rights Reserved. */ #include <linux/types.h> @@ -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 */ @@ -78,10 +78,10 @@ void shub1_bte_error_handler(unsigned long _nodepda) * There are errors which still need to be cleaned up by * hubiio_crb_error_handler */ - mod_timer(recovery_timer, HZ * 5); + mod_timer(recovery_timer, jiffies + (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) { @@ -95,17 +95,17 @@ void shub1_bte_error_handler(unsigned long _nodepda) icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i)); if (icrbd.d_bteop) { - mod_timer(recovery_timer, HZ * 5); + mod_timer(recovery_timer, jiffies + (HZ * 5)); BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n", err_nodepda, smp_processor_id(), i)); - return; + return 1; } } } BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda, smp_processor_id())); - /* Reenable both bte interfaces */ + /* Re-enable both bte interfaces */ imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM); imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1; REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval); @@ -124,6 +124,46 @@ 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) { + bte->bh_error = BTE_SHUB2_ERROR(status); + continue; + } + if (!(status & IBLS_BUSY)) + continue; + mod_timer(recovery_timer, jiffies + (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 +175,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 +199,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++) { @@ -205,7 +247,7 @@ bte_crb_error_handler(cnodeid_t cnode, int btenum, /* * The caller has already figured out the error type, we save that - * in the bte handle structure for the thread excercising the + * in the bte handle structure for the thread exercising the * interface to consume. */ bte->bh_error = ioe->ie_errortype + BTEFAIL_OFFSET; |
