diff options
author | imp <imp@FreeBSD.org> | 2008-12-05 05:20:08 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2008-12-05 05:20:08 +0000 |
commit | 409a3b958d3b16d4c0d1484009dad362acc631b9 (patch) | |
tree | 362a8b8c8dcd4d9163fffccb494b8213b432928a /sys/dev/pccbb | |
parent | a0ac240584481270ec3cbf5038e24cde78c094d5 (diff) | |
download | FreeBSD-src-409a3b958d3b16d4c0d1484009dad362acc631b9.zip FreeBSD-src-409a3b958d3b16d4c0d1484009dad362acc631b9.tar.gz |
Move to using filter for the change interrupts. Also rework the power
interrupt code to be more robust. I've been running these changes for
over a year... With these changes, I don't see the ath card going
into reset like the code in the tree.
Diffstat (limited to 'sys/dev/pccbb')
-rw-r--r-- | sys/dev/pccbb/pccbb.c | 23 | ||||
-rw-r--r-- | sys/dev/pccbb/pccbb_pci.c | 34 | ||||
-rw-r--r-- | sys/dev/pccbb/pccbbvar.h | 4 |
3 files changed, 24 insertions, 37 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index fb0f9b7..76dc00e 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -344,7 +344,7 @@ cbb_detach(device_t brdev) sc->flags |= CBB_KTHREAD_DONE; while (sc->flags & CBB_KTHREAD_RUNNING) { DEVPRINTF((sc->dev, "Waiting for thread to die\n")); - cv_broadcast(&sc->cv); + wakeup(&sc->intrhand); msleep(sc->event_thread, &sc->mtx, PWAIT, "cbbun", 0); } mtx_unlock(&sc->mtx); @@ -353,8 +353,6 @@ cbb_detach(device_t brdev) bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, sc->base_res); mtx_destroy(&sc->mtx); - cv_destroy(&sc->cv); - cv_destroy(&sc->powercv); return (0); } @@ -435,11 +433,8 @@ cbb_driver_added(device_t brdev, driver_t *driver) } free(devlist, M_TEMP); - if (wake > 0) { - mtx_lock(&sc->mtx); - cv_signal(&sc->cv); - mtx_unlock(&sc->mtx); - } + if (wake > 0) + wakeup(&sc->intrhand); } void @@ -519,12 +514,12 @@ cbb_event_thread(void *arg) * a chance to run. */ mtx_lock(&sc->mtx); - cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); - cv_wait(&sc->cv, &sc->mtx); + cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD | CBB_SOCKET_MASK_CSTS); + msleep(&sc->intrhand, &sc->mtx, PZERO, "-", 0); err = 0; while (err != EWOULDBLOCK && (sc->flags & CBB_KTHREAD_DONE) == 0) - err = cv_timedwait(&sc->cv, &sc->mtx, hz / 4); + err = msleep(&sc->intrhand, &sc->mtx, PZERO, "-", hz / 5); } DEVPRINTF((sc->dev, "Thread terminating\n")); sc->flags &= ~CBB_KTHREAD_RUNNING; @@ -800,7 +795,7 @@ cbb_power(device_t brdev, int volts) sane = 10; while (!(cbb_get(sc, CBB_SOCKET_STATE) & CBB_STATE_POWER_CYCLE) && cnt == sc->powerintr && sane-- > 0) - cv_timedwait(&sc->powercv, &sc->mtx, hz / 20); + msleep(&sc->powerintr, &sc->mtx, PZERO, "-", hz / 20); mtx_unlock(&sc->mtx); /* * The TOPIC95B requires a little bit extra time to get @@ -1575,9 +1570,7 @@ cbb_resume(device_t self) cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); /* Signal the thread to wakeup. */ - mtx_lock(&sc->mtx); - cv_signal(&sc->cv); - mtx_unlock(&sc->mtx); + wakeup(&sc->intrhand); error = bus_generic_resume(self); diff --git a/sys/dev/pccbb/pccbb_pci.c b/sys/dev/pccbb/pccbb_pci.c index 49b9cd1..5d38921 100644 --- a/sys/dev/pccbb/pccbb_pci.c +++ b/sys/dev/pccbb/pccbb_pci.c @@ -117,7 +117,7 @@ __FBSDID("$FreeBSD$"); pci_read_config(DEV, REG, SIZE) MASK1) MASK2, SIZE) static void cbb_chipinit(struct cbb_softc *sc); -static void cbb_pci_intr(void *arg); +static int cbb_pci_filt(void *arg); static struct yenta_chipinfo { uint32_t yc_id; @@ -313,8 +313,6 @@ cbb_pci_attach(device_t brdev) parent = device_get_parent(brdev); mtx_init(&sc->mtx, device_get_nameunit(brdev), "cbb", MTX_DEF); - cv_init(&sc->cv, "cbb cv"); - cv_init(&sc->powercv, "cbb cv"); sc->chipset = cbb_chipset(pci_get_devid(brdev), NULL); sc->dev = brdev; sc->cbdev = NULL; @@ -332,7 +330,6 @@ cbb_pci_attach(device_t brdev) if (!sc->base_res) { device_printf(brdev, "Could not map register memory\n"); mtx_destroy(&sc->mtx); - cv_destroy(&sc->cv); return (ENOMEM); } else { DEVPRINTF((brdev, "Found memory at %08lx\n", @@ -416,7 +413,7 @@ cbb_pci_attach(device_t brdev) } if (bus_setup_intr(brdev, sc->irq_res, INTR_TYPE_AV | INTR_MPSAFE, - NULL, cbb_pci_intr, sc, &sc->intrhand)) { + cbb_pci_filt, NULL, sc, &sc->intrhand)) { device_printf(brdev, "couldn't establish interrupt\n"); goto err; } @@ -451,7 +448,6 @@ err: sc->base_res); } mtx_destroy(&sc->mtx); - cv_destroy(&sc->cv); return (ENOMEM); } @@ -686,11 +682,13 @@ cbb_pci_shutdown(device_t brdev) return (0); } -static void -cbb_pci_intr(void *arg) +#define DELTA (CBB_SOCKET_MASK_CD) +static int +cbb_pci_filt(void *arg) { struct cbb_softc *sc = arg; uint32_t sockevent; + int retval = FILTER_STRAY; /* * Read the socket event. Sometimes, the theory goes, the PCI @@ -705,9 +703,6 @@ cbb_pci_intr(void *arg) */ sockevent = cbb_get(sc, CBB_SOCKET_EVENT); if (sockevent != 0 && (sockevent & ~CBB_SOCKET_EVENT_VALID_MASK) == 0) { - /* ack the interrupt */ - cbb_set(sc, CBB_SOCKET_EVENT, sockevent); - /* * If anything has happened to the socket, we assume that * the card is no longer OK, and we shouldn't call its @@ -721,24 +716,24 @@ cbb_pci_intr(void *arg) * of the pccard software used a similar trick and achieved * excellent results. */ - if (sockevent & CBB_SOCKET_EVENT_CD) { - mtx_lock(&sc->mtx); - cbb_clrb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); + if (sockevent & DELTA) { + cbb_clrb(sc, CBB_SOCKET_MASK, DELTA); + cbb_set(sc, CBB_SOCKET_EVENT, DELTA); sc->cardok = 0; cbb_disable_func_intr(sc); - cv_signal(&sc->cv); - mtx_unlock(&sc->mtx); + wakeup(&sc->intrhand); } /* * If we get a power interrupt, wakeup anybody that might * be waiting for one. */ if (sockevent & CBB_SOCKET_EVENT_POWER) { - mtx_lock(&sc->mtx); + cbb_clrb(sc, CBB_SOCKET_MASK, CBB_SOCKET_EVENT_POWER); + cbb_set(sc, CBB_SOCKET_EVENT, CBB_SOCKET_EVENT_POWER); sc->powerintr++; - cv_signal(&sc->powercv); - mtx_unlock(&sc->mtx); + wakeup((void *)&sc->powerintr); } + retval = FILTER_HANDLED; } /* * Some chips also require us to read the old ExCA registe for @@ -753,6 +748,7 @@ cbb_pci_intr(void *arg) * the event independent of the CBB_SOCKET_EVENT_CD above. */ exca_getb(&sc->exca[0], EXCA_CSC); + return retval; } /************************************************************************/ diff --git a/sys/dev/pccbb/pccbbvar.h b/sys/dev/pccbb/pccbbvar.h index ef2d82f..a7b6aa6 100644 --- a/sys/dev/pccbb/pccbbvar.h +++ b/sys/dev/pccbb/pccbbvar.h @@ -67,8 +67,6 @@ struct cbb_softc { unsigned int secbus; unsigned int subbus; struct mtx mtx; - struct cv cv; - struct cv powercv; int cardok; u_int32_t flags; #define CBB_16BIT_CARD 0x20000000 @@ -89,7 +87,7 @@ struct cbb_softc { device_t cbdev; struct proc *event_thread; void (*chipinit)(struct cbb_softc *); - volatile int powerintr; + int powerintr; }; /* result of detect_card */ |