Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Apr 2011 06:37:09 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        cvs-src-old@freebsd.org
Subject:   cvs commit: src/sys/dev/ath if_ath.c src/sys/dev/ath/ath_hal/ar5416 ar5416_interrupts.c
Message-ID:  <201104230637.p3N6bMcU060411@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
adrian      2011-04-23 06:37:09 UTC

  FreeBSD src repository

  Modified files:
    sys/dev/ath          if_ath.c 
    sys/dev/ath/ath_hal/ar5416 ar5416_interrupts.c 
  Log:
  SVN rev 220966 on 2011-04-23 06:37:09Z by adrian
  
  Fix a corner-case of interrupt handling which resulted in potentially
  spurious (and fatal) interrupt errors.
  
  One user reported seeing this:
  
  Apr 22 18:04:24 ceres kernel: ar5416GetPendingInterrupts: fatal error,
    ISR_RAC 0x0 SYNC_CAUSE 0x2000
  
  SYNC_CAUSE of 0x2000 is AR_INTR_SYNC_LOCAL_TIMEOUT which is a bus timeout;
  this shouldn't cause HAL_INT_FATAL to be set.
  
  After checking out ath9k, ath9k_ar9002_hw_get_isr() clears (*masked)
  before continuing, regardless of whether any bits in the ISR registers
  are set. So if AR_INTR_SYNC_CAUSE is set to something that isn't
  treated as fatal, and AR_ISR isn't read or is read and is 0, then
  (*masked) wouldn't be cleared. Thus any of the existing bits set
  that were passed in would be preserved in the output.
  
  The caller in if_ath - ath_intr() - wasn't setting the masked value
  to 0 before calling ath_hal_getisr(), so anything that was present
  in that uninitialised variable would be preserved in the case above
  of AR_ISR=0, AR_INTR_SYNC_CAUSE != 0; and if the HAL_INT_FATAL bit
  was set, a fatal condition would be interpreted and the chip was
  reset.
  
  This patch does the following:
  
  * ath_intr() - set masked to 0 before calling ath_hal_getisr();
  * ar5416GetPendingInterrupts() - clear (*masked) before processing
    continues; so if the interrupt source is AR_INTR_SYNC_CAUSE
    and it isn't fatal, the hardware isn't reset via returning
    HAL_INT_FATAL.
  
  This doesn't fix any underlying errors which trigger
  AR_INTR_SYNC_LOCAL_TIMEOUT - which is a bus timeout of some
  sort - so that likely should be further investigated.
  
  Revision  Changes    Path
  1.10      +5 -3      src/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c
  1.317     +6 -1      src/sys/dev/ath/if_ath.c



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104230637.p3N6bMcU060411>