Add locking to mlx(4) to make it MPSAFE along with some other fixes:
- Use callout(9) rather than timeout(9). - Add a mutex as an I/O lock that protects the adapter and is used for the I/O path. - Add an sx lock as a configuration lock that protects the relationship of configured volumes. - Freeze the request queue when a DMA load is deferred with EINPROGRESS and unfreeze the queue when the DMA callback is invoked. - Explicitly poll the hardware while waiting to submit a command to allow completed commands to free up slots in the command ring. - Remove driver-wide 'initted' variable from mlx_*_fw_handshake() routines. That state should be per-controller instead. Add it as an argument since the first caller knows when it is the first caller. - Remove explicit bus_space tag/handle and use bus_*() rather than bus_space_*(). - Move duplicated PCI device ID probing into a mlx_pci_match() routine. - Don't check for PCIM_CMD_MEMEN (the PCI bus will enable that when allocating the resource) and use pci_enable_busmaster() rather than manipulating the register directly. Tested by: no one despite multiple requests (hope it works)
This commit is contained in:
parent
8b3daf895a
commit
0fca6f8bf5
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sx.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
@ -84,10 +86,17 @@ mlxd_open(struct disk *dp)
|
||||
return (ENXIO);
|
||||
|
||||
/* controller not active? */
|
||||
if (sc->mlxd_controller->mlx_state & MLX_STATE_SHUTDOWN)
|
||||
MLX_CONFIG_LOCK(sc->mlxd_controller);
|
||||
MLX_IO_LOCK(sc->mlxd_controller);
|
||||
if (sc->mlxd_controller->mlx_state & MLX_STATE_SHUTDOWN) {
|
||||
MLX_IO_UNLOCK(sc->mlxd_controller);
|
||||
MLX_CONFIG_UNLOCK(sc->mlxd_controller);
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
sc->mlxd_flags |= MLXD_OPEN;
|
||||
MLX_IO_UNLOCK(sc->mlxd_controller);
|
||||
MLX_CONFIG_UNLOCK(sc->mlxd_controller);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -97,10 +106,14 @@ mlxd_close(struct disk *dp)
|
||||
struct mlxd_softc *sc = (struct mlxd_softc *)dp->d_drv1;
|
||||
|
||||
debug_called(1);
|
||||
|
||||
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
MLX_CONFIG_LOCK(sc->mlxd_controller);
|
||||
MLX_IO_LOCK(sc->mlxd_controller);
|
||||
sc->mlxd_flags &= ~MLXD_OPEN;
|
||||
MLX_IO_UNLOCK(sc->mlxd_controller);
|
||||
MLX_CONFIG_UNLOCK(sc->mlxd_controller);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -142,13 +155,16 @@ mlxd_strategy(mlx_bio *bp)
|
||||
}
|
||||
|
||||
/* XXX may only be temporarily offline - sleep? */
|
||||
MLX_IO_LOCK(sc->mlxd_controller);
|
||||
if (sc->mlxd_drive->ms_state == MLX_SYSD_OFFLINE) {
|
||||
MLX_IO_UNLOCK(sc->mlxd_controller);
|
||||
MLX_BIO_SET_ERROR(bp, ENXIO);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
MLX_BIO_STATS_START(bp);
|
||||
mlx_submit_buf(sc->mlxd_controller, bp);
|
||||
MLX_IO_UNLOCK(sc->mlxd_controller);
|
||||
return;
|
||||
|
||||
bad:
|
||||
@ -232,7 +248,6 @@ mlxd_attach(device_t dev)
|
||||
sc->mlxd_disk->d_mediasize = MLX_BLKSIZE * (off_t)sc->mlxd_drive->ms_size;
|
||||
sc->mlxd_disk->d_fwsectors = sc->mlxd_drive->ms_sectors;
|
||||
sc->mlxd_disk->d_fwheads = sc->mlxd_drive->ms_heads;
|
||||
sc->mlxd_disk->d_flags = DISKFLAG_NEEDSGIANT;
|
||||
|
||||
/*
|
||||
* Set maximum I/O size to the lesser of the recommended maximum and the practical
|
||||
|
@ -30,7 +30,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sx.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
@ -88,6 +91,21 @@ struct mlx_ident
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct mlx_ident *
|
||||
mlx_pci_match(device_t dev)
|
||||
{
|
||||
struct mlx_ident *m;
|
||||
|
||||
for (m = mlx_identifiers; m->vendor != 0; m++) {
|
||||
if ((m->vendor == pci_get_vendor(dev)) &&
|
||||
(m->device == pci_get_device(dev)) &&
|
||||
((m->subvendor == 0) || ((m->subvendor == pci_get_subvendor(dev)) &&
|
||||
(m->subdevice == pci_get_subdevice(dev)))))
|
||||
return (m);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
mlx_pci_probe(device_t dev)
|
||||
{
|
||||
@ -95,15 +113,10 @@ mlx_pci_probe(device_t dev)
|
||||
|
||||
debug_called(1);
|
||||
|
||||
for (m = mlx_identifiers; m->vendor != 0; m++) {
|
||||
if ((m->vendor == pci_get_vendor(dev)) &&
|
||||
(m->device == pci_get_device(dev)) &&
|
||||
((m->subvendor == 0) || ((m->subvendor == pci_get_subvendor(dev)) &&
|
||||
(m->subdevice == pci_get_subdevice(dev))))) {
|
||||
|
||||
device_set_desc(dev, m->desc);
|
||||
return(BUS_PROBE_DEFAULT);
|
||||
}
|
||||
m = mlx_pci_match(dev);
|
||||
if (m != NULL) {
|
||||
device_set_desc(dev, m->desc);
|
||||
return(BUS_PROBE_DEFAULT);
|
||||
}
|
||||
return(ENXIO);
|
||||
}
|
||||
@ -112,45 +125,29 @@ static int
|
||||
mlx_pci_attach(device_t dev)
|
||||
{
|
||||
struct mlx_softc *sc;
|
||||
int i, error;
|
||||
u_int32_t command;
|
||||
struct mlx_ident *m;
|
||||
int error;
|
||||
|
||||
debug_called(1);
|
||||
|
||||
/*
|
||||
* Make sure we are going to be able to talk to this board.
|
||||
*/
|
||||
command = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
if ((command & PCIM_CMD_MEMEN) == 0) {
|
||||
device_printf(dev, "memory window not available\n");
|
||||
return(ENXIO);
|
||||
}
|
||||
/* force the busmaster enable bit on */
|
||||
command |= PCIM_CMD_BUSMASTEREN;
|
||||
pci_write_config(dev, PCIR_COMMAND, command, 2);
|
||||
pci_enable_busmaster(dev);
|
||||
|
||||
/*
|
||||
* Initialise softc.
|
||||
*/
|
||||
sc = device_get_softc(dev);
|
||||
bzero(sc, sizeof(*sc));
|
||||
sc->mlx_dev = dev;
|
||||
|
||||
/*
|
||||
* Work out what sort of adapter this is (we need to know this in order
|
||||
* to map the appropriate interface resources).
|
||||
*/
|
||||
sc->mlx_iftype = 0;
|
||||
for (i = 0; mlx_identifiers[i].vendor != 0; i++) {
|
||||
if ((mlx_identifiers[i].vendor == pci_get_vendor(dev)) &&
|
||||
(mlx_identifiers[i].device == pci_get_device(dev))) {
|
||||
sc->mlx_iftype = mlx_identifiers[i].iftype;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sc->mlx_iftype == 0) /* shouldn't happen */
|
||||
m = mlx_pci_match(dev);
|
||||
if (m == NULL) /* shouldn't happen */
|
||||
return(ENXIO);
|
||||
|
||||
sc->mlx_iftype = m->iftype;
|
||||
|
||||
mtx_init(&sc->mlx_io_lock, "mlx I/O", NULL, MTX_DEF);
|
||||
sx_init(&sc->mlx_config_lock, "mlx config");
|
||||
callout_init_mtx(&sc->mlx_timeout, &sc->mlx_io_lock, 0);
|
||||
|
||||
/*
|
||||
* Allocate the PCI register window.
|
||||
*/
|
||||
@ -183,8 +180,6 @@ mlx_pci_attach(device_t dev)
|
||||
mlx_free(sc);
|
||||
return(ENXIO);
|
||||
}
|
||||
sc->mlx_btag = rman_get_bustag(sc->mlx_mem);
|
||||
sc->mlx_bhandle = rman_get_bushandle(sc->mlx_mem);
|
||||
|
||||
/*
|
||||
* Allocate the parent bus DMA tag appropriate for PCI.
|
||||
|
@ -78,18 +78,18 @@
|
||||
#define MLX_V3_FWERROR_PARAM1 0x00
|
||||
#define MLX_V3_FWERROR_PARAM2 0x01
|
||||
|
||||
#define MLX_V3_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_MAILBOX + idx, val)
|
||||
#define MLX_V3_GET_STATUS_IDENT(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_STATUS_IDENT)
|
||||
#define MLX_V3_GET_STATUS(sc) bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_STATUS)
|
||||
#define MLX_V3_GET_IDBR(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IDBR)
|
||||
#define MLX_V3_PUT_IDBR(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IDBR, val)
|
||||
#define MLX_V3_GET_ODBR(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_ODBR)
|
||||
#define MLX_V3_PUT_ODBR(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_ODBR, val)
|
||||
#define MLX_V3_PUT_IER(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IER, val)
|
||||
#define MLX_V3_GET_FWERROR(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR)
|
||||
#define MLX_V3_PUT_FWERROR(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR, val)
|
||||
#define MLX_V3_GET_FWERROR_PARAM1(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR_PARAM1)
|
||||
#define MLX_V3_GET_FWERROR_PARAM2(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR_PARAM2)
|
||||
#define MLX_V3_PUT_MAILBOX(sc, idx, val) bus_write_1(sc->mlx_mem, MLX_V3_MAILBOX + idx, val)
|
||||
#define MLX_V3_GET_STATUS_IDENT(sc) bus_read_1 (sc->mlx_mem, MLX_V3_STATUS_IDENT)
|
||||
#define MLX_V3_GET_STATUS(sc) bus_read_2 (sc->mlx_mem, MLX_V3_STATUS)
|
||||
#define MLX_V3_GET_IDBR(sc) bus_read_1 (sc->mlx_mem, MLX_V3_IDBR)
|
||||
#define MLX_V3_PUT_IDBR(sc, val) bus_write_1(sc->mlx_mem, MLX_V3_IDBR, val)
|
||||
#define MLX_V3_GET_ODBR(sc) bus_read_1 (sc->mlx_mem, MLX_V3_ODBR)
|
||||
#define MLX_V3_PUT_ODBR(sc, val) bus_write_1(sc->mlx_mem, MLX_V3_ODBR, val)
|
||||
#define MLX_V3_PUT_IER(sc, val) bus_write_1(sc->mlx_mem, MLX_V3_IER, val)
|
||||
#define MLX_V3_GET_FWERROR(sc) bus_read_1 (sc->mlx_mem, MLX_V3_FWERROR)
|
||||
#define MLX_V3_PUT_FWERROR(sc, val) bus_write_1(sc->mlx_mem, MLX_V3_FWERROR, val)
|
||||
#define MLX_V3_GET_FWERROR_PARAM1(sc) bus_read_1 (sc->mlx_mem, MLX_V3_FWERROR_PARAM1)
|
||||
#define MLX_V3_GET_FWERROR_PARAM2(sc) bus_read_1 (sc->mlx_mem, MLX_V3_FWERROR_PARAM2)
|
||||
|
||||
#define MLX_V3_IDB_FULL (1<<0) /* mailbox is full */
|
||||
#define MLX_V3_IDB_INIT_BUSY (1<<1) /* initialisation in progress */
|
||||
@ -115,18 +115,18 @@
|
||||
#define MLX_V4_FWERROR_PARAM2 0x1001
|
||||
|
||||
/* use longword access? */
|
||||
#define MLX_V4_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_MAILBOX + idx, val)
|
||||
#define MLX_V4_GET_STATUS_IDENT(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_STATUS_IDENT)
|
||||
#define MLX_V4_GET_STATUS(sc) bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_STATUS)
|
||||
#define MLX_V4_GET_IDBR(sc) bus_space_read_4 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IDBR)
|
||||
#define MLX_V4_PUT_IDBR(sc, val) bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IDBR, val)
|
||||
#define MLX_V4_GET_ODBR(sc) bus_space_read_4 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_ODBR)
|
||||
#define MLX_V4_PUT_ODBR(sc, val) bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_ODBR, val)
|
||||
#define MLX_V4_PUT_IER(sc, val) bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IER, val)
|
||||
#define MLX_V4_GET_FWERROR(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR)
|
||||
#define MLX_V4_PUT_FWERROR(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR, val)
|
||||
#define MLX_V4_GET_FWERROR_PARAM1(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR_PARAM1)
|
||||
#define MLX_V4_GET_FWERROR_PARAM2(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR_PARAM2)
|
||||
#define MLX_V4_PUT_MAILBOX(sc, idx, val) bus_write_1(sc->mlx_mem, MLX_V4_MAILBOX + idx, val)
|
||||
#define MLX_V4_GET_STATUS_IDENT(sc) bus_read_1 (sc->mlx_mem, MLX_V4_STATUS_IDENT)
|
||||
#define MLX_V4_GET_STATUS(sc) bus_read_2 (sc->mlx_mem, MLX_V4_STATUS)
|
||||
#define MLX_V4_GET_IDBR(sc) bus_read_4 (sc->mlx_mem, MLX_V4_IDBR)
|
||||
#define MLX_V4_PUT_IDBR(sc, val) bus_write_4(sc->mlx_mem, MLX_V4_IDBR, val)
|
||||
#define MLX_V4_GET_ODBR(sc) bus_read_4 (sc->mlx_mem, MLX_V4_ODBR)
|
||||
#define MLX_V4_PUT_ODBR(sc, val) bus_write_4(sc->mlx_mem, MLX_V4_ODBR, val)
|
||||
#define MLX_V4_PUT_IER(sc, val) bus_write_4(sc->mlx_mem, MLX_V4_IER, val)
|
||||
#define MLX_V4_GET_FWERROR(sc) bus_read_1 (sc->mlx_mem, MLX_V4_FWERROR)
|
||||
#define MLX_V4_PUT_FWERROR(sc, val) bus_write_1(sc->mlx_mem, MLX_V4_FWERROR, val)
|
||||
#define MLX_V4_GET_FWERROR_PARAM1(sc) bus_read_1 (sc->mlx_mem, MLX_V4_FWERROR_PARAM1)
|
||||
#define MLX_V4_GET_FWERROR_PARAM2(sc) bus_read_1 (sc->mlx_mem, MLX_V4_FWERROR_PARAM2)
|
||||
|
||||
#define MLX_V4_IDB_FULL (1<<0) /* mailbox is full */
|
||||
#define MLX_V4_IDB_INIT_BUSY (1<<1) /* initialisation in progress */
|
||||
@ -160,18 +160,18 @@
|
||||
#define MLX_V5_FWERROR_PARAM1 0x50
|
||||
#define MLX_V5_FWERROR_PARAM2 0x51
|
||||
|
||||
#define MLX_V5_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_MAILBOX + idx, val)
|
||||
#define MLX_V5_GET_STATUS_IDENT(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_STATUS_IDENT)
|
||||
#define MLX_V5_GET_STATUS(sc) bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_STATUS)
|
||||
#define MLX_V5_GET_IDBR(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IDBR)
|
||||
#define MLX_V5_PUT_IDBR(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IDBR, val)
|
||||
#define MLX_V5_GET_ODBR(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_ODBR)
|
||||
#define MLX_V5_PUT_ODBR(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_ODBR, val)
|
||||
#define MLX_V5_PUT_IER(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IER, val)
|
||||
#define MLX_V5_GET_FWERROR(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR)
|
||||
#define MLX_V5_PUT_FWERROR(sc, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR, val)
|
||||
#define MLX_V5_GET_FWERROR_PARAM1(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR_PARAM1)
|
||||
#define MLX_V5_GET_FWERROR_PARAM2(sc) bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR_PARAM2)
|
||||
#define MLX_V5_PUT_MAILBOX(sc, idx, val) bus_write_1(sc->mlx_mem, MLX_V5_MAILBOX + idx, val)
|
||||
#define MLX_V5_GET_STATUS_IDENT(sc) bus_read_1 (sc->mlx_mem, MLX_V5_STATUS_IDENT)
|
||||
#define MLX_V5_GET_STATUS(sc) bus_read_2 (sc->mlx_mem, MLX_V5_STATUS)
|
||||
#define MLX_V5_GET_IDBR(sc) bus_read_1 (sc->mlx_mem, MLX_V5_IDBR)
|
||||
#define MLX_V5_PUT_IDBR(sc, val) bus_write_1(sc->mlx_mem, MLX_V5_IDBR, val)
|
||||
#define MLX_V5_GET_ODBR(sc) bus_read_1 (sc->mlx_mem, MLX_V5_ODBR)
|
||||
#define MLX_V5_PUT_ODBR(sc, val) bus_write_1(sc->mlx_mem, MLX_V5_ODBR, val)
|
||||
#define MLX_V5_PUT_IER(sc, val) bus_write_1(sc->mlx_mem, MLX_V5_IER, val)
|
||||
#define MLX_V5_GET_FWERROR(sc) bus_read_1 (sc->mlx_mem, MLX_V5_FWERROR)
|
||||
#define MLX_V5_PUT_FWERROR(sc, val) bus_write_1(sc->mlx_mem, MLX_V5_FWERROR, val)
|
||||
#define MLX_V5_GET_FWERROR_PARAM1(sc) bus_read_1 (sc->mlx_mem, MLX_V5_FWERROR_PARAM1)
|
||||
#define MLX_V5_GET_FWERROR_PARAM2(sc) bus_read_1 (sc->mlx_mem, MLX_V5_FWERROR_PARAM2)
|
||||
|
||||
#define MLX_V5_IDB_EMPTY (1<<0) /* mailbox is empty */
|
||||
#define MLX_V5_IDB_INIT_DONE (1<<1) /* initialisation has completed */
|
||||
|
@ -113,8 +113,6 @@ struct mlx_softc
|
||||
struct resource *mlx_mem; /* mailbox interface window */
|
||||
int mlx_mem_rid;
|
||||
int mlx_mem_type;
|
||||
bus_space_handle_t mlx_bhandle; /* bus space handle */
|
||||
bus_space_tag_t mlx_btag; /* bus space tag */
|
||||
bus_dma_tag_t mlx_parent_dmat;/* parent DMA tag */
|
||||
bus_dma_tag_t mlx_buffer_dmat;/* data buffer DMA tag */
|
||||
struct resource *mlx_irq; /* interrupt */
|
||||
@ -149,7 +147,10 @@ struct mlx_softc
|
||||
#define MLX_STATE_SHUTDOWN (1<<1) /* controller is shut down */
|
||||
#define MLX_STATE_OPEN (1<<2) /* control device is open */
|
||||
#define MLX_STATE_SUSPEND (1<<3) /* controller is suspended */
|
||||
struct callout_handle mlx_timeout; /* periodic status monitor */
|
||||
#define MLX_STATE_QFROZEN (1<<4) /* bio queue frozen */
|
||||
struct mtx mlx_io_lock;
|
||||
struct sx mlx_config_lock;
|
||||
struct callout mlx_timeout; /* periodic status monitor */
|
||||
time_t mlx_lastpoll; /* last time_second we polled for status */
|
||||
u_int16_t mlx_lastevent; /* sequence number of the last event we recorded */
|
||||
int mlx_currevent; /* sequence number last time we looked */
|
||||
@ -160,7 +161,6 @@ struct mlx_softc
|
||||
struct mlx_rebuild_status mlx_rebuildstat; /* last rebuild status */
|
||||
struct mlx_pause mlx_pause; /* pending pause operation details */
|
||||
|
||||
int mlx_locks; /* reentrancy avoidance */
|
||||
int mlx_flags;
|
||||
#define MLX_SPINUP_REPORTED (1<<0) /* "spinning up drives" message displayed */
|
||||
#define MLX_EVENTLOG_BUSY (1<<1) /* currently reading event log */
|
||||
@ -174,34 +174,17 @@ struct mlx_softc
|
||||
int (* mlx_tryqueue)(struct mlx_softc *sc, struct mlx_command *mc);
|
||||
int (* mlx_findcomplete)(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
|
||||
void (* mlx_intaction)(struct mlx_softc *sc, int action);
|
||||
int (* mlx_fw_handshake)(struct mlx_softc *sc, int *error, int *param1, int *param2);
|
||||
int (* mlx_fw_handshake)(struct mlx_softc *sc, int *error, int *param1, int *param2, int first);
|
||||
#define MLX_INTACTION_DISABLE 0
|
||||
#define MLX_INTACTION_ENABLE 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Simple (stupid) locks.
|
||||
*
|
||||
* Note that these are designed to avoid reentrancy, not concurrency, and will
|
||||
* need to be replaced with something better.
|
||||
*/
|
||||
#define MLX_LOCK_COMPLETING (1<<0)
|
||||
#define MLX_LOCK_STARTING (1<<1)
|
||||
|
||||
static __inline int
|
||||
mlx_lock_tas(struct mlx_softc *sc, int lock)
|
||||
{
|
||||
if ((sc)->mlx_locks & (lock))
|
||||
return(1);
|
||||
atomic_set_int(&sc->mlx_locks, lock);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
mlx_lock_clr(struct mlx_softc *sc, int lock)
|
||||
{
|
||||
atomic_clear_int(&sc->mlx_locks, lock);
|
||||
}
|
||||
#define MLX_IO_LOCK(sc) mtx_lock(&(sc)->mlx_io_lock)
|
||||
#define MLX_IO_UNLOCK(sc) mtx_unlock(&(sc)->mlx_io_lock)
|
||||
#define MLX_IO_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mlx_io_lock, MA_OWNED)
|
||||
#define MLX_CONFIG_LOCK(sc) sx_xlock(&(sc)->mlx_config_lock)
|
||||
#define MLX_CONFIG_UNLOCK(sc) sx_xunlock(&(sc)->mlx_config_lock)
|
||||
#define MLX_CONFIG_ASSERT_LOCKED(sc) sx_assert(&(sc)->mlx_config_lock, SA_XLOCKED)
|
||||
|
||||
/*
|
||||
* Interface between bus connections and driver core.
|
||||
|
Loading…
Reference in New Issue
Block a user