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
This commit is contained in:
jhb 2014-11-18 21:55:50 +00:00
parent e608775202
commit 9cc63a16af
2 changed files with 131 additions and 101 deletions

View File

@ -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

View File

@ -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