From 1c617b0215c987e6d4fa0ebf715289dc62fad795 Mon Sep 17 00:00:00 2001 From: jhb Date: Mon, 17 Sep 2012 15:27:30 +0000 Subject: 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) --- sys/dev/mlx/mlx_pci.c | 71 ++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 38 deletions(-) (limited to 'sys/dev/mlx/mlx_pci.c') diff --git a/sys/dev/mlx/mlx_pci.c b/sys/dev/mlx/mlx_pci.c index 92ad878..abc2d90 100644 --- a/sys/dev/mlx/mlx_pci.c +++ b/sys/dev/mlx/mlx_pci.c @@ -30,7 +30,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include +#include #include #include @@ -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. -- cgit v1.1