The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/mlx/mlx_pci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999 Michael Smith
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/kernel.h>
   33 #include <sys/module.h>
   34 
   35 #include <sys/bus.h>
   36 #include <sys/conf.h>
   37 
   38 #include <machine/bus_memio.h>
   39 #include <machine/bus_pio.h>
   40 #include <machine/bus.h>
   41 #include <machine/resource.h>
   42 #include <sys/rman.h>
   43 
   44 #include <geom/geom_disk.h>
   45 
   46 #include <dev/pci/pcireg.h>
   47 #include <dev/pci/pcivar.h>
   48 
   49 #include <dev/mlx/mlx_compat.h>
   50 #include <dev/mlx/mlxio.h>
   51 #include <dev/mlx/mlxvar.h>
   52 #include <dev/mlx/mlxreg.h>
   53 
   54 static int                      mlx_pci_probe(device_t dev);
   55 static int                      mlx_pci_attach(device_t dev);
   56 
   57 static device_method_t mlx_methods[] = {
   58     /* Device interface */
   59     DEVMETHOD(device_probe,     mlx_pci_probe),
   60     DEVMETHOD(device_attach,    mlx_pci_attach),
   61     DEVMETHOD(device_detach,    mlx_detach),
   62     DEVMETHOD(device_shutdown,  mlx_shutdown),
   63     DEVMETHOD(device_suspend,   mlx_suspend),
   64     DEVMETHOD(device_resume,    mlx_resume),
   65 
   66     DEVMETHOD(bus_print_child,  bus_generic_print_child),
   67     DEVMETHOD(bus_driver_added, bus_generic_driver_added),
   68     { 0, 0 }
   69 };
   70 
   71 static driver_t mlx_pci_driver = {
   72         "mlx",
   73         mlx_methods,
   74         sizeof(struct mlx_softc)
   75 };
   76 
   77 DRIVER_MODULE(mlx, pci, mlx_pci_driver, mlx_devclass, 0, 0);
   78 
   79 struct mlx_ident
   80 {
   81     u_int16_t   vendor;
   82     u_int16_t   device;
   83     u_int16_t   subvendor;
   84     u_int16_t   subdevice;
   85     int         iftype;
   86     char        *desc;
   87 } mlx_identifiers[] = {
   88     {0x1069, 0x0001, 0x0000, 0x0000, MLX_IFTYPE_2, "Mylex version 2 RAID interface"},
   89     {0x1069, 0x0002, 0x0000, 0x0000, MLX_IFTYPE_3, "Mylex version 3 RAID interface"},
   90     {0x1069, 0x0010, 0x0000, 0x0000, MLX_IFTYPE_4, "Mylex version 4 RAID interface"},
   91     {0x1011, 0x1065, 0x1069, 0x0020, MLX_IFTYPE_5, "Mylex version 5 RAID interface"},
   92     {0, 0, 0, 0, 0, 0}
   93 };
   94 
   95 static int
   96 mlx_pci_probe(device_t dev)
   97 {
   98     struct mlx_ident    *m;
   99 
  100     debug_called(1);
  101 
  102     for (m = mlx_identifiers; m->vendor != 0; m++) {
  103         if ((m->vendor == pci_get_vendor(dev)) &&
  104             (m->device == pci_get_device(dev)) &&
  105             ((m->subvendor == 0) || ((m->subvendor == pci_get_subvendor(dev)) &&
  106                                      (m->subdevice == pci_get_subdevice(dev))))) {
  107             
  108             device_set_desc(dev, m->desc);
  109             return(-10);        /* allow room to be overridden */
  110         }
  111     }
  112     return(ENXIO);
  113 }
  114 
  115 static int
  116 mlx_pci_attach(device_t dev)
  117 {
  118     struct mlx_softc    *sc;
  119     int                 i, error;
  120     u_int32_t           command;
  121 
  122     debug_called(1);
  123 
  124     /*
  125      * Make sure we are going to be able to talk to this board.
  126      */
  127     command = pci_read_config(dev, PCIR_COMMAND, 2);
  128     if ((command & PCIM_CMD_MEMEN) == 0) {
  129         device_printf(dev, "memory window not available\n");
  130         return(ENXIO);
  131     }
  132     /* force the busmaster enable bit on */
  133     command |= PCIM_CMD_BUSMASTEREN;
  134     pci_write_config(dev, PCIR_COMMAND, command, 2);
  135 
  136     /*
  137      * Initialise softc.
  138      */
  139     sc = device_get_softc(dev);
  140     bzero(sc, sizeof(*sc));
  141     sc->mlx_dev = dev;
  142 
  143     /*
  144      * Work out what sort of adapter this is (we need to know this in order
  145      * to map the appropriate interface resources).
  146      */
  147     sc->mlx_iftype = 0;
  148     for (i = 0; mlx_identifiers[i].vendor != 0; i++) {
  149         if ((mlx_identifiers[i].vendor == pci_get_vendor(dev)) &&
  150             (mlx_identifiers[i].device == pci_get_device(dev))) {
  151             sc->mlx_iftype = mlx_identifiers[i].iftype;
  152             break;
  153         }
  154     }
  155     if (sc->mlx_iftype == 0)            /* shouldn't happen */
  156         return(ENXIO);
  157     
  158     /*
  159      * Allocate the PCI register window.
  160      */
  161     
  162     /* type 2/3 adapters have an I/O region we don't prefer at base 0 */
  163     switch(sc->mlx_iftype) {
  164     case MLX_IFTYPE_2:
  165     case MLX_IFTYPE_3:
  166         sc->mlx_mem_type = SYS_RES_MEMORY;
  167         sc->mlx_mem_rid = MLX_CFG_BASE1;
  168         sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type,
  169                 &sc->mlx_mem_rid, RF_ACTIVE);
  170         if (sc->mlx_mem == NULL) {
  171             sc->mlx_mem_type = SYS_RES_IOPORT;
  172             sc->mlx_mem_rid = MLX_CFG_BASE0;
  173             sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type,
  174                 &sc->mlx_mem_rid, RF_ACTIVE);
  175         }
  176         break;
  177     case MLX_IFTYPE_4:
  178     case MLX_IFTYPE_5:
  179         sc->mlx_mem_type = SYS_RES_MEMORY;
  180         sc->mlx_mem_rid = MLX_CFG_BASE0;
  181         sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type,
  182                 &sc->mlx_mem_rid, RF_ACTIVE);
  183         break;
  184     }
  185     if (sc->mlx_mem == NULL) {
  186         device_printf(sc->mlx_dev, "couldn't allocate mailbox window\n");
  187         mlx_free(sc);
  188         return(ENXIO);
  189     }
  190     sc->mlx_btag = rman_get_bustag(sc->mlx_mem);
  191     sc->mlx_bhandle = rman_get_bushandle(sc->mlx_mem);
  192 
  193     /*
  194      * Allocate the parent bus DMA tag appropriate for PCI.
  195      */
  196     error = bus_dma_tag_create(NULL,                    /* parent */
  197                                1, 0,                    /* alignment, boundary */
  198                                BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
  199                                BUS_SPACE_MAXADDR,       /* highaddr */
  200                                NULL, NULL,              /* filter, filterarg */
  201                                MAXBSIZE, MLX_NSEG,      /* maxsize, nsegments */
  202                                BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
  203                                BUS_DMA_ALLOCNOW,        /* flags */
  204                                NULL,                    /* lockfunc */
  205                                NULL,                    /* lockarg */
  206                                &sc->mlx_parent_dmat);
  207     if (error != 0) {
  208         device_printf(dev, "can't allocate parent DMA tag\n");
  209         mlx_free(sc);
  210         return(ENOMEM);
  211     }
  212 
  213     /*
  214      * Do bus-independant initialisation.
  215      */
  216     error = mlx_attach(sc);
  217     if (error != 0)
  218         return(error);
  219     
  220     /*
  221      * Start the controller.
  222      */
  223     mlx_startup(sc);
  224     return(0);
  225 }

Cache object: ff06261378c38cb541ee495e2ad8b77c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.