Make it use mutex(9) and condvar(9), bye bye spl(9) and tsleep(9).

Fully stable with all debugging options turned on, unless someday any
problem appears :-)
This commit is contained in:
xtraeme 2007-12-05 18:07:34 +00:00
parent 67637efccc
commit dc5ade8ebb
2 changed files with 52 additions and 39 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: arcmsr.c,v 1.2 2007/12/05 16:02:25 xtraeme Exp $ */
/* $NetBSD: arcmsr.c,v 1.3 2007/12/05 18:07:34 xtraeme Exp $ */
/* $OpenBSD: arc.c,v 1.68 2007/10/27 03:28:27 dlg Exp $ */
/*
@ -20,7 +20,7 @@
#include "bio.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: arcmsr.c,v 1.2 2007/12/05 16:02:25 xtraeme Exp $");
__KERNEL_RCSID(0, "$NetBSD: arcmsr.c,v 1.3 2007/12/05 18:07:34 xtraeme Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@ -28,7 +28,8 @@ __KERNEL_RCSID(0, "$NetBSD: arcmsr.c,v 1.2 2007/12/05 16:02:25 xtraeme Exp $");
#include <sys/malloc.h>
#include <sys/device.h>
#include <sys/kthread.h>
#include <sys/rwlock.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#if NBIO > 0
#include <sys/ioctl.h>
@ -143,7 +144,8 @@ arc_attach(device_t parent, device_t self, void *aux)
struct scsipi_channel *chan = &sc->sc_chan;
sc->sc_talking = 0;
rw_init(&sc->sc_rwlock);
mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_BIO);
cv_init(&sc->sc_condvar, "arcdb");
if (arc_map_pci_resources(sc, pa) != 0) {
/* error message printed by arc_map_pci_resources */
@ -214,6 +216,7 @@ arc_detach(device_t self, int flags)
shutdownhook_disestablish(sc->sc_shutdownhook);
mutex_enter(&sc->sc_mutex);
if (arc_msg0(sc, ARC_REG_INB_MSG0_STOP_BGRB) != 0)
aprint_error("%s: timeout waiting to stop bg rebuild\n",
device_xname(&sc->sc_dev));
@ -221,6 +224,7 @@ arc_detach(device_t self, int flags)
if (arc_msg0(sc, ARC_REG_INB_MSG0_FLUSH_CACHE) != 0)
aprint_error("%s: timeout waiting to flush cache\n",
device_xname(&sc->sc_dev));
mutex_exit(&sc->sc_mutex);
return 0;
}
@ -230,6 +234,7 @@ arc_shutdown(void *xsc)
{
struct arc_softc *sc = xsc;
mutex_enter(&sc->sc_mutex);
if (arc_msg0(sc, ARC_REG_INB_MSG0_STOP_BGRB) != 0)
aprint_error("%s: timeout waiting to stop bg rebuild\n",
device_xname(&sc->sc_dev));
@ -237,6 +242,7 @@ arc_shutdown(void *xsc)
if (arc_msg0(sc, ARC_REG_INB_MSG0_FLUSH_CACHE) != 0)
aprint_error("%s: timeout waiting to flush cache\n",
device_xname(&sc->sc_dev));
mutex_exit(&sc->sc_mutex);
}
static void
@ -256,9 +262,12 @@ arc_intr(void *arg)
struct arc_io_cmd *cmd;
uint32_t reg, intrstat;
mutex_enter(&sc->sc_mutex);
intrstat = arc_read(sc, ARC_REG_INTRSTAT);
if (intrstat == 0x0)
if (intrstat == 0x0) {
mutex_exit(&sc->sc_mutex);
return 0;
}
intrstat &= ARC_REG_INTRSTAT_POSTQUEUE | ARC_REG_INTRSTAT_DOORBELL;
arc_write(sc, ARC_REG_INTRSTAT, intrstat);
@ -268,7 +277,7 @@ arc_intr(void *arg)
/* if an ioctl is talking, wake it up */
arc_write(sc, ARC_REG_INTRMASK,
~ARC_REG_INTRMASK_POSTQUEUE);
wakeup(sc);
cv_broadcast(&sc->sc_condvar);
} else {
/* otherwise drop it */
reg = arc_read(sc, ARC_REG_OUTB_DOORBELL);
@ -278,6 +287,7 @@ arc_intr(void *arg)
ARC_REG_INB_DOORBELL_READ_OK);
}
}
mutex_exit(&sc->sc_mutex);
while ((reg = arc_pop(sc)) != 0xffffffff) {
cmd = (struct arc_io_cmd *)(kva +
@ -306,7 +316,6 @@ arc_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
struct arc_msg_scsicmd *cmd;
uint32_t reg;
uint8_t target;
int s;
switch (req) {
case ADAPTER_REQ_GROW_RESOURCES:
@ -330,28 +339,24 @@ arc_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
xs->sense.scsi_sense.asc = 0x20;
xs->error = XS_SENSE;
xs->status = SCSI_CHECK;
s = splbio();
scsipi_done(xs);
goto out;
return;
}
s = splbio();
ccb = arc_get_ccb(sc);
if (ccb == NULL) {
xs->error = XS_RESOURCE_SHORTAGE;
scsipi_done(xs);
goto out;
return;
}
splx(s);
ccb->ccb_xs = xs;
if (arc_load_xs(ccb) != 0) {
xs->error = XS_DRIVER_STUFFUP;
s = splbio();
arc_put_ccb(sc, ccb);
scsipi_done(xs);
goto out;
return;
}
cmd = &ccb->ccb_cmd->cmd;
@ -381,7 +386,6 @@ arc_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
ccb->ccb_offset, ARC_MAX_IOCMDLEN,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
s = splbio();
arc_push(sc, reg);
if (xs->xs_control & XS_CTL_POLL) {
if (arc_complete(sc, ccb, xs->timeout) != 0) {
@ -389,8 +393,6 @@ arc_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
scsipi_done(xs);
}
}
out:
splx(s);
}
int
@ -573,19 +575,30 @@ arc_query_firmware(struct arc_softc *sc)
struct arc_msg_firmware_info fwinfo;
char string[81]; /* sizeof(vendor)*2+1 */
mutex_enter(&sc->sc_mutex);
if (arc_wait_eq(sc, ARC_REG_OUTB_ADDR1, ARC_REG_OUTB_ADDR1_FIRMWARE_OK,
ARC_REG_OUTB_ADDR1_FIRMWARE_OK) != 0) {
aprint_debug("%s: timeout waiting for firmware ok\n",
device_xname(&sc->sc_dev));
mutex_enter(&sc->sc_mutex);
return 1;
}
if (arc_msg0(sc, ARC_REG_INB_MSG0_GET_CONFIG) != 0) {
aprint_debug("%s: timeout waiting for get config\n",
device_xname(&sc->sc_dev));
mutex_exit(&sc->sc_mutex);
return 1;
}
if (arc_msg0(sc, ARC_REG_INB_MSG0_START_BGRB) != 0) {
aprint_debug("%s: timeout waiting to start bg rebuild\n",
device_xname(&sc->sc_dev));
mutex_exit(&sc->sc_mutex);
return 1;
}
mutex_exit(&sc->sc_mutex);
arc_read_region(sc, ARC_REG_MSGBUF, &fwinfo, sizeof(fwinfo));
DNPRINTF(ARC_D_INIT, "%s: signature: 0x%08x\n",
@ -632,12 +645,6 @@ arc_query_firmware(struct arc_softc *sc)
sc->sc_req_count = htole32(fwinfo.queue_len);
if (arc_msg0(sc, ARC_REG_INB_MSG0_START_BGRB) != 0) {
aprint_debug("%s: timeout waiting to start bg rebuild\n",
device_xname(&sc->sc_dev));
return 1;
}
aprint_normal("%s: %d ports, %dMB SDRAM, firmware <%s>\n",
device_xname(&sc->sc_dev), htole32(fwinfo.sata_ports),
htole32(fwinfo.sdram_size), string);
@ -1174,39 +1181,32 @@ out:
void
arc_lock(struct arc_softc *sc)
{
int s;
rw_enter(&sc->sc_rwlock, RW_WRITER);
s = splbio();
mutex_enter(&sc->sc_mutex);
arc_write(sc, ARC_REG_INTRMASK, ~ARC_REG_INTRMASK_POSTQUEUE);
sc->sc_talking = 1;
splx(s);
}
void
arc_unlock(struct arc_softc *sc)
{
int s;
KASSERT(mutex_owned(&sc->sc_mutex));
s = splbio();
sc->sc_talking = 0;
arc_write(sc, ARC_REG_INTRMASK,
~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRMASK_DOORBELL));
splx(s);
rw_exit(&sc->sc_rwlock);
mutex_exit(&sc->sc_mutex);
}
void
arc_wait(struct arc_softc *sc)
{
int s;
KASSERT(mutex_owned(&sc->sc_mutex));
s = splbio();
arc_write(sc, ARC_REG_INTRMASK,
~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRMASK_DOORBELL));
if (tsleep(sc, PWAIT|PCATCH, "arcdb", hz) == EWOULDBLOCK)
if (cv_timedwait_sig(&sc->sc_condvar, &sc->sc_mutex, hz) ==
EWOULDBLOCK)
arc_write(sc, ARC_REG_INTRMASK, ~ARC_REG_INTRMASK_POSTQUEUE);
splx(s);
}
#if NBIO > 0
@ -1315,6 +1315,8 @@ arc_read(struct arc_softc *sc, bus_size_t r)
{
uint32_t v;
KASSERT(mutex_owned(&sc->sc_mutex));
bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
BUS_SPACE_BARRIER_READ);
v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
@ -1337,6 +1339,8 @@ arc_read_region(struct arc_softc *sc, bus_size_t r, void *buf, size_t len)
void
arc_write(struct arc_softc *sc, bus_size_t r, uint32_t v)
{
KASSERT(mutex_owned(&sc->sc_mutex));
DNPRINTF(ARC_D_RW, "%s: arc_write 0x%lx 0x%08x\n",
device_xname(&sc->sc_dev), r, v);
@ -1360,6 +1364,8 @@ arc_wait_eq(struct arc_softc *sc, bus_size_t r, uint32_t mask,
{
int i;
KASSERT(mutex_owned(&sc->sc_mutex));
DNPRINTF(ARC_D_RW, "%s: arc_wait_eq 0x%lx 0x%08x 0x%08x\n",
device_xname(&sc->sc_dev), r, mask, target);
@ -1393,6 +1399,8 @@ arc_wait_ne(struct arc_softc *sc, bus_size_t r, uint32_t mask,
int
arc_msg0(struct arc_softc *sc, uint32_t m)
{
KASSERT(mutex_owned(&sc->sc_mutex));
/* post message */
arc_write(sc, ARC_REG_INB_MSG0, m);
/* wait for the fw to do it */
@ -1520,17 +1528,21 @@ arc_get_ccb(struct arc_softc *sc)
{
struct arc_ccb *ccb;
mutex_enter(&sc->sc_mutex);
ccb = TAILQ_FIRST(&sc->sc_ccb_free);
if (ccb != NULL)
TAILQ_REMOVE(&sc->sc_ccb_free, ccb, ccb_link);
mutex_exit(&sc->sc_mutex);
return ccb;
}
void
arc_put_ccb(struct arc_softc *sc, struct arc_ccb *ccb)
{
mutex_enter(&sc->sc_mutex);
ccb->ccb_xs = NULL;
memset(ccb->ccb_cmd, 0, ARC_MAX_IOCMDLEN);
TAILQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_link);
mutex_exit(&sc->sc_mutex);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: arcmsrvar.h,v 1.2 2007/12/05 16:02:26 xtraeme Exp $ */
/* $NetBSD: arcmsrvar.h,v 1.3 2007/12/05 18:07:34 xtraeme Exp $ */
/* Derived from $OpenBSD: arc.c,v 1.68 2007/10/27 03:28:27 dlg Exp $ */
/*
@ -330,7 +330,8 @@ struct arc_softc {
struct lwp *sc_lwp;
volatile int sc_talking;
krwlock_t sc_rwlock;
kmutex_t sc_mutex;
kcondvar_t sc_condvar;
struct sysmon_envsys *sc_sme;
envsys_data_t *sc_sensors;