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/bhnd/bhnd.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) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
    5  * Copyright (c) 2017 The FreeBSD Foundation
    6  * All rights reserved.
    7  *
    8  * Portions of this software were developed by Landon Fuller
    9  * under sponsorship from the FreeBSD Foundation.
   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  *    without modification.
   17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   18  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   19  *    redistribution must be conditioned upon including a substantially
   20  *    similar Disclaimer requirement for further binary redistribution.
   21  *
   22  * NO WARRANTY
   23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   25  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   26  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   27  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   28  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   31  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   33  * THE POSSIBILITY OF SUCH DAMAGES.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD$");
   38 
   39 /*
   40  * Broadcom Home Networking Division (HND) Bus Driver.
   41  * 
   42  * The Broadcom HND family of devices consists of both SoCs and host-connected
   43  * networking chipsets containing a common family of Broadcom IP cores,
   44  * including an integrated MIPS and/or ARM cores.
   45  * 
   46  * HND devices expose a nearly identical interface whether accessible over a 
   47  * native SoC interconnect, or when connected via a host interface such as 
   48  * PCIe. As a result, the majority of hardware support code should be re-usable 
   49  * across host drivers for HND networking chipsets, as well as FreeBSD support 
   50  * for Broadcom MIPS/ARM HND SoCs.
   51  * 
   52  * Earlier HND models used the siba(4) on-chip interconnect, while later models
   53  * use bcma(4); the programming model is almost entirely independent
   54  * of the actual underlying interconect.
   55  */
   56 
   57 #include <sys/param.h>
   58 #include <sys/kernel.h>
   59 #include <sys/bus.h>
   60 #include <sys/module.h>
   61 #include <sys/sbuf.h>
   62 #include <sys/systm.h>
   63 
   64 #include <machine/bus.h>
   65 #include <sys/rman.h>
   66 #include <machine/resource.h>
   67 
   68 #include <dev/bhnd/cores/pmu/bhnd_pmu.h>
   69 
   70 #include "bhnd_chipc_if.h"
   71 #include "bhnd_nvram_if.h"
   72 
   73 #include "bhnd.h"
   74 #include "bhndreg.h"
   75 #include "bhndvar.h"
   76 
   77 #include "bhnd_private.h"
   78 
   79 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
   80 
   81 /**
   82  * bhnd_generic_probe_nomatch() reporting configuration.
   83  */
   84 static const struct bhnd_nomatch {
   85         uint16_t        vendor;         /**< core designer */
   86         uint16_t        device;         /**< core id */
   87         bool            if_verbose;     /**< print when bootverbose is set. */
   88 } bhnd_nomatch_table[] = {
   89         { BHND_MFGID_ARM,       BHND_COREID_OOB_ROUTER,         true    },
   90         { BHND_MFGID_ARM,       BHND_COREID_EROM,               true    },
   91         { BHND_MFGID_ARM,       BHND_COREID_PL301,              true    },
   92         { BHND_MFGID_ARM,       BHND_COREID_APB_BRIDGE,         true    },
   93         { BHND_MFGID_ARM,       BHND_COREID_AXI_UNMAPPED,       false   },
   94         { BHND_MFGID_INVALID,   BHND_COREID_INVALID,            false   }
   95 };
   96 
   97 static int                       bhnd_delete_children(struct bhnd_softc *sc);
   98 
   99 /**
  100  * Default bhnd(4) bus driver implementation of DEVICE_ATTACH().
  101  *
  102  * This implementation calls device_probe_and_attach() for each of the device's
  103  * children, in bhnd probe order.
  104  */
  105 int
  106 bhnd_generic_attach(device_t dev)
  107 {
  108         struct bhnd_softc       *sc;
  109         int                      error;
  110 
  111         if (device_is_attached(dev))
  112                 return (EBUSY);
  113 
  114         sc = device_get_softc(dev);
  115         sc->dev = dev;
  116 
  117         /* Probe and attach all children */
  118         if ((error = bhnd_bus_probe_children(dev))) {
  119                 bhnd_delete_children(sc);
  120                 return (error);
  121         }
  122 
  123         return (0);
  124 }
  125 
  126 /**
  127  * Detach and delete all children, in reverse of their attach order.
  128  */
  129 static int
  130 bhnd_delete_children(struct bhnd_softc *sc)
  131 {
  132         device_t                *devs;
  133         int                      ndevs;
  134         int                      error;
  135 
  136         /* Fetch children in detach order */
  137         error = bhnd_bus_get_children(sc->dev, &devs, &ndevs,
  138             BHND_DEVICE_ORDER_DETACH);
  139         if (error)
  140                 return (error);
  141 
  142         /* Perform detach */
  143         for (int i = 0; i < ndevs; i++) {
  144                 device_t child = devs[i];
  145 
  146                 /* Terminate on first error */
  147                 if ((error = device_delete_child(sc->dev, child)))
  148                         goto cleanup;
  149         }
  150 
  151 cleanup:
  152         bhnd_bus_free_children(devs);
  153         return (error);
  154 }
  155 
  156 /**
  157  * Default bhnd(4) bus driver implementation of DEVICE_DETACH().
  158  *
  159  * This implementation calls device_detach() for each of the device's
  160  * children, in reverse bhnd probe order, terminating if any call to
  161  * device_detach() fails.
  162  */
  163 int
  164 bhnd_generic_detach(device_t dev)
  165 {
  166         struct bhnd_softc       *sc;
  167         int                      error;
  168 
  169         if (!device_is_attached(dev))
  170                 return (EBUSY);
  171 
  172         sc = device_get_softc(dev);
  173 
  174         if ((error = bhnd_delete_children(sc)))
  175                 return (error);
  176 
  177         return (0);
  178 }
  179 
  180 /**
  181  * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN().
  182  * 
  183  * This implementation calls device_shutdown() for each of the device's
  184  * children, in reverse bhnd probe order, terminating if any call to
  185  * device_shutdown() fails.
  186  */
  187 int
  188 bhnd_generic_shutdown(device_t dev)
  189 {
  190         device_t        *devs;
  191         int              ndevs;
  192         int              error;
  193 
  194         if (!device_is_attached(dev))
  195                 return (EBUSY);
  196 
  197         /* Fetch children in detach order */
  198         error = bhnd_bus_get_children(dev, &devs, &ndevs,
  199             BHND_DEVICE_ORDER_DETACH);
  200         if (error)
  201                 return (error);
  202 
  203         /* Perform shutdown */
  204         for (int i = 0; i < ndevs; i++) {
  205                 device_t child = devs[i];
  206 
  207                 /* Terminate on first error */
  208                 if ((error = device_shutdown(child)))
  209                         goto cleanup;
  210         }
  211 
  212 cleanup:
  213         bhnd_bus_free_children(devs);
  214         return (error);
  215 }
  216 
  217 /**
  218  * Default bhnd(4) bus driver implementation of DEVICE_RESUME().
  219  *
  220  * This implementation calls BUS_RESUME_CHILD() for each of the device's
  221  * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD()
  222  * fails.
  223  */
  224 int
  225 bhnd_generic_resume(device_t dev)
  226 {
  227         device_t        *devs;
  228         int              ndevs;
  229         int              error;
  230 
  231         if (!device_is_attached(dev))
  232                 return (EBUSY);
  233 
  234         /* Fetch children in attach order */
  235         error = bhnd_bus_get_children(dev, &devs, &ndevs,
  236             BHND_DEVICE_ORDER_ATTACH);
  237         if (error)
  238                 return (error);
  239 
  240         /* Perform resume */
  241         for (int i = 0; i < ndevs; i++) {
  242                 device_t child = devs[i];
  243 
  244                 /* Terminate on first error */
  245                 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child)))
  246                         goto cleanup;
  247         }
  248 
  249 cleanup:
  250         bhnd_bus_free_children(devs);
  251         return (error);
  252 }
  253 
  254 /**
  255  * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND().
  256  *
  257  * This implementation calls BUS_SUSPEND_CHILD() for each of the device's
  258  * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD()
  259  * fails, the suspend operation is terminated and any devices that were
  260  * suspended are resumed immediately by calling their BUS_RESUME_CHILD()
  261  * methods.
  262  */
  263 int
  264 bhnd_generic_suspend(device_t dev)
  265 {
  266         device_t        *devs;
  267         int              ndevs;
  268         int              error;
  269 
  270         if (!device_is_attached(dev))
  271                 return (EBUSY);
  272 
  273         /* Fetch children in detach order */
  274         error = bhnd_bus_get_children(dev, &devs, &ndevs,
  275             BHND_DEVICE_ORDER_DETACH);
  276         if (error)
  277                 return (error);
  278 
  279         /* Perform suspend */
  280         for (int i = 0; i < ndevs; i++) {
  281                 device_t child = devs[i];
  282                 error = BUS_SUSPEND_CHILD(device_get_parent(child), child);
  283 
  284                 /* On error, resume suspended devices and then terminate */
  285                 if (error) {
  286                         for (int j = 0; j < i; j++) {
  287                                 BUS_RESUME_CHILD(device_get_parent(devs[j]),
  288                                     devs[j]);
  289                         }
  290 
  291                         goto cleanup;
  292                 }
  293         }
  294 
  295 cleanup:
  296         bhnd_bus_free_children(devs);
  297         return (error);
  298 }
  299 
  300 /**
  301  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER().
  302  *
  303  * This implementation determines probe ordering based on the device's class
  304  * and other properties, including whether the device is serving as a host
  305  * bridge.
  306  */
  307 int
  308 bhnd_generic_get_probe_order(device_t dev, device_t child)
  309 {
  310         switch (bhnd_get_class(child)) {
  311         case BHND_DEVCLASS_CC:
  312                 /* Must be early enough to provide NVRAM access to the
  313                  * host bridge */
  314                 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST);
  315 
  316         case BHND_DEVCLASS_CC_B:
  317                 /* fall through */
  318         case BHND_DEVCLASS_PMU:
  319                 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY);
  320 
  321         case BHND_DEVCLASS_SOC_ROUTER:
  322                 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE);
  323 
  324         case BHND_DEVCLASS_SOC_BRIDGE:
  325                 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST);
  326                 
  327         case BHND_DEVCLASS_CPU:
  328                 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST);
  329 
  330         case BHND_DEVCLASS_RAM:
  331                 /* fall through */
  332         case BHND_DEVCLASS_MEMC:
  333                 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY);
  334                 
  335         case BHND_DEVCLASS_NVRAM:
  336                 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY);
  337 
  338         case BHND_DEVCLASS_PCI:
  339         case BHND_DEVCLASS_PCIE:
  340         case BHND_DEVCLASS_PCCARD:
  341         case BHND_DEVCLASS_ENET:
  342         case BHND_DEVCLASS_ENET_MAC:
  343         case BHND_DEVCLASS_ENET_PHY:
  344         case BHND_DEVCLASS_WLAN:
  345         case BHND_DEVCLASS_WLAN_MAC:
  346         case BHND_DEVCLASS_WLAN_PHY:
  347         case BHND_DEVCLASS_EROM:
  348         case BHND_DEVCLASS_OTHER:
  349         case BHND_DEVCLASS_INVALID:
  350                 if (bhnd_bus_find_hostb_device(dev) == child)
  351                         return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY);
  352 
  353                 return (BHND_PROBE_DEFAULT);
  354         default:
  355                 return (BHND_PROBE_DEFAULT);
  356         }
  357 }
  358 
  359 /**
  360  * Default bhnd(4) bus driver implementation of BHND_BUS_ALLOC_PMU().
  361  */
  362 int
  363 bhnd_generic_alloc_pmu(device_t dev, device_t child)
  364 {
  365         struct bhnd_softc               *sc;
  366         struct bhnd_resource            *r;
  367         struct bhnd_core_clkctl         *clkctl;
  368         struct resource_list            *rl;
  369         struct resource_list_entry      *rle;
  370         device_t                         pmu_dev;
  371         bhnd_addr_t                      r_addr;
  372         bhnd_size_t                      r_size;
  373         bus_size_t                       pmu_regs;
  374         u_int                            max_latency;
  375         int                              error;
  376 
  377         bus_topo_assert();
  378 
  379         if (device_get_parent(child) != dev)
  380                 return (EINVAL);
  381 
  382         sc = device_get_softc(dev);
  383         clkctl = bhnd_get_pmu_info(child);
  384         pmu_regs = BHND_CLK_CTL_ST;
  385 
  386         /* already allocated? */
  387         if (clkctl != NULL) {
  388                 panic("duplicate PMU allocation for %s",
  389                     device_get_nameunit(child));
  390         }
  391 
  392         /* Determine address+size of the core's PMU register block */
  393         error = bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &r_addr,
  394             &r_size);
  395         if (error) {
  396                 device_printf(sc->dev, "error fetching register block info for "
  397                     "%s: %d\n", device_get_nameunit(child), error);
  398                 return (error);
  399         }
  400 
  401         if (r_size < (pmu_regs + sizeof(uint32_t))) {
  402                 device_printf(sc->dev, "pmu offset %#jx would overrun %s "
  403                     "register block\n", (uintmax_t)pmu_regs,
  404                     device_get_nameunit(child));
  405                 return (ENODEV);
  406         }
  407 
  408         /* Locate actual resource containing the core's register block */
  409         if ((rl = BUS_GET_RESOURCE_LIST(dev, child)) == NULL) {
  410                 device_printf(dev, "NULL resource list returned for %s\n",
  411                     device_get_nameunit(child));
  412                 return (ENXIO);
  413         }
  414 
  415         if ((rle = resource_list_find(rl, SYS_RES_MEMORY, 0)) == NULL) {
  416                 device_printf(dev, "cannot locate core register resource "
  417                     "for %s\n", device_get_nameunit(child));
  418                 return (ENXIO);
  419         }
  420 
  421         if (rle->res == NULL) {
  422                 device_printf(dev, "core register resource unallocated for "
  423                     "%s\n", device_get_nameunit(child));
  424                 return (ENXIO);
  425         }
  426 
  427         if (r_addr+pmu_regs < rman_get_start(rle->res) ||
  428             r_addr+pmu_regs >= rman_get_end(rle->res))
  429         {
  430                 device_printf(dev, "core register resource does not map PMU "
  431                     "registers at %#jx\n for %s\n", r_addr+pmu_regs,
  432                     device_get_nameunit(child));
  433                 return (ENXIO);
  434         }
  435 
  436         /* Adjust PMU register offset relative to the actual start address
  437          * of the core's register block allocation.
  438          * 
  439          * XXX: The saved offset will be invalid if bus_adjust_resource is
  440          * used to modify the resource's start address.
  441          */
  442         if (rman_get_start(rle->res) > r_addr)
  443                 pmu_regs -= rman_get_start(rle->res) - r_addr;
  444         else
  445                 pmu_regs -= r_addr - rman_get_start(rle->res);
  446 
  447         /* Retain a PMU reference for the clkctl instance state */
  448         pmu_dev = bhnd_retain_provider(child, BHND_SERVICE_PMU);
  449         if (pmu_dev == NULL) {
  450                 device_printf(sc->dev, "PMU not found\n");
  451                 return (ENXIO);
  452         }
  453 
  454         /* Fetch the maximum transition latency from our PMU */
  455         max_latency = bhnd_pmu_get_max_transition_latency(pmu_dev);
  456 
  457         /* Allocate a new bhnd_resource wrapping the standard resource we
  458          * fetched from the resource list; we'll free this in
  459          * bhnd_generic_release_pmu() */
  460         r = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT);
  461         if (r == NULL) {
  462                 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
  463                 return (ENOMEM);
  464         }
  465 
  466         r->res = rle->res;
  467         r->direct = ((rman_get_flags(rle->res) & RF_ACTIVE) != 0);
  468 
  469         /* Allocate the clkctl instance */
  470         clkctl = bhnd_alloc_core_clkctl(child, pmu_dev, r, pmu_regs,
  471             max_latency);
  472         if (clkctl == NULL) {
  473                 free(r, M_BHND);
  474                 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
  475                 return (ENOMEM);
  476         }
  477 
  478         bhnd_set_pmu_info(child, clkctl);
  479         return (0);
  480 }
  481 
  482 /**
  483  * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_PMU().
  484  */
  485 int
  486 bhnd_generic_release_pmu(device_t dev, device_t child)
  487 {
  488         struct bhnd_core_clkctl *clkctl;
  489         struct bhnd_resource    *r;
  490         device_t                 pmu_dev;
  491 
  492         bus_topo_assert();
  493 
  494         if (device_get_parent(child) != dev)
  495                 return (EINVAL);
  496 
  497         clkctl = bhnd_get_pmu_info(child);
  498         if (clkctl == NULL)
  499                 panic("pmu over-release for %s", device_get_nameunit(child));
  500 
  501         /* Clear all FORCE, AREQ, and ERSRC flags, unless we're already in
  502          * RESET. Suspending a core clears clkctl automatically (and attempting
  503          * to access the PMU registers in a suspended core will trigger a
  504          * system livelock). */
  505         if (!bhnd_is_hw_suspended(clkctl->cc_dev)) {
  506                 BHND_CLKCTL_LOCK(clkctl);
  507 
  508                 /* Clear all FORCE, AREQ, and ERSRC flags */
  509                 BHND_CLKCTL_SET_4(clkctl, 0x0, BHND_CCS_FORCE_MASK |
  510                     BHND_CCS_AREQ_MASK | BHND_CCS_ERSRC_REQ_MASK);
  511 
  512                 BHND_CLKCTL_UNLOCK(clkctl);
  513         }
  514 
  515         /* Clear child's PMU info reference */
  516         bhnd_set_pmu_info(child, NULL);
  517 
  518         /* Before freeing the clkctl instance, save a pointer to resources we
  519          * need to clean up manually */
  520         r = clkctl->cc_res;
  521         pmu_dev = clkctl->cc_pmu_dev;
  522 
  523         /* Free the clkctl instance */
  524         bhnd_free_core_clkctl(clkctl);
  525 
  526         /* Free the child's bhnd resource wrapper */
  527         free(r, M_BHND);
  528 
  529         /* Release the child's PMU provider reference */
  530         bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
  531 
  532         return (0);
  533 }
  534 
  535 /**
  536  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_LATENCY().
  537  */
  538 int
  539 bhnd_generic_get_clock_latency(device_t dev, device_t child, bhnd_clock clock,
  540     u_int *latency)
  541 {
  542         struct bhnd_core_clkctl *clkctl;
  543 
  544         if (device_get_parent(child) != dev)
  545                 return (EINVAL);
  546 
  547         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
  548                 panic("no active PMU allocation");
  549 
  550         return (bhnd_pmu_get_clock_latency(clkctl->cc_pmu_dev, clock, latency));
  551 }
  552 
  553 /**
  554  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_FREQ().
  555  */
  556 int
  557 bhnd_generic_get_clock_freq(device_t dev, device_t child, bhnd_clock clock,
  558     u_int *freq)
  559 {
  560         struct bhnd_core_clkctl *clkctl;
  561 
  562         if (device_get_parent(child) != dev)
  563                 return (EINVAL);
  564 
  565         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
  566                 panic("no active PMU allocation");
  567 
  568         return (bhnd_pmu_get_clock_freq(clkctl->cc_pmu_dev, clock, freq));
  569 }
  570 
  571 /**
  572  * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_CLOCK().
  573  */
  574 int
  575 bhnd_generic_request_clock(device_t dev, device_t child, bhnd_clock clock)
  576 {
  577         struct bhnd_core_clkctl *clkctl;
  578         uint32_t                 avail;
  579         uint32_t                 req;
  580         int                      error;
  581 
  582         if (device_get_parent(child) != dev)
  583                 return (EINVAL);
  584 
  585         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
  586                 panic("no active PMU allocation");
  587 
  588         BHND_ASSERT_CLKCTL_AVAIL(clkctl);
  589 
  590         avail = 0x0;
  591         req = 0x0;
  592 
  593         switch (clock) {
  594         case BHND_CLOCK_DYN:
  595                 break;
  596         case BHND_CLOCK_ILP:
  597                 req |= BHND_CCS_FORCEILP;
  598                 break;
  599         case BHND_CLOCK_ALP:
  600                 req |= BHND_CCS_FORCEALP;
  601                 avail |= BHND_CCS_ALPAVAIL;
  602                 break;
  603         case BHND_CLOCK_HT:
  604                 req |= BHND_CCS_FORCEHT;
  605                 avail |= BHND_CCS_HTAVAIL;
  606                 break;
  607         default:
  608                 device_printf(dev, "%s requested unknown clock: %#x\n",
  609                     device_get_nameunit(clkctl->cc_dev), clock);
  610                 return (ENODEV);
  611         }
  612 
  613         BHND_CLKCTL_LOCK(clkctl);
  614 
  615         /* Issue request */
  616         BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_FORCE_MASK);
  617 
  618         /* Wait for clock availability */
  619         error = bhnd_core_clkctl_wait(clkctl, avail, avail);
  620 
  621         BHND_CLKCTL_UNLOCK(clkctl);
  622 
  623         return (error);
  624 }
  625 
  626 /**
  627  * Default bhnd(4) bus driver implementation of BHND_BUS_ENABLE_CLOCKS().
  628  */
  629 int
  630 bhnd_generic_enable_clocks(device_t dev, device_t child, uint32_t clocks)
  631 {
  632         struct bhnd_core_clkctl *clkctl;
  633         uint32_t                 avail;
  634         uint32_t                 req;
  635         int                      error;
  636 
  637         if (device_get_parent(child) != dev)
  638                 return (EINVAL);
  639 
  640         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
  641                 panic("no active PMU allocation");
  642 
  643         BHND_ASSERT_CLKCTL_AVAIL(clkctl);
  644 
  645         avail = 0x0;
  646         req = 0x0;
  647 
  648         /* Build clock request flags */
  649         if (clocks & BHND_CLOCK_DYN)            /* nothing to enable */
  650                 clocks &= ~BHND_CLOCK_DYN;
  651 
  652         if (clocks & BHND_CLOCK_ILP)            /* nothing to enable */
  653                 clocks &= ~BHND_CLOCK_ILP;
  654 
  655         if (clocks & BHND_CLOCK_ALP) {
  656                 req |= BHND_CCS_ALPAREQ;
  657                 avail |= BHND_CCS_ALPAVAIL;
  658                 clocks &= ~BHND_CLOCK_ALP;
  659         }
  660 
  661         if (clocks & BHND_CLOCK_HT) {
  662                 req |= BHND_CCS_HTAREQ;
  663                 avail |= BHND_CCS_HTAVAIL;
  664                 clocks &= ~BHND_CLOCK_HT;
  665         }
  666 
  667         /* Check for unknown clock values */
  668         if (clocks != 0x0) {
  669                 device_printf(dev, "%s requested unknown clocks: %#x\n",
  670                     device_get_nameunit(clkctl->cc_dev), clocks);
  671                 return (ENODEV);
  672         }
  673 
  674         BHND_CLKCTL_LOCK(clkctl);
  675 
  676         /* Issue request */
  677         BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_AREQ_MASK);
  678 
  679         /* Wait for clock availability */
  680         error = bhnd_core_clkctl_wait(clkctl, avail, avail);
  681 
  682         BHND_CLKCTL_UNLOCK(clkctl);
  683 
  684         return (error);
  685 }
  686 
  687 /**
  688  * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_EXT_RSRC().
  689  */
  690 int
  691 bhnd_generic_request_ext_rsrc(device_t dev, device_t child, u_int rsrc)
  692 {
  693         struct bhnd_core_clkctl *clkctl;
  694         uint32_t                 req;
  695         uint32_t                 avail;
  696         int                      error;
  697 
  698         if (device_get_parent(child) != dev)
  699                 return (EINVAL);
  700 
  701         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
  702                 panic("no active PMU allocation");
  703 
  704         BHND_ASSERT_CLKCTL_AVAIL(clkctl);
  705 
  706         if (rsrc > BHND_CCS_ERSRC_MAX)
  707                 return (EINVAL);
  708 
  709         req = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ);
  710         avail = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_STS);
  711 
  712         BHND_CLKCTL_LOCK(clkctl);
  713 
  714         /* Write request */
  715         BHND_CLKCTL_SET_4(clkctl, req, req);
  716 
  717         /* Wait for resource availability */
  718         error = bhnd_core_clkctl_wait(clkctl, avail, avail);
  719 
  720         BHND_CLKCTL_UNLOCK(clkctl);
  721 
  722         return (error);
  723 }
  724 
  725 /**
  726  * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_EXT_RSRC().
  727  */
  728 int
  729 bhnd_generic_release_ext_rsrc(device_t dev, device_t child, u_int rsrc)
  730 {
  731         struct bhnd_core_clkctl *clkctl;
  732         uint32_t                 mask;
  733 
  734         if (device_get_parent(child) != dev)
  735                 return (EINVAL);
  736 
  737         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
  738                 panic("no active PMU allocation");
  739 
  740         BHND_ASSERT_CLKCTL_AVAIL(clkctl);
  741 
  742         if (rsrc > BHND_CCS_ERSRC_MAX)
  743                 return (EINVAL);
  744 
  745         mask = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ);
  746 
  747         /* Clear request */
  748         BHND_CLKCTL_LOCK(clkctl);
  749         BHND_CLKCTL_SET_4(clkctl, 0x0, mask);
  750         BHND_CLKCTL_UNLOCK(clkctl);
  751 
  752         return (0);
  753 }
  754 
  755 /**
  756  * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID().
  757  * 
  758  * This implementation assumes that port and region numbers are 0-indexed and
  759  * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and
  760  * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall
  761  * within the defined range.
  762  */
  763 static bool
  764 bhnd_generic_is_region_valid(device_t dev, device_t child,
  765     bhnd_port_type type, u_int port, u_int region)
  766 {
  767         if (port >= bhnd_get_port_count(child, type))
  768                 return (false);
  769 
  770         if (region >= bhnd_get_region_count(child, type, port))
  771                 return (false);
  772 
  773         return (true);
  774 }
  775 
  776 /**
  777  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
  778  * 
  779  * This implementation searches @p dev for a registered NVRAM child device.
  780  * 
  781  * If no NVRAM device is registered with @p dev, the request is delegated to
  782  * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
  783  */
  784 int
  785 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name,
  786     void *buf, size_t *size, bhnd_nvram_type type)
  787 {
  788         device_t                 nvram, parent;
  789         int                      error;
  790 
  791         /* If a NVRAM device is available, consult it first */
  792         nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM);
  793         if (nvram != NULL) {
  794                 error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type);
  795                 bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM);
  796                 return (error);
  797         }
  798 
  799         /* Otherwise, try to delegate to parent */
  800         if ((parent = device_get_parent(dev)) == NULL)
  801                 return (ENODEV);
  802 
  803         return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
  804             name, buf, size, type));
  805 }
  806 
  807 /**
  808  * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
  809  * 
  810  * This implementation requests the device's struct resource_list via
  811  * BUS_GET_RESOURCE_LIST.
  812  */
  813 int
  814 bhnd_generic_print_child(device_t dev, device_t child)
  815 {
  816         struct resource_list    *rl;
  817         int                     retval = 0;
  818 
  819         retval += bus_print_child_header(dev, child);
  820 
  821         rl = BUS_GET_RESOURCE_LIST(dev, child);
  822 
  823         if (rl != NULL) {
  824                 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
  825                     "%#jx");
  826 
  827                 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ,
  828                     "%#jd");
  829         }
  830 
  831         retval += printf(" at core %u", bhnd_get_core_index(child));
  832 
  833         retval += bus_print_child_domain(dev, child);
  834         retval += bus_print_child_footer(dev, child);
  835 
  836         return (retval);
  837 }
  838 
  839 /**
  840  * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH().
  841  * 
  842  * This implementation requests the device's struct resource_list via
  843  * BUS_GET_RESOURCE_LIST.
  844  */
  845 void
  846 bhnd_generic_probe_nomatch(device_t dev, device_t child)
  847 {
  848         struct resource_list            *rl;
  849         const struct bhnd_nomatch       *nm;
  850         bool                             report;
  851 
  852         /* Fetch reporting configuration for this device */
  853         report = true;
  854         for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) {
  855                 if (nm->vendor != bhnd_get_vendor(child))
  856                         continue;
  857 
  858                 if (nm->device != bhnd_get_device(child))
  859                         continue;
  860 
  861                 report = false;
  862                 if (bootverbose && nm->if_verbose)
  863                         report = true;
  864                 break;
  865         }
  866 
  867         if (!report)
  868                 return;
  869 
  870         /* Print the non-matched device info */
  871         device_printf(dev, "<%s %s, rev %hhu>", bhnd_get_vendor_name(child),
  872                 bhnd_get_device_name(child), bhnd_get_hwrev(child));
  873 
  874         rl = BUS_GET_RESOURCE_LIST(dev, child);
  875         if (rl != NULL) {
  876                 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
  877                 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%#jd");
  878         }
  879 
  880         printf(" at core %u (no driver attached)\n",
  881             bhnd_get_core_index(child));
  882 }
  883 
  884 static int
  885 bhnd_child_pnpinfo(device_t dev, device_t child, struct sbuf *sb)
  886 {
  887         if (device_get_parent(child) != dev)
  888                 return (BUS_CHILD_PNPINFO(device_get_parent(dev), child, sb));
  889 
  890         sbuf_printf(sb, "vendor=0x%hx device=0x%hx rev=0x%hhx",
  891             bhnd_get_vendor(child), bhnd_get_device(child),
  892             bhnd_get_hwrev(child));
  893 
  894         return (0);
  895 }
  896 
  897 static int
  898 bhnd_child_location(device_t dev, device_t child, struct sbuf *sb)
  899 {
  900         bhnd_addr_t     addr;
  901         bhnd_size_t     size;
  902 
  903         if (device_get_parent(child) != dev)
  904                 return (BUS_CHILD_LOCATION(device_get_parent(dev), child, sb));
  905 
  906         if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size))
  907                 return (0);
  908 
  909         sbuf_printf(sb, "port0.0=0x%llx", (unsigned long long) addr);
  910         return (0);
  911 }
  912 
  913 /**
  914  * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED().
  915  * 
  916  * This implementation manages internal bhnd(4) state, and must be called
  917  * by subclassing drivers.
  918  */
  919 void
  920 bhnd_generic_child_deleted(device_t dev, device_t child)
  921 {
  922 
  923         /* Free device info */
  924         if (bhnd_get_pmu_info(child) != NULL) {
  925                 /* Releasing PMU requests automatically would be nice,
  926                  * but we can't reference per-core PMU register
  927                  * resource after driver detach */
  928                 panic("%s leaked device pmu state\n",
  929                     device_get_nameunit(child));
  930         }
  931 }
  932 
  933 /**
  934  * Helper function for implementing BUS_SUSPEND_CHILD().
  935  *
  936  * TODO: Power management
  937  * 
  938  * If @p child is not a direct child of @p dev, suspension is delegated to
  939  * the @p dev parent.
  940  */
  941 int
  942 bhnd_generic_suspend_child(device_t dev, device_t child)
  943 {
  944         if (device_get_parent(child) != dev)
  945                 BUS_SUSPEND_CHILD(device_get_parent(dev), child);
  946 
  947         return bus_generic_suspend_child(dev, child);
  948 }
  949 
  950 /**
  951  * Helper function for implementing BUS_RESUME_CHILD().
  952  *
  953  * TODO: Power management
  954  * 
  955  * If @p child is not a direct child of @p dev, suspension is delegated to
  956  * the @p dev parent.
  957  */
  958 int
  959 bhnd_generic_resume_child(device_t dev, device_t child)
  960 {
  961         if (device_get_parent(child) != dev)
  962                 BUS_RESUME_CHILD(device_get_parent(dev), child);
  963 
  964         return bus_generic_resume_child(dev, child);
  965 }
  966 
  967 /**
  968  * Default bhnd(4) bus driver implementation of BUS_SETUP_INTR().
  969  *
  970  * This implementation of BUS_SETUP_INTR() will delegate interrupt setup
  971  * to the parent of @p dev, if any.
  972  */
  973 int
  974 bhnd_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
  975     int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
  976     void **cookiep)
  977 {
  978         return (bus_generic_setup_intr(dev, child, irq, flags, filter, intr,
  979             arg, cookiep));
  980 }
  981 
  982 /*
  983  * Delegate all indirect I/O to the parent device. When inherited by
  984  * non-bridged bus implementations, resources will never be marked as
  985  * indirect, and these methods will never be called.
  986  */
  987 #define BHND_IO_READ(_type, _name, _method)                             \
  988 static _type                                                            \
  989 bhnd_read_ ## _name (device_t dev, device_t child,                      \
  990     struct bhnd_resource *r, bus_size_t offset)                         \
  991 {                                                                       \
  992         return (BHND_BUS_READ_ ## _method(                              \
  993                     device_get_parent(dev), child, r, offset));         \
  994 }
  995 
  996 #define BHND_IO_WRITE(_type, _name, _method)                            \
  997 static void                                                             \
  998 bhnd_write_ ## _name (device_t dev, device_t child,                     \
  999     struct bhnd_resource *r, bus_size_t offset, _type value)            \
 1000 {                                                                       \
 1001         return (BHND_BUS_WRITE_ ## _method(                             \
 1002                     device_get_parent(dev), child, r, offset,           \
 1003                     value));    \
 1004 }
 1005 
 1006 #define BHND_IO_MISC(_type, _op, _method)                               \
 1007 static void                                                             \
 1008 bhnd_ ## _op (device_t dev, device_t child,                             \
 1009     struct bhnd_resource *r, bus_size_t offset, _type datap,            \
 1010     bus_size_t count)                                                   \
 1011 {                                                                       \
 1012         BHND_BUS_ ## _method(device_get_parent(dev), child, r,          \
 1013             offset, datap, count);                                      \
 1014 }       
 1015 
 1016 #define BHND_IO_METHODS(_type, _size)                                   \
 1017         BHND_IO_READ(_type, _size, _size)                               \
 1018         BHND_IO_WRITE(_type, _size, _size)                              \
 1019                                                                         \
 1020         BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size)         \
 1021         BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size)        \
 1022                                                                         \
 1023         BHND_IO_MISC(_type*, read_multi_ ## _size,                      \
 1024             READ_MULTI_ ## _size)                                       \
 1025         BHND_IO_MISC(_type*, write_multi_ ## _size,                     \
 1026             WRITE_MULTI_ ## _size)                                      \
 1027                                                                         \
 1028         BHND_IO_MISC(_type*, read_multi_stream_ ## _size,               \
 1029            READ_MULTI_STREAM_ ## _size)                                 \
 1030         BHND_IO_MISC(_type*, write_multi_stream_ ## _size,              \
 1031            WRITE_MULTI_STREAM_ ## _size)                                \
 1032                                                                         \
 1033         BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size)   \
 1034         BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \
 1035                                                                         \
 1036         BHND_IO_MISC(_type*, read_region_ ## _size,                     \
 1037             READ_REGION_ ## _size)                                      \
 1038         BHND_IO_MISC(_type*, write_region_ ## _size,                    \
 1039             WRITE_REGION_ ## _size)                                     \
 1040                                                                         \
 1041         BHND_IO_MISC(_type*, read_region_stream_ ## _size,              \
 1042             READ_REGION_STREAM_ ## _size)                               \
 1043         BHND_IO_MISC(_type*, write_region_stream_ ## _size,             \
 1044             WRITE_REGION_STREAM_ ## _size)                              \
 1045 
 1046 BHND_IO_METHODS(uint8_t, 1);
 1047 BHND_IO_METHODS(uint16_t, 2);
 1048 BHND_IO_METHODS(uint32_t, 4);
 1049 
 1050 static void 
 1051 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r,
 1052     bus_size_t offset, bus_size_t length, int flags)
 1053 {
 1054         BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length,
 1055             flags);
 1056 }
 1057 
 1058 static device_method_t bhnd_methods[] = {
 1059         /* Device interface */ \
 1060         DEVMETHOD(device_attach,                bhnd_generic_attach),
 1061         DEVMETHOD(device_detach,                bhnd_generic_detach),
 1062         DEVMETHOD(device_shutdown,              bhnd_generic_shutdown),
 1063         DEVMETHOD(device_suspend,               bhnd_generic_suspend),
 1064         DEVMETHOD(device_resume,                bhnd_generic_resume),
 1065 
 1066         /* Bus interface */
 1067         DEVMETHOD(bus_child_deleted,            bhnd_generic_child_deleted),
 1068         DEVMETHOD(bus_probe_nomatch,            bhnd_generic_probe_nomatch),
 1069         DEVMETHOD(bus_print_child,              bhnd_generic_print_child),
 1070         DEVMETHOD(bus_child_pnpinfo,            bhnd_child_pnpinfo),
 1071         DEVMETHOD(bus_child_location,           bhnd_child_location),
 1072 
 1073         DEVMETHOD(bus_suspend_child,            bhnd_generic_suspend_child),
 1074         DEVMETHOD(bus_resume_child,             bhnd_generic_resume_child),
 1075 
 1076         DEVMETHOD(bus_set_resource,             bus_generic_rl_set_resource),
 1077         DEVMETHOD(bus_get_resource,             bus_generic_rl_get_resource),
 1078         DEVMETHOD(bus_delete_resource,          bus_generic_rl_delete_resource),
 1079         DEVMETHOD(bus_alloc_resource,           bus_generic_rl_alloc_resource),
 1080         DEVMETHOD(bus_adjust_resource,          bus_generic_adjust_resource),
 1081         DEVMETHOD(bus_release_resource,         bus_generic_rl_release_resource),
 1082         DEVMETHOD(bus_activate_resource,        bus_generic_activate_resource),
 1083         DEVMETHOD(bus_deactivate_resource,      bus_generic_deactivate_resource),
 1084 
 1085         DEVMETHOD(bus_setup_intr,               bhnd_generic_setup_intr),
 1086         DEVMETHOD(bus_teardown_intr,            bus_generic_teardown_intr),
 1087         DEVMETHOD(bus_config_intr,              bus_generic_config_intr),
 1088         DEVMETHOD(bus_bind_intr,                bus_generic_bind_intr),
 1089         DEVMETHOD(bus_describe_intr,            bus_generic_describe_intr),
 1090 
 1091         DEVMETHOD(bus_get_dma_tag,              bus_generic_get_dma_tag),
 1092 
 1093         /* BHND interface */
 1094         DEVMETHOD(bhnd_bus_get_chipid,          bhnd_bus_generic_get_chipid),
 1095         DEVMETHOD(bhnd_bus_is_hw_disabled,      bhnd_bus_generic_is_hw_disabled),
 1096 
 1097         DEVMETHOD(bhnd_bus_get_probe_order,     bhnd_generic_get_probe_order),
 1098 
 1099         DEVMETHOD(bhnd_bus_alloc_pmu,           bhnd_generic_alloc_pmu),
 1100         DEVMETHOD(bhnd_bus_release_pmu,         bhnd_generic_release_pmu),
 1101         DEVMETHOD(bhnd_bus_request_clock,       bhnd_generic_request_clock),
 1102         DEVMETHOD(bhnd_bus_enable_clocks,       bhnd_generic_enable_clocks),
 1103         DEVMETHOD(bhnd_bus_request_ext_rsrc,    bhnd_generic_request_ext_rsrc),
 1104         DEVMETHOD(bhnd_bus_release_ext_rsrc,    bhnd_generic_release_ext_rsrc),
 1105         DEVMETHOD(bhnd_bus_get_clock_latency,   bhnd_generic_get_clock_latency),
 1106         DEVMETHOD(bhnd_bus_get_clock_freq,      bhnd_generic_get_clock_freq),
 1107 
 1108         DEVMETHOD(bhnd_bus_is_region_valid,     bhnd_generic_is_region_valid),
 1109         DEVMETHOD(bhnd_bus_get_nvram_var,       bhnd_generic_get_nvram_var),
 1110 
 1111         /* BHND interface (bus I/O) */
 1112         DEVMETHOD(bhnd_bus_read_1,              bhnd_read_1),
 1113         DEVMETHOD(bhnd_bus_read_2,              bhnd_read_2),
 1114         DEVMETHOD(bhnd_bus_read_4,              bhnd_read_4),
 1115         DEVMETHOD(bhnd_bus_write_1,             bhnd_write_1),
 1116         DEVMETHOD(bhnd_bus_write_2,             bhnd_write_2),
 1117         DEVMETHOD(bhnd_bus_write_4,             bhnd_write_4),
 1118 
 1119         DEVMETHOD(bhnd_bus_read_stream_1,       bhnd_read_stream_1),
 1120         DEVMETHOD(bhnd_bus_read_stream_2,       bhnd_read_stream_2),
 1121         DEVMETHOD(bhnd_bus_read_stream_4,       bhnd_read_stream_4),
 1122         DEVMETHOD(bhnd_bus_write_stream_1,      bhnd_write_stream_1),
 1123         DEVMETHOD(bhnd_bus_write_stream_2,      bhnd_write_stream_2),
 1124         DEVMETHOD(bhnd_bus_write_stream_4,      bhnd_write_stream_4),
 1125 
 1126         DEVMETHOD(bhnd_bus_read_multi_1,        bhnd_read_multi_1),
 1127         DEVMETHOD(bhnd_bus_read_multi_2,        bhnd_read_multi_2),
 1128         DEVMETHOD(bhnd_bus_read_multi_4,        bhnd_read_multi_4),
 1129         DEVMETHOD(bhnd_bus_write_multi_1,       bhnd_write_multi_1),
 1130         DEVMETHOD(bhnd_bus_write_multi_2,       bhnd_write_multi_2),
 1131         DEVMETHOD(bhnd_bus_write_multi_4,       bhnd_write_multi_4),
 1132 
 1133         DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1),
 1134         DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2),
 1135         DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4),
 1136         DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1),
 1137         DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2),
 1138         DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4),
 1139 
 1140         DEVMETHOD(bhnd_bus_set_multi_1,         bhnd_set_multi_1),
 1141         DEVMETHOD(bhnd_bus_set_multi_2,         bhnd_set_multi_2),
 1142         DEVMETHOD(bhnd_bus_set_multi_4,         bhnd_set_multi_4),
 1143 
 1144         DEVMETHOD(bhnd_bus_set_region_1,        bhnd_set_region_1),
 1145         DEVMETHOD(bhnd_bus_set_region_2,        bhnd_set_region_2),
 1146         DEVMETHOD(bhnd_bus_set_region_4,        bhnd_set_region_4),
 1147 
 1148         DEVMETHOD(bhnd_bus_read_region_1,       bhnd_read_region_1),
 1149         DEVMETHOD(bhnd_bus_read_region_2,       bhnd_read_region_2),
 1150         DEVMETHOD(bhnd_bus_read_region_4,       bhnd_read_region_4),
 1151         DEVMETHOD(bhnd_bus_write_region_1,      bhnd_write_region_1),
 1152         DEVMETHOD(bhnd_bus_write_region_2,      bhnd_write_region_2),
 1153         DEVMETHOD(bhnd_bus_write_region_4,      bhnd_write_region_4),
 1154 
 1155         DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1),
 1156         DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2),
 1157         DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4),
 1158         DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1),
 1159         DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2),
 1160         DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4),
 1161 
 1162         DEVMETHOD(bhnd_bus_barrier,                     bhnd_barrier),
 1163 
 1164         DEVMETHOD_END
 1165 };
 1166 
 1167 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc));
 1168 MODULE_VERSION(bhnd, 1);

Cache object: 2080dc18b722f74e2bf857b0a7e9486b


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