aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2014-11-18 21:55:50 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2014-11-18 21:55:50 +0000
commitcaddd60abd10124e93c4dd27471567bc26dc4ee0 (patch)
tree3a9d54e8b27ae0f63da52f426c5f88ba72393647 /sys/dev
parent23c31a3c5d322944396562a893e0d949fb91ad2a (diff)
downloadsrc-caddd60abd10124e93c4dd27471567bc26dc4ee0.tar.gz
src-caddd60abd10124e93c4dd27471567bc26dc4ee0.zip
Add locking to mly(4) and mark MPSAFE.
- Add a per-softc mutex. - Use mutex as CAM sim lock. - Use taskqueue_thread instead of taskqueue_swi_giant. - Use callout(9) instead of timeout(9). - Use bus_*() instead of bus_space_*(). Tested by: no one
Notes
Notes: svn path=/head/; revision=274677
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/mly/mly.c179
-rw-r--r--sys/dev/mly/mlyvar.h53
2 files changed, 131 insertions, 101 deletions
diff --git a/sys/dev/mly/mly.c b/sys/dev/mly/mly.c
index a58b21b8f08e..1ea371a62a9b 100644
--- a/sys/dev/mly/mly.c
+++ b/sys/dev/mly/mly.c
@@ -88,7 +88,8 @@ static void mly_periodic(void *data);
static int mly_immediate_command(struct mly_command *mc);
static int mly_start(struct mly_command *mc);
static void mly_done(struct mly_softc *sc);
-static void mly_complete(void *context, int pending);
+static void mly_complete(struct mly_softc *sc);
+static void mly_complete_handler(void *context, int pending);
static int mly_alloc_command(struct mly_softc *sc, struct mly_command **mcp);
static void mly_release_command(struct mly_command *mc);
@@ -116,7 +117,7 @@ static void mly_printstate(struct mly_softc *sc);
static void mly_print_command(struct mly_command *mc);
static void mly_print_packet(struct mly_command *mc);
static void mly_panic(struct mly_softc *sc, char *reason);
-static int mly_timeout(struct mly_softc *sc);
+static void mly_timeout(void *arg);
#endif
void mly_print_controller(int controller);
@@ -151,7 +152,6 @@ MODULE_DEPEND(mly, cam, 1, 1, 1);
static struct cdevsw mly_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
.d_open = mly_user_open,
.d_close = mly_user_close,
.d_ioctl = mly_user_ioctl,
@@ -216,8 +216,11 @@ mly_attach(device_t dev)
debug_called(1);
sc->mly_dev = dev;
+ mtx_init(&sc->mly_lock, "mly", NULL, MTX_DEF);
+ callout_init_mtx(&sc->mly_periodic, &sc->mly_lock, 0);
#ifdef MLY_DEBUG
+ callout_init_mtx(&sc->mly_timeout, &sc->mly_lock, 0);
if (device_get_unit(sc->mly_dev) == 0)
mly_softc0 = sc;
#endif
@@ -238,7 +241,7 @@ mly_attach(device_t dev)
/*
* Initialise command-completion task.
*/
- TASK_INIT(&sc->mly_task_complete, 0, mly_complete, sc);
+ TASK_INIT(&sc->mly_task_complete, 0, mly_complete_handler, sc);
/* disable interrupts before we start talking to the controller */
MLY_MASK_INTERRUPTS(sc);
@@ -260,7 +263,10 @@ mly_attach(device_t dev)
/*
* Obtain controller feature information
*/
- if ((error = mly_get_controllerinfo(sc)))
+ MLY_LOCK(sc);
+ error = mly_get_controllerinfo(sc);
+ MLY_UNLOCK(sc);
+ if (error)
goto out;
/*
@@ -274,13 +280,16 @@ mly_attach(device_t dev)
* Get the current event counter for health purposes, populate the initial
* health status buffer.
*/
- if ((error = mly_get_eventstatus(sc)))
- goto out;
+ MLY_LOCK(sc);
+ error = mly_get_eventstatus(sc);
/*
* Enable memory-mailbox mode.
*/
- if ((error = mly_enable_mmbox(sc)))
+ if (error == 0)
+ error = mly_enable_mmbox(sc);
+ MLY_UNLOCK(sc);
+ if (error)
goto out;
/*
@@ -297,6 +306,7 @@ mly_attach(device_t dev)
/*
* Mark all attached devices for rescan.
*/
+ MLY_LOCK(sc);
mly_scan_devices(sc);
/*
@@ -305,6 +315,7 @@ mly_attach(device_t dev)
* the SCSI subsystem gets to us, courtesy of the "SCSI settling delay".
*/
mly_periodic((void *)sc);
+ MLY_UNLOCK(sc);
/*
* Create the control device.
@@ -317,7 +328,7 @@ mly_attach(device_t dev)
MLY_UNMASK_INTERRUPTS(sc);
#ifdef MLY_DEBUG
- timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz);
+ callout_reset(&sc->mly_timeout, MLY_CMD_TIMEOUT * hz, mly_timeout, sc);
#endif
out:
@@ -353,8 +364,6 @@ mly_pci_attach(struct mly_softc *sc)
mly_printf(sc, "can't allocate register window\n");
goto fail;
}
- sc->mly_btag = rman_get_bustag(sc->mly_regs_resource);
- sc->mly_bhandle = rman_get_bushandle(sc->mly_regs_resource);
/*
* Allocate and connect our interrupt.
@@ -365,7 +374,7 @@ mly_pci_attach(struct mly_softc *sc)
mly_printf(sc, "can't allocate interrupt\n");
goto fail;
}
- if (bus_setup_intr(sc->mly_dev, sc->mly_irq, INTR_TYPE_CAM | INTR_ENTROPY, NULL, mly_intr, sc, &sc->mly_intr)) {
+ if (bus_setup_intr(sc->mly_dev, sc->mly_irq, INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE, NULL, mly_intr, sc, &sc->mly_intr)) {
mly_printf(sc, "can't set up interrupt\n");
goto fail;
}
@@ -405,7 +414,7 @@ mly_pci_attach(struct mly_softc *sc)
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
0, /* flags */
busdma_lock_mutex, /* lockfunc */
- &Giant, /* lockarg */
+ &sc->mly_lock, /* lockarg */
&sc->mly_buffer_dmat)) {
mly_printf(sc, "can't allocate buffer DMA tag\n");
goto fail;
@@ -511,18 +520,25 @@ mly_shutdown(device_t dev)
struct mly_softc *sc = device_get_softc(dev);
debug_called(1);
-
- if (sc->mly_state & MLY_STATE_OPEN)
+
+ MLY_LOCK(sc);
+ if (sc->mly_state & MLY_STATE_OPEN) {
+ MLY_UNLOCK(sc);
return(EBUSY);
+ }
/* kill the periodic event */
- untimeout(mly_periodic, sc, sc->mly_periodic);
+ callout_stop(&sc->mly_periodic);
+#ifdef MLY_DEBUG
+ callout_stop(&sc->mly_timeout);
+#endif
/* flush controller */
mly_printf(sc, "flushing cache...");
printf("%s\n", mly_flush(sc) ? "failed" : "done");
MLY_MASK_INTERRUPTS(sc);
+ MLY_UNLOCK(sc);
return(0);
}
@@ -538,7 +554,9 @@ mly_intr(void *arg)
debug_called(2);
+ MLY_LOCK(sc);
mly_done(sc);
+ MLY_UNLOCK(sc);
};
/********************************************************************************
@@ -676,6 +694,13 @@ mly_free(struct mly_softc *sc)
/* Remove the management device */
destroy_dev(sc->mly_dev_t);
+ if (sc->mly_intr)
+ bus_teardown_intr(sc->mly_dev, sc->mly_irq, sc->mly_intr);
+ callout_drain(&sc->mly_periodic);
+#ifdef MLY_DEBUG
+ callout_drain(&sc->mly_timeout);
+#endif
+
/* detach from CAM */
mly_cam_detach(sc);
@@ -711,8 +736,6 @@ mly_free(struct mly_softc *sc)
bus_dma_tag_destroy(sc->mly_mmbox_dmat);
/* disconnect the interrupt handler */
- if (sc->mly_intr)
- bus_teardown_intr(sc->mly_dev, sc->mly_irq, sc->mly_intr);
if (sc->mly_irq != NULL)
bus_release_resource(sc->mly_dev, SYS_RES_IRQ, sc->mly_irq_rid, sc->mly_irq);
@@ -723,6 +746,8 @@ mly_free(struct mly_softc *sc)
/* release the register window mapping */
if (sc->mly_regs_resource != NULL)
bus_release_resource(sc->mly_dev, SYS_RES_MEMORY, sc->mly_regs_rid, sc->mly_regs_resource);
+
+ mtx_destroy(&sc->mly_lock);
}
/********************************************************************************
@@ -1086,6 +1111,7 @@ mly_ioctl(struct mly_softc *sc, struct mly_command_ioctl *ioctl, void **data, si
int error;
debug_called(1);
+ MLY_ASSERT_LOCKED(sc);
mc = NULL;
if (mly_alloc_command(sc, &mc)) {
@@ -1375,6 +1401,7 @@ mly_periodic(void *data)
int bus, target;
debug_called(2);
+ MLY_ASSERT_LOCKED(sc);
/*
* Scan devices.
@@ -1398,7 +1425,7 @@ mly_periodic(void *data)
mly_check_event(sc);
/* reschedule ourselves */
- sc->mly_periodic = timeout(mly_periodic, sc, MLY_PERIODIC_INTERVAL * hz);
+ callout_schedule(&sc->mly_periodic, MLY_PERIODIC_INTERVAL * hz);
}
/********************************************************************************
@@ -1415,21 +1442,19 @@ static int
mly_immediate_command(struct mly_command *mc)
{
struct mly_softc *sc = mc->mc_sc;
- int error, s;
+ int error;
debug_called(1);
- /* spinning at splcam is ugly, but we're only used during controller init */
- s = splcam();
+ MLY_ASSERT_LOCKED(sc);
if ((error = mly_start(mc))) {
- splx(s);
return(error);
}
if (sc->mly_state & MLY_STATE_INTERRUPTS_ON) {
/* sleep on the command */
while(!(mc->mc_flags & MLY_CMD_COMPLETE)) {
- tsleep(mc, PRIBIO, "mlywait", 0);
+ mtx_sleep(mc, &sc->mly_lock, PRIBIO, "mlywait", 0);
}
} else {
/* spin and collect status while we do */
@@ -1437,7 +1462,6 @@ mly_immediate_command(struct mly_command *mc)
mly_done(mc->mc_sc);
}
}
- splx(s);
return(0);
}
@@ -1453,9 +1477,9 @@ mly_start(struct mly_command *mc)
{
struct mly_softc *sc = mc->mc_sc;
union mly_command_packet *pkt;
- int s;
debug_called(2);
+ MLY_ASSERT_LOCKED(sc);
/*
* Set the command up for delivery to the controller.
@@ -1467,8 +1491,6 @@ mly_start(struct mly_command *mc)
mc->mc_timestamp = time_second;
#endif
- s = splcam();
-
/*
* Do we have to use the hardware mailbox?
*/
@@ -1477,7 +1499,6 @@ mly_start(struct mly_command *mc)
* Check to see if the controller is ready for us.
*/
if (MLY_IDBR_TRUE(sc, MLY_HM_CMDSENT)) {
- splx(s);
return(EBUSY);
}
mc->mc_flags |= MLY_CMD_BUSY;
@@ -1494,7 +1515,6 @@ mly_start(struct mly_command *mc)
/* check to see if the next index is free yet */
if (pkt->mmbox.flag != 0) {
- splx(s);
return(EBUSY);
}
mc->mc_flags |= MLY_CMD_BUSY;
@@ -1502,13 +1522,11 @@ mly_start(struct mly_command *mc)
/* copy in new command */
bcopy(mc->mc_packet->mmbox.data, pkt->mmbox.data, sizeof(pkt->mmbox.data));
/* barrier to ensure completion of previous write before we write the flag */
- bus_space_barrier(sc->mly_btag, sc->mly_bhandle, 0, 0,
- BUS_SPACE_BARRIER_WRITE);
+ bus_barrier(sc->mly_regs_resource, 0, 0, BUS_SPACE_BARRIER_WRITE);
/* copy flag last */
pkt->mmbox.flag = mc->mc_packet->mmbox.flag;
/* barrier to ensure completion of previous write before we notify the controller */
- bus_space_barrier(sc->mly_btag, sc->mly_bhandle, 0, 0,
- BUS_SPACE_BARRIER_WRITE);
+ bus_barrier(sc->mly_regs_resource, 0, 0, BUS_SPACE_BARRIER_WRITE);
/* signal controller, update index */
MLY_SET_REG(sc, sc->mly_idbr, MLY_AM_CMDSENT);
@@ -1516,7 +1534,6 @@ mly_start(struct mly_command *mc)
}
mly_enqueue_busy(mc);
- splx(s);
return(0);
}
@@ -1529,9 +1546,9 @@ mly_done(struct mly_softc *sc)
struct mly_command *mc;
union mly_status_packet *sp;
u_int16_t slot;
- int s, worked;
+ int worked;
- s = splcam();
+ MLY_ASSERT_LOCKED(sc);
worked = 0;
/* pick up hardware-mailbox commands */
@@ -1589,12 +1606,11 @@ mly_done(struct mly_softc *sc)
MLY_SET_REG(sc, sc->mly_odbr, MLY_AM_STSREADY);
}
- splx(s);
if (worked) {
if (sc->mly_state & MLY_STATE_INTERRUPTS_ON)
- taskqueue_enqueue(taskqueue_swi_giant, &sc->mly_task_complete);
+ taskqueue_enqueue(taskqueue_thread, &sc->mly_task_complete);
else
- mly_complete(sc, 0);
+ mly_complete(sc);
}
}
@@ -1602,13 +1618,21 @@ mly_done(struct mly_softc *sc)
* Process completed commands
*/
static void
-mly_complete(void *context, int pending)
+mly_complete_handler(void *context, int pending)
{
struct mly_softc *sc = (struct mly_softc *)context;
+
+ MLY_LOCK(sc);
+ mly_complete(sc);
+ MLY_UNLOCK(sc);
+}
+
+static void
+mly_complete(struct mly_softc *sc)
+{
struct mly_command *mc;
void (* mc_complete)(struct mly_command *mc);
-
debug_called(2);
/*
@@ -1935,15 +1959,18 @@ mly_cam_attach(struct mly_softc *sc)
if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc,
device_get_unit(sc->mly_dev),
- &Giant,
+ &sc->mly_lock,
sc->mly_controllerinfo->maximum_parallel_commands,
1, devq)) == NULL) {
return(ENOMEM);
}
+ MLY_LOCK(sc);
if (xpt_bus_register(sc->mly_cam_sim[chn], sc->mly_dev, chn)) {
+ MLY_UNLOCK(sc);
mly_printf(sc, "CAM XPT phsyical channel registration failed\n");
return(ENXIO);
}
+ MLY_UNLOCK(sc);
debug(1, "registered physical channel %d", chn);
}
}
@@ -1955,15 +1982,18 @@ mly_cam_attach(struct mly_softc *sc)
for (i = 0; i < sc->mly_controllerinfo->virtual_channels_present; i++, chn++) {
if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc,
device_get_unit(sc->mly_dev),
- &Giant,
+ &sc->mly_lock,
sc->mly_controllerinfo->maximum_parallel_commands,
0, devq)) == NULL) {
return(ENOMEM);
}
+ MLY_LOCK(sc);
if (xpt_bus_register(sc->mly_cam_sim[chn], sc->mly_dev, chn)) {
+ MLY_UNLOCK(sc);
mly_printf(sc, "CAM XPT virtual channel registration failed\n");
return(ENXIO);
}
+ MLY_UNLOCK(sc);
debug(1, "registered virtual channel %d", chn);
}
@@ -1987,12 +2017,14 @@ mly_cam_detach(struct mly_softc *sc)
debug_called(1);
+ MLY_LOCK(sc);
for (i = 0; i < sc->mly_cam_channels; i++) {
if (sc->mly_cam_sim[i] != NULL) {
xpt_bus_deregister(cam_sim_path(sc->mly_cam_sim[i]));
cam_sim_free(sc->mly_cam_sim[i], 0);
}
}
+ MLY_UNLOCK(sc);
if (sc->mly_cam_devq != NULL)
cam_simq_free(sc->mly_cam_devq);
}
@@ -2030,6 +2062,7 @@ mly_cam_action(struct cam_sim *sim, union ccb *ccb)
struct mly_softc *sc = cam_sim_softc(sim);
debug_called(2);
+ MLY_ASSERT_LOCKED(sc);
switch (ccb->ccb_h.func_code) {
@@ -2173,7 +2206,6 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
struct mly_command_scsi_small *ss;
int bus, target;
int error;
- int s;
bus = cam_sim_bus(sim);
target = csio->ccb_h.target_id;
@@ -2220,11 +2252,9 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
* Get a command, or push the ccb back to CAM and freeze the queue.
*/
if ((error = mly_alloc_command(sc, &mc))) {
- s = splcam();
xpt_freeze_simq(sim, 1);
csio->ccb_h.status |= CAM_REQUEUE_REQ;
sc->mly_qfrzn_cnt++;
- splx(s);
return(error);
}
@@ -2270,11 +2300,9 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
/* give the command to the controller */
if ((error = mly_start(mc))) {
- s = splcam();
xpt_freeze_simq(sim, 1);
csio->ccb_h.status |= CAM_REQUEUE_REQ;
sc->mly_qfrzn_cnt++;
- splx(s);
return(error);
}
@@ -2306,7 +2334,6 @@ mly_cam_complete(struct mly_command *mc)
struct mly_btl *btl;
u_int8_t cmd;
int bus, target;
- int s;
debug_called(2);
@@ -2359,12 +2386,10 @@ mly_cam_complete(struct mly_command *mc)
break;
}
- s = splcam();
if (sc->mly_qfrzn_cnt) {
csio->ccb_h.status |= CAM_RELEASE_SIMQ;
sc->mly_qfrzn_cnt--;
}
- splx(s);
xpt_done((union ccb *)csio);
mly_release_command(mc);
@@ -2805,7 +2830,9 @@ mly_user_open(struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct mly_softc *sc = dev->si_drv1;
+ MLY_LOCK(sc);
sc->mly_state |= MLY_STATE_OPEN;
+ MLY_UNLOCK(sc);
return(0);
}
@@ -2817,7 +2844,9 @@ mly_user_close(struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct mly_softc *sc = dev->si_drv1;
+ MLY_LOCK(sc);
sc->mly_state &= ~MLY_STATE_OPEN;
+ MLY_UNLOCK(sc);
return (0);
}
@@ -2855,13 +2884,16 @@ static int
mly_user_command(struct mly_softc *sc, struct mly_user_command *uc)
{
struct mly_command *mc;
- int error, s;
+ int error;
/* allocate a command */
+ MLY_LOCK(sc);
if (mly_alloc_command(sc, &mc)) {
+ MLY_UNLOCK(sc);
error = ENOMEM;
goto out; /* XXX Linux version will wait for a command */
}
+ MLY_UNLOCK(sc);
/* handle data size/direction */
mc->mc_length = (uc->DataTransferLength >= 0) ? uc->DataTransferLength : -uc->DataTransferLength;
@@ -2888,12 +2920,14 @@ mly_user_command(struct mly_softc *sc, struct mly_user_command *uc)
mc->mc_complete = NULL;
/* execute the command */
- if ((error = mly_start(mc)) != 0)
+ MLY_LOCK(sc);
+ if ((error = mly_start(mc)) != 0) {
+ MLY_UNLOCK(sc);
goto out;
- s = splcam();
+ }
while (!(mc->mc_flags & MLY_CMD_COMPLETE))
- tsleep(mc, PRIBIO, "mlyioctl", 0);
- splx(s);
+ mtx_sleep(mc, &sc->mly_lock, PRIBIO, "mlyioctl", 0);
+ MLY_UNLOCK(sc);
/* return the data to userspace */
if (uc->DataTransferLength > 0)
@@ -2916,8 +2950,11 @@ mly_user_command(struct mly_softc *sc, struct mly_user_command *uc)
out:
if (mc->mc_data != NULL)
free(mc->mc_data, M_DEVBUF);
- if (mc != NULL)
+ if (mc != NULL) {
+ MLY_LOCK(sc);
mly_release_command(mc);
+ MLY_UNLOCK(sc);
+ }
return(error);
}
@@ -2931,32 +2968,36 @@ static int
mly_user_health(struct mly_softc *sc, struct mly_user_health *uh)
{
struct mly_health_status mh;
- int error, s;
+ int error;
/* fetch the current health status from userspace */
if ((error = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh))) != 0)
return(error);
/* spin waiting for a status update */
- s = splcam();
+ MLY_LOCK(sc);
error = EWOULDBLOCK;
while ((error != 0) && (sc->mly_event_change == mh.change_counter))
- error = tsleep(&sc->mly_event_change, PRIBIO | PCATCH, "mlyhealth", 0);
- splx(s);
+ error = mtx_sleep(&sc->mly_event_change, &sc->mly_lock, PRIBIO | PCATCH,
+ "mlyhealth", 0);
+ mh = sc->mly_mmbox->mmm_health.status;
+ MLY_UNLOCK(sc);
- /* copy the controller's health status buffer out (there is a race here if it changes again) */
- error = copyout(&sc->mly_mmbox->mmm_health.status, uh->HealthStatusBuffer,
- sizeof(uh->HealthStatusBuffer));
+ /* copy the controller's health status buffer out */
+ error = copyout(&mh, uh->HealthStatusBuffer, sizeof(mh));
return(error);
}
#ifdef MLY_DEBUG
-static int
-mly_timeout(struct mly_softc *sc)
+static void
+mly_timeout(void *arg)
{
+ struct mly_softc *sc;
struct mly_command *mc;
int deadline;
+ sc = arg;
+ MLY_ASSERT_LOCKED(sc);
deadline = time_second - MLY_CMD_TIMEOUT;
TAILQ_FOREACH(mc, &sc->mly_busy, mc_link) {
if ((mc->mc_timestamp < deadline)) {
@@ -2966,8 +3007,6 @@ mly_timeout(struct mly_softc *sc)
}
}
- timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz);
-
- return (0);
+ callout_reset(&sc->mly_timeout, MLY_CMD_TIMEOUT * hz, mly_timeout, sc);
}
#endif
diff --git a/sys/dev/mly/mlyvar.h b/sys/dev/mly/mlyvar.h
index 7413fa40e9eb..6bec8ebe6a45 100644
--- a/sys/dev/mly/mlyvar.h
+++ b/sys/dev/mly/mlyvar.h
@@ -59,10 +59,6 @@
# include <sys/taskqueue.h>
-#ifndef INTR_ENTROPY
-# define INTR_ENTROPY 0
-#endif
-
/********************************************************************************
********************************************************************************
Driver Variable Definitions
@@ -161,8 +157,6 @@ struct mly_softc {
struct cdev *mly_dev_t;
struct resource *mly_regs_resource; /* register interface window */
int mly_regs_rid; /* resource ID */
- bus_space_handle_t mly_bhandle; /* bus space handle */
- bus_space_tag_t mly_btag; /* bus space tag */
bus_dma_tag_t mly_parent_dmat; /* parent DMA tag */
bus_dma_tag_t mly_buffer_dmat; /* data buffer/command DMA tag */
struct resource *mly_irq; /* interrupt */
@@ -195,6 +189,7 @@ struct mly_softc {
u_int32_t mly_mmbox_status_index; /* index we next expect status at */
/* controller features, limits and status */
+ struct mtx mly_lock;
int mly_state;
#define MLY_STATE_OPEN (1<<1)
#define MLY_STATE_INTERRUPTS_ON (1<<2)
@@ -219,7 +214,7 @@ struct mly_softc {
u_int32_t mly_event_change; /* event status change indicator */
u_int32_t mly_event_counter; /* next event for which we anticpiate status */
u_int32_t mly_event_waiting; /* next event the controller will post status for */
- struct callout_handle mly_periodic; /* periodic event handling */
+ struct callout mly_periodic; /* periodic event handling */
/* CAM connection */
struct cam_devq *mly_cam_devq; /* CAM device queue */
@@ -230,29 +225,37 @@ struct mly_softc {
/* command-completion task */
struct task mly_task_complete; /* deferred-completion task */
int mly_qfrzn_cnt; /* Track simq freezes */
+
+#ifdef MLY_DEBUG
+ struct callout mly_timeout;
+#endif
};
+#define MLY_LOCK(sc) mtx_lock(&(sc)->mly_lock)
+#define MLY_UNLOCK(sc) mtx_unlock(&(sc)->mly_lock)
+#define MLY_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mly_lock, MA_OWNED)
+
/*
* Register access helpers.
*/
-#define MLY_SET_REG(sc, reg, val) bus_space_write_1(sc->mly_btag, sc->mly_bhandle, reg, val)
-#define MLY_GET_REG(sc, reg) bus_space_read_1 (sc->mly_btag, sc->mly_bhandle, reg)
-#define MLY_GET_REG2(sc, reg) bus_space_read_2 (sc->mly_btag, sc->mly_bhandle, reg)
-#define MLY_GET_REG4(sc, reg) bus_space_read_4 (sc->mly_btag, sc->mly_bhandle, reg)
+#define MLY_SET_REG(sc, reg, val) bus_write_1(sc->mly_regs_resource, reg, val)
+#define MLY_GET_REG(sc, reg) bus_read_1 (sc->mly_regs_resource, reg)
+#define MLY_GET_REG2(sc, reg) bus_read_2 (sc->mly_regs_resource, reg)
+#define MLY_GET_REG4(sc, reg) bus_read_4 (sc->mly_regs_resource, reg)
#define MLY_SET_MBOX(sc, mbox, ptr) \
do { \
- bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox, *((u_int32_t *)ptr)); \
- bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 4, *((u_int32_t *)ptr + 1)); \
- bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 8, *((u_int32_t *)ptr + 2)); \
- bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 12, *((u_int32_t *)ptr + 3)); \
+ bus_write_4(sc->mly_regs_resource, mbox, *((u_int32_t *)ptr)); \
+ bus_write_4(sc->mly_regs_resource, mbox + 4, *((u_int32_t *)ptr + 1)); \
+ bus_write_4(sc->mly_regs_resource, mbox + 8, *((u_int32_t *)ptr + 2)); \
+ bus_write_4(sc->mly_regs_resource, mbox + 12, *((u_int32_t *)ptr + 3)); \
} while(0);
#define MLY_GET_MBOX(sc, mbox, ptr) \
do { \
- *((u_int32_t *)ptr) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox); \
- *((u_int32_t *)ptr + 1) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 4); \
- *((u_int32_t *)ptr + 2) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 8); \
- *((u_int32_t *)ptr + 3) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 12); \
+ *((u_int32_t *)ptr) = bus_read_4(sc->mly_regs_resource, mbox); \
+ *((u_int32_t *)ptr + 1) = bus_read_4(sc->mly_regs_resource, mbox + 4); \
+ *((u_int32_t *)ptr + 2) = bus_read_4(sc->mly_regs_resource, mbox + 8); \
+ *((u_int32_t *)ptr + 3) = bus_read_4(sc->mly_regs_resource, mbox + 12); \
} while(0);
#define MLY_IDBR_TRUE(sc, mask) \
@@ -315,46 +318,34 @@ mly_initq_ ## name (struct mly_softc *sc) \
static __inline void \
mly_enqueue_ ## name (struct mly_command *mc) \
{ \
- int s; \
\
- s = splcam(); \
TAILQ_INSERT_TAIL(&mc->mc_sc->mly_ ## name, mc, mc_link); \
MLYQ_ADD(mc->mc_sc, index); \
- splx(s); \
} \
static __inline void \
mly_requeue_ ## name (struct mly_command *mc) \
{ \
- int s; \
\
- s = splcam(); \
TAILQ_INSERT_HEAD(&mc->mc_sc->mly_ ## name, mc, mc_link); \
MLYQ_ADD(mc->mc_sc, index); \
- splx(s); \
} \
static __inline struct mly_command * \
mly_dequeue_ ## name (struct mly_softc *sc) \
{ \
struct mly_command *mc; \
- int s; \
\
- s = splcam(); \
if ((mc = TAILQ_FIRST(&sc->mly_ ## name)) != NULL) { \
TAILQ_REMOVE(&sc->mly_ ## name, mc, mc_link); \
MLYQ_REMOVE(sc, index); \
} \
- splx(s); \
return(mc); \
} \
static __inline void \
mly_remove_ ## name (struct mly_command *mc) \
{ \
- int s; \
\
- s = splcam(); \
TAILQ_REMOVE(&mc->mc_sc->mly_ ## name, mc, mc_link); \
MLYQ_REMOVE(mc->mc_sc, index); \
- splx(s); \
} \
struct hack