commit d824e5bcfec6e1f475be2b740219811313fea2a1 Author: Jiri Slaby Date: Sat Jun 23 14:07:48 2007 +0200 isr cleanup diff --git a/ath/if_ath_pci.c b/ath/if_ath_pci.c index a2962ca..3c789bf 100644 --- a/ath/if_ath_pci.c +++ b/ath/if_ath_pci.c @@ -46,9 +46,9 @@ } \ } while (0) -#define DPRINTF(sc, _m, _fmt...) do { \ - if (sc->sc_debug & (_m)) \ - printk(_fmt); \ +#define DPRINTF(sc, _m, _fmt...) do { \ + if (sc->sc_debug & (_m) && printk_ratelimit()) \ + printk(_fmt); \ } while (0) enum { ATH_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ @@ -128,45 +128,16 @@ static struct ieee80211_ops ath_hw_ops = { .hw_scan = d_hw_scan*/ }; -static inline u32 ath_hw_reg_read(struct ath_hw *hw, u16 reg) -{ - return readl(hw->ah_sh + reg); -} - -static inline void ath_hw_reg_write(struct ath_hw *hw, u32 val, u16 reg) -{ - writel(val, hw->ah_sh + reg); -} - -#define ATH_HW_IRQ_PENDING 0x4008 - static irqreturn_t ath_intr(int irq, void *dev_id) { - struct net_device *dev = dev_id; - struct ath_softc *sc = dev->priv; + struct ath_softc *sc = dev_id; struct ath_hw *ah = sc->ah; enum ath5k_int status; - int needmark; + unsigned int counter = 1000; - if (sc->sc_invalid) { - /* - * The hardware is not ready/present, don't touch anything. - * Note this can happen early on if the IRQ is shared. - */ - DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid; ignored\n", __func__); - return IRQ_NONE; - } - if (!ath_hw_reg_read(ah, ATH_HW_IRQ_PENDING)) + if (sc->sc_invalid || !ath5k_hw_is_intr_pending(ah)) return IRQ_NONE; return IRQ_HANDLED; - if ((dev->flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) { - DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, dev->flags); - ath5k_hw_get_isr(ah, &status); /* clear ISR */ - ath5k_hw_set_intr(ah, 0); /* disable further intr's */ - return IRQ_HANDLED; - } - needmark = 0; do { /* @@ -186,11 +157,11 @@ return IRQ_HANDLED; * by the hal. */ sc->sc_stats.ast_hardware++; - ath5k_hw_set_intr(ah, 0); /* disable intr's until reset */ + ath5k_hw_set_intr(ah, 0); /* disable intrs until rst */ tasklet_schedule(&sc->sc_fataltq); } else if (status & AR5K_INT_RXORN) { sc->sc_stats.ast_rxorn++; - ath5k_hw_set_intr(ah, 0); /* disable intr's until reset */ + ath5k_hw_set_intr(ah, 0); /* disable intrs until rst */ tasklet_schedule(&sc->sc_rxorntq); } else { if (status & AR5K_INT_SWBA) { @@ -242,7 +213,11 @@ return IRQ_HANDLED; ath5k_hw_set_intr(ah, sc->sc_imask); } } - } while (ath5k_hw_is_intr_pending(ah)); + } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0); + + if (!counter) + printk(KERN_WARNING "ath: too much interrupts, giving up for " + "now\n"); return IRQ_HANDLED; } diff --git a/openhal/ath5k_hw.c b/openhal/ath5k_hw.c index 091010b..df71d23 100644 --- a/openhal/ath5k_hw.c +++ b/openhal/ath5k_hw.c @@ -1703,11 +1703,10 @@ ath5k_hw_update_tx_triglevel(struct ath_hw *hal, bool increase) /* * Check if we have pending interrupts */ -bool -ath5k_hw_is_intr_pending(struct ath_hw *hal) +bool ath5k_hw_is_intr_pending(struct ath_hw *hal) { AR5K_TRACE; - return AR5K_REG_READ(AR5K_INTPEND) == true ? true : false; + return AR5K_REG_READ(AR5K_INTPEND); } /*