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/bcma/bcma_subr.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 <landon@landonf.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 #include <sys/param.h>
   40 #include <sys/bus.h>
   41 #include <sys/kernel.h>
   42 #include <sys/limits.h>
   43 #include <sys/systm.h>
   44 
   45 #include <machine/bus.h>
   46 #include <machine/resource.h>
   47 
   48 #include <dev/bhnd/bhndvar.h>
   49 
   50 #include "bcma_dmp.h"
   51 
   52 #include "bcmavar.h"
   53 
   54 /* Return the resource ID for a device's agent register allocation */
   55 #define BCMA_AGENT_RID(_dinfo)  \
   56     (BCMA_AGENT_RID_BASE + BCMA_DINFO_COREIDX(_dinfo))
   57 
   58  /**
   59  * Allocate and initialize new core config structure.
   60  * 
   61  * @param core_index Core index on the bus.
   62  * @param core_unit Core unit number.
   63  * @param vendor Core designer.
   64  * @param device Core identifier (e.g. part number).
   65  * @param hwrev Core revision.
   66  */
   67 struct bcma_corecfg *
   68 bcma_alloc_corecfg(u_int core_index, int core_unit, uint16_t vendor,
   69     uint16_t device, uint8_t hwrev)
   70 {
   71         struct bcma_corecfg *cfg;
   72 
   73         cfg = malloc(sizeof(*cfg), M_BHND, M_NOWAIT);
   74         if (cfg == NULL)
   75                 return NULL;
   76 
   77         cfg->core_info = (struct bhnd_core_info) {
   78                 .vendor = vendor,
   79                 .device = device,
   80                 .hwrev = hwrev,
   81                 .core_idx = core_index,
   82                 .unit = core_unit
   83         };
   84 
   85         STAILQ_INIT(&cfg->master_ports);
   86         cfg->num_master_ports = 0;
   87 
   88         STAILQ_INIT(&cfg->dev_ports);
   89         cfg->num_dev_ports = 0;
   90 
   91         STAILQ_INIT(&cfg->bridge_ports);
   92         cfg->num_bridge_ports = 0;
   93 
   94         STAILQ_INIT(&cfg->wrapper_ports);
   95         cfg->num_wrapper_ports = 0;
   96 
   97         return (cfg);
   98 }
   99 
  100 /**
  101  * Deallocate the given core config and any associated resources.
  102  * 
  103  * @param corecfg Core info to be deallocated.
  104  */
  105 void
  106 bcma_free_corecfg(struct bcma_corecfg *corecfg)
  107 {
  108         struct bcma_mport *mport, *mnext;
  109         struct bcma_sport *sport, *snext;
  110 
  111         STAILQ_FOREACH_SAFE(mport, &corecfg->master_ports, mp_link, mnext) {
  112                 free(mport, M_BHND);
  113         }
  114 
  115         STAILQ_FOREACH_SAFE(sport, &corecfg->dev_ports, sp_link, snext) {
  116                 bcma_free_sport(sport);
  117         }
  118 
  119         STAILQ_FOREACH_SAFE(sport, &corecfg->bridge_ports, sp_link, snext) {
  120                 bcma_free_sport(sport);
  121         }
  122 
  123         STAILQ_FOREACH_SAFE(sport, &corecfg->wrapper_ports, sp_link, snext) {
  124                 bcma_free_sport(sport);
  125         }
  126 
  127         free(corecfg, M_BHND);
  128 }
  129 
  130 /**
  131  * Return the @p cfg port list for @p type.
  132  * 
  133  * @param cfg The core configuration.
  134  * @param type The requested port type.
  135  */
  136 struct bcma_sport_list *
  137 bcma_corecfg_get_port_list(struct bcma_corecfg *cfg, bhnd_port_type type)
  138 {
  139         switch (type) {
  140         case BHND_PORT_DEVICE:
  141                 return (&cfg->dev_ports);
  142                 break;
  143         case BHND_PORT_BRIDGE:
  144                 return (&cfg->bridge_ports);
  145                 break;
  146         case BHND_PORT_AGENT:
  147                 return (&cfg->wrapper_ports);
  148                 break;
  149         default:
  150                 return (NULL);
  151         }
  152 }
  153 
  154 /**
  155  * Populate the resource list and bcma_map RIDs using the maps defined on
  156  * @p ports.
  157  * 
  158  * @param bus The requesting bus device.
  159  * @param dinfo The device info instance to be initialized.
  160  * @param ports The set of ports to be enumerated
  161  */
  162 static void
  163 bcma_dinfo_init_port_resource_info(device_t bus, struct bcma_devinfo *dinfo,
  164     struct bcma_sport_list *ports)
  165 {
  166         struct bcma_map         *map;
  167         struct bcma_sport       *port;
  168         bhnd_addr_t              end;
  169 
  170         STAILQ_FOREACH(port, ports, sp_link) {
  171                 STAILQ_FOREACH(map, &port->sp_maps, m_link) {
  172                         /*
  173                          * Create the corresponding device resource list entry.
  174                          * 
  175                          * We necessarily skip registration if the region's
  176                          * device memory range is not representable via
  177                          * rman_res_t.
  178                          * 
  179                          * When rman_res_t is migrated to uintmax_t, any
  180                          * range should be representable.
  181                          */
  182                         end = map->m_base + map->m_size;
  183                         if (map->m_base <= RM_MAX_END && end <= RM_MAX_END) {
  184                                 map->m_rid = resource_list_add_next(
  185                                     &dinfo->resources, SYS_RES_MEMORY,
  186                                     map->m_base, end, map->m_size);
  187                         } else if (bootverbose) {
  188                                 device_printf(bus,
  189                                     "core%u %s%u.%u: region %llx-%llx extends "
  190                                         "beyond supported addressable range\n",
  191                                     dinfo->corecfg->core_info.core_idx,
  192                                     bhnd_port_type_name(port->sp_type),
  193                                     port->sp_num, map->m_region_num,
  194                                     (unsigned long long) map->m_base,
  195                                     (unsigned long long) end);
  196                         }
  197                 }
  198         }
  199 }
  200 
  201 /**
  202  * Allocate the per-core agent register block for a device info structure.
  203  * 
  204  * If an agent0.0 region is not defined on @p dinfo, the device info
  205  * agent resource is set to NULL and 0 is returned.
  206  * 
  207  * @param bus The requesting bus device.
  208  * @param child The bcma child device.
  209  * @param dinfo The device info associated with @p child
  210  * 
  211  * @retval 0 success
  212  * @retval non-zero resource allocation failed.
  213  */
  214 static int
  215 bcma_dinfo_init_agent(device_t bus, device_t child, struct bcma_devinfo *dinfo)
  216 {
  217         bhnd_addr_t     addr;
  218         bhnd_size_t     size;
  219         rman_res_t      r_start, r_count, r_end;
  220         int             error;
  221 
  222         KASSERT(dinfo->res_agent == NULL, ("double allocation of agent"));
  223 
  224         /* Verify that the agent register block exists and is
  225          * mappable */
  226         if (bhnd_get_port_rid(child, BHND_PORT_AGENT, 0, 0) == -1)
  227                 return (0);     /* nothing to do */
  228 
  229         /* Fetch the address of the agent register block */
  230         error = bhnd_get_region_addr(child, BHND_PORT_AGENT, 0, 0,
  231             &addr, &size);
  232         if (error) {
  233                 device_printf(bus, "failed fetching agent register block "
  234                     "address for core %u\n", BCMA_DINFO_COREIDX(dinfo));
  235                 return (error);
  236         }
  237 
  238         /* Allocate the resource */
  239         r_start = addr;
  240         r_count = size;
  241         r_end = r_start + r_count - 1;
  242 
  243         dinfo->rid_agent = BCMA_AGENT_RID(dinfo);
  244         dinfo->res_agent = BHND_BUS_ALLOC_RESOURCE(bus, bus, SYS_RES_MEMORY,
  245             &dinfo->rid_agent, r_start, r_end, r_count, RF_ACTIVE|RF_SHAREABLE);
  246         if (dinfo->res_agent == NULL) {
  247                 device_printf(bus, "failed allocating agent register block for "
  248                     "core %u\n", BCMA_DINFO_COREIDX(dinfo));
  249                 return (ENXIO);
  250         }
  251 
  252         return (0);
  253 }
  254 
  255 /**
  256  * Populate the list of interrupts for a device info structure
  257  * previously initialized via bcma_dinfo_alloc_agent().
  258  * 
  259  * If an agent0.0 region is not mapped on @p dinfo, the OOB interrupt bank is
  260  * assumed to be unavailable and 0 is returned.
  261  * 
  262  * @param bus The requesting bus device.
  263  * @param dinfo The device info instance to be initialized.
  264  */
  265 static int
  266 bcma_dinfo_init_intrs(device_t bus, device_t child,
  267     struct bcma_devinfo *dinfo)
  268 {
  269         uint32_t dmpcfg, oobw;
  270 
  271         /* Agent block must be mapped */
  272         if (dinfo->res_agent == NULL)
  273                 return (0);
  274 
  275         /* Agent must support OOB */
  276         dmpcfg = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_CONFIG);
  277         if (!BCMA_DMP_GET_FLAG(dmpcfg, BCMA_DMP_CFG_OOB))
  278                 return (0);
  279 
  280         /* Fetch width of the OOB interrupt bank */
  281         oobw = bhnd_bus_read_4(dinfo->res_agent,
  282              BCMA_DMP_OOB_OUTWIDTH(BCMA_OOB_BANK_INTR));
  283         if (oobw >= BCMA_OOB_NUM_SEL) {
  284                 device_printf(bus, "ignoring invalid OOBOUTWIDTH for core %u: "
  285                     "%#x\n", BCMA_DINFO_COREIDX(dinfo), oobw);
  286                 return (0);
  287         }
  288 
  289         /* Fetch OOBSEL busline values and populate list of interrupt
  290          * descriptors */
  291         for (uint32_t sel = 0; sel < oobw; sel++) {
  292                 struct bcma_intr        *intr;
  293                 uint32_t                 selout;
  294                 uint8_t                  line;
  295 
  296                 if (dinfo->num_intrs == UINT_MAX)
  297                         return (ENOMEM);
  298 
  299                 selout = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_OOBSELOUT(
  300                     BCMA_OOB_BANK_INTR, sel));
  301 
  302                 line = (selout >> BCMA_DMP_OOBSEL_SHIFT(sel)) &
  303                     BCMA_DMP_OOBSEL_BUSLINE_MASK;
  304 
  305                 intr = bcma_alloc_intr(BCMA_OOB_BANK_INTR, sel, line);
  306                 if (intr == NULL) {
  307                         device_printf(bus, "failed allocating interrupt "
  308                             "descriptor %#x for core %u\n", sel,
  309                             BCMA_DINFO_COREIDX(dinfo));
  310                         return (ENOMEM);
  311                 }
  312 
  313                 STAILQ_INSERT_HEAD(&dinfo->intrs, intr, i_link);
  314                 dinfo->num_intrs++;
  315         }
  316 
  317         return (0);
  318 }
  319 
  320 /**
  321  * Allocate and return a new empty device info structure.
  322  * 
  323  * @param bus The requesting bus device.
  324  * 
  325  * @retval NULL if allocation failed.
  326  */
  327 struct bcma_devinfo *
  328 bcma_alloc_dinfo(device_t bus)
  329 {
  330         struct bcma_devinfo *dinfo;
  331 
  332         dinfo = malloc(sizeof(struct bcma_devinfo), M_BHND, M_NOWAIT|M_ZERO);
  333         if (dinfo == NULL)
  334                 return (NULL);
  335 
  336         dinfo->corecfg = NULL;
  337         dinfo->res_agent = NULL;
  338         dinfo->rid_agent = -1;
  339 
  340         STAILQ_INIT(&dinfo->intrs);
  341         dinfo->num_intrs = 0;
  342 
  343         resource_list_init(&dinfo->resources);
  344 
  345         return (dinfo);
  346 }
  347 
  348 /**
  349  * Initialize a device info structure previously allocated via
  350  * bcma_alloc_dinfo, assuming ownership of the provided core
  351  * configuration.
  352  * 
  353  * @param bus The requesting bus device.
  354  * @param child The bcma child device.
  355  * @param dinfo The device info associated with @p child
  356  * @param corecfg Device core configuration; ownership of this value
  357  * will be assumed by @p dinfo.
  358  * 
  359  * @retval 0 success
  360  * @retval non-zero initialization failed.
  361  */
  362 int
  363 bcma_init_dinfo(device_t bus, device_t child, struct bcma_devinfo *dinfo,
  364     struct bcma_corecfg *corecfg)
  365 {
  366         struct bcma_intr        *intr;
  367         int                      error;
  368 
  369         KASSERT(dinfo->corecfg == NULL, ("dinfo previously initialized"));
  370 
  371         /* Save core configuration value */
  372         dinfo->corecfg = corecfg;
  373 
  374         /* The device ports must always be initialized first to ensure that
  375          * rid 0 maps to the first device port */
  376         bcma_dinfo_init_port_resource_info(bus, dinfo, &corecfg->dev_ports);
  377         bcma_dinfo_init_port_resource_info(bus, dinfo, &corecfg->bridge_ports);
  378         bcma_dinfo_init_port_resource_info(bus, dinfo, &corecfg->wrapper_ports);
  379 
  380         /* Now that we've defined the port resources, we can map the device's
  381          * agent registers (if any) */
  382         if ((error = bcma_dinfo_init_agent(bus, child, dinfo)))
  383                 goto failed;
  384 
  385         /* With agent registers mapped, we can populate the device's interrupt
  386          * descriptors */
  387         if ((error = bcma_dinfo_init_intrs(bus, child, dinfo)))
  388                 goto failed;
  389 
  390         /* Finally, map the interrupt descriptors */
  391         STAILQ_FOREACH(intr, &dinfo->intrs, i_link) {
  392                 /* Already mapped? */
  393                 if (intr->i_mapped)
  394                         continue;
  395 
  396                 /* Map the interrupt */
  397                 error = BHND_BUS_MAP_INTR(bus, child, intr->i_sel,
  398                     &intr->i_irq);
  399                 if (error) {
  400                         device_printf(bus, "failed mapping interrupt line %u "
  401                             "for core %u: %d\n", intr->i_sel,
  402                             BCMA_DINFO_COREIDX(dinfo), error);
  403                         goto failed;
  404                 }
  405 
  406                 intr->i_mapped = true;
  407 
  408                 /* Add to resource list */
  409                 intr->i_rid = resource_list_add_next(&dinfo->resources,
  410                     SYS_RES_IRQ, intr->i_irq, intr->i_irq, 1);
  411         }
  412 
  413         return (0);
  414 
  415 failed:
  416         /* Owned by the caller on failure */
  417         dinfo->corecfg = NULL;
  418 
  419         return (error);
  420 }
  421 
  422 /**
  423  * Deallocate the given device info structure and any associated resources.
  424  * 
  425  * @param bus The requesting bus device.
  426  * @param dinfo Device info to be deallocated.
  427  */
  428 void
  429 bcma_free_dinfo(device_t bus, device_t child, struct bcma_devinfo *dinfo)
  430 {
  431         struct bcma_intr *intr, *inext;
  432 
  433         resource_list_free(&dinfo->resources);
  434 
  435         if (dinfo->corecfg != NULL)
  436                 bcma_free_corecfg(dinfo->corecfg);
  437 
  438         /* Release agent resource, if any */
  439         if (dinfo->res_agent != NULL) {
  440                 bhnd_release_resource(bus, SYS_RES_MEMORY, dinfo->rid_agent,
  441                     dinfo->res_agent);
  442         }
  443 
  444         /* Clean up interrupt descriptors */
  445         STAILQ_FOREACH_SAFE(intr, &dinfo->intrs, i_link, inext) {
  446                 STAILQ_REMOVE(&dinfo->intrs, intr, bcma_intr, i_link);
  447 
  448                 /* Release our IRQ mapping */
  449                 if (intr->i_mapped) {
  450                         BHND_BUS_UNMAP_INTR(bus, child, intr->i_irq);
  451                         intr->i_mapped = false;
  452                 }
  453 
  454                 bcma_free_intr(intr);
  455         }
  456 
  457         free(dinfo, M_BHND);
  458 }
  459 
  460 /**
  461  * Allocate and initialize a new interrupt descriptor.
  462  * 
  463  * @param bank OOB bank.
  464  * @param sel OOB selector.
  465  * @param line OOB bus line.
  466  */
  467 struct bcma_intr *
  468 bcma_alloc_intr(uint8_t bank, uint8_t sel, uint8_t line)
  469 {
  470         struct bcma_intr *intr;
  471 
  472         if (bank >= BCMA_OOB_NUM_BANKS)
  473                 return (NULL);
  474 
  475         if (sel >= BCMA_OOB_NUM_SEL)
  476                 return (NULL);
  477 
  478         if (line >= BCMA_OOB_NUM_BUSLINES)
  479                 return (NULL);
  480 
  481         intr = malloc(sizeof(*intr), M_BHND, M_NOWAIT);
  482         if (intr == NULL)
  483                 return (NULL);
  484 
  485         intr->i_bank = bank;
  486         intr->i_sel = sel;
  487         intr->i_busline = line;
  488         intr->i_mapped = false;
  489         intr->i_irq = 0;
  490 
  491         return (intr);
  492 }
  493 
  494 /**
  495  * Deallocate all resources associated with the given interrupt descriptor.
  496  * 
  497  * @param intr Interrupt descriptor to be deallocated.
  498  */
  499 void
  500 bcma_free_intr(struct bcma_intr *intr)
  501 {
  502         KASSERT(!intr->i_mapped, ("interrupt %u still mapped", intr->i_sel));
  503 
  504         free(intr, M_BHND);
  505 }
  506 
  507 /**
  508  * Allocate and initialize new slave port descriptor.
  509  * 
  510  * @param port_num Per-core port number.
  511  * @param port_type Port type.
  512  */
  513 struct bcma_sport *
  514 bcma_alloc_sport(bcma_pid_t port_num, bhnd_port_type port_type)
  515 {
  516         struct bcma_sport *sport;
  517 
  518         sport = malloc(sizeof(struct bcma_sport), M_BHND, M_NOWAIT);
  519         if (sport == NULL)
  520                 return NULL;
  521 
  522         sport->sp_num = port_num;
  523         sport->sp_type = port_type;
  524         sport->sp_num_maps = 0;
  525         STAILQ_INIT(&sport->sp_maps);
  526 
  527         return sport;
  528 }
  529 
  530 /**
  531  * Deallocate all resources associated with the given port descriptor.
  532  * 
  533  * @param sport Port descriptor to be deallocated.
  534  */
  535 void
  536 bcma_free_sport(struct bcma_sport *sport) {
  537         struct bcma_map *map, *mapnext;
  538 
  539         STAILQ_FOREACH_SAFE(map, &sport->sp_maps, m_link, mapnext) {
  540                 free(map, M_BHND);
  541         }
  542 
  543         free(sport, M_BHND);
  544 }
  545 
  546 /**
  547  * Given a bcma(4) child's device info, spin waiting for the device's DMP
  548  * resetstatus register to clear.
  549  * 
  550  * @param child The bcma(4) child device.
  551  * @param dinfo The @p child device info.
  552  * 
  553  * @retval 0 success
  554  * @retval ENODEV if @p dinfo does not map an agent register resource.
  555  * @retval ETIMEDOUT if timeout occurs
  556  */
  557 int
  558 bcma_dmp_wait_reset(device_t child, struct bcma_devinfo *dinfo)
  559 {
  560         uint32_t rst;
  561 
  562         if (dinfo->res_agent == NULL)
  563                 return (ENODEV);
  564 
  565         /* 300us should be long enough, but there are references to this
  566          * requiring up to 10ms when performing reset of an 80211 core
  567          * after a MAC PSM microcode watchdog event. */
  568         for (int i = 0; i < 10000; i += 10) {
  569                 rst = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_RESETSTATUS);
  570                 if (rst == 0)
  571                         return (0);
  572 
  573                 DELAY(10);
  574         }
  575 
  576         device_printf(child, "BCMA_DMP_RESETSTATUS timeout\n");
  577         return (ETIMEDOUT);
  578 }
  579 
  580 /**
  581  * Set the bcma(4) child's DMP resetctrl register value, and then wait
  582  * for all backplane operations to complete.
  583  * 
  584  * @param child The bcma(4) child device.
  585  * @param dinfo The @p child device info.
  586  * @param value The new ioctrl value to set.
  587  * 
  588  * @retval 0 success
  589  * @retval ENODEV if @p dinfo does not map an agent register resource.
  590  * @retval ETIMEDOUT if timeout occurs waiting for reset completion
  591  */
  592 int
  593 bcma_dmp_write_reset(device_t child, struct bcma_devinfo *dinfo, uint32_t value)
  594 {
  595         uint32_t rst;
  596 
  597         if (dinfo->res_agent == NULL)
  598                 return (ENODEV);
  599 
  600         /* Already in requested reset state? */
  601         rst = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_RESETCTRL);
  602         if (rst == value)
  603                 return (0);
  604 
  605         bhnd_bus_write_4(dinfo->res_agent, BCMA_DMP_RESETCTRL, value);
  606         bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_RESETCTRL); /* read-back */
  607         DELAY(10);
  608 
  609         return (bcma_dmp_wait_reset(child, dinfo));
  610 }

Cache object: ffa14b3592ac9e5f778a01b22969f693


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