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/arch/powerpc/pci/pci_machdep_ofw.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 /* $NetBSD: pci_machdep_ofw.c,v 1.22 2017/06/01 02:45:07 chs Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2007 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Tim Rightnour
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Generic OFW routines for pci_machdep
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __KERNEL_RCSID(0, "$NetBSD: pci_machdep_ofw.c,v 1.22 2017/06/01 02:45:07 chs Exp $");
   38 
   39 #include <sys/types.h>
   40 #include <sys/param.h>
   41 #include <sys/time.h>
   42 #include <sys/systm.h>
   43 #include <sys/errno.h>
   44 #include <sys/device.h>
   45 #include <sys/kmem.h>
   46 #include <sys/bus.h>
   47 #include <sys/intr.h>
   48 
   49 #include <uvm/uvm_extern.h>
   50 
   51 #include <machine/autoconf.h>
   52 #include <machine/pio.h>
   53 
   54 #include <dev/pci/pcivar.h>
   55 #include <dev/pci/pcireg.h>
   56 #include <dev/pci/ppbreg.h>
   57 #include <dev/pci/pcidevs.h>
   58 #include <dev/pci/pciconf.h>
   59 
   60 #include <dev/ofw/openfirm.h>
   61 #include <dev/ofw/ofw_pci.h>
   62 
   63 pcitag_t genppc_pci_indirect_make_tag(void *, int, int, int);
   64 void genppc_pci_indirect_decompose_tag(void *, pcitag_t, int *, int *, int *);
   65 
   66 ofw_pic_node_t picnodes[8];
   67 int nrofpics = 0;
   68 
   69 int
   70 genofw_find_picnode(int node)
   71 {
   72         int i;
   73 
   74         for (i = 0; i < 8; i++)
   75                 if (node == picnodes[i].node)
   76                         return i;
   77         return -1;
   78 }
   79 
   80 void
   81 genofw_find_ofpics(int startnode)
   82 {
   83         int node, iparent, child, iranges[6], irgot=0, i;
   84         uint32_t reg[12];
   85         char name[32];
   86 
   87         for (node = startnode; node; node = OF_peer(node)) {
   88                 if ((child = OF_child(node)) != 0)
   89                         genofw_find_ofpics(child);
   90                 memset(name, 0, sizeof(name));
   91                 if (OF_getprop(node, "name", name, sizeof(name)) == -1)
   92                         continue;
   93                 if (strncmp(name, "interrupt-controller", 20) == 0)
   94                         goto foundic;
   95 
   96                 if (OF_getprop(node, "interrupt-controller", name,
   97                     sizeof(name)) > -1)
   98                         goto foundic;
   99 
  100                 if (OF_getprop(node, "device_type", name, sizeof(name)) == -1)
  101                         continue;
  102                 if (strncmp(name, "interrupt-controller", 20) == 0)
  103                         goto foundic;
  104 
  105                 /* if we didn't find one, skip to the next */
  106                 continue;
  107 foundic:
  108                 picnodes[nrofpics].node = node;
  109                 if (OF_getprop(node, "interrupt-parent", &iparent,
  110                     sizeof(iparent)) == sizeof(iparent))
  111                         picnodes[nrofpics].parent = iparent;
  112                 if (OF_getprop(node, "#interrupt-cells", &iparent,
  113                     sizeof(iparent)) == sizeof(iparent))
  114                         picnodes[nrofpics].cells = iparent;
  115                 else
  116                         picnodes[nrofpics].cells = 1;
  117 
  118                 picnodes[nrofpics].intrs = 0;
  119                 irgot = OF_getprop(node, "interrupt-ranges", iranges,
  120                     sizeof(int)*6); /* XXX is this ok? */
  121                 if (irgot >= sizeof(int)) {
  122                         for (i=0; i < irgot/4; i++)
  123                                 if (!picnodes[nrofpics].intrs)
  124                                         picnodes[nrofpics].intrs = iranges[i];
  125                 }
  126 
  127                 irgot = OF_getprop(node, "reg", reg, sizeof(reg));
  128 
  129                 if (!picnodes[nrofpics].intrs)
  130                         picnodes[nrofpics].intrs = 16;
  131 
  132                 if (nrofpics > 0)
  133                         picnodes[nrofpics].offset = picnodes[nrofpics-1].offset
  134                             + picnodes[nrofpics-1].intrs;
  135                 else
  136                         picnodes[nrofpics].offset = 0;
  137                 OF_getprop(node, "device_type", name, sizeof(name));
  138                 if (strcmp(name, "open-pic") == 0)
  139                         picnodes[nrofpics].type = PICNODE_TYPE_OPENPIC;
  140                 if (strcmp(name, "interrupt-controller") == 0) {
  141                         OF_getprop(node, "compatible", name, sizeof(name));
  142                         if (strcmp(name, "heathrow") == 0)
  143                                 picnodes[nrofpics].type = PICNODE_TYPE_HEATHROW;
  144                         if (strcmp(name, "pnpPNP,0") == 0)
  145                                 picnodes[nrofpics].type = PICNODE_TYPE_8259;
  146                         if (strcmp(name, "chrp,iic") == 0) {
  147                                 picnodes[nrofpics].type = PICNODE_TYPE_8259;
  148                                 if (irgot >= 9 * sizeof(uint32_t) &&
  149                                     reg[7] == 0x4d0)
  150                                         picnodes[nrofpics].type =
  151                                             PICNODE_TYPE_IVR;
  152                         }
  153                 }
  154                 if (strlen(name) == 0) {
  155                         /* probably a Pegasos, assume 8259 */
  156                         picnodes[nrofpics].type = PICNODE_TYPE_8259;
  157                 }
  158                 nrofpics++;
  159         }
  160 }
  161 
  162 /* Fix up the various picnode offsets */
  163 void
  164 genofw_fixup_picnode_offsets(void)
  165 {
  166         int i, curoff;
  167 
  168         curoff=0;
  169 
  170         for (i=0; i < nrofpics; i++) {
  171                 if (picnodes[i].type == PICNODE_TYPE_8259 ||
  172                     picnodes[i].type == PICNODE_TYPE_IVR) {
  173                         picnodes[i].offset = 0;
  174                         curoff = picnodes[i].intrs;
  175                 }
  176         }
  177         for (i=0; i < nrofpics; i++) {
  178                 /* now skip the 8259 */
  179                 if (picnodes[i].type == PICNODE_TYPE_8259)
  180                         continue;
  181                 if (picnodes[i].type == PICNODE_TYPE_IVR)
  182                         continue;
  183 
  184                 picnodes[i].offset = curoff;
  185                 curoff += picnodes[i].intrs;
  186         }
  187 }
  188 
  189 /* we are given a pci devnode, and dig from there */
  190 void
  191 genofw_setup_pciintr_map(void *v, struct genppc_pci_chipset_businfo *pbi,
  192     int pcinode)
  193 {
  194         int node;
  195         u_int32_t map[160];
  196         int parent, len;
  197         int curdev, foundirqs=0;
  198         int i, reclen, nrofpcidevs=0;
  199         u_int32_t acells, icells, pcells;
  200         prop_dictionary_t dict;
  201         prop_dictionary_t sub=0;
  202         pci_chipset_tag_t pc = (pci_chipset_tag_t)v;
  203 
  204         len = OF_getprop(pcinode, "interrupt-map", map, sizeof(map));
  205         if (len == -1)
  206                 goto nomap;
  207 
  208         if (OF_getprop(pcinode, "#address-cells", &acells,
  209             sizeof(acells)) == -1)
  210                 acells = 1;
  211         if (OF_getprop(pcinode, "#interrupt-cells", &icells,
  212             sizeof(icells)) == -1)
  213                 icells = 1;
  214 
  215         parent = map[acells+icells];
  216         if (OF_getprop(parent, "#interrupt-cells", &pcells,
  217             sizeof(pcells)) == -1)
  218                 pcells = 1;
  219 
  220         reclen = acells+pcells+icells+1;
  221         nrofpcidevs = len / (reclen * sizeof(int));
  222 
  223         dict = prop_dictionary_create_with_capacity(nrofpcidevs*2);
  224         KASSERT(dict != NULL);
  225 
  226         curdev = -1;
  227         prop_dictionary_set(pbi->pbi_properties, "ofw-pci-intrmap", dict);
  228         for (i = 0; i < nrofpcidevs; i++) {
  229                 prop_number_t intr_num;
  230                 int dev, pin, pic, func;
  231                 char key[20];
  232 
  233                 pic = genofw_find_picnode(map[i*reclen + acells + icells]);
  234                 KASSERT(pic != -1);
  235                 dev = (map[i*reclen] >> 8) / 0x8;
  236                 func = (map[i*reclen] >> 8) % 0x8;
  237                 if (curdev != dev)
  238                         sub = prop_dictionary_create_with_capacity(4);
  239                 pin = map[i*reclen + acells];
  240                 intr_num = prop_number_create_integer(map[i*reclen + acells + icells + 1] + picnodes[pic].offset);
  241                 snprintf(key, sizeof(key), "pin-%c", 'A' + (pin-1));
  242                 prop_dictionary_set(sub, key, intr_num);
  243                 prop_object_release(intr_num);
  244                 /* should we care about level? */
  245 
  246                 snprintf(key, sizeof(key), "devfunc-%d", dev*0x8 + func);
  247                 prop_dictionary_set(dict, key, sub);
  248                 if (curdev != dev) {
  249                         prop_object_release(sub);
  250                         curdev = dev;
  251                 }
  252         }
  253         /* the mapping is complete */
  254         prop_object_release(dict);
  255         aprint_debug("%s\n", prop_dictionary_externalize(pbi->pbi_properties));
  256         return;
  257 
  258 nomap:
  259         /* so, we have one of those annoying machines that doesn't provide
  260          * a nice simple map of interrupts.  We get to do this the hard
  261          * way instead.  Lucky us.
  262          */
  263         for (node = OF_child(pcinode), nrofpcidevs=0; node;
  264             node = OF_peer(node))
  265                 nrofpcidevs++;
  266         dict = prop_dictionary_create_with_capacity(nrofpcidevs*2);
  267         KASSERT(dict != NULL);
  268         prop_dictionary_set(pbi->pbi_properties, "ofw-pci-intrmap", dict);
  269 
  270         for (node = OF_child(pcinode); node; node = OF_peer(node)) {
  271                 uint32_t irqs[4], reg[5];
  272                 prop_number_t intr_num;
  273                 int dev, pin, func;
  274                 char key[20];
  275 
  276                 /* walk the bus looking for pci devices and map them */
  277                 if (OF_getprop(node, "AAPL,interrupts", irqs, 4) > 0) {
  278                         dev = 0;
  279                         if (OF_getprop(node, "reg", reg, 5) > 0) {
  280                                 dev = ((reg[0] & 0x0000ff00) >> 8) / 0x8;
  281                                 func = ((reg[0] & 0x0000ff00) >> 8) % 0x8;
  282                         } else if (OF_getprop(node, "assigned-addresses",
  283                                        reg, 5) > 0) {
  284                                 dev = ((reg[0] & 0x0000ff00) >> 8) / 0x8;
  285                                 func = ((reg[0] & 0x0000ff00) >> 8) % 0x8;
  286                         }
  287                         if (dev == 0) {
  288                                 aprint_error("cannot figure out device num "
  289                                     "for node 0x%x\n", node);
  290                                 continue;
  291                         }
  292                         sub = prop_dictionary_create_with_capacity(4);
  293                         if (OF_getprop(node, "interrupts", &pin, 4) < 0)
  294                                 pin = 1;
  295                         intr_num = prop_number_create_integer(irqs[0]);
  296                         snprintf(key, sizeof(key), "pin-%c", 'A' + (pin-1));
  297                         prop_dictionary_set(sub, key, intr_num);
  298                         prop_object_release(intr_num);
  299                         snprintf(key, sizeof(key), "devfunc-%d", dev*0x8 + func);
  300                         prop_dictionary_set(dict, key, sub);
  301                         prop_object_release(sub);
  302                         foundirqs++;
  303                 }
  304         }
  305         if (foundirqs)
  306                 return;
  307 
  308         /*
  309          * If we got this far, we have a super-annoying OFW.
  310          * They didn't bother to fill in any interrupt properties anywhere,
  311          * so we pray that they filled in the ones on the pci devices.
  312          */
  313         for (node = OF_child(pcinode); node; node = OF_peer(node)) {
  314                 uint32_t reg[5], irq;
  315                 prop_number_t intr_num;
  316                 pcitag_t tag;
  317                 int dev, pin, func;
  318                 char key[20];
  319 
  320                 if (OF_getprop(node, "reg", reg, 5) > 0) {
  321                         dev = ((reg[0] & 0x0000ff00) >> 8) / 0x8;
  322                         func = ((reg[0] & 0x0000ff00) >> 8) % 0x8;
  323 
  324                         tag = pci_make_tag(pc, pc->pc_bus, dev, func);
  325                         irq = PCI_INTERRUPT_LINE(pci_conf_read(pc, tag,
  326                             PCI_INTERRUPT_REG));
  327                         if (irq == 255)
  328                                 irq = 0;
  329 
  330                         sub = prop_dictionary_create_with_capacity(4);
  331                         if (OF_getprop(node, "interrupts", &pin, 4) < 0)
  332                                 pin = 1;
  333                         intr_num = prop_number_create_integer(irq);
  334                         snprintf(key, sizeof(key), "pin-%c", 'A' + (pin-1));
  335                         prop_dictionary_set(sub, key, intr_num);
  336                         prop_object_release(intr_num);
  337                         snprintf(key, sizeof(key), "devfunc-%d", dev*0x8 + func);
  338                         prop_dictionary_set(dict, key, sub);
  339                         prop_object_release(sub);
  340                 }
  341         }
  342         aprint_debug("%s\n", prop_dictionary_externalize(pbi->pbi_properties));
  343 }
  344 
  345 int
  346 genofw_find_node_by_devfunc(int startnode, int bus, int dev, int func)
  347 {
  348         int node, sz, p=0;
  349         uint32_t reg;
  350 
  351         for (node = startnode; node; node = p) {
  352                 sz = OF_getprop(node, "reg", &reg, sizeof(reg));
  353                 if (sz != sizeof(reg))
  354                         continue;
  355                 if (OFW_PCI_PHYS_HI_BUS(reg) == bus &&
  356                     OFW_PCI_PHYS_HI_DEVICE(reg) == dev &&
  357                     OFW_PCI_PHYS_HI_FUNCTION(reg) == func)
  358                         return node;
  359                 if ((p = OF_child(node)))
  360                         continue;
  361                 while (node) {
  362                         if ((p = OF_peer(node)))
  363                                 break;
  364                         node = OF_parent(node);
  365                 }
  366         }
  367         /* couldn't find it */
  368         return -1;
  369 }
  370 
  371 int
  372 genofw_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
  373 {
  374         struct genppc_pci_chipset_businfo *pbi;
  375         prop_dictionary_t dict, devsub;
  376         prop_object_t pinsub;
  377         prop_number_t pbus;
  378         int busno, pin, line, dev, origdev, func, i;
  379         char key[20];
  380 
  381         pin = pa->pa_intrpin;
  382         line = pa->pa_intrline;
  383         busno = pa->pa_bus;
  384         origdev = dev = pa->pa_device;
  385         func = pa->pa_function;
  386         i = 0;
  387 
  388         pbi = SIMPLEQ_FIRST(&pa->pa_pc->pc_pbi);
  389         while (busno--)
  390                 pbi = SIMPLEQ_NEXT(pbi, next);
  391         KASSERT(pbi != NULL);
  392 
  393         dict = prop_dictionary_get(pbi->pbi_properties, "ofw-pci-intrmap");
  394 
  395         if (dict != NULL)
  396                 i = prop_dictionary_count(dict);
  397 
  398         if (dict == NULL || i == 0) {
  399                 /* We have an unmapped bus, now it gets hard */
  400                 pbus = prop_dictionary_get(pbi->pbi_properties,
  401                     "ofw-pcibus-parent");
  402                 if (pbus == NULL)
  403                         goto bad;
  404                 busno = prop_number_integer_value(pbus);
  405                 pbus = prop_dictionary_get(pbi->pbi_properties,
  406                     "ofw-pcibus-rawdevnum");
  407                 dev = prop_number_integer_value(pbus);
  408 
  409                 /* now that we know the parent bus, we need to find its pbi */
  410                 pbi = SIMPLEQ_FIRST(&pa->pa_pc->pc_pbi);
  411                 while (busno--)
  412                         pbi = SIMPLEQ_NEXT(pbi, next);
  413                 KASSERT(pbi != NULL);
  414 
  415                 /* swizzle the pin */
  416                 pin = ((pin + origdev - 1) & 3) + 1;
  417 
  418                 /* now we have the pbi, ask for dict again */
  419                 dict = prop_dictionary_get(pbi->pbi_properties,
  420                     "ofw-pci-intrmap");
  421                 if (dict == NULL)
  422                         goto bad;
  423         }
  424 
  425         /* No IRQ used. */
  426         if (pin == 0)
  427                 goto bad;
  428         if (pin > 4) {
  429                 aprint_error("pci_intr_map: bad interrupt pin %d\n", pin);
  430                 goto bad;
  431         }
  432 
  433         snprintf(key, sizeof(key), "devfunc-%d", dev*0x8 + func);
  434         devsub = prop_dictionary_get(dict, key);
  435         if (devsub == NULL)
  436                 goto bad;
  437         snprintf(key, sizeof(key), "pin-%c", 'A' + (pin-1));
  438         pinsub = prop_dictionary_get(devsub, key);
  439         if (pinsub == NULL)
  440                 goto bad;
  441         line = prop_number_integer_value(pinsub);
  442 
  443         if (line == 0 || line == 255) {
  444                 aprint_error("pci_intr_map: no mapping for pin %c\n",'@' + pin);
  445                 goto bad;
  446         }
  447 
  448         *ihp = line;
  449         return 0;
  450 
  451 bad:
  452         *ihp = -1;
  453         return 1;
  454 }
  455 
  456 int
  457 genofw_pci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id)
  458 {
  459         pci_chipset_tag_t pct = v;
  460         struct genppc_pci_chipset_businfo *pbi;
  461         prop_number_t pbus;
  462         pcitag_t tag;
  463         pcireg_t class;
  464         int node;
  465 
  466         /* We have already mapped MPIC's if we have them, so leave them alone */
  467         if (PCI_VENDOR(id) == PCI_VENDOR_IBM &&
  468             PCI_PRODUCT(id) == PCI_PRODUCT_IBM_MPIC2)
  469                 return 0;
  470 
  471         if (PCI_VENDOR(id) == PCI_VENDOR_IBM &&
  472             PCI_PRODUCT(id) == PCI_PRODUCT_IBM_MPIC)
  473                 return 0;
  474 
  475         /* I highly doubt there are any CHRP ravens, but just in case */
  476         if (PCI_VENDOR(id) == PCI_VENDOR_MOT &&
  477             PCI_PRODUCT(id) == PCI_PRODUCT_MOT_RAVEN)
  478                 return (PCI_CONF_ALL & ~PCI_CONF_MAP_MEM);
  479 
  480         /*
  481          * Pegasos2 specific stuff.
  482          */
  483         if (strncmp(model_name, "Pegasos2", 8) == 0) {
  484 
  485                 /* never reconfigure the MV64361 host bridge */
  486                 if (PCI_VENDOR(id) == PCI_VENDOR_MARVELL &&
  487                     PCI_PRODUCT(id) == PCI_PRODUCT_MARVELL_MV64360)
  488                         return 0;
  489 
  490                 /* we want to leave viaide(4) alone */
  491                 if (PCI_VENDOR(id) == PCI_VENDOR_VIATECH &&
  492                     PCI_PRODUCT(id) == PCI_PRODUCT_VIATECH_VT82C586A_IDE)
  493                         return 0;
  494 
  495                 /* leave the audio IO alone */
  496                 if (PCI_VENDOR(id) == PCI_VENDOR_VIATECH &&
  497                     PCI_PRODUCT(id) == PCI_PRODUCT_VIATECH_VT82C686A_AC97)
  498                         return (PCI_CONF_ALL & ~PCI_CONF_MAP_IO);
  499 
  500         }
  501 
  502         tag = pci_make_tag(pct, bus, dev, func);
  503         class = pci_conf_read(pct, tag, PCI_CLASS_REG);
  504 
  505         /* leave video cards alone */
  506         if (PCI_CLASS(class) == PCI_CLASS_DISPLAY)
  507                 return 0;
  508 
  509         /* NOTE, all device specific stuff must be above this line */
  510         /* don't do this on the primary host bridge */
  511         if (bus == 0 && dev == 0 && func == 0)
  512                 return PCI_CONF_DEFAULT;
  513 
  514         /*
  515          * PCI bridges have special needs.  We need to discover where they
  516          * came from, and wire them appropriately.
  517          */
  518         if (PCI_CLASS(class) == PCI_CLASS_BRIDGE &&
  519             PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_PCI) {
  520                 pbi = kmem_alloc(sizeof(*pbi), KM_SLEEP);
  521                 pbi->pbi_properties = prop_dictionary_create();
  522                 KASSERT(pbi->pbi_properties != NULL);
  523                 node = genofw_find_node_by_devfunc(pct->pc_node, bus, dev,
  524                     func);
  525                 if (node == -1) {
  526                         aprint_error("Cannot find node for device "
  527                             "bus %d dev %d func %d\n", bus, dev, func);
  528                         prop_object_release(pbi->pbi_properties);
  529                         kmem_free(pbi, sizeof(*pbi));
  530                         return (PCI_CONF_DEFAULT);
  531                 }
  532                 genofw_setup_pciintr_map((void *)pct, pbi, node);
  533 
  534                 /* record the parent bus, and the parent device number */
  535                 pbus = prop_number_create_integer(bus);
  536                 prop_dictionary_set(pbi->pbi_properties, "ofw-pcibus-parent",
  537                     pbus);
  538                 prop_object_release(pbus);
  539                 pbus = prop_number_create_integer(dev);
  540                 prop_dictionary_set(pbi->pbi_properties, "ofw-pcibus-rawdevnum",
  541                     pbus);
  542                 prop_object_release(pbus);
  543 
  544                 SIMPLEQ_INSERT_TAIL(&pct->pc_pbi, pbi, next);
  545         }
  546 
  547         return (PCI_CONF_DEFAULT);
  548 }

Cache object: a1bcb98986c29c4caf0ad6ee872263b1


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