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/aacraid/aacraid_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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2000 Michael Smith
    5  * Copyright (c) 2001 Scott Long
    6  * Copyright (c) 2000 BSDi
    7  * Copyright (c) 2001-2010 Adaptec, Inc.
    8  * Copyright (c) 2010-2012 PMC-Sierra, Inc.
    9  * All rights reserved.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 /*
   37  * PCI bus interface and resource allocation.
   38  */
   39 
   40 #include "opt_aacraid.h"
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/kernel.h>
   45 #include <sys/module.h>
   46 
   47 #include <sys/bio.h>
   48 #include <sys/bus.h>
   49 #include <sys/conf.h>
   50 #include <sys/disk.h>
   51 
   52 #include <machine/bus.h>
   53 #include <machine/resource.h>
   54 #include <sys/rman.h>
   55 
   56 #include <dev/pci/pcireg.h>
   57 #include <dev/pci/pcivar.h>
   58 
   59 #include <dev/aacraid/aacraid_reg.h>
   60 #include <sys/aac_ioctl.h>
   61 #include <dev/aacraid/aacraid_debug.h>
   62 #include <dev/aacraid/aacraid_var.h>
   63 
   64 static int      aacraid_pci_probe(device_t dev);
   65 static int      aacraid_pci_attach(device_t dev);
   66 
   67 static device_method_t aacraid_methods[] = {
   68         /* Device interface */
   69         DEVMETHOD(device_probe,         aacraid_pci_probe),
   70         DEVMETHOD(device_attach,        aacraid_pci_attach),
   71         DEVMETHOD(device_detach,        aacraid_detach),
   72         DEVMETHOD(device_suspend,       aacraid_suspend),
   73         DEVMETHOD(device_resume,        aacraid_resume),
   74 
   75         DEVMETHOD(bus_print_child,      bus_generic_print_child),
   76         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
   77         { 0, 0 }
   78 };
   79 
   80 static driver_t aacraid_pci_driver = {
   81         "aacraid",
   82         aacraid_methods,
   83         sizeof(struct aac_softc)
   84 };
   85 
   86 struct aac_ident
   87 {
   88         u_int16_t               vendor;
   89         u_int16_t               device;
   90         u_int16_t               subvendor;
   91         u_int16_t               subdevice;
   92         int                     hwif;
   93         int                     quirks;
   94         char                    *desc;
   95 } aacraid_family_identifiers[] = {
   96         {0x9005, 0x028b, 0, 0, AAC_HWIF_SRC, 0,
   97          "Adaptec RAID Controller"},
   98         {0x9005, 0x028c, 0, 0, AAC_HWIF_SRCV, 0,
   99          "Adaptec RAID Controller"},
  100         {0x9005, 0x028d, 0, 0, AAC_HWIF_SRCV, 0,
  101          "Adaptec RAID Controller"},
  102         {0, 0, 0, 0, 0, 0, 0}
  103 };
  104 
  105 DRIVER_MODULE(aacraid, pci, aacraid_pci_driver, 0, 0);
  106 MODULE_PNP_INFO("U16:vendor;U16:device", pci, aacraid,
  107     aacraid_family_identifiers,
  108     nitems(aacraid_family_identifiers) - 1);
  109 MODULE_DEPEND(aacraid, pci, 1, 1, 1);
  110 
  111 static struct aac_ident *
  112 aac_find_ident(device_t dev)
  113 {
  114         struct aac_ident *m;
  115         u_int16_t vendid, devid;
  116 
  117         vendid = pci_get_vendor(dev);
  118         devid = pci_get_device(dev);
  119 
  120         for (m = aacraid_family_identifiers; m->vendor != 0; m++) {
  121                 if ((m->vendor == vendid) && (m->device == devid))
  122                         return (m);
  123         }
  124 
  125         return (NULL);
  126 }
  127 
  128 /*
  129  * Determine whether this is one of our supported adapters.
  130  */
  131 static int
  132 aacraid_pci_probe(device_t dev)
  133 {
  134         struct aac_ident *id;
  135 
  136         fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
  137 
  138         if ((id = aac_find_ident(dev)) != NULL) {
  139                 device_set_desc(dev, id->desc);
  140                 return(BUS_PROBE_DEFAULT);
  141         }
  142         return(ENXIO);
  143 }
  144 
  145 /*
  146  * Allocate resources for our device, set up the bus interface.
  147  */
  148 static int
  149 aacraid_pci_attach(device_t dev)
  150 {
  151         struct aac_softc *sc;
  152         struct aac_ident *id;
  153         int error;
  154         u_int32_t command;
  155 
  156         fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
  157 
  158         /*
  159          * Initialise softc.
  160          */
  161         sc = device_get_softc(dev);
  162         bzero(sc, sizeof(*sc));
  163         sc->aac_dev = dev;
  164 
  165         /* assume failure is 'not configured' */
  166         error = ENXIO;
  167 
  168         /* 
  169          * Verify that the adapter is correctly set up in PCI space.
  170          */
  171         pci_enable_busmaster(dev);
  172         command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
  173         if (!(command & PCIM_CMD_BUSMASTEREN)) {
  174                 device_printf(sc->aac_dev, "can't enable bus-master feature\n");
  175                 goto out;
  176         }
  177 
  178         /* 
  179          * Detect the hardware interface version, set up the bus interface
  180          * indirection.
  181          */
  182         id = aac_find_ident(dev);
  183         sc->aac_hwif = id->hwif;
  184         switch(sc->aac_hwif) {
  185         case AAC_HWIF_SRC:
  186                 fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for PMC SRC");
  187                 sc->aac_if = aacraid_src_interface;
  188                 break;
  189         case AAC_HWIF_SRCV:
  190                 fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for PMC SRCv");
  191                 sc->aac_if = aacraid_srcv_interface;
  192                 break;
  193         default:
  194                 sc->aac_hwif = AAC_HWIF_UNKNOWN;
  195                 device_printf(sc->aac_dev, "unknown hardware type\n");
  196                 error = ENXIO;
  197                 goto out;
  198         }
  199 
  200         /* assume failure is 'out of memory' */
  201         error = ENOMEM;
  202 
  203         /*
  204          * Allocate the PCI register window.
  205          */
  206         sc->aac_regs_rid0 = PCIR_BAR(0);
  207         if ((sc->aac_regs_res0 = bus_alloc_resource_any(sc->aac_dev,
  208             SYS_RES_MEMORY, &sc->aac_regs_rid0, RF_ACTIVE)) == NULL) {
  209                 device_printf(sc->aac_dev,
  210                     "couldn't allocate register window 0\n");
  211                 goto out;
  212         }
  213         sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
  214         sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
  215 
  216         sc->aac_regs_rid1 = PCIR_BAR(2);
  217         if ((sc->aac_regs_res1 = bus_alloc_resource_any(sc->aac_dev,
  218             SYS_RES_MEMORY, &sc->aac_regs_rid1, RF_ACTIVE)) == NULL) {
  219                 device_printf(sc->aac_dev,
  220                     "couldn't allocate register window 1\n");
  221                 goto out;
  222         }
  223         sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
  224         sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
  225 
  226         /*
  227          * Allocate the parent bus DMA tag appropriate for our PCI interface.
  228          * 
  229          * Note that some of these controllers are 64-bit capable.
  230          */
  231         if (bus_dma_tag_create(bus_get_dma_tag(dev),    /* parent */
  232                                PAGE_SIZE, 0,            /* algnmnt, boundary */
  233                                BUS_SPACE_MAXADDR,       /* lowaddr */
  234                                BUS_SPACE_MAXADDR,       /* highaddr */
  235                                NULL, NULL,              /* filter, filterarg */
  236                                BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
  237                                BUS_SPACE_UNRESTRICTED,  /* nsegments */
  238                                BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
  239                                0,                       /* flags */
  240                                NULL, NULL,              /* No locking needed */
  241                                &sc->aac_parent_dmat)) {
  242                 device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
  243                 goto out;
  244         }
  245 
  246         /* Set up quirks */
  247         sc->flags = id->quirks;
  248 
  249         /*
  250          * Do bus-independent initialisation.
  251          */
  252         error = aacraid_attach(sc);
  253 
  254 out:
  255         if (error)
  256                 aacraid_free(sc);
  257         return(error);
  258 }

Cache object: 49e94d9fff589ad368bec0ea966d6bba


[ 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.