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

wpi_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@34805 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Colin Günther
2009-12-29 17:50:44 +00:00
parent 92ba12f110
commit 49fbc5438e
3 changed files with 15 additions and 19 deletions
@@ -966,7 +966,7 @@ wpi_alloc_rx_ring(struct wpi_softc *sc, struct wpi_rx_ring *ring)
goto fail;
}
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
@@ -1011,7 +1011,7 @@ wpi_alloc_rx_ring(struct wpi_softc *sc, struct wpi_rx_ring *ring)
error = ENOMEM; /* XXX unique code */
goto fail;
}
bus_dmamap_sync(ring->data_dmat, data->map,
bus_dmamap_sync(ring->data_dmat, data->map,
BUS_DMASYNC_PREWRITE);
data->m = m;
@@ -1764,6 +1764,7 @@ wpi_intr(void *arg)
WPI_LOCK(sc);
#if !defined(__HAIKU__)
r = WPI_READ(sc, WPI_INTR);
if (r == 0 || r == 0xffffffff) {
WPI_UNLOCK(sc);
@@ -1772,6 +1773,10 @@ wpi_intr(void *arg)
/* disable interrupts */
WPI_WRITE(sc, WPI_MASK, 0);
#else
r = atomic_and((int32 *)&sc->sc_intr_status, 0);
#endif
/* ack interrupts */
WPI_WRITE(sc, WPI_INTR, r);
@@ -201,6 +201,10 @@ struct wpi_softc {
struct wpi_power_group groups[WPI_POWER_GROUPS_COUNT];
int8_t maxpwr[IEEE80211_CHAN_MAX];
char domain[4]; /*reglatory domain XXX */
#if defined(__HAIKU__)
uint32_t sc_intr_status;
#endif
};
#define WPI_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
@@ -20,6 +20,7 @@
HAIKU_FBSD_WLAN_DRIVER_GLUE(iprowifi3945, wpi, pci)
NO_HAIKU_FBSD_MII_DRIVER();
NO_HAIKU_REENABLE_INTERRUPTS();
HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_WLAN);
HAIKU_FIRMWARE_VERSION(2144);
@@ -29,28 +30,14 @@ HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
{
struct wpi_softc* sc = (struct wpi_softc*)device_get_softc(dev);
uint32 r;
HAIKU_INTR_REGISTER_STATE;
HAIKU_INTR_REGISTER_ENTER();
if ((r = WPI_READ(sc, WPI_INTR)) == 0 || r == 0xffffffff) {
HAIKU_INTR_REGISTER_LEAVE();
if ((r = WPI_READ(sc, WPI_INTR)) == 0 || r == 0xffffffff)
return 0;
}
atomic_or((int32*)&sc->sc_intr_status, r);
/* disable interrupts */
WPI_WRITE(sc, WPI_MASK, 0);
HAIKU_INTR_REGISTER_LEAVE();
return 1;
}
void
HAIKU_REENABLE_INTERRUPTS(device_t dev)
{
struct wpi_softc* sc = (struct wpi_softc*)device_get_softc(dev);
/* enable interrupts */
WPI_WRITE(sc, WPI_MASK, WPI_INTR_MASK);
}