Read the interrupt status only once, to prevent wrong status reads in the

iwn_intr function. This should fix firmware timeouts, which occure due to
the second read just returns wrong values.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34804 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Colin Günther
2009-12-29 17:40:59 +00:00
parent ca833f9f1b
commit 92ba12f110
3 changed files with 23 additions and 16 deletions
@@ -1808,6 +1808,7 @@ iwn_intr(void *arg)
IWN_LOCK(sc); IWN_LOCK(sc);
#if !defined(__HAIKU__)
/* disable interrupts */ /* disable interrupts */
IWN_WRITE(sc, IWN_MASK, 0); IWN_WRITE(sc, IWN_MASK, 0);
@@ -1821,6 +1822,10 @@ iwn_intr(void *arg)
if (r1 == 0xffffffff) if (r1 == 0xffffffff)
goto done; /* hardware gone */ goto done; /* hardware gone */
#else
r1 = atomic_and((int32*)&sc->sc_intr_status_1, 0);
r2 = atomic_and((int32*)&sc->sc_intr_status_2, 0);
#endif
/* ack interrupts */ /* ack interrupts */
IWN_WRITE(sc, IWN_INTR, r1); IWN_WRITE(sc, IWN_INTR, r1);
@@ -2928,7 +2933,7 @@ iwn_power_calibration(struct iwn_softc *sc, int temp)
DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n", DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n",
__func__, sc->temp, temp); __func__, sc->temp, temp);
/* adjust Tx power if need be (delta >= 3°C) */ /* adjust Tx power if need be (delta >= 3C) */
if (abs(temp - sc->temp) < 3) if (abs(temp - sc->temp) < 3)
return; return;
@@ -200,6 +200,11 @@ struct iwn_softc {
int16_t eeprom_voltage; int16_t eeprom_voltage;
int8_t maxpwr2GHz; int8_t maxpwr2GHz;
int8_t maxpwr5GHz; int8_t maxpwr5GHz;
#if defined(__HAIKU__)
uint32_t sc_intr_status_1;
uint32_t sc_intr_status_2;
#endif
}; };
#define IWN_LOCK_INIT(_sc) \ #define IWN_LOCK_INIT(_sc) \
@@ -30,30 +30,27 @@ HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
{ {
struct iwn_softc* sc = (struct iwn_softc*)device_get_softc(dev); struct iwn_softc* sc = (struct iwn_softc*)device_get_softc(dev);
uint32 r1, r2; uint32 r1, r2;
HAIKU_INTR_REGISTER_STATE;
HAIKU_INTR_REGISTER_ENTER();
r1 = IWN_READ(sc, IWN_INTR); r1 = IWN_READ(sc, IWN_INTR);
r2 = IWN_READ(sc, IWN_INTR_STATUS); r2 = IWN_READ(sc, IWN_INTR_STATUS);
if (r1 == 0 && r2 == 0) { if (r1 == 0 && r2 == 0) {
/* not for us */ /* not for us */
IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK); IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
HAIKU_INTR_REGISTER_LEAVE();
return 0; return 0;
} }
if (r1 == 0xffffffff) { if (r1 == 0xffffffff) {
/* hardware gone */ /* hardware gone */
HAIKU_INTR_REGISTER_LEAVE();
return 0; return 0;
} }
atomic_or((int32*)&sc->sc_intr_status_1, r1);
atomic_or((int32*)&sc->sc_intr_status_2, r2);
/* disable interrupts */ /* disable interrupts */
IWN_WRITE(sc, IWN_MASK, 0); IWN_WRITE(sc, IWN_MASK, 0);
HAIKU_INTR_REGISTER_LEAVE();
return 1; return 1;
} }