mlx_pci.c revision 58188
151973Smsmith/*-
251973Smsmith * Copyright (c) 1999 Michael Smith
351973Smsmith * All rights reserved.
451973Smsmith *
551973Smsmith * Redistribution and use in source and binary forms, with or without
651973Smsmith * modification, are permitted provided that the following conditions
751973Smsmith * are met:
851973Smsmith * 1. Redistributions of source code must retain the above copyright
951973Smsmith *    notice, this list of conditions and the following disclaimer.
1051973Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1151973Smsmith *    notice, this list of conditions and the following disclaimer in the
1251973Smsmith *    documentation and/or other materials provided with the distribution.
1351973Smsmith *
1451973Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1551973Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1651973Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1751973Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1851973Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1951973Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2051973Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2151973Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2251973Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2351973Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2451973Smsmith * SUCH DAMAGE.
2551973Smsmith *
2651973Smsmith *	$FreeBSD: head/sys/dev/mlx/mlx_pci.c 58188 2000-03-18 02:01:37Z msmith $
2751973Smsmith */
2851973Smsmith
2951973Smsmith#include <sys/param.h>
3051973Smsmith#include <sys/systm.h>
3151973Smsmith#include <sys/malloc.h>
3251973Smsmith#include <sys/kernel.h>
3351973Smsmith
3451973Smsmith#include <sys/bus.h>
3551973Smsmith#include <sys/buf.h>
3651973Smsmith#include <sys/conf.h>
3751973Smsmith#include <sys/devicestat.h>
3851973Smsmith#include <sys/disk.h>
3951973Smsmith
4051973Smsmith#include <machine/bus_memio.h>
4151973Smsmith#include <machine/bus_pio.h>
4251973Smsmith#include <machine/bus.h>
4351973Smsmith#include <machine/resource.h>
4451973Smsmith#include <sys/rman.h>
4551973Smsmith
4651973Smsmith#include <pci/pcireg.h>
4751973Smsmith#include <pci/pcivar.h>
4851973Smsmith
4951973Smsmith#include <dev/mlx/mlxio.h>
5051973Smsmith#include <dev/mlx/mlxvar.h>
5152544Smsmith#include <dev/mlx/mlxreg.h>
5251973Smsmith
5351973Smsmithstatic int			mlx_pci_probe(device_t dev);
5451973Smsmithstatic int			mlx_pci_attach(device_t dev);
5551973Smsmith
5651973Smsmithstatic device_method_t mlx_methods[] = {
5751973Smsmith    /* Device interface */
5851973Smsmith    DEVMETHOD(device_probe,	mlx_pci_probe),
5951973Smsmith    DEVMETHOD(device_attach,	mlx_pci_attach),
6051973Smsmith    DEVMETHOD(device_detach,	mlx_detach),
6151973Smsmith    DEVMETHOD(device_shutdown,	mlx_shutdown),
6251973Smsmith    DEVMETHOD(device_suspend,	mlx_suspend),
6351973Smsmith    DEVMETHOD(device_resume,	mlx_resume),
6451973Smsmith
6551973Smsmith    DEVMETHOD(bus_print_child,	bus_generic_print_child),
6651973Smsmith    DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
6751973Smsmith    { 0, 0 }
6851973Smsmith};
6951973Smsmith
7051973Smsmithstatic driver_t mlx_pci_driver = {
7151973Smsmith	"mlx",
7251973Smsmith	mlx_methods,
7351973Smsmith	sizeof(struct mlx_softc)
7451973Smsmith};
7551973Smsmith
7651973SmsmithDRIVER_MODULE(mlx, pci, mlx_pci_driver, mlx_devclass, 0, 0);
7751973Smsmith
7854419Smsmithstruct mlx_ident
7951973Smsmith{
8051973Smsmith    u_int16_t	vendor;
8151973Smsmith    u_int16_t	device;
8254419Smsmith    u_int16_t	subvendor;
8354419Smsmith    u_int16_t	subdevice;
8451973Smsmith    int		iftype;
8551973Smsmith    char	*desc;
8651973Smsmith} mlx_identifiers[] = {
8758188Smsmith    {0x1069, 0x0001, 0x0000, 0x0000, MLX_IFTYPE_2, "Mylex version 2 RAID interface"},
8854419Smsmith    {0x1069, 0x0002, 0x0000, 0x0000, MLX_IFTYPE_3, "Mylex version 3 RAID interface"},
8954419Smsmith    {0x1069, 0x0010, 0x0000, 0x0000, MLX_IFTYPE_4, "Mylex version 4 RAID interface"},
9054419Smsmith    {0x1011, 0x1065, 0x1069, 0x0020, MLX_IFTYPE_5, "Mylex version 5 RAID interface"},
9154419Smsmith    {0, 0, 0, 0, 0, 0}
9251973Smsmith};
9351973Smsmith
9451973Smsmithstatic int
9551973Smsmithmlx_pci_probe(device_t dev)
9651973Smsmith{
9754419Smsmith    struct mlx_ident	*m;
9851973Smsmith
9958188Smsmith    debug_called(1);
10051973Smsmith
10154419Smsmith    for (m = mlx_identifiers; m->vendor != 0; m++) {
10254419Smsmith	if ((m->vendor == pci_get_vendor(dev)) &&
10354419Smsmith	    (m->device == pci_get_device(dev)) &&
10454419Smsmith	    ((m->subvendor == 0) || ((m->subvendor == pci_get_subvendor(dev)) &&
10554419Smsmith				     (m->subdevice == pci_get_subdevice(dev))))) {
10651973Smsmith
10754419Smsmith	    device_set_desc(dev, m->desc);
10851973Smsmith	    return(0);
10951973Smsmith	}
11051973Smsmith    }
11151973Smsmith    return(ENXIO);
11251973Smsmith}
11351973Smsmith
11451973Smsmithstatic int
11551973Smsmithmlx_pci_attach(device_t dev)
11651973Smsmith{
11751973Smsmith    struct mlx_softc	*sc;
11851973Smsmith    int			i, rid, error;
11951973Smsmith    u_int32_t		command;
12051973Smsmith
12158188Smsmith    debug_called(1);
12251973Smsmith
12351973Smsmith    /*
12451973Smsmith     * Make sure we are going to be able to talk to this board.
12551973Smsmith     */
12658188Smsmith    command = pci_read_config(dev, PCIR_COMMAND, 2);
12751973Smsmith    if ((command & PCIM_CMD_MEMEN) == 0) {
12851973Smsmith	device_printf(dev, "memory window not available\n");
12951973Smsmith	return(ENXIO);
13051973Smsmith    }
13158188Smsmith    /* force the busmaster enable bit on */
13258188Smsmith    command |= PCIM_CMD_BUSMASTEREN;
13358188Smsmith    pci_write_config(dev, PCIR_COMMAND, command, 2);
13451973Smsmith
13551973Smsmith    /*
13651973Smsmith     * Initialise softc.
13751973Smsmith     */
13851973Smsmith    sc = device_get_softc(dev);
13951973Smsmith    bzero(sc, sizeof(*sc));
14051973Smsmith    sc->mlx_dev = dev;
14151973Smsmith
14251973Smsmith    /*
14351973Smsmith     * Work out what sort of adapter this is (we need to know this in order
14451973Smsmith     * to map the appropriate interface resources).
14551973Smsmith     */
14651973Smsmith    sc->mlx_iftype = 0;
14751973Smsmith    for (i = 0; mlx_identifiers[i].vendor != 0; i++) {
14851973Smsmith	if ((mlx_identifiers[i].vendor == pci_get_vendor(dev)) &&
14951973Smsmith	    (mlx_identifiers[i].device == pci_get_device(dev))) {
15051973Smsmith	    sc->mlx_iftype = mlx_identifiers[i].iftype;
15151973Smsmith	    break;
15251973Smsmith	}
15351973Smsmith    }
15451973Smsmith    if (sc->mlx_iftype == 0)		/* shouldn't happen */
15551973Smsmith	return(ENXIO);
15651973Smsmith
15751973Smsmith    /*
15851973Smsmith     * Allocate the PCI register window.
15951973Smsmith     */
16051973Smsmith
16158188Smsmith    /* type 2/3 adapters have an I/O region we don't use at base 0 */
16258188Smsmith    switch(sc->mlx_iftype) {
16358188Smsmith    case MLX_IFTYPE_2:
16458188Smsmith    case MLX_IFTYPE_3:
16558188Smsmith	rid = MLX_CFG_BASE1;
16658188Smsmith	break;
16758188Smsmith    case MLX_IFTYPE_4:
16858188Smsmith    case MLX_IFTYPE_5:
16958188Smsmith	rid = MLX_CFG_BASE0;
17058188Smsmith	break;
17158188Smsmith    }
17251973Smsmith    sc->mlx_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE);
17351973Smsmith    if (sc->mlx_mem == NULL) {
17451973Smsmith	device_printf(sc->mlx_dev, "couldn't allocate mailbox window\n");
17551973Smsmith	mlx_free(sc);
17651973Smsmith	return(ENXIO);
17751973Smsmith    }
17851973Smsmith    sc->mlx_btag = rman_get_bustag(sc->mlx_mem);
17951973Smsmith    sc->mlx_bhandle = rman_get_bushandle(sc->mlx_mem);
18051973Smsmith
18151973Smsmith    /*
18251973Smsmith     * Allocate the parent bus DMA tag appropriate for PCI.
18351973Smsmith     */
18451973Smsmith    error = bus_dma_tag_create(NULL, 			/* parent */
18551973Smsmith			       1, 0, 			/* alignment, boundary */
18651973Smsmith			       BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
18751973Smsmith			       BUS_SPACE_MAXADDR, 	/* highaddr */
18851973Smsmith			       NULL, NULL, 		/* filter, filterarg */
18958188Smsmith			       MAXBSIZE, MLX_NSEG_NEW,	/* maxsize, nsegments */
19051973Smsmith			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
19151973Smsmith			       BUS_DMA_ALLOCNOW,	/* flags */
19251973Smsmith			       &sc->mlx_parent_dmat);
19351973Smsmith    if (error != 0) {
19451973Smsmith	device_printf(dev, "can't allocate parent DMA tag\n");
19551973Smsmith	mlx_free(sc);
19651973Smsmith	return(ENOMEM);
19751973Smsmith    }
19851973Smsmith
19951973Smsmith    /*
20051973Smsmith     * Do bus-independant initialisation.
20151973Smsmith     */
20251973Smsmith    error = mlx_attach(sc);
20351973Smsmith    if (error != 0) {
20451973Smsmith	mlx_free(sc);
20551973Smsmith	return(error);
20651973Smsmith    }
20751973Smsmith
20851973Smsmith    /*
20951973Smsmith     * Start the controller.
21051973Smsmith     */
21151973Smsmith    mlx_startup(sc);
21251973Smsmith    return(0);
21351973Smsmith}
214